Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Linux Kernel Patch v2.4, patch-2.4.0-test9 (000/112)

13 views
Skip to first unread message

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part000

lines added deleted
linux/CREDITS : 25 3 2
linux/Documentation/Configure.help : 357 175 37
linux/Documentation/DocBook/Makefile : 22 4 3
linux/Documentation/DocBook/kernel-api.tmpl : 19 5 1
linux/Documentation/DocBook/videobook.tmpl : 8 1 1
linux/Documentation/SubmittingDrivers : 112 112 0
linux/Documentation/arm/README : 36 30 0
linux/Documentation/cciss.txt : 47 47 0
linux/Documentation/cpqarray.txt : 7 1 0
linux/Documentation/fb/sa1100fb.txt : 39 39 0
linux/Documentation/filesystems/ext2.txt : 224 224 0
linux/Documentation/filesystems/proc.txt : 11 0 5
linux/Documentation/kbuild/00-INDEX : 5 2 0
linux/Documentation/kbuild/makefiles.txt : 1226 1226 0
linux/Documentation/mkdev.cciss : 40 40 0
linux/Documentation/networking/8139too.txt : 90 31 16
linux/Documentation/networking/cs89x0.txt : 1354 688 666
linux/Documentation/networking/sk98lin.txt : 25 9 3
linux/Documentation/networking/tuntap.txt : 69 18 25
linux/Documentation/networking/vortex.txt : 11 3 2
linux/Documentation/oops-tracing.txt : 9 2 1
linux/Documentation/pci.txt : 11 5 0
linux/Documentation/sound/AD1816 : 82 9 52
linux/Documentation/sound/ESS : 13 4 3
linux/Documentation/sound/ESS1868 : 65 9 38
linux/Documentation/sound/INSTALL.awe : 13 1 4
linux/Documentation/sound/Introduction : 70 14 9
linux/Documentation/sound/NEWS : 42 42 0
linux/Documentation/sound/PSS-updates : 88 88 0
linux/Documentation/usb/CREDITS : 26 6 0
linux/Documentation/usb/URB.txt : 111 36 9
linux/Documentation/usb/error-codes.txt : 22 9 0
linux/Documentation/usb/ov511.txt : 88 27 19
linux/MAINTAINERS : 98 41 2
linux/Makefile : 37 5 4
linux/README : 9 2 1
linux/Rules.make : 9 3 0
linux/arch/alpha/Makefile : 19 5 1
linux/arch/alpha/boot/Makefile : 8 1 1
linux/arch/alpha/config.in : 8 2 0
linux/arch/alpha/kernel/pci_iommu.c : 9 2 0
linux/arch/alpha/kernel/smp.c : 33 6 6
linux/arch/alpha/kernel/time.c : 77 6 40
linux/arch/alpha/math-emu/Makefile : 8 1 1
linux/arch/alpha/math-emu/math.c : 66 0 60
linux/arch/alpha/math-emu/qrnnd.S : 163 163 0
linux/arch/alpha/math-emu/sfp-util.h : 24 6 11
linux/arch/alpha/mm/extable.c : 8 1 1
linux/arch/alpha/mm/fault.c : 8 1 1
linux/arch/arm/Makefile : 86 17 39
linux/arch/arm/boot/Makefile : 13 7 0
linux/arch/arm/boot/bootp/bootp.lds : 12 9 0
linux/arch/arm/boot/bootp/init.S : 16 10 2
linux/arch/arm/boot/compressed/Makefile : 10 4 0
linux/arch/arm/boot/compressed/head-netwinder.S : 12 9 0
linux/arch/arm/boot/compressed/head.S : 13 6 2
linux/arch/arm/boot/compressed/ll_char_wr.S : 21 9 5
linux/arch/arm/boot/compressed/setup-sa1100.S : 12 0 6
linux/arch/arm/boot/compressed/vmlinux.lds.in : 12 9 0
linux/arch/arm/config.in : 249 83 40
linux/arch/arm/def-configs/assabet : 425 159 134
linux/arch/arm/def-configs/brutus : 257 93 60
linux/arch/arm/def-configs/cerf : 423 423 0
linux/arch/arm/def-configs/clps7500 : 490 490 0
linux/arch/arm/def-configs/lart : 522 231 146
linux/arch/arm/def-configs/shark : 655 655 0
linux/arch/arm/kernel/Makefile : 47 15 10
linux/arch/arm/kernel/arch.c : 503 29 394
linux/arch/arm/kernel/arch.h : 74 0 74
linux/arch/arm/kernel/armksyms.c : 36 9 17
linux/arch/arm/kernel/arthur.c : 15 9 1
linux/arch/arm/kernel/bios32.c : 12 3 3
linux/arch/arm/kernel/calls.S : 16 7 3
linux/arch/arm/kernel/debug-armo.S : 16 7 3
linux/arch/arm/kernel/debug-armv.S : 74 42 6
linux/arch/arm/kernel/dec21285.c : 27 7 4
linux/arch/arm/kernel/dma-arc.c : 95 18 13
linux/arch/arm/kernel/dma-footbridge.c : 34 7 10
linux/arch/arm/kernel/dma-isa.c : 121 49 33
linux/arch/arm/kernel/dma-rpc.c : 138 34 27
linux/arch/arm/kernel/dma.c : 62 15 8
linux/arch/arm/kernel/dma.h : 48 0 48
linux/arch/arm/kernel/ecard.c : 60 17 19
linux/arch/arm/kernel/entry-armo.S : 43 18 14
linux/arch/arm/kernel/entry-armv.S : 87 41 11
linux/arch/arm/kernel/entry-common.S : 12 9 0
linux/arch/arm/kernel/ftv-pci.c : 51 51 0
linux/arch/arm/kernel/head-armo.S : 16 7 3
linux/arch/arm/kernel/head-armv.S : 127 41 21
linux/arch/arm/kernel/hw-footbridge.c : 692 0 692
linux/arch/arm/kernel/hw-sa1100.c : 184 0 184
linux/arch/arm/kernel/init_task.c : 10 4 0
linux/arch/arm/kernel/irq.c : 28 12 10
linux/arch/arm/kernel/isa.c : 19 10 3
linux/arch/arm/kernel/leds-ebsa110.c : 56 23 8
linux/arch/arm/kernel/leds-footbridge.c : 257 0 257
linux/arch/arm/kernel/leds-ftvpci.c : 31 31 0
linux/arch/arm/kernel/leds-sa1100.c : 437 0 437
linux/arch/arm/kernel/oldlatches.c : 17 10 3
linux/arch/arm/kernel/plx90x0.c : 198 198 0
linux/arch/arm/kernel/process.c : 25 6 2
linux/arch/arm/kernel/ptrace.c : 19 11 5
linux/arch/arm/kernel/ptrace.h : 12 9 0
linux/arch/arm/kernel/semaphore.c : 19 8 4
linux/arch/arm/kernel/setup.c : 46 8 4
linux/arch/arm/kernel/signal.c : 12 4 1
linux/arch/arm/kernel/sys_arm.c : 25 11 8
linux/arch/arm/kernel/time-acorn.c : 32 11 7
linux/arch/arm/kernel/time.c : 90 22 38
linux/arch/arm/kernel/traps.c : 29 9 7
linux/arch/arm/kernel/via82c505.c : 186 186 0
linux/arch/arm/lib/Makefile : 7 1 0
linux/arch/arm/lib/backtrace.S : 13 6 2
linux/arch/arm/lib/changebit.S : 15 6 3
linux/arch/arm/lib/clearbit.S : 15 6 3
linux/arch/arm/lib/copy_page.S : 16 6 3
linux/arch/arm/lib/csumipv6.S : 13 6 2
linux/arch/arm/lib/csumpartial.S : 13 6 2
linux/arch/arm/lib/csumpartialcopy.S : 13 6 2
linux/arch/arm/lib/csumpartialcopyuser.S : 26 12 2
linux/arch/arm/lib/delay.S : 13 6 2
linux/arch/arm/lib/findbit.S : 15 6 3
linux/arch/arm/lib/floppydma.S : 13 6 2
linux/arch/arm/lib/getconsdata.c : 13 6 2
linux/arch/arm/lib/io-acorn.S : 13 6 2
linux/arch/arm/lib/io-ebsa110.S : 13 6 2
linux/arch/arm/lib/io-shark.c : 17 6 2
linux/arch/arm/lib/memchr.S : 16 7 3
linux/arch/arm/lib/memcpy.S : 16 7 3
linux/arch/arm/lib/memset.S : 16 7 3
linux/arch/arm/lib/memzero.S : 13 6 2
linux/arch/arm/lib/setbit.S : 15 6 3
linux/arch/arm/lib/strchr.S : 16 7 3
linux/arch/arm/lib/strncpy_from_user.S : 13 6 2
linux/arch/arm/lib/strnlen_user.S : 13 6 2
linux/arch/arm/lib/strrchr.S : 16 7 3
linux/arch/arm/lib/testchangebit.S : 15 6 3
linux/arch/arm/lib/testclearbit.S : 15 6 3
linux/arch/arm/lib/testsetbit.S : 15 6 3
linux/arch/arm/lib/uaccess-armo.S : 18 8 4
linux/arch/arm/lib/uaccess.S : 20 9 5
linux/arch/arm/mach-footbridge/Makefile : 27 6 6
linux/arch/arm/mach-footbridge/arch.c : 8 1 1
linux/arch/arm/mach-footbridge/ebsa285-leds.c : 13 5 2
linux/arch/arm/mach-footbridge/netwinder-leds.c : 13 6 2
linux/arch/arm/mach-sa1100/Makefile : 34 34 0
linux/arch/arm/mach-sa1100/arch.c : 291 291 0
linux/arch/arm/mach-sa1100/hw.c : 188 188 0
linux/arch/arm/mach-sa1100/leds.c : 429 429 0
linux/arch/arm/mach-shark/Makefile : 32 32 0
linux/arch/arm/mach-shark/arch.c : 31 31 0
linux/arch/arm/mach-shark/dma.c : 25 25 0
linux/arch/arm/mach-shark/mm.c : 30 30 0
linux/arch/arm/mach-shark/pci.c : 27 27 0
linux/arch/arm/mm/Makefile : 83 43 22
linux/arch/arm/mm/consistent.c : 62 20 8
linux/arch/arm/mm/extable.c : 6 1 1
linux/arch/arm/mm/fault-armo.c : 12 4 1
linux/arch/arm/mm/fault-armv.c : 25 9 2
linux/arch/arm/mm/fault-common.c : 37 7 3
linux/arch/arm/mm/init.c : 65 19 5
linux/arch/arm/mm/ioremap.c : 6 1 1
linux/arch/arm/mm/map.h : 25 0 25
linux/arch/arm/mm/mm-armo.c : 46 14 5
linux/arch/arm/mm/mm-armv.c : 126 36 23
linux/arch/arm/mm/mm-clps7500.c : 40 12 11
linux/arch/arm/mm/mm-ebsa110.c : 38 15 9
linux/arch/arm/mm/mm-footbridge.c : 153 62 48
linux/arch/arm/mm/mm-l7200.c : 35 10 9
linux/arch/arm/mm/mm-nexuspci.c : 44 14 13
linux/arch/arm/mm/mm-rpc.c : 44 17 14
linux/arch/arm/mm/mm-sa1100.c : 289 97 111
linux/arch/arm/mm/mm-shark.c : 25 0 25
linux/arch/arm/mm/mm-tbox.c : 71 13 44
linux/arch/arm/mm/proc-arm2,3.S : 20 10 4
linux/arch/arm/mm/proc-arm6,7.S : 254 87 62
linux/arch/arm/mm/proc-arm720.S : 293 100 60
linux/arch/arm/mm/proc-arm920.S : 602 602 0
linux/arch/arm/mm/proc-sa110.S : 1321 670 558
linux/arch/arm/mm/proc-syms.c : 31 31 0
linux/arch/arm/mm/small_page.c : 93 17 11
linux/arch/i386/config.in : 16 3 0
linux/arch/i386/defconfig : 185 77 12
linux/arch/i386/kernel/Makefile : 8 1 1
linux/arch/i386/kernel/acpi.c : 141 35 25
linux/arch/i386/kernel/apic.c : 8 1 1
linux/arch/i386/kernel/bluesmoke.c : 109 109 0
linux/arch/i386/kernel/entry.S : 19 6 0
linux/arch/i386/kernel/io_apic.c : 53 10 9
linux/arch/i386/kernel/mpparse.c : 30 5 5
linux/arch/i386/kernel/mtrr.c : 159 45 16
linux/arch/i386/kernel/process.c : 33 6 6
linux/arch/i386/kernel/ptrace.c : 10 0 4
linux/arch/i386/kernel/setup.c : 85 15 14
linux/arch/i386/kernel/signal.c : 13 7 0
linux/arch/i386/kernel/smp.c : 34 5 4
linux/arch/i386/kernel/smpboot.c : 86 12 12
linux/arch/i386/kernel/time.c : 62 4 35
linux/arch/i386/kernel/traps.c : 113 35 18
linux/arch/i386/kernel/vm86.c : 10 2 2
linux/arch/i386/mm/ioremap.c : 8 1 1
linux/arch/ia64/config.in : 7 1 0
linux/arch/ia64/kernel/efi.c : 37 0 31
linux/arch/m68k/config.in : 8 2 0
linux/arch/m68k/kernel/time.c : 37 0 31
linux/arch/m68k/mac/misc.c : 45 1 31
linux/arch/mips/baget/vacserial.c : 8 1 1
linux/arch/mips/config.in : 8 2 0
linux/arch/mips/dec/time.c : 37 0 31
linux/arch/mips/kernel/gdb-stub.c : 8 1 1
linux/arch/mips/kernel/time.c : 37 0 31
linux/arch/mips/sgi/kernel/indy_timer.c : 37 0 31
linux/arch/mips64/config.in : 8 2 0
linux/arch/mips64/sgi-ip22/ip22-timer.c : 37 0 31
linux/arch/mips64/sgi-ip27/ip27-timer.c : 37 0 31
linux/arch/ppc/8260_io/Config.in : 21 9 6
linux/arch/ppc/8260_io/Makefile : 10 2 2
linux/arch/ppc/8260_io/commproc.c : 57 27 7
linux/arch/ppc/8260_io/enet.c : 62 12 9
linux/arch/ppc/8260_io/fcc_enet.c : 1601 1601 0
linux/arch/ppc/8260_io/uart.c : 66 11 12
linux/arch/ppc/8xx_io/enet.c : 26 7 4
linux/arch/ppc/8xx_io/fec.c : 24 6 3
linux/arch/ppc/amiga/time.c : 49 0 36
linux/arch/ppc/chrpboot/Makefile : 15 4 2
linux/arch/ppc/chrpboot/addnote.c : 32 12 1
linux/arch/ppc/coffboot/Makefile : 8 1 1
linux/arch/ppc/coffboot/chrpmain.c : 124 52 13
linux/arch/ppc/config.in : 97 42 16
linux/arch/ppc/configs/common_defconfig : 520 146 61
linux/arch/ppc/configs/est8260_defconfig : 188 43 27
linux/arch/ppc/configs/gemini_defconfig : 244 40 53
linux/arch/ppc/configs/rpxcllf_defconfig : 188 46 22
linux/arch/ppc/defconfig : 519 150 60
linux/arch/ppc/kernel/Makefile : 12 4 2
linux/arch/ppc/kernel/apus_setup.c : 36 7 9
linux/arch/ppc/kernel/chrp_pci.c : 149 68 27
linux/arch/ppc/kernel/chrp_setup.c : 205 85 59
linux/arch/ppc/kernel/chrp_time.c : 107 28 22
linux/arch/ppc/kernel/entry.S : 91 35 14
linux/arch/ppc/kernel/feature.c : 290 146 29
linux/arch/ppc/kernel/gemini_setup.c : 24 3 1
linux/arch/ppc/kernel/hashtable.S : 19 6 0
linux/arch/ppc/kernel/head.S : 408 113 67
linux/arch/ppc/kernel/head_8xx.S : 73 45 0
linux/arch/ppc/kernel/idle.c : 7 1 0
linux/arch/ppc/kernel/irq.c : 41 16 12
linux/arch/ppc/kernel/m8260_setup.c : 37 17 6
linux/arch/ppc/kernel/m8xx_setup.c : 84 32 28
linux/arch/ppc/kernel/misc.S : 169 72 31
linux/arch/ppc/kernel/mol.h : 68 68 0
linux/arch/ppc/kernel/oak_setup.c : 12 2 1
linux/arch/ppc/kernel/open_pic.c : 25 6 6
linux/arch/ppc/kernel/pci.c : 510 276 151
linux/arch/ppc/kernel/pmac_backlight.c : 33 8 10
linux/arch/ppc/kernel/pmac_nvram.c : 43 8 6
linux/arch/ppc/kernel/pmac_pci.c : 73 21 11
linux/arch/ppc/kernel/pmac_pic.c : 19 2 7
linux/arch/ppc/kernel/pmac_setup.c : 155 41 42
linux/arch/ppc/kernel/pmac_time.c : 164 37 28
linux/arch/ppc/kernel/ppc-stub.c : 12 3 3
linux/arch/ppc/kernel/ppc_ksyms.c : 97 34 10
linux/arch/ppc/kernel/prep_setup.c : 176 67 40
linux/arch/ppc/kernel/prep_time.c : 82 18 28
linux/arch/ppc/kernel/process.c : 69 10 14
linux/arch/ppc/kernel/prom.c : 370 149 81
linux/arch/ppc/kernel/setup.c : 48 11 3
linux/arch/ppc/kernel/signal.c : 73 3 8
linux/arch/ppc/kernel/smp.c : 454 238 103
linux/arch/ppc/kernel/syscalls.c : 94 12 12
linux/arch/ppc/kernel/time.c : 435 210 147
linux/arch/ppc/kernel/traps.c : 171 111 33
linux/arch/ppc/kernel/walnut_setup.c : 12 2 1
linux/arch/ppc/kernel/xics.c : 8 1 1
linux/arch/ppc/lib/string.S : 329 174 73
linux/arch/ppc/mbxboot/misc.c : 11 5 0
linux/arch/ppc/mm/extable.c : 77 40 8
linux/arch/ppc/mm/fault.c : 17 3 1
linux/arch/ppc/mm/init.c : 651 161 159
linux/arch/ppc/xmon/start.c : 127 46 20
linux/arch/ppc/xmon/xmon.c : 342 165 15
linux/arch/sh/boot/compressed/Makefile : 8 1 1
linux/arch/sh/config.in : 8 2 0
linux/arch/sh/kernel/entry.S : 395 144 92
linux/arch/sh/kernel/head.S : 10 1 1
linux/arch/sh/kernel/io.c : 6 1 1
linux/arch/sh/kernel/irq_imask.c : 27 4 3
linux/arch/sh/kernel/irq_ipr.c : 14 2 0
linux/arch/sh/kernel/process.c : 35 10 9
linux/arch/sh/kernel/setup_cqreek.c : 136 45 19
linux/arch/sh/kernel/sh_bios.c : 22 6 6
linux/arch/sh/kernel/sh_ksyms.c : 43 29 0
linux/arch/sh/kernel/time.c : 47 2 32
linux/arch/sh/kernel/traps.c : 19 10 3
linux/arch/sh/lib/checksum.S : 27 5 5
linux/arch/sh/mm/cache.c : 182 108 16
linux/arch/sh/mm/fault.c : 270 105 74
linux/arch/sh/mm/init.c : 7 1 0
linux/arch/sh/vmlinux.lds.S : 19 3 2
linux/arch/sparc/config.in : 16 1 9
linux/arch/sparc/kernel/pcic.c : 33 1 8
linux/arch/sparc/kernel/sparc-stub.c : 8 1 1
linux/arch/sparc/kernel/time.c : 43 1 32
linux/arch/sparc64/boot/piggyback.c : 17 3 3
linux/arch/sparc64/config.in : 16 1 9
linux/arch/sparc64/kernel/auxio.c : 16 2 1
linux/arch/sparc64/kernel/central.c : 25 4 4
linux/arch/sparc64/kernel/entry.S : 16 3 3
linux/arch/sparc64/kernel/irq.c : 57 2 10
linux/arch/sparc64/kernel/pci.c : 23 0 3
linux/arch/sparc64/kernel/pci_psycho.c : 22 2 3
linux/arch/sparc64/kernel/sbus.c : 33 6 10
linux/arch/sparc64/kernel/setup.c : 23 5 1
linux/arch/sparc64/kernel/starfire.c : 88 28 8
linux/arch/sparc64/kernel/sys_sparc32.c : 39 5 3
linux/arch/sparc64/kernel/time.c : 94 23 33
linux/arch/sparc64/lib/rwlock.S : 75 16 32
linux/arch/sparc64/mm/fault.c : 14 2 2
linux/arch/sparc64/mm/init.c : 44 4 9
linux/drivers/Makefile : 257 52 198
linux/drivers/acorn/block/fd1772.c : 8 1 1
linux/drivers/acorn/block/mfmhd.c : 8 1 1
linux/drivers/acorn/char/Makefile : 21 2 6
linux/drivers/acorn/char/defkeymap-acorn.c : 15 6 3
linux/drivers/acorn/char/i2c.c : 28 9 5
linux/drivers/acorn/char/keyb_arc.c : 50 13 11
linux/drivers/acorn/char/keyb_ps2.c : 51 11 11
linux/drivers/acorn/char/mouse_rpc.c : 31 11 7
linux/drivers/acorn/char/pcf8583.c : 18 7 4
linux/drivers/acorn/char/pcf8583.h : 12 9 0
linux/drivers/acorn/char/serial-atomwide.c : 24 10 7
linux/drivers/acorn/char/serial-card.c : 13 6 2
linux/drivers/acorn/char/serial-dualsp.c : 18 8 4
linux/drivers/acorn/net/ether1.c : 276 117 125
linux/drivers/acorn/net/ether1.h : 16 7 3
linux/drivers/acorn/net/ether3.c : 12 7 1
linux/drivers/acorn/net/ether3.h : 15 8 2
linux/drivers/acorn/net/etherh.c : 29 8 4
linux/drivers/acorn/scsi/acornscsi-io.S : 11 7 1
linux/drivers/acorn/scsi/acornscsi.c : 32 7 3
linux/drivers/acorn/scsi/acornscsi.h : 15 8 2
linux/drivers/acorn/scsi/arxescsi.c : 7 0 1
linux/drivers/acorn/scsi/cumana_2.c : 111 36 44
linux/drivers/acorn/scsi/cumana_2.h : 24 9 3
linux/drivers/acorn/scsi/eesox.c : 112 35 42
linux/drivers/acorn/scsi/eesox.h : 24 9 3
linux/drivers/acorn/scsi/fas216.c : 39 8 5
linux/drivers/acorn/scsi/fas216.h : 15 8 2
linux/drivers/acorn/scsi/msgqueue.c : 17 8 3
linux/drivers/acorn/scsi/msgqueue.h : 15 8 2
linux/drivers/acorn/scsi/powertec.c : 93 25 32
linux/drivers/acorn/scsi/powertec.h : 24 9 3
linux/drivers/acorn/scsi/queue.c : 541 137 267
linux/drivers/acorn/scsi/queue.h : 93 22 32
linux/drivers/acpi/Makefile : 34 13 4
linux/drivers/acpi/common/Makefile : 28 28 0
linux/drivers/acpi/common/cmalloc.c : 59 12 11
linux/drivers/acpi/common/cmclib.c : 821 821 0
linux/drivers/acpi/common/cmcopy.c : 227 26 45
linux/drivers/acpi/common/cmdebug.c : 303 63 74
linux/drivers/acpi/common/cmdelete.c : 143 22 29
linux/drivers/acpi/common/cmeval.c : 141 21 21
linux/drivers/acpi/common/cmglobal.c : 205 89 49
linux/drivers/acpi/common/cminit.c : 58 11 10
linux/drivers/acpi/common/cmobject.c : 350 55 58
linux/drivers/acpi/common/cmutils.c : 490 75 96
linux/drivers/acpi/common/cmxface.c : 75 14 16
linux/drivers/acpi/cpu.c : 88 27 10
linux/drivers/acpi/dispatcher/Makefile : 28 28 0
linux/drivers/acpi/dispatcher/dsfield.c : 310 71 59
linux/drivers/acpi/dispatcher/dsmethod.c : 491 125 137
linux/drivers/acpi/dispatcher/dsmthdat.c : 534 92 89
linux/drivers/acpi/dispatcher/dsobject.c : 397 83 74
linux/drivers/acpi/dispatcher/dsopcode.c : 367 117 65
linux/drivers/acpi/dispatcher/dsutils.c : 448 118 92
linux/drivers/acpi/dispatcher/dswexec.c : 234 61 31
linux/drivers/acpi/dispatcher/dswload.c : 562 172 108
linux/drivers/acpi/dispatcher/dswscope.c : 63 10 10
linux/drivers/acpi/dispatcher/dswstate.c : 223 30 27
linux/drivers/acpi/driver.c : 9 3 0
linux/drivers/acpi/ec.c : 200 61 59
linux/drivers/acpi/events/Makefile : 28 28 0
linux/drivers/acpi/events/evevent.c : 157 26 20
linux/drivers/acpi/events/evmisc.c : 64 11 10
linux/drivers/acpi/events/evregion.c : 460 151 71
linux/drivers/acpi/events/evrgnini.c : 380 75 85
linux/drivers/acpi/events/evsci.c : 148 33 35
linux/drivers/acpi/events/evxface.c : 185 34 33
linux/drivers/acpi/events/evxfevnt.c : 155 66 16
linux/drivers/acpi/events/evxfregn.c : 200 35 40
linux/drivers/acpi/hardware/Makefile : 28 28 0
linux/drivers/acpi/hardware/hwacpi.c : 31 4 4
linux/drivers/acpi/hardware/hwcpu32.c : 153 20 19
linux/drivers/acpi/hardware/hwgpe.c : 24 5 4
linux/drivers/acpi/hardware/hwregs.c : 236 76 53
linux/drivers/acpi/hardware/hwxface.c : 271 60 46
linux/drivers/acpi/include/accommon.h : 661 661 0
linux/drivers/acpi/include/acconfig.h : 186 186 0
linux/drivers/acpi/include/acdebug.h : 396 396 0
linux/drivers/acpi/include/acdispat.h : 401 401 0
linux/drivers/acpi/include/acenv.h : 268 121 49
linux/drivers/acpi/include/acevents.h : 210 210 0
linux/drivers/acpi/include/acexcep.h : 277 148 91
linux/drivers/acpi/include/acglobal.h : 320 320 0
linux/drivers/acpi/include/achware.h : 169 169 0
linux/drivers/acpi/include/acinterp.h : 526 526 0
linux/drivers/acpi/include/aclocal.h : 851 851 0
linux/drivers/acpi/include/acmacros.h : 435 435 0
linux/drivers/acpi/include/acnamesp.h : 393 393 0
linux/drivers/acpi/include/acobject.h : 546 118 219
linux/drivers/acpi/include/acoutput.h : 124 124 0
linux/drivers/acpi/include/acparser.h : 345 345 0
linux/drivers/acpi/include/acpi.h : 37 9 9
linux/drivers/acpi/include/acpiosxf.h : 41 5 5
linux/drivers/acpi/include/acpixf.h : 8 1 1
linux/drivers/acpi/include/acresrc.h : 304 304 0
linux/drivers/acpi/include/actables.h : 267 97 120
linux/drivers/acpi/include/actbl.h : 190 190 0
linux/drivers/acpi/include/actbl32.h : 16 2 1
linux/drivers/acpi/include/actbl64.h : 51 7 7
linux/drivers/acpi/include/actypes.h : 351 75 74
linux/drivers/acpi/include/amlcode.h : 160 24 43
linux/drivers/acpi/include/common.h : 650 0 650
linux/drivers/acpi/include/config.h : 185 0 185
linux/drivers/acpi/include/debugger.h : 394 0 394
linux/drivers/acpi/include/dispatch.h : 384 0 383
linux/drivers/acpi/include/events.h : 209 0 209
linux/drivers/acpi/include/globals.h : 311 0 311
linux/drivers/acpi/include/hardware.h : 169 0 169
linux/drivers/acpi/include/internal.h : 850 0 850
linux/drivers/acpi/include/interp.h : 660 0 660
linux/drivers/acpi/include/macros.h : 423 0 423
linux/drivers/acpi/include/namesp.h : 424 0 424
linux/drivers/acpi/include/output.h : 124 0 124
linux/drivers/acpi/include/parser.h : 327 0 327
linux/drivers/acpi/include/resource.h : 300 0 300
linux/drivers/acpi/include/tables.h : 168 0 168
linux/drivers/acpi/interpreter/Makefile : 28 28 0
linux/drivers/acpi/interpreter/amconfig.c : 152 29 33
linux/drivers/acpi/interpreter/amcreate.c : 463 97 98
linux/drivers/acpi/interpreter/amdump.c : 41 41 0
linux/drivers/acpi/interpreter/amdyadic.c : 282 51 62
linux/drivers/acpi/interpreter/amfield.c : 178 21 85
linux/drivers/acpi/interpreter/amfldio.c : 216 47 28
linux/drivers/acpi/interpreter/ammisc.c : 161 31 36
linux/drivers/acpi/interpreter/ammonad.c : 413 88 69
linux/drivers/acpi/interpreter/amnames.c : 191 24 69
linux/drivers/acpi/interpreter/amprep.c : 225 40 39
linux/drivers/acpi/interpreter/amregion.c : 143 28 18
linux/drivers/acpi/interpreter/amresnte.c : 396 84 109
linux/drivers/acpi/interpreter/amresolv.c : 199 43 35
linux/drivers/acpi/interpreter/amresop.c : 200 40 28
linux/drivers/acpi/interpreter/amstore.c : 151 26 22
linux/drivers/acpi/interpreter/amstoren.c : 200 49 40
linux/drivers/acpi/interpreter/amstorob.c : 73 15 13
linux/drivers/acpi/interpreter/amsystem.c : 75 13 12
linux/drivers/acpi/interpreter/amutils.c : 225 31 66
linux/drivers/acpi/interpreter/amxface.c : 56 10 9
linux/drivers/acpi/namespace/Makefile : 28 28 0
linux/drivers/acpi/namespace/nsaccess.c : 636 115 207
linux/drivers/acpi/namespace/nsalloc.c : 729 351 192
linux/drivers/acpi/namespace/nsdump.c : 36 36 0
linux/drivers/acpi/namespace/nseval.c : 502 105 103
linux/drivers/acpi/namespace/nsload.c : 295 72 87
linux/drivers/acpi/namespace/nsnames.c : 526 54 337
linux/drivers/acpi/namespace/nsobject.c : 468 52 243
linux/drivers/acpi/namespace/nssearch.c : 736 134 432
linux/drivers/acpi/namespace/nsutils.c : 750 100 356
linux/drivers/acpi/namespace/nswalk.c : 246 54 59
linux/drivers/acpi/namespace/nsxfname.c : 273 50 61
linux/drivers/acpi/namespace/nsxfobj.c : 339 56 64
linux/drivers/acpi/os.c : 72 11 8
linux/drivers/acpi/parser/Makefile : 28 28 0
linux/drivers/acpi/parser/psargs.c : 315 117 53
linux/drivers/acpi/parser/psfind.c : 319 319 0
linux/drivers/acpi/parser/psopcode.c : 531 217 165
linux/drivers/acpi/parser/psparse.c : 1058 603 143
linux/drivers/acpi/parser/psscope.c : 233 52 63
linux/drivers/acpi/parser/pstree.c : 260 45 44
linux/drivers/acpi/parser/psutils.c : 340 112 59
linux/drivers/acpi/parser/pswalk.c : 198 47 36
linux/drivers/acpi/parser/psxface.c : 120 48 25
linux/drivers/acpi/resources/Makefile : 28 28 0
linux/drivers/acpi/resources/rsaddr.c : 148 29 24
linux/drivers/acpi/resources/rscalc.c : 372 148 35
linux/drivers/acpi/resources/rscreate.c : 445 64 171
linux/drivers/acpi/resources/rsdump.c : 43 5 4
linux/drivers/acpi/resources/rsio.c : 61 7 6
linux/drivers/acpi/resources/rsirq.c : 67 9 9
linux/drivers/acpi/resources/rslist.c : 81 13 11
linux/drivers/acpi/resources/rsmemory.c : 61 7 6
linux/drivers/acpi/resources/rsmisc.c : 52 6 5
linux/drivers/acpi/resources/rsutils.c : 221 29 70
linux/drivers/acpi/resources/rsxface.c : 181 66 18
linux/drivers/acpi/sys.c : 9 3 0
linux/drivers/acpi/table.c : 306 306 0
linux/drivers/acpi/tables/Makefile : 28 28 0
linux/drivers/acpi/tables/tbget.c : 90 18 13
linux/drivers/acpi/tables/tbinstal.c : 208 54 63
linux/drivers/acpi/tables/tbtable.c : 172 31 27
linux/drivers/acpi/tables/tbutils.c : 133 21 20
linux/drivers/acpi/tables/tbxface.c : 135 21 19
linux/drivers/acpi/tables.c : 303 0 303
linux/drivers/block/Config.in : 26 1 14
linux/drivers/block/Makefile : 33 2 13
linux/drivers/block/amiflop.c : 45 6 6
linux/drivers/block/cciss.c : 1917 1917 0
linux/drivers/block/cciss.h : 201 201 0
linux/drivers/block/cciss_cmd.h : 254 254 0
linux/drivers/block/cpqarray.c : 241 55 36
linux/drivers/block/cpqarray.h : 16 4 3
linux/drivers/block/floppy.c : 158 20 20
linux/drivers/block/genhd.c : 17 0 4
linux/drivers/block/ida_ioctl.h : 23 8 1
linux/drivers/block/linear.c : 213 0 213
linux/drivers/block/ll_rw_blk.c : 18 2 3
linux/drivers/block/loop.c : 16 2 1
linux/drivers/block/lvm-snap.c : 434 0 434
linux/drivers/block/lvm.c : 2569 0 2569
linux/drivers/block/md.c : 3867 0 3867
linux/drivers/block/paride/paride.h : 12 4 0
linux/drivers/block/raid0.c : 356 0 356
linux/drivers/block/raid1.c : 1897 0 1897
linux/drivers/block/raid5.c : 2371 0 2371
linux/drivers/block/swim3.c : 21 8 0
linux/drivers/block/xd.c : 25 5 5
linux/drivers/block/xor.c : 2728 0 2728
linux/drivers/cdrom/cdrom.c : 18 3 1
linux/drivers/cdrom/mcd.c : 17 2 2
linux/drivers/cdrom/sonycd535.c : 39 6 6
linux/drivers/char/Config.in : 35 4 4
linux/drivers/char/Makefile : 60 20 11
linux/drivers/char/acquirewdt.c : 37 11 15
linux/drivers/char/drm/dma.c : 11 1 1
linux/drivers/char/drm/drm.h : 21 6 1
linux/drivers/char/drm/drmP.h : 110 76 0
linux/drivers/char/drm/gamma_dma.c : 28 3 4
linux/drivers/char/drm/gamma_drv.c : 212 26 26
linux/drivers/char/drm/i810_dma.c : 69 7 9
linux/drivers/char/drm/i810_drv.c : 235 29 29
linux/drivers/char/drm/lists.c : 89 1 19
linux/drivers/char/drm/lock.c : 47 1 7
linux/drivers/char/drm/mga_bufs.c : 123 5 30
linux/drivers/char/drm/mga_context.c : 36 3 6
linux/drivers/char/drm/mga_dma.c : 992 157 240
linux/drivers/char/drm/mga_drm.h : 47 16 11
linux/drivers/char/drm/mga_drv.c : 355 59 55
linux/drivers/char/drm/mga_drv.h : 243 99 32
linux/drivers/char/drm/mga_state.c : 664 97 157
linux/drivers/char/drm/r128_dma.c : 31 1 23
linux/drivers/char/drm/r128_drv.c : 42 4 4
linux/drivers/char/drm/r128_drv.h : 22 3 3
linux/drivers/char/drm/tdfx_drv.c : 252 30 30
linux/drivers/char/drm/vm.c : 8 0 2
linux/drivers/char/efirtc.c : 8 1 1
linux/drivers/char/ftape/lowlevel/ftape-calibr.c : 8 1 1
linux/drivers/char/hp600_keyb.c : 8 1 1
linux/drivers/char/i810-tco.c : 11 1 2
linux/drivers/char/i810_rng.c : 441 117 91
linux/drivers/char/joystick/pcigame.c : 9 1 1
linux/drivers/char/lp.c : 16 5 4
linux/drivers/char/mem.c : 92 19 38
linux/drivers/char/misc.c : 45 4 14
linux/drivers/char/mixcomwd.c : 50 12 11
linux/drivers/char/nvram.c : 42 20 5
linux/drivers/char/nwflash.c : 187 36 25
linux/drivers/char/pcwd.c : 30 5 8
linux/drivers/char/ppdev.c : 51 16 10
linux/drivers/char/qpmouse.c : 15 6 1
linux/drivers/char/raw.c : 14 4 4
linux/drivers/char/rtc.c : 8 1 1
linux/drivers/char/sbc60xxwdt.c : 5 1 1
linux/drivers/char/serial.c : 31 7 3
linux/drivers/char/serial_amba.c : 2030 2030 0
linux/drivers/char/sh-sci.c : 219 128 12
linux/drivers/char/sh-sci.h : 118 53 8
linux/drivers/char/softdog.c : 49 18 13
linux/drivers/char/toshiba.c : 522 522 0
linux/drivers/char/tty_io.c : 9 3 0
linux/drivers/char/wdt.c : 117 54 21
linux/drivers/char/wdt285.c : 18 2 3
linux/drivers/char/wdt977.c : 7 1 0
linux/drivers/char/wdt_pci.c : 98 35 13
linux/drivers/i2c/i2c-algo-bit.c : 12 3 3
linux/drivers/i2c/i2c-core.c : 8 1 1
linux/drivers/i2o/i2o_proc.c : 40 7 8
linux/drivers/ide/icside.c : 102 4 71
linux/drivers/ide/ide-pci.c : 38 12 4
linux/drivers/ide/ide-proc.c : 8 1 1
linux/drivers/ide/ide.c : 20 5 2
linux/drivers/ide/via82cxxx.c : 103 18 24
linux/drivers/ieee1394/hosts.c : 45 6 8
linux/drivers/ieee1394/hosts.h : 18 2 2
linux/drivers/ieee1394/ieee1394_core.c : 91 29 17
linux/drivers/ieee1394/ieee1394_core.h : 29 6 3
linux/drivers/ieee1394/ieee1394_syms.c : 32 11 1
linux/drivers/ieee1394/ieee1394_transactions.c : 82 14 43
linux/drivers/ieee1394/ieee1394_types.h : 17 2 2
linux/drivers/ieee1394/ohci1394.c : 400 141 81
linux/drivers/ieee1394/ohci1394.h : 40 13 6
linux/drivers/ieee1394/pcilynx.c : 615 186 118
linux/drivers/ieee1394/pcilynx.h : 56 10 5
linux/drivers/ieee1394/raw1394.c : 243 85 18
linux/drivers/ieee1394/raw1394.h : 28 4 1
linux/drivers/ieee1394/video1394.c : 207 58 8
linux/drivers/ieee1394/video1394.h : 8 1 1
linux/drivers/isdn/avmb1/b1.c : 8 1 1
linux/drivers/isdn/avmb1/b1dma.c : 9 2 1
linux/drivers/isdn/avmb1/c4.c : 9 2 1
linux/drivers/isdn/avmb1/capi.c : 73 10 10
linux/drivers/isdn/avmb1/capidrv.c : 57 9 9
linux/drivers/isdn/avmb1/t1isa.c : 8 1 1
linux/drivers/isdn/eicon/Divas_mod.c : 35 6 8
linux/drivers/isdn/eicon/common.c : 127 33 29
linux/drivers/isdn/eicon/eicon_mod.c : 113 29 16
linux/drivers/isdn/eicon/idi.h : 13 2 2
linux/drivers/isdn/eicon/md5sums.asc : 8 1 1
linux/drivers/isdn/hisax/hfc_pci.c : 15 2 0
linux/drivers/macintosh/Makefile : 123 47 56
linux/drivers/macintosh/adb.c : 15 9 0
linux/drivers/macintosh/adbhid.c : 875 875 0
linux/drivers/macintosh/mac_hid.c : 492 492 0
linux/drivers/macintosh/mac_keyb.c : 108 33 47
linux/drivers/macintosh/macio-adb.c : 8 2 0
linux/drivers/macintosh/macserial.c : 48 8 6
linux/drivers/macintosh/mediabay.c : 33 9 2
linux/drivers/macintosh/nvram.c : 44 26 0
linux/drivers/macintosh/rtc.c : 157 157 0
linux/drivers/macintosh/via-cuda.c : 205 80 42
linux/drivers/macintosh/via-pmu.c : 992 388 175
linux/drivers/md/Config.in : 22 22 0
linux/drivers/md/Makefile : 35 35 0
linux/drivers/md/linear.c : 213 213 0
linux/drivers/md/lvm-snap.c : 436 436 0
linux/drivers/md/lvm.c : 2567 2567 0
linux/drivers/md/md.c : 3878 3878 0
linux/drivers/md/raid0.c : 356 356 0
linux/drivers/md/raid1.c : 1897 1897 0
linux/drivers/md/raid5.c : 2371 2371 0
linux/drivers/md/xor.c : 2728 2728 0
linux/drivers/media/radio/Config.in : 7 1 0
linux/drivers/media/radio/Makefile : 7 1 0
linux/drivers/media/radio/radio-maestro.c : 384 384 0
linux/drivers/media/video/bttv-driver.c : 31 5 3
linux/drivers/media/video/bttv.h : 11 0 5
linux/drivers/media/video/buz.c : 7 1 0
linux/drivers/media/video/cpia_usb.c : 63 17 7
linux/drivers/mtd/cfi_cmdset_0002.c : 8 1 1
linux/drivers/mtd/mapped.c : 7 0 1
linux/drivers/net/3c505.c : 29 6 6
linux/drivers/net/3c507.c : 29 4 2
linux/drivers/net/3c509.c : 57 9 7
linux/drivers/net/3c527.c : 8 1 1
linux/drivers/net/3c59x.c : 150 30 44
linux/drivers/net/8139too.c : 1034 294 232
linux/drivers/net/8390.h : 16 5 5
linux/drivers/net/Config.in : 53 14 15
linux/drivers/net/Makefile : 18 4 1
linux/drivers/net/Space.c : 23 1 9
linux/drivers/net/acenic.c : 174 64 26
linux/drivers/net/acenic.h : 17 2 2
linux/drivers/net/acenic_firmware.h : 20 3 4
linux/drivers/net/aironet4500_core.c : 8 1 1
linux/drivers/net/am79c961a.c : 132 31 22
linux/drivers/net/am79c961a.h : 17 5 0
linux/drivers/net/appletalk/Makefile : 18 5 5
linux/drivers/net/appletalk/ipddp.c : 125 17 46
linux/drivers/net/arcnet/arcnet.c : 9 0 3
linux/drivers/net/arcnet/com20020-isa.c : 8 1 1
linux/drivers/net/arcnet/com20020-pci.c : 17 2 2
linux/drivers/net/atp.c : 1024 399 211
linux/drivers/net/atp.h : 364 128 135
linux/drivers/net/auto_irq.c : 18 5 0
linux/drivers/net/bonding.c : 84 9 28
linux/drivers/net/cs89x0.c : 241 118 36
linux/drivers/net/declance.c : 20 4 3
linux/drivers/net/dummy.c : 85 13 39
linux/drivers/net/eepro100.c : 8 2 0
linux/drivers/net/eexpress.c : 7 1 0
linux/drivers/net/epic100.c : 12 3 3
linux/drivers/net/eql.c : 283 55 81
linux/drivers/net/gmac.c : 389 217 36
linux/drivers/net/gmac.h : 58 29 2
linux/drivers/net/hamachi.c : 1904 1904 0
linux/drivers/net/hamradio/pi2.c : 17 2 2
linux/drivers/net/hamradio/pt.c : 26 3 3
linux/drivers/net/ioc3-eth.c : 8 1 1
linux/drivers/net/irda/toshoboe.c : 7 0 1
linux/drivers/net/lne390.c : 114 25 21
linux/drivers/net/ne2.c : 19 3 3
linux/drivers/net/ne2k-pci.c : 30 6 5
linux/drivers/net/net_init.c : 97 14 22
linux/drivers/net/pcmcia/xircom_tulip_cb.c : 11 1 4
linux/drivers/net/pppox.c : 36 6 7
linux/drivers/net/rrunner.c : 8 1 1
linux/drivers/net/rtl8129.c : 144 34 18
linux/drivers/net/setup.c : 107 6 62
linux/drivers/net/sis900.c : 278 122 32
linux/drivers/net/sis900.h : 35 14 2
linux/drivers/net/sk98lin/h/lm80.h : 20 5 2
linux/drivers/net/sk98lin/h/skaddr.h : 205 53 37
linux/drivers/net/sk98lin/h/skcsum.h : 97 41 11
linux/drivers/net/sk98lin/h/skdebug.h : 20 5 2
linux/drivers/net/sk98lin/h/skdrv1st.h : 39 17 2
linux/drivers/net/sk98lin/h/skerror.h : 20 5 2
linux/drivers/net/sk98lin/h/skgedrv.h : 20 5 2
linux/drivers/net/sk98lin/h/skgehw.h : 68 33 2
linux/drivers/net/sk98lin/h/skgehwt.h : 20 5 2
linux/drivers/net/sk98lin/h/skgei2c.h : 20 5 2
linux/drivers/net/sk98lin/h/skgeinit.h : 135 51 42
linux/drivers/net/sk98lin/h/skgepnm2.h : 87 32 14
linux/drivers/net/sk98lin/h/skgepnmi.h : 137 51 10
linux/drivers/net/sk98lin/h/skgesirq.h : 31 9 2
linux/drivers/net/sk98lin/h/ski2c.h : 36 11 4
linux/drivers/net/sk98lin/h/skqueue.h : 20 5 2
linux/drivers/net/sk98lin/h/skrlmt.h : 20 5 2
linux/drivers/net/sk98lin/h/sktimer.h : 20 5 2
linux/drivers/net/sk98lin/h/sktypes.h : 21 6 2
linux/drivers/net/sk98lin/h/skvpd.h : 257 68 55
linux/drivers/net/sk98lin/h/xmac_ii.h : 34 11 3
linux/drivers/net/sk98lin/skaddr.c : 766 113 198
linux/drivers/net/sk98lin/skcsum.c : 325 99 47
linux/drivers/net/sk98lin/skge.c : 107 42 9
linux/drivers/net/sk98lin/skgehwt.c : 38 6 5
linux/drivers/net/sk98lin/skgeinit.c : 1046 275 174
linux/drivers/net/sk98lin/skgepnmi.c : 512 277 34
linux/drivers/net/sk98lin/skgesirq.c : 243 113 17
linux/drivers/net/sk98lin/ski2c.c : 895 247 182
linux/drivers/net/sk98lin/sklm80.c : 38 6 5
linux/drivers/net/sk98lin/skqueue.c : 38 6 5
linux/drivers/net/sk98lin/skrlmt.c : 39 7 5
linux/drivers/net/sk98lin/sktimer.c : 38 6 5
linux/drivers/net/sk98lin/skvpd.c : 1196 324 309
linux/drivers/net/sk98lin/skxmac2.c : 126 46 7
linux/drivers/net/skfp/skfddi.c : 9 2 1
linux/drivers/net/sundance.c : 1271 1271 0
linux/drivers/net/sunlance.c : 7 1 0
linux/drivers/net/tokenring/tms380tr.c : 7 1 0
linux/drivers/net/tulip/tulip_core.c : 44 6 4
linux/drivers/net/tun.c : 80 13 22
linux/drivers/net/wan/Makefile : 8 2 0
linux/drivers/net/wan/comx-hw-comx.c : 123 33 11
linux/drivers/net/wan/comx-hw-locomx.c : 52 13 3
linux/drivers/net/wan/comx-hw-mixcom.c : 75 20 5
linux/drivers/net/wan/comx-proto-fr.c : 84 22 5
linux/drivers/net/wan/comx-proto-ppp.c : 8 2 0
linux/drivers/net/wan/comx.c : 144 45 15
linux/drivers/net/wan/cosa.c : 28 3 5
linux/drivers/net/wan/sdla.c : 21 6 0
linux/drivers/net/winbond-840.c : 1352 1352 0
linux/drivers/parport/ChangeLog : 8 5 0
linux/drivers/parport/parport_pc.c : 24 5 1
linux/drivers/pci/names.c : 6 2 1
linux/drivers/pci/pci.c : 226 66 116
linux/drivers/pci/pci.ids : 41 9 4
linux/drivers/pci/proc.c : 10 2 2
linux/drivers/pci/quirks.c : 17 2 2
linux/drivers/pcmcia/cardbus.c : 34 6 7
linux/drivers/pcmcia/cs.c : 110 22 17
linux/drivers/pcmcia/yenta.c : 11 5 0
linux/drivers/pnp/isapnp.c : 29 7 7
linux/drivers/s390/Config.in : 17 1 10
linux/drivers/scsi/3w-xxxx.c : 74 17 24
linux/drivers/scsi/3w-xxxx.h : 13 0 2
linux/drivers/scsi/53c7,8xx.c : 9 3 2
linux/drivers/scsi/53c7,8xx.h : 16 0 3
linux/drivers/scsi/53c7xx.c : 9 3 2
linux/drivers/scsi/53c7xx.h : 16 0 3
linux/drivers/scsi/AM53C974.c : 14 3 4
linux/drivers/scsi/BusLogic.c : 80 10 14
linux/drivers/scsi/ChangeLog.ips : 23 16 1
linux/drivers/scsi/Config.in : 68 15 12
linux/drivers/scsi/Makefile : 187 59 57
linux/drivers/scsi/NCR53c406a.c : 13 1 3
linux/drivers/scsi/a2091.c : 18 1 5
linux/drivers/scsi/a2091.h : 24 0 5
linux/drivers/scsi/a3000.c : 18 1 5
linux/drivers/scsi/a3000.h : 24 0 5
linux/drivers/scsi/advansys.c : 11 1 3
linux/drivers/scsi/aha152x.c : 10 1 3
linux/drivers/scsi/aha1542.c : 10 1 3
linux/drivers/scsi/aha1740.c : 13 1 3
linux/drivers/scsi/aic7xxx.c : 13 1 3
linux/drivers/scsi/amiga7xx.h : 14 1 2
linux/drivers/scsi/atari_scsi.c : 9 1 4
linux/drivers/scsi/atari_scsi.h : 27 0 7
linux/drivers/scsi/atp870u.c : 9 1 4
linux/drivers/scsi/blz1230.c : 18 1 5
linux/drivers/scsi/blz2060.c : 18 1 5
linux/drivers/scsi/bvme6000.h : 14 1 2
linux/drivers/scsi/cpqfc.Readme : 216 216 0
linux/drivers/scsi/cpqfcTS.h : 39 39 0
linux/drivers/scsi/cpqfcTSchip.h : 238 238 0
linux/drivers/scsi/cpqfcTScontrol.c : 2200 2200 0
linux/drivers/scsi/cpqfcTSi2c.c : 493 493 0
linux/drivers/scsi/cpqfcTSinit.c : 1815 1815 0
linux/drivers/scsi/cpqfcTSioctl.h : 84 84 0
linux/drivers/scsi/cpqfcTSstructs.h : 1494 1494 0
linux/drivers/scsi/cpqfcTStrigger.c : 30 30 0
linux/drivers/scsi/cpqfcTSworker.c : 6238 6238 0
linux/drivers/scsi/cpqioctl.c : 76 76 0
linux/drivers/scsi/cyberstorm.c : 18 1 5
linux/drivers/scsi/cyberstormII.c : 18 1 4
linux/drivers/scsi/dc390.h : 16 0 4
linux/drivers/scsi/dmx3191d.c : 11 1 5
linux/drivers/scsi/dmx3191d.h : 26 0 4
linux/drivers/scsi/dtc.c : 10 1 4
linux/drivers/scsi/dtc.h : 26 0 7
linux/drivers/scsi/eata.c : 14 2 3
linux/drivers/scsi/eata_dma.c : 12 1 3
linux/drivers/scsi/eata_dma.h : 17 0 4
linux/drivers/scsi/eata_pio.c : 13 1 3
linux/drivers/scsi/esp.c : 11 1 3
linux/drivers/scsi/fastlane.c : 18 1 6
linux/drivers/scsi/fcal.c : 12 1 4
linux/drivers/scsi/fd_mcs.c : 10 1 3
linux/drivers/scsi/fdomain.c : 10 1 3
linux/drivers/scsi/g_NCR5380.c : 15 3 2
linux/drivers/scsi/g_NCR5380.h : 17 0 4
linux/drivers/scsi/gdth.c : 8 1 3
linux/drivers/scsi/gvp11.c : 18 1 5
linux/drivers/scsi/hosts.c : 832 8 763
linux/drivers/scsi/hosts.h : 19 0 6
linux/drivers/scsi/ibmmca.c : 13 1 3
linux/drivers/scsi/ide-scsi.c : 56 8 18
linux/drivers/scsi/imm.c : 11 1 3
linux/drivers/scsi/in2000.c : 12 1 6
linux/drivers/scsi/ini9100u.c : 11 1 3
linux/drivers/scsi/inia100.c : 11 1 3
linux/drivers/scsi/ips.c : 4597 2326 909
linux/drivers/scsi/ips.h : 261 114 22
linux/drivers/scsi/mac53c94.c : 46 22 0
linux/drivers/scsi/mac53c94.h : 15 2 0
linux/drivers/scsi/mac_scsi.c : 10 1 4
linux/drivers/scsi/mca_53c9x.c : 11 1 3
linux/drivers/scsi/megaraid.c : 9 1 3
linux/drivers/scsi/mesh.c : 56 25 0
linux/drivers/scsi/mesh.h : 15 2 0
linux/drivers/scsi/mvme16x.h : 14 1 2
linux/drivers/scsi/ncr53c8xx.c : 8 1 3
linux/drivers/scsi/ncr53c8xx.h : 16 0 4
linux/drivers/scsi/oktagon_esp.c : 18 1 4
linux/drivers/scsi/pas16.c : 14 2 2
linux/drivers/scsi/pas16.h : 16 0 3
linux/drivers/scsi/pci2000.c : 10 1 3
linux/drivers/scsi/pci2220i.c : 19 2 4
linux/drivers/scsi/pluto.c : 12 1 4
linux/drivers/scsi/ppa.c : 11 1 3
linux/drivers/scsi/psi240i.c : 11 1 3
linux/drivers/scsi/qla1280.c : 12 1 3
linux/drivers/scsi/qlogicfas.c : 22 3 4
linux/drivers/scsi/qlogicfc.c : 11 1 5
linux/drivers/scsi/qlogicisp.c : 9 1 3
linux/drivers/scsi/qlogicpti.c : 11 1 3
linux/drivers/scsi/scsi.c : 522 97 218
linux/drivers/scsi/scsi.h : 7 1 0
linux/drivers/scsi/scsi_debug.c : 13 1 3
linux/drivers/scsi/scsi_error.c : 9 3 0
linux/drivers/scsi/scsi_lib.c : 121 34 11
linux/drivers/scsi/scsi_module.c : 30 8 4
linux/drivers/scsi/scsi_queue.c : 8 1 1
linux/drivers/scsi/scsi_scan.c : 26 7 3
linux/drivers/scsi/scsi_syms.c : 13 0 3
linux/drivers/scsi/sd.c : 254 63 58
linux/drivers/scsi/seagate.c : 152 10 122
linux/drivers/scsi/seagate.h : 16 0 4
linux/drivers/scsi/sg.c : 518 99 96
linux/drivers/scsi/sgiwd93.c : 18 1 5
linux/drivers/scsi/sim710.c : 10 3 2
linux/drivers/scsi/sim710.h : 16 0 3
linux/drivers/scsi/sr.c : 33 4 4
linux/drivers/scsi/st.c : 112 57 8
linux/drivers/scsi/sun3_scsi.c : 11 1 4
linux/drivers/scsi/sym53c416.c : 10 3 2
linux/drivers/scsi/sym53c8xx.c : 26 5 3
linux/drivers/scsi/sym53c8xx.h : 16 0 4
linux/drivers/scsi/sym53c8xx_comm.h : 9 2 1
linux/drivers/scsi/t128.c : 10 1 3
linux/drivers/scsi/t128.h : 17 0 4
linux/drivers/scsi/tmscsim.c : 9 3 2
linux/drivers/scsi/u14-34f.c : 14 2 3
linux/drivers/scsi/ultrastor.c : 10 1 3
linux/drivers/scsi/wd7000.c : 10 1 3
linux/drivers/sound/Config.in : 20 1 6
linux/drivers/sound/Makefile : 42 2 6
linux/drivers/sound/ac97_codec.c : 307 106 54
linux/drivers/sound/adlib_card.c : 23 0 6
linux/drivers/sound/aedsp16.c : 72 11 18
linux/drivers/sound/cmpci.c : 73 8 14
linux/drivers/sound/cs4232.c : 19 2 2
linux/drivers/sound/cs4281.c : 2678 2678 0
linux/drivers/sound/cs4281_hwdefs.h : 1234 1234 0
linux/drivers/sound/cs46xx.c : 30 2 8
linux/drivers/sound/dev_table.c : 8 0 2
linux/drivers/sound/dmasound/awacs_defs.h : 11 5 0
linux/drivers/sound/dmasound/dmasound_awacs.c : 133 46 3
linux/drivers/sound/emu10k1/audio.c : 31 4 0
linux/drivers/sound/emu10k1/ecard.h : 7 1 0
linux/drivers/sound/emu10k1/emu_wrapper.h : 9 0 5
linux/drivers/sound/emu10k1/main.c : 45 7 7
linux/drivers/sound/emu10k1/midi.c : 8 1 1
linux/drivers/sound/emu10k1/mixer.c : 15 2 0
linux/drivers/sound/es1370.c : 26 3 3
linux/drivers/sound/es1371.c : 26 3 3
linux/drivers/sound/esssolo1.c : 40 4 5
linux/drivers/sound/gus_card.c : 23 3 1
linux/drivers/sound/mad16.c : 91 19 31
linux/drivers/sound/mpu401.h : 9 1 2
linux/drivers/sound/msnd_pinnacle.c : 43 6 13
linux/drivers/sound/opl3.c : 112 27 15
linux/drivers/sound/opl3sa.c : 53 3 15
linux/drivers/sound/pss.c : 211 118 15
linux/drivers/sound/sb.h : 9 1 2
linux/drivers/sound/sb_card.c : 88 28 8
linux/drivers/sound/sb_common.c : 78 15 24
linux/drivers/sound/sequencer.c : 138 9 48
linux/drivers/sound/sequencer_syms.c : 10 0 4
linux/drivers/sound/softoss.c : 1532 0 1532
linux/drivers/sound/softoss.h : 161 0 161
linux/drivers/sound/softoss_rs.c : 127 0 127
linux/drivers/sound/sonicvibes.c : 26 3 3
linux/drivers/sound/sound_core.c : 68 7 24
linux/drivers/sound/sound_syms.c : 8 0 3
linux/drivers/sound/sound_timer.c : 17 2 2
linux/drivers/sound/soundcard.c : 125 19 37
linux/drivers/sound/trident.c : 26 4 2
linux/drivers/sound/trix.c : 55 4 16
linux/drivers/sound/uart401.c : 236 74 102
linux/drivers/sound/uart6850.c : 78 12 12
linux/drivers/sound/vidc.c : 82 12 13
linux/drivers/sound/vidc.h : 16 7 3
linux/drivers/sound/vidc_fill.S : 23 8 4
linux/drivers/sound/vwsnd.c : 49 6 14
linux/drivers/sound/waveartist.c : 7 0 1
linux/drivers/sound/wf_midi.c : 9 1 2
linux/drivers/sound/ymf_sb.c : 44 5 5
linux/drivers/telephony/Makefile : 52 17 23
linux/drivers/telephony/ixj.c : 5259 2251 707
linux/drivers/telephony/ixj.h : 426 319 6
linux/drivers/telephony/phonedev.c : 61 6 17
linux/drivers/usb/Config.in : 7 1 0
linux/drivers/usb/Makefile : 44 3 7
linux/drivers/usb/acm.c : 20 3 1
linux/drivers/usb/dabusb.h : 8 1 1
linux/drivers/usb/dc2xx.c : 23 3 2
linux/drivers/usb/devices.c : 11 3 1
linux/drivers/usb/devio.c : 343 90 140
linux/drivers/usb/hid.c : 43 8 3
linux/drivers/usb/hub.c : 783 343 192
linux/drivers/usb/hub.h : 54 7 22
linux/drivers/usb/microtek.c : 58 26 5
linux/drivers/usb/net1080.c : 1099 1099 0
linux/drivers/usb/ov511.c : 1136 493 190
linux/drivers/usb/ov511.h : 45 9 2
linux/drivers/usb/pegasus.c : 1192 520 313
linux/drivers/usb/scanner.c : 14 8 0
linux/drivers/usb/scanner.h : 49 13 3
linux/drivers/usb/serial/ftdi_sio.c : 63 6 32
linux/drivers/usb/serial/usb-serial.h : 29 16 0
linux/drivers/usb/serial/usbserial.c : 44 5 19
linux/drivers/usb/serial/visor.c : 301 134 66
linux/drivers/usb/serial/whiteheat.c : 65 5 26
linux/drivers/usb/storage/Makefile : 8 1 1
linux/drivers/usb/storage/debug.c : 171 158 1
linux/drivers/usb/storage/debug.h : 17 3 1
linux/drivers/usb/storage/freecom.c : 613 469 18
linux/drivers/usb/storage/freecom.h : 14 2 1
linux/drivers/usb/storage/initializers.c : 60 60 0
linux/drivers/usb/storage/initializers.h : 44 44 0
linux/drivers/usb/storage/protocol.c : 25 3 3
linux/drivers/usb/storage/scsiglue.c : 143 58 23
linux/drivers/usb/storage/shuttle_usbat.c : 882 311 304
linux/drivers/usb/storage/shuttle_usbat.h : 17 2 2
linux/drivers/usb/storage/transport.c : 197 57 22
linux/drivers/usb/storage/transport.h : 18 2 2
linux/drivers/usb/storage/usb.c : 478 114 95
linux/drivers/usb/storage/usb.h : 37 6 4
linux/drivers/usb/uhci.c : 200 35 31
linux/drivers/usb/usb-core.c : 21 0 8
linux/drivers/usb/usb-ohci.c : 890 312 151
linux/drivers/usb/usb-ohci.h : 88 10 22
linux/drivers/usb/usb-uhci.c : 248 94 11
linux/drivers/usb/usb.c : 247 50 61
linux/drivers/video/Config.in : 8 1 1
linux/drivers/video/Makefile : 10 3 0
linux/drivers/video/acornfb.c : 117 47 17
linux/drivers/video/acornfb.h : 25 9 5
linux/drivers/video/aty.h : 30 10 1
linux/drivers/video/aty128.h : 30 10 1
linux/drivers/video/aty128fb.c : 187 77 18
linux/drivers/video/atyfb.c : 262 108 25
linux/drivers/video/chipsfb.c : 43 12 3
linux/drivers/video/controlfb.c : 92 47 5
linux/drivers/video/cyber2000fb.c : 68 13 9
linux/drivers/video/cyber2000fb.h : 12 7 1
linux/drivers/video/fbcon.c : 28 4 4
linux/drivers/video/fbmem.c : 12 2 2
linux/drivers/video/matrox/matroxfb_base.c : 64 21 21
linux/drivers/video/offb.c : 155 80 26
linux/drivers/video/riva/fbdev.c : 26 4 2
linux/drivers/video/sa1100fb.c : 253 112 30
linux/drivers/video/sisfb.c : 54 4 9
linux/drivers/video/valkyriefb.c : 14 2 0
linux/fs/Config.in : 22 6 3
linux/fs/Makefile : 416 68 325
linux/fs/adfs/adfs.h : 7 1 0
linux/fs/adfs/dir.c : 16 7 3
linux/fs/adfs/dir_f.c : 12 5 1
linux/fs/adfs/dir_f.h : 16 7 3
linux/fs/adfs/dir_fplus.c : 12 5 1
linux/fs/adfs/dir_fplus.h : 16 7 3
linux/fs/adfs/file.c : 7 0 1
linux/fs/adfs/inode.c : 12 5 1
linux/fs/adfs/map.c : 12 5 1
linux/fs/adfs/super.c : 22 7 2
linux/fs/attr.c : 48 29 0
linux/fs/bfs/inode.c : 8 1 1
linux/fs/block_dev.c : 90 41 9
linux/fs/buffer.c : 222 78 16
linux/fs/coda/cache.c : 201 33 141
linux/fs/coda/cnode.c : 166 25 71
linux/fs/coda/coda_linux.c : 20 0 7
linux/fs/coda/dir.c : 98 28 15
linux/fs/coda/file.c : 32 6 3
linux/fs/coda/inode.c : 218 96 34
linux/fs/coda/pioctl.c : 23 2 3
linux/fs/coda/psdev.c : 221 38 55
linux/fs/coda/symlink.c : 7 0 1
linux/fs/coda/sysctl.c : 36 5 6
linux/fs/coda/upcall.c : 88 11 14
linux/fs/cramfs/uncompress.c : 8 1 1
linux/fs/dcache.c : 46 18 9
linux/fs/devices.c : 10 1 3
linux/fs/dnotify.c : 140 140 0
linux/fs/dquot.c : 16 4 1
linux/fs/ext2/balloc.c : 7 1 0
linux/fs/ext2/bitmap.c : 8 1 1
linux/fs/ext2/dir.c : 7 1 0
linux/fs/ext2/file.c : 7 1 0
linux/fs/ext2/fsync.c : 7 1 0
linux/fs/ext2/ialloc.c : 7 1 0
linux/fs/ext2/inode.c : 7 1 0
linux/fs/ext2/ioctl.c : 7 1 0
linux/fs/ext2/namei.c : 7 1 0
linux/fs/ext2/super.c : 16 2 1
linux/fs/ext2/symlink.c : 7 1 0
linux/fs/fcntl.c : 239 50 21
linux/fs/file_table.c : 70 22 35
linux/fs/filesystems.c : 21 0 8
linux/fs/inode.c : 56 17 13
linux/fs/lockd/clntlock.c : 15 2 0
linux/fs/lockd/clntproc.c : 60 13 5
linux/fs/lockd/host.c : 10 2 2
linux/fs/lockd/svc.c : 26 6 6
linux/fs/lockd/svclock.c : 17 3 1
linux/fs/lockd/svcshare.c : 7 0 1
linux/fs/lockd/xdr.c : 24 3 1
linux/fs/lockd/xdr4.c : 24 3 1
linux/fs/locks.c : 1259 632 138
linux/fs/minix/Makefile : 8 1 1
linux/fs/minix/bitmap.c : 51 0 17
linux/fs/minix/file.c : 24 14 0
linux/fs/minix/fsync.c : 344 0 344
linux/fs/minix/inode.c : 593 13 562
linux/fs/minix/itree_common.c : 417 417 0
linux/fs/minix/itree_v1.c : 63 63 0
linux/fs/minix/itree_v2.c : 68 68 0
linux/fs/minix/namei.c : 24 0 4
linux/fs/minix/truncate.c : 420 0 420
linux/fs/namei.c : 137 38 6
linux/fs/ncpfs/file.c : 8 1 1
linux/fs/nfs/dir.c : 38 11 7
linux/fs/nfs/file.c : 15 5 2
linux/fs/nfs/inode.c : 7 1 0
linux/fs/nfs/nfs3proc.c : 24 7 3
linux/fs/nfs/nfsroot.c : 7 1 0
linux/fs/nfs/proc.c : 12 4 2
linux/fs/nfs/unlink.c : 29 6 2
linux/fs/nfsd/export.c : 32 9 5
linux/fs/nfsd/nfs3proc.c : 7 1 0
linux/fs/nfsd/nfs3xdr.c : 8 1 1
linux/fs/nfsd/nfsctl.c : 8 1 1
linux/fs/nfsd/nfsfh.c : 8 1 1
linux/fs/nfsd/nfssvc.c : 21 5 3
linux/fs/nfsd/nfsxdr.c : 8 1 1
linux/fs/nfsd/vfs.c : 100 43 2
linux/fs/open.c : 46 13 1
linux/fs/partitions/acorn.c : 20 8 3
linux/fs/partitions/check.c : 36 12 4
linux/fs/partitions/mac.c : 44 6 4
linux/fs/proc/generic.c : 8 1 1
linux/fs/proc/proc_misc.c : 59 22 14
linux/fs/proc/procfs_syms.c : 10 3 1
linux/fs/ramfs/inode.c : 8 1 1
linux/fs/read_write.c : 56 15 0
linux/fs/smbfs/inode.c : 22 8 1
linux/fs/super.c : 135 40 22
linux/fs/udf/ialloc.c : 11 1 4
linux/fs/ufs/ialloc.c : 10 1 3
linux/include/asm-alpha/atomic.h : 107 18 25
linux/include/asm-alpha/bitops.h : 258 127 14
linux/include/asm-alpha/elf.h : 8 1 1
linux/include/asm-alpha/fcntl.h : 27 8 1
linux/include/asm-alpha/resource.h : 18 3 1
linux/include/asm-alpha/semaphore-helper.h : 8 1 1
linux/include/asm-alpha/spinlock.h : 74 11 15
linux/include/asm-alpha/system.h : 151 41 17
linux/include/asm-alpha/termios.h : 7 1 0
linux/include/asm-arm/arch-arc/dma.h : 23 10 6
linux/include/asm-arm/arch-arc/hardware.h : 32 11 7
linux/include/asm-arm/arch-arc/ide.h : 27 12 8
linux/include/asm-arm/arch-arc/io.h : 18 8 4
linux/include/asm-arm/arch-arc/irq.h : 34 9 5
linux/include/asm-arm/arch-arc/irqs.h : 18 8 4
linux/include/asm-arm/arch-arc/keyboard.h : 18 8 4
linux/include/asm-arm/arch-arc/memory.h : 13 6 2
linux/include/asm-arm/arch-arc/oldlatches.h : 19 7 5
linux/include/asm-arm/arch-arc/processor.h : 20 9 5
linux/include/asm-arm/arch-arc/serial.h : 20 9 5
linux/include/asm-arm/arch-arc/system.h : 13 6 2
linux/include/asm-arm/arch-arc/time.h : 22 10 6
linux/include/asm-arm/arch-arc/timex.h : 16 7 3
linux/include/asm-arm/arch-arc/uncompress.h : 13 6 2
linux/include/asm-arm/arch-cl7500/hardware.h : 8 1 1
linux/include/asm-arm/arch-cl7500/irq.h : 8 1 1
linux/include/asm-arm/arch-cl7500/system.h : 8 1 1
linux/include/asm-arm/arch-ebsa110/dma.h : 16 7 3
linux/include/asm-arm/arch-ebsa110/hardware.h : 13 6 2
linux/include/asm-arm/arch-ebsa110/io.h : 13 6 2
linux/include/asm-arm/arch-ebsa110/irq.h : 16 7 3
linux/include/asm-arm/arch-ebsa110/irqs.h : 13 6 2
linux/include/asm-arm/arch-ebsa110/memory.h : 24 11 7
linux/include/asm-arm/arch-ebsa110/processor.h : 18 8 4
linux/include/asm-arm/arch-ebsa110/serial.h : 18 8 4
linux/include/asm-arm/arch-ebsa110/system.h : 38 16 5
linux/include/asm-arm/arch-ebsa110/time.h : 13 6 2
linux/include/asm-arm/arch-ebsa110/timex.h : 16 7 3
linux/include/asm-arm/arch-ebsa110/uncompress.h : 13 6 2
linux/include/asm-arm/arch-ebsa110/vmalloc.h : 12 7 1
linux/include/asm-arm/arch-ebsa285/dma.h : 14 4 4
linux/include/asm-arm/arch-ebsa285/hardware.h : 16 7 3
linux/include/asm-arm/arch-ebsa285/ide.h : 18 8 4
linux/include/asm-arm/arch-ebsa285/io.h : 29 10 6
linux/include/asm-arm/arch-ebsa285/irq.h : 30 13 9
linux/include/asm-arm/arch-ebsa285/memory.h : 26 12 8
linux/include/asm-arm/arch-ebsa285/processor.h : 18 8 4
linux/include/asm-arm/arch-ebsa285/serial.h : 20 9 5
linux/include/asm-arm/arch-ebsa285/system.h : 25 8 4
linux/include/asm-arm/arch-ebsa285/time.h : 20 4 4
linux/include/asm-arm/arch-ebsa285/timex.h : 16 7 3
linux/include/asm-arm/arch-ebsa285/uncompress.h : 13 6 2
linux/include/asm-arm/arch-ebsa285/vmalloc.h : 10 5 1
linux/include/asm-arm/arch-nexuspci/dma.h : 13 7 0
linux/include/asm-arm/arch-nexuspci/hardware.h : 14 8 0
linux/include/asm-arm/arch-nexuspci/irq.h : 13 7 0
linux/include/asm-arm/arch-nexuspci/irqs.h : 21 12 3
linux/include/asm-arm/arch-nexuspci/system.h : 14 8 0
linux/include/asm-arm/arch-nexuspci/time.h : 13 7 0
linux/include/asm-arm/arch-nexuspci/uncompress.h : 13 7 0
linux/include/asm-arm/arch-rpc/acornfb.h : 16 7 3
linux/include/asm-arm/arch-rpc/dma.h : 12 7 1
linux/include/asm-arm/arch-rpc/hardware.h : 16 7 3
linux/include/asm-arm/arch-rpc/ide.h : 18 8 4
linux/include/asm-arm/arch-rpc/io.h : 13 6 2
linux/include/asm-arm/arch-rpc/irq.h : 21 8 4
linux/include/asm-arm/arch-rpc/irqs.h : 13 6 2
linux/include/asm-arm/arch-rpc/keyboard.h : 18 7 4
linux/include/asm-arm/arch-rpc/memory.h : 28 13 9
linux/include/asm-arm/arch-rpc/processor.h : 20 9 5
linux/include/asm-arm/arch-rpc/serial.h : 18 8 4
linux/include/asm-arm/arch-rpc/system.h : 26 8 4
linux/include/asm-arm/arch-rpc/time.h : 22 10 6
linux/include/asm-arm/arch-rpc/timex.h : 16 7 3
linux/include/asm-arm/arch-rpc/uncompress.h : 13 6 2
linux/include/asm-arm/arch-rpc/vmalloc.h : 12 7 1
linux/include/asm-arm/arch-sa1100/SA-1100.h : 10 2 2
linux/include/asm-arm/arch-sa1100/assabet.h : 19 3 3
linux/include/asm-arm/arch-sa1100/bitsy.h : 7 1 0
linux/include/asm-arm/arch-sa1100/cerf.h : 8 3 0
linux/include/asm-arm/arch-sa1100/hardware.h : 81 25 12
linux/include/asm-arm/arch-sa1100/ide.h : 115 25 32
linux/include/asm-arm/arch-sa1100/memory.h : 31 9 9
linux/include/asm-arm/arch-sa1100/mmzone.h : 89 23 34
linux/include/asm-arm/arch-sa1100/system.h : 16 3 6
linux/include/asm-arm/arch-sa1100/thinclient.h : 10 2 2
linux/include/asm-arm/arch-sa1100/vmalloc.h : 5 1 1
linux/include/asm-arm/arch-shark/hardware.h : 41 11 7
linux/include/asm-arm/arch-shark/io.h : 8 2 0
linux/include/asm-arm/arch-shark/keyboard.h : 63 9 42
linux/include/asm-arm/arch-shark/system.h : 22 10 3
linux/include/asm-arm/arch-shark/time.h : 24 3 10
linux/include/asm-arm/arch-shark/vmalloc.h : 17 17 0
linux/include/asm-arm/arch-tbox/dma.h : 37 37 0
linux/include/asm-arm/arch-tbox/hardware.h : 60 60 0
linux/include/asm-arm/arch-tbox/ide.h : 3 3 0
linux/include/asm-arm/arch-tbox/io.h : 55 55 0
linux/include/asm-arm/arch-tbox/irq.h : 50 50 0
linux/include/asm-arm/arch-tbox/irqs.h : 29 29 0
linux/include/asm-arm/arch-tbox/keyboard.h : 29 29 0
linux/include/asm-arm/arch-tbox/memory.h : 38 38 0
linux/include/asm-arm/arch-tbox/param.h : 1 1 0
linux/include/asm-arm/arch-tbox/processor.h : 24 24 0
linux/include/asm-arm/arch-tbox/serial.h : 34 34 0
linux/include/asm-arm/arch-tbox/system.h : 33 33 0
linux/include/asm-arm/arch-tbox/time.h : 36 36 0
linux/include/asm-arm/arch-tbox/timex.h : 8 8 0
linux/include/asm-arm/arch-tbox/uncompress.h : 42 42 0
linux/include/asm-arm/arch-tbox/vmalloc.h : 17 17 0
linux/include/asm-arm/atomic.h : 24 11 7
linux/include/asm-arm/bugs.h : 12 5 1
linux/include/asm-arm/cache.h : 6 1 1
linux/include/asm-arm/checksum.h : 6 1 1
linux/include/asm-arm/cpu-multi26.h : 12 9 0
linux/include/asm-arm/cpu-multi32.h : 213 105 80
linux/include/asm-arm/cpu-single.h : 105 44 28
linux/include/asm-arm/dec21285.h : 144 0 144
linux/include/asm-arm/dma.h : 20 1 6
linux/include/asm-arm/fcntl.h : 27 9 0
linux/include/asm-arm/floppy.h : 16 7 3
linux/include/asm-arm/hardware/dec21285.h : 148 148 0
linux/include/asm-arm/hardware/ioc.h : 67 67 0
linux/include/asm-arm/hardware/iomd.h : 249 249 0
linux/include/asm-arm/hardware/memc.h : 26 26 0
linux/include/asm-arm/hardware/pci_v3.h : 148 148 0
linux/include/asm-arm/hardware/serial_amba.h : 91 91 0
linux/include/asm-arm/hardware.h : 16 7 3
linux/include/asm-arm/io.h : 21 6 3
linux/include/asm-arm/ioc.h : 59 0 59
linux/include/asm-arm/iomd.h : 245 0 245
linux/include/asm-arm/keyboard.h : 16 7 3
linux/include/asm-arm/leds.h : 18 7 4
linux/include/asm-arm/linux_logo.h : 16 7 3
linux/include/asm-arm/mach/arch.h : 13 6 2
linux/include/asm-arm/mach/dma.h : 26 11 5
linux/include/asm-arm/mach/map.h : 10 4 0
linux/include/asm-arm/mach/pci.h : 12 7 1
linux/include/asm-arm/memc.h : 17 0 17
linux/include/asm-arm/memory.h : 19 8 4
linux/include/asm-arm/mmu_context.h : 18 8 4
linux/include/asm-arm/mmzone.h : 15 6 3
linux/include/asm-arm/param.h : 13 6 2
linux/include/asm-arm/parport.h : 9 2 2
linux/include/asm-arm/pgalloc.h : 30 9 3
linux/include/asm-arm/pgtable.h : 32 12 2
linux/include/asm-arm/posix_types.h : 18 8 4
linux/include/asm-arm/proc-armo/assembler.h : 18 8 4
linux/include/asm-arm/proc-armo/cache.h : 21 9 4
linux/include/asm-arm/proc-armo/io.h : 8 0 8
linux/include/asm-arm/proc-armo/locks.h : 18 7 4
linux/include/asm-arm/proc-armo/page.h : 13 6 2
linux/include/asm-arm/proc-armo/pgtable.h : 16 7 3
linux/include/asm-arm/proc-armo/processor.h : 30 14 10
linux/include/asm-arm/proc-armo/ptrace.h : 22 8 2
linux/include/asm-arm/proc-armo/shmparam.h : 18 7 4
linux/include/asm-arm/proc-armo/system.h : 15 6 3
linux/include/asm-arm/proc-armo/uaccess.h : 13 6 2
linux/include/asm-arm/proc-armo/uncompress.h : 13 6 2
linux/include/asm-arm/proc-armv/assembler.h : 18 8 4
linux/include/asm-arm/proc-armv/cache.h : 215 109 59
linux/include/asm-arm/proc-armv/domain.h : 13 6 2
linux/include/asm-arm/proc-armv/io.h : 35 0 35
linux/include/asm-arm/proc-armv/locks.h : 16 7 3
linux/include/asm-arm/proc-armv/page.h : 13 6 2
linux/include/asm-arm/proc-armv/pgtable.h : 19 8 4
linux/include/asm-arm/proc-armv/processor.h : 28 13 9
linux/include/asm-arm/proc-armv/ptrace.h : 31 10 2
linux/include/asm-arm/proc-armv/shmparam.h : 20 8 5
linux/include/asm-arm/proc-armv/system.h : 52 6 33
linux/include/asm-arm/proc-armv/uaccess.h : 12 5 2
linux/include/asm-arm/proc-armv/uncompress.h : 13 6 2
linux/include/asm-arm/proc-fns.h : 57 21 8
linux/include/asm-arm/processor.h : 13 6 2
linux/include/asm-arm/procinfo.h : 13 6 2
linux/include/asm-arm/resource.h : 18 3 1
linux/include/asm-arm/serial.h : 18 8 4
linux/include/asm-arm/setup.h : 20 9 5
linux/include/asm-arm/timex.h : 16 7 3
linux/include/asm-i386/atomic.h : 128 26 32
linux/include/asm-i386/bitops.h : 213 64 41
linux/include/asm-i386/fcntl.h : 29 10 0
linux/include/asm-i386/resource.h : 18 3 1
linux/include/asm-i386/rwlock.h : 27 2 5
linux/include/asm-i386/semaphore.h : 107 12 12
linux/include/asm-i386/spinlock.h : 72 11 14
linux/include/asm-i386/system.h : 36 15 4
linux/include/asm-ia64/fcntl.h : 27 9 0
linux/include/asm-ia64/resource.h : 18 3 1
linux/include/asm-m68k/fcntl.h : 27 9 0
linux/include/asm-m68k/resource.h : 18 3 1
linux/include/asm-mips/fcntl.h : 27 9 0
linux/include/asm-mips/resource.h : 18 3 1
linux/include/asm-mips64/fcntl.h : 27 9 0
linux/include/asm-mips64/resource.h : 18 3 1
linux/include/asm-ppc/atomic.h : 87 12 18
linux/include/asm-ppc/backlight.h : 6 1 1
linux/include/asm-ppc/bitops.h : 306 87 68
linux/include/asm-ppc/bootx.h : 5 0 1
linux/include/asm-ppc/cpm_8260.h : 242 171 20
linux/include/asm-ppc/fcntl.h : 46 21 0
linux/include/asm-ppc/feature.h : 20 6 1
linux/include/asm-ppc/hardirq.h : 23 7 0
linux/include/asm-ppc/heathrow.h : 9 5 0
linux/include/asm-ppc/highmem.h : 121 121 0
linux/include/asm-ppc/ide.h : 15 0 2
linux/include/asm-ppc/immap_8260.h : 15 5 3
linux/include/asm-ppc/io.h : 123 70 10
linux/include/asm-ppc/irq.h : 9 3 0
linux/include/asm-ppc/keylargo.h : 103 103 0
linux/include/asm-ppc/kmap_types.h : 10 10 0
linux/include/asm-ppc/machdep.h : 17 2 2
linux/include/asm-ppc/mbx.h : 7 1 0
linux/include/asm-ppc/mman.h : 10 2 2
linux/include/asm-ppc/nvram.h : 32 10 3
linux/include/asm-ppc/pci-bridge.h : 23 7 2
linux/include/asm-ppc/pgtable.h : 8 1 1
linux/include/asm-ppc/processor.h : 7 1 0
linux/include/asm-ppc/prom.h : 16 5 0
linux/include/asm-ppc/resource.h : 18 3 1
linux/include/asm-ppc/serial.h : 22 0 11
linux/include/asm-ppc/smp.h : 14 4 3
linux/include/asm-ppc/spinlock.h : 7 1 0
linux/include/asm-ppc/system.h : 125 81 7
linux/include/asm-ppc/time.h : 96 78 5
linux/include/asm-ppc/uaccess.h : 34 5 3
linux/include/asm-ppc/uninorth.h : 83 83 0
linux/include/asm-ppc/unistd.h : 14 4 4
linux/include/asm-s390/fcntl.h : 27 9 0
linux/include/asm-s390/resource.h : 18 3 1
linux/include/asm-sh/atomic.h : 79 6 19
linux/include/asm-sh/bitops.h : 124 20 14
linux/include/asm-sh/checksum.h : 39 8 4
linux/include/asm-sh/delay.h : 9 2 1
linux/include/asm-sh/fcntl.h : 47 21 0
linux/include/asm-sh/ide.h : 9 2 1
linux/include/asm-sh/io_hd64461.h : 10 4 0
linux/include/asm-sh/irq.h : 23 3 0
linux/include/asm-sh/page.h : 32 8 2
linux/include/asm-sh/pci.h : 68 8 8
linux/include/asm-sh/pgtable.h : 97 33 29
linux/include/asm-sh/resource.h : 18 3 1
linux/include/asm-sh/string.h : 47 9 4
linux/include/asm-sh/system.h : 78 22 11
linux/include/asm-sh/uaccess.h : 65 14 10
linux/include/asm-sh/unistd.h : 99 22 22
linux/include/asm-sparc/atomic.h : 29 3 8
linux/include/asm-sparc/bitops.h : 15 4 1
linux/include/asm-sparc/fcntl.h : 27 9 0
linux/include/asm-sparc/io.h : 23 5 1
linux/include/asm-sparc/resource.h : 18 3 1
linux/include/asm-sparc/system.h : 15 4 1
linux/include/asm-sparc64/atomic.h : 8 1 1
linux/include/asm-sparc64/bitops.h : 15 4 1
linux/include/asm-sparc64/fcntl.h : 27 9 0
linux/include/asm-sparc64/io.h : 22 5 1
linux/include/asm-sparc64/resource.h : 18 3 1
linux/include/asm-sparc64/smp.h : 19 1 4
linux/include/asm-sparc64/starfire.h : 21 21 0
linux/include/asm-sparc64/system.h : 37 15 5
linux/include/linux/ac97_codec.h : 18 4 1
linux/include/linux/adb.h : 15 1 1
linux/include/linux/adfs_fs.h : 8 1 1
linux/include/linux/arcdevice.h : 7 0 1
linux/include/linux/atalk.h : 8 1 1
linux/include/linux/blk.h : 8 1 1
linux/include/linux/brlock.h : 25 15 2
linux/include/linux/byteorder/swab.h : 42 9 9
linux/include/linux/capability.h : 10 4 0
linux/include/linux/cciss_ioctl.h : 186 186 0
linux/include/linux/coda.h : 188 27 63
linux/include/linux/coda_cache.h : 23 1 13
linux/include/linux/coda_fs_i.h : 14 5 2
linux/include/linux/coda_linux.h : 36 9 7
linux/include/linux/coda_psdev.h : 48 3 12
linux/include/linux/cuda.h : 9 2 1
linux/include/linux/dcache.h : 13 2 2
linux/include/linux/devpts_fs.h : 29 4 4
linux/include/linux/dnotify.h : 25 25 0
linux/include/linux/elf.h : 8 2 0
linux/include/linux/ext2_fs_sb.h : 8 0 2
linux/include/linux/fcntl.h : 24 20 0
linux/include/linux/fs.h : 99 23 1
linux/include/linux/gameport.h : 7 1 0
linux/include/linux/hdlcdrv.h : 91 11 11
linux/include/linux/hfs_fs.h : 14 2 2
linux/include/linux/hfs_sysdep.h : 128 19 19
linux/include/linux/highmem.h : 8 1 1
linux/include/linux/if_pppox.h : 8 1 1
linux/include/linux/inet.h : 7 0 1
linux/include/linux/ixjuser.h : 157 58 32
linux/include/linux/kernel.h : 7 1 0
linux/include/linux/kmod.h : 7 1 0
linux/include/linux/locks.h : 24 9 2
linux/include/linux/major.h : 31 13 2
linux/include/linux/minix_fs.h : 15 6 1
linux/include/linux/miscdevice.h : 8 2 0
linux/include/linux/mm.h : 111 34 9
linux/include/linux/mmzone.h : 16 3 2
linux/include/linux/module.h : 14 0 8
linux/include/linux/mount.h : 9 1 2
linux/include/linux/nfs_mount.h : 7 1 0
linux/include/linux/nfsd/export.h : 9 2 1
linux/include/linux/pci.h : 197 64 44
linux/include/linux/pci_ids.h : 61 15 5
linux/include/linux/pmu.h : 118 49 15
linux/include/linux/raid/md.h : 8 1 1
linux/include/linux/raid/md_compatible.h : 12 1 5
linux/include/linux/sched.h : 23 3 0
linux/include/linux/signal.h : 107 13 13
linux/include/linux/slab.h : 22 0 9
linux/include/linux/sunrpc/clnt.h : 7 1 0
linux/include/linux/swap.h : 175 121 25
linux/include/linux/sysctl.h : 48 18 3
linux/include/linux/tcp.h : 63 58 0
linux/include/linux/telephony.h : 119 52 18
linux/include/linux/time.h : 43 36 1
linux/include/linux/timex.h : 32 15 3
linux/include/linux/toshiba.h : 36 36 0
linux/include/linux/tqueue.h : 8 1 1
linux/include/linux/usb.h : 132 37 35
linux/include/linux/usbdevice_fs.h : 7 1 0
linux/include/linux/vmalloc.h : 9 0 3
linux/include/linux/vt_buffer.h : 43 5 5
linux/include/linux/wait.h : 26 3 3
linux/include/linux/zftape.h : 17 2 2
linux/include/net/addrconf.h : 78 9 9
linux/include/net/checksum.h : 8 1 1
linux/include/net/dn_route.h : 23 3 3
linux/include/net/dsfield.h : 40 5 5
linux/include/net/dst.h : 64 8 8
linux/include/net/if_inet6.h : 17 2 2
linux/include/net/ip.h : 53 6 6
linux/include/net/ip6_fib.h : 17 2 2
linux/include/net/ip6_route.h : 8 1 1
linux/include/net/ip_fib.h : 74 9 9
linux/include/net/ipv6.h : 54 7 7
linux/include/net/ndisc.h : 8 1 1
linux/include/net/neighbour.h : 61 8 8
linux/include/net/pkt_cls.h : 8 1 1
linux/include/net/pkt_sched.h : 73 9 9
linux/include/net/profile.h : 135 16 16
linux/include/net/route.h : 41 5 5
linux/include/net/snmp.h : 119 38 15
linux/include/net/sock.h : 265 30 31
linux/include/net/tcp.h : 221 26 38
linux/include/net/x25.h : 8 1 1
linux/include/pcmcia/ss.h : 7 1 0
linux/include/scsi/scsi_ioctl.h : 13 7 0
linux/include/scsi/sg.h : 15 6 2
linux/init/main.c : 9 0 3
linux/init/version.c : 8 1 1
linux/ipc/shm.c : 77 13 8
linux/kernel/exit.c : 7 1 0
linux/kernel/kmod.c : 44 39 0
linux/kernel/ksyms.c : 37 8 2
linux/kernel/sched.c : 150 44 45
linux/kernel/signal.c : 59 19 15
linux/kernel/softirq.c : 23 9 1
linux/kernel/sys.c : 18 0 3
linux/kernel/sysctl.c : 21 7 1
linux/kernel/timer.c : 17 0 4
linux/mm/filemap.c : 273 67 141
linux/mm/memory.c : 27 4 3
linux/mm/mremap.c : 10 4 0
linux/mm/page_alloc.c : 530 315 73
linux/mm/page_io.c : 9 2 1
linux/mm/slab.c : 183 39 87
linux/mm/swap.c : 272 251 3
linux/mm/swap_state.c : 27 4 2
linux/mm/vmalloc.c : 8 1 1
linux/mm/vmscan.c : 1069 692 131
linux/net/Makefile : 265 48 195
linux/net/appletalk/aarp.c : 10 3 0
linux/net/core/dev.c : 121 34 37
linux/net/core/sock.c : 27 5 2
linux/net/ipv4/af_inet.c : 46 4 5
linux/net/ipv4/arp.c : 47 15 16
linux/net/ipv4/inetpeer.c : 14 2 2
linux/net/ipv4/ip_sockglue.c : 62 23 15
linux/net/ipv4/netfilter/ip_fw_compat.c : 10 4 0
linux/net/ipv4/netfilter/ip_fw_compat_masq.c : 13 6 1
linux/net/ipv4/netfilter/ip_nat_ftp.c : 11 3 2
linux/net/ipv4/netfilter/ip_nat_standalone.c : 7 1 0
linux/net/ipv4/netfilter/ip_queue.c : 8 1 1
linux/net/ipv4/netfilter/ipt_MIRROR.c : 8 1 1
linux/net/ipv4/netfilter/ipt_REJECT.c : 48 10 5
linux/net/ipv4/netfilter/iptable_mangle.c : 7 1 0
linux/net/ipv4/protocol.c : 11 1 4
linux/net/ipv4/route.c : 8 1 1
linux/net/ipv4/sysctl_net_ipv4.c : 50 7 16
linux/net/ipv4/tcp.c : 105 70 6
linux/net/ipv4/tcp_input.c : 49 8 7
linux/net/ipv4/tcp_ipv4.c : 43 7 6
linux/net/ipv4/tcp_minisocks.c : 24 3 1
linux/net/ipv4/tcp_timer.c : 8 1 1
linux/net/ipv4/udp.c : 138 38 31
linux/net/ipv4/utils.c : 12 0 6
linux/net/ipv6/af_inet6.c : 117 36 20
linux/net/ipv6/ip6_fib.c : 20 2 4
linux/net/ipv6/mcast.c : 21 1 3
linux/net/ipv6/protocol.c : 13 2 5
linux/net/ipv6/udp.c : 50 12 11
linux/net/socket.c : 8 1 1
linux/net/sunrpc/auth_unix.c : 9 2 1
linux/net/sunrpc/clnt.c : 16 2 1
linux/net/sunrpc/sched.c : 39 6 6
linux/net/sunrpc/sysctl.c : 19 5 5
linux/net/sunrpc/xprt.c : 18 1 4
linux/net/x25/af_x25.c : 29 8 1
linux/net/x25/x25_dev.c : 23 4 2
linux/net/x25/x25_link.c : 27 5 1
linux/net/x25/x25_out.c : 40 9 4
linux/scripts/Configure : 8 1 1
linux/scripts/ksymoops/README : 11 4 3
linux/scripts/makelst : 21 21 0
linux/scripts/mkdep.c : 62 14 16
linux/scripts/ver_linux : 8 2 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part015

#!/bin/sh -x
# this is part 015 of a 112 - part archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck
if test "$Scheck" != 015; then
echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&
+ ppc_md.time_init = mk48t59_init;
X }
X
X #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
diff -u --recursive --new-file v2.4.0-test8/linux/arch/ppc/kernel/prep_time.c linux/arch/ppc/kernel/prep_time.c
--- v2.4.0-test8/linux/arch/ppc/kernel/prep_time.c Thu Jul 13 09:42:50 2000
+++ linux/arch/ppc/kernel/prep_time.c Sun Sep 17 09:48:07 2000
@@ -15,6 +15,7 @@
X #include <linux/string.h>
X #include <linux/mm.h>
X #include <linux/interrupt.h>
+#include <linux/time.h>
X #include <linux/timex.h>
X #include <linux/kernel_stat.h>
X #include <linux/init.h>
@@ -99,28 +100,34 @@
X unsigned long mc146818_get_rtc_time(void)
X {
X unsigned int year, mon, day, hour, min, sec;
- int i;
+ int uip, i;
X
X /* The Linux interpretation of the CMOS clock register contents:
X * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
X * RTC registers show the second which has precisely just started.
X * Let's hope other operating systems interpret the RTC the same way.
X */
- /* read RTC exactly on falling edge of update flag */
- for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
- if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
- break;
- for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */
- if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
- break;
- do { /* Isn't this overkill ? UIP above should guarantee consistency */
+
+ /* Since the UIP flag is set for about 2.2 ms and the clock
+ * is typically written with a precision of 1 jiffy, trying
+ * to obtain a precision better than a few milliseconds is
+ * an illusion. Only consistency is interesting, this also
+ * allows to use the routine for /dev/rtc without a potential
+ * 1 second kernel busy loop triggered by any reader of /dev/rtc.
+ */
+
+ for ( i = 0; i<1000000; i++) {
+ uip = CMOS_READ(RTC_FREQ_SELECT);
X sec = CMOS_READ(RTC_SECONDS);
X min = CMOS_READ(RTC_MINUTES);
X hour = CMOS_READ(RTC_HOURS);
X day = CMOS_READ(RTC_DAY_OF_MONTH);
X mon = CMOS_READ(RTC_MONTH);
X year = CMOS_READ(RTC_YEAR);
- } while (sec != CMOS_READ(RTC_SECONDS));
+ uip |= CMOS_READ(RTC_FREQ_SELECT);
+ if ((uip & RTC_UIP)==0) break;
+ }
+
X if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY)
X || RTC_ALWAYS_BCD)
X {
@@ -177,28 +184,11 @@
X {
X unsigned char save_control;
X unsigned int year, mon, day, hour, min, sec;
- int i;
X
- /* Make sure the time is not stopped. */
- save_control = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLB);
-
- ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA,
- (save_control & (~MK48T59_RTC_CB_STOP)));
-
- /* Now make sure the read bit is off so the value will change. */
+ /* Simple: freeze the clock, read it and allow updates again */
X save_control = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLA);
X save_control &= ~MK48T59_RTC_CA_READ;
X ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA, save_control);
-
- /* Read the seconds value to see when it changes. */
- sec = ppc_md.nvram_read_val(MK48T59_RTC_SECONDS);
-
- /* Wait until the seconds value changes, then read the value. */
- for (i = 0 ; i < 1000000 ; i++) { /* may take up to 1 second... */
- if (ppc_md.nvram_read_val(MK48T59_RTC_SECONDS) != sec) {
- break;
- }
- }
X
X /* Set the register to read the value. */
X ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA,
diff -u --recursive --new-file v2.4.0-test8/linux/arch/ppc/kernel/process.c linux/arch/ppc/kernel/process.c
--- v2.4.0-test8/linux/arch/ppc/kernel/process.c Tue Sep 5 13:50:02 2000
+++ linux/arch/ppc/kernel/process.c Sun Sep 17 09:48:07 2000
@@ -234,7 +234,6 @@
X prev->thread.vrsave )
X giveup_altivec(prev);
X #endif /* CONFIG_ALTIVEC */
- prev->last_processor = prev->processor;
X current_set[smp_processor_id()] = new;
X #endif /* CONFIG_SMP */
X /* Avoid the trap. On smp this this never happens since
@@ -266,7 +265,7 @@
X last_task_used_altivec);
X
X #ifdef CONFIG_SMP
- printk(" CPU: %d last CPU: %d", current->processor,current->last_processor);
+ printk(" CPU: %d", current->processor);
X #endif /* CONFIG_SMP */
X
X printk("\n");
@@ -379,9 +378,6 @@
X childregs->msr &= ~MSR_VEC;
X #endif /* CONFIG_ALTIVEC */
X
-#ifdef CONFIG_SMP
- p->last_processor = NO_PROC_ID;
-#endif /* CONFIG_SMP */
X return 0;
X }
X
@@ -441,8 +437,8 @@
X current->thread.fpscr = 0;
X }
X
-asmlinkage int sys_clone(int p1, int p2, int p3, int p4, int p5, int p6,
- struct pt_regs *regs)
+int sys_clone(int p1, int p2, int p3, int p4, int p5, int p6,
+ struct pt_regs *regs)
X {
X unsigned long clone_flags = p1;
X int res;
@@ -460,8 +456,8 @@
X return res;
X }
X
-asmlinkage int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6,
- struct pt_regs *regs)
+int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6,
+ struct pt_regs *regs)
X {
X
X int res;
@@ -478,15 +474,15 @@
X return res;
X }
X
-asmlinkage int sys_vfork(int p1, int p2, int p3, int p4, int p5, int p6,
- struct pt_regs *regs)
+int sys_vfork(int p1, int p2, int p3, int p4, int p5, int p6,
+ struct pt_regs *regs)
X {
X return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1], regs, 0);
X }
X
-asmlinkage int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
- unsigned long a3, unsigned long a4, unsigned long a5,
- struct pt_regs *regs)
+int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
+ unsigned long a3, unsigned long a4, unsigned long a5,
+ struct pt_regs *regs)
X {
X int error;
X char * filename;
diff -u --recursive --new-file v2.4.0-test8/linux/arch/ppc/kernel/prom.c linux/arch/ppc/kernel/prom.c
--- v2.4.0-test8/linux/arch/ppc/kernel/prom.c Thu Jul 13 09:42:50 2000
+++ linux/arch/ppc/kernel/prom.c Sun Sep 17 09:48:07 2000
@@ -140,8 +140,7 @@
X static long g_max_loc_X = 0;
X static long g_max_loc_Y = 0;
X
-unsigned long disp_BATL = 0;
-unsigned long disp_BATU = 0;
+unsigned long disp_BAT[2] = {0, 0};
X
X #define cmapsz (16*256)
X
@@ -276,8 +275,7 @@
X prom_drawstring(msg);
X #endif
X return;
- }
-
+ }
X
X for (p = msg; *p != 0; p = q) {
X for (q = p; *q != 0 && *q != '\n'; ++q)
@@ -362,7 +360,7 @@
X /* copy the holding pattern code to someplace safe (0) */
X /* the holding pattern is now within the first 0x100
X bytes of the kernel image -- paulus */
- memcpy((void *)0, KERNELBASE + offset, 0x100);
+ memcpy((void *)0, (void *)(KERNELBASE + offset), 0x100);
X flush_icache_range(0, 0x100);
X
X /* look for cpus */
@@ -556,6 +554,54 @@
X }
X #endif /* CONFIG_PPC64BRIDGE */
X
+static __init void
+prom_instantiate_rtas(void)
+{
+ ihandle prom_rtas;
+ unsigned int i;
+ struct prom_args prom_args;
+ unsigned long offset = reloc_offset();
+
+ prom_rtas = call_prom(RELOC("finddevice"), 1, 1, RELOC("/rtas"));
+ if (prom_rtas == (void *) -1)
+ return;
+
+ RELOC(rtas_size) = 0;
+ call_prom(RELOC("getprop"), 4, 1, prom_rtas,
+ RELOC("rtas-size"), &RELOC(rtas_size), sizeof(rtas_size));
+ prom_print(RELOC("instantiating rtas"));
+ if (RELOC(rtas_size) == 0) {
+ RELOC(rtas_data) = 0;
+ } else {
+ /*
+ * Ask OF for some space for RTAS.
+ * Actually OF has bugs so we just arbitrarily
+ * use memory at the 6MB point.
+ */
+ RELOC(rtas_data) = 6 << 20;
+ prom_print(RELOC(" at "));
+ prom_print_hex(RELOC(rtas_data));
+ }
+
+ prom_rtas = call_prom(RELOC("open"), 1, 1, RELOC("/rtas"));
+ prom_print(RELOC("..."));
+ prom_args.service = RELOC("call-method");
+ prom_args.nargs = 3;
+ prom_args.nret = 2;
+ prom_args.args[0] = RELOC("instantiate-rtas");
+ prom_args.args[1] = prom_rtas;
+ prom_args.args[2] = (void *) RELOC(rtas_data);
+ RELOC(prom)(&prom_args);
+ i = 0;
+ if (prom_args.args[3] == 0)
+ i = (unsigned int)prom_args.args[4];
+ RELOC(rtas_entry) = i;
+ if ((RELOC(rtas_entry) == -1) || (RELOC(rtas_entry) == 0))
+ prom_print(RELOC(" failed\n"));
+ else
+ prom_print(RELOC(" done\n"));
+}
+
X /*
X * We enter here early on, when the Open Firmware prom is still
X * handling exceptions and the MMU hash table for us.
@@ -566,7 +612,7 @@
X {
X int chrp = 0;
X unsigned long mem;
- ihandle prom_rtas, prom_mmu, prom_op;
+ ihandle prom_mmu, prom_op;
X unsigned long offset = reloc_offset();
X int l;
X char *p, *d;
@@ -650,47 +696,7 @@
X mem = ALIGN(mem + strlen(d) + 1);
X }
X
- prom_rtas = call_prom(RELOC("finddevice"), 1, 1, RELOC("/rtas"));
- if (prom_rtas != (void *) -1) {
- int i, nargs;
- struct prom_args prom_args;
-
- RELOC(rtas_size) = 0;
- call_prom(RELOC("getprop"), 4, 1, prom_rtas,
- RELOC("rtas-size"), &RELOC(rtas_size), sizeof(rtas_size));
- prom_print(RELOC("instantiating rtas"));
- if (RELOC(rtas_size) == 0) {
- RELOC(rtas_data) = 0;
- } else {
- /*
- * Ask OF for some space for RTAS.
- * Actually OF has bugs so we just arbitrarily
- * use memory at the 6MB point.
- */
- RELOC(rtas_data) = 6 << 20;
- prom_print(RELOC(" at "));
- prom_print_hex(RELOC(rtas_data));
- }
- prom_rtas = call_prom(RELOC("open"), 1, 1, RELOC("/rtas"));
- prom_print(RELOC("..."));
- nargs = 3;
- prom_args.service = RELOC("call-method");
- prom_args.nargs = nargs;
- prom_args.nret = 2;
- prom_args.args[0] = RELOC("instantiate-rtas");
- prom_args.args[1] = prom_rtas;
- prom_args.args[2] = (void *) RELOC(rtas_data);
- RELOC(prom)(&prom_args);
- if (prom_args.args[nargs] != 0)
- i = 0;
- else
- i = (int)prom_args.args[nargs+1];
- RELOC(rtas_entry) = i;
- if ((RELOC(rtas_entry) == -1) || (RELOC(rtas_entry) == 0))
- prom_print(RELOC(" failed\n"));
- else
- prom_print(RELOC(" done\n"));
- }
+ prom_instantiate_rtas();
X
X #ifdef CONFIG_PPC64BRIDGE
X /*
@@ -737,7 +743,7 @@
X
X /* We assume the phys. address size is 3 cells */
X if (prom_args.args[nargs] != 0)
- prom_print(RELOC(" (translate failed) "));
+ prom_print(RELOC(" (translate failed)\n"));
X else
X phys = (unsigned long)prom_args.args[nargs+3];
X }
@@ -752,8 +758,6 @@
X if (prom_version >= 3) {
X prom_print(RELOC("Calling quiesce ...\n"));
X call_prom(RELOC("quiesce"), 0, 0);
- offset = reloc_offset();
- phys = offset + KERNELBASE;
X }
X
X #ifdef CONFIG_BOOTX_TEXT
@@ -769,7 +773,9 @@
X }
X #endif
X
- prom_print(RELOC("returning from prom_init\n"));
+ prom_print(RELOC("returning "));
+ prom_print_hex(phys);
+ prom_print(RELOC(" from prom_init\n"));
X RELOC(prom_stdout) = 0;
X return phys;
X }
@@ -836,9 +842,8 @@
X }
X
X /* Calc BAT values for mapping the display and store them
- * in disp_BATH and disp_BATL. Those values are then used
- * from head.S to map the display during identify_machine()
- * and MMU_Init()
+ * in disp_BAT. Those values are then used from head.S to map
+ * the display during identify_machine() and MMU_Init()
X *
X * For now, the display is mapped in place (1:1). This should
X * be changed if the display physical address overlaps
@@ -862,13 +867,13 @@
X if ((_get_PVR() >> 16) != 1) {
X /* 603, 604, G3, G4, ... */
X addr &= 0xFF000000UL;
- RELOC(disp_BATU) = addr | (BL_16M<<2) | 2;
- RELOC(disp_BATL) = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW);
+ RELOC(disp_BAT[0]) = addr | (BL_16M<<2) | 2;
+ RELOC(disp_BAT[1]) = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW);
X } else {
X /* 601 */
X addr &= 0xFF800000UL;
- RELOC(disp_BATU) = addr | (_PAGE_NO_CACHE | PP_RWXX) | 4;
- RELOC(disp_BATL) = addr | BL_8M | 0x40;
+ RELOC(disp_BAT[0]) = addr | (_PAGE_NO_CACHE | PP_RWXX) | 4;
+ RELOC(disp_BAT[1]) = addr | BL_8M | 0x40;
X }
X bi->logicalDisplayBase = bi->dispDeviceBase;
X }
@@ -1003,34 +1008,52 @@
X unsigned address;
X boot_infos_t* bi;
X unsigned long offset = reloc_offset();
-
- prom_print(RELOC("Initializing fake screen\n"));
-
- call_prom(RELOC("getprop"), 4, 1, dp, RELOC("width"),
- &width, sizeof(width));
- call_prom(RELOC("getprop"), 4, 1, dp, RELOC("height"),
- &height, sizeof(height));
- call_prom(RELOC("getprop"), 4, 1, dp, RELOC("depth"),
- &depth, sizeof(depth));
+ struct pci_reg_property addrs[8];
+ int i, naddrs;
+ char name[32];
+ char *getprop = RELOC("getprop");
+
+ prom_print(RELOC("Initializing fake screen: "));
+
+ memset(name, 0, sizeof(name));
+ call_prom(getprop, 4, 1, dp, RELOC("name"), name, sizeof(name));
+ name[sizeof(name)-1] = 0;
+ prom_print(name);
+ prom_print(RELOC("\n"));
+ call_prom(getprop, 4, 1, dp, RELOC("width"), &width, sizeof(width));
+ call_prom(getprop, 4, 1, dp, RELOC("height"), &height, sizeof(height));
+ call_prom(getprop, 4, 1, dp, RELOC("depth"), &depth, sizeof(depth));
X pitch = width * ((depth + 7) / 8);
- call_prom(RELOC("getprop"), 4, 1, dp, RELOC("linebytes"),
+ call_prom(getprop, 4, 1, dp, RELOC("linebytes"),
X &pitch, sizeof(pitch));
- address = 0;
- if (pitch == 1) {
- address = 0xfa000000;
+ if (pitch == 1)
X pitch = 0x1000; /* for strange IBM display */
- }
- call_prom(RELOC("getprop"), 4, 1, dp, RELOC("address"),
+ address = 0;
+ call_prom(getprop, 4, 1, dp, RELOC("address"),
X &address, sizeof(address));
X if (address == 0) {
- prom_print(RELOC("Failed to get address\n"));
- return;
+ /* look for an assigned address with a size of >= 1MB */
+ naddrs = (int) call_prom(getprop, 4, 1, dp,
+ RELOC("assigned-addresses"),
+ addrs, sizeof(addrs));
+ naddrs /= sizeof(struct pci_reg_property);
+ for (i = 0; i < naddrs; ++i) {
+ if (addrs[i].size_lo >= (1 << 20)) {
+ address = addrs[i].addr.a_lo;
+ /* use the BE aperture if possible */
+ if (addrs[i].size_lo >= (16 << 20))
+ address += (8 << 20);
+ break;
+ }
+ }
+ if (address == 0) {
+ prom_print(RELOC("Failed to get address\n"));
+ return;
+ }
X }
-#if 0
X /* kludge for valkyrie */
- if (strcmp(dp->name, "valkyrie") == 0)
- address += 0x1000;
-#endif
+ if (strcmp(name, RELOC("valkyrie")) == 0)
+ address += 0x1000;
X
X RELOC(disp_bi) = &fake_bi;
X bi = PTRRELOC((&fake_bi));
@@ -1334,11 +1357,19 @@
X */
X if (get_property(node, "interrupt-controller", &l)) {
X int i,j;
+ int cvt_irq;
+
+ /* XXX on chrp, offset interrupt numbers for the
+ 8259 by 0, those for the openpic by 16 */
+ cvt_irq = _machine == _MACH_chrp
+ && get_property(node, "interrupt-parent", NULL) == 0;
X np->intrs = (struct interrupt_info *) mem_start;
X np->n_intrs = ipsize / isize;
X mem_start += np->n_intrs * sizeof(struct interrupt_info);
X for (i = 0; i < np->n_intrs; ++i) {
X np->intrs[i].line = *interrupts++;
+ if (cvt_irq)
+ np->intrs[i].line = openpic_to_irq(np->intrs[i].line);
X np->intrs[i].sense = 0;
X if (isize > 1)
X np->intrs[i].sense = *interrupts++;
@@ -2072,7 +2103,6 @@
X * changes.
X */
X
-__init
X void
X map_bootx_text(void)
X {
@@ -2083,7 +2113,10 @@
X offset = ((unsigned long) disp_bi->dispDeviceBase) - base;
X size = disp_bi->dispDeviceRowBytes * disp_bi->dispDeviceRect[3] + offset
X + disp_bi->dispDeviceRect[0];
- disp_bi->logicalDisplayBase = ioremap(base, size) + offset;
+ disp_bi->logicalDisplayBase = ioremap(base, size);
+ if (disp_bi->logicalDisplayBase == 0)
+ return;
+ disp_bi->logicalDisplayBase += offset;
X bootx_text_mapped = 1;
X }
X
@@ -2102,6 +2135,35 @@
X return base;
X }
X
+/* Adjust the display to a new resolution */
+void
+bootx_update_display(unsigned long phys, int width, int height,
+ int depth, int pitch)
+{
+ if (disp_bi == 0)
+ return;
+ /* check it's the same frame buffer (within 16MB) */
+ if ((phys ^ (unsigned long)disp_bi->dispDeviceBase) & 0xff000000)
+ return;
+
+ disp_bi->dispDeviceBase = (__u8 *) phys;
+ disp_bi->dispDeviceRect[0] = 0;
+ disp_bi->dispDeviceRect[1] = 0;
+ disp_bi->dispDeviceRect[2] = width;
+ disp_bi->dispDeviceRect[3] = height;
+ disp_bi->dispDeviceDepth = depth;
+ disp_bi->dispDeviceRowBytes = pitch;
+ if (bootx_text_mapped) {
+ iounmap(disp_bi->logicalDisplayBase);
+ bootx_text_mapped = 0;
+ }
+ map_bootx_text();
+ g_loc_X = 0;
+ g_loc_Y = 0;
+ g_max_loc_X = width / 8;
+ g_max_loc_Y = height / 16;
+}
+
X __pmac
X static void
X clearscreen(void)
@@ -2162,6 +2224,9 @@
X (bi->dispDeviceDepth >> 3)) >> 2;
X int i,j;
X
+#ifdef CONFIG_ADB_PMU
+ pmu_suspend(); /* PMU will not shut us down ! */
+#endif
X for (i=0; i<(bi->dispDeviceRect[3] - bi->dispDeviceRect[1] - 16); i++)
X {
X unsigned long *src_ptr = src;
@@ -2178,6 +2243,9 @@
X *(dst_ptr++) = 0;
X dst += (bi->dispDeviceRowBytes >> 2);
X }
+#ifdef CONFIG_ADB_PMU
+ pmu_resume(); /* PMU will not shut us down ! */
+#endif
X }
X #endif /* ndef NO_SCROLL */
X
diff -u --recursive --new-file v2.4.0-test8/linux/arch/ppc/kernel/setup.c linux/arch/ppc/kernel/setup.c
--- v2.4.0-test8/linux/arch/ppc/kernel/setup.c Thu Jul 13 09:42:50 2000
+++ linux/arch/ppc/kernel/setup.c Sun Sep 17 09:48:07 2000
@@ -35,6 +35,8 @@
X #include <asm/bootx.h>
X #include <asm/machdep.h>
X #include <asm/feature.h>
+#include <asm/uaccess.h>
+
X #ifdef CONFIG_OAK
X #include "oak_setup.h"
X #endif /* CONFIG_OAK */
@@ -655,16 +657,18 @@
X }
X
X /* Checks "l2cr=xxxx" command-line option */
-void ppc_setup_l2cr(char *str, int *ints)
+int ppc_setup_l2cr(char *str)
X {
X if ( ((_get_PVR() >> 16) == 8) || ((_get_PVR() >> 16) == 12) )
X {
X unsigned long val = simple_strtoul(str, NULL, 0);
X printk(KERN_INFO "l2cr set to %lx\n", val);
- _set_L2CR(0);
- _set_L2CR(val);
+ _set_L2CR(0); /* force invalidate by disable cache */
+ _set_L2CR(val); /* and enable it */
X }
+ return 1;
X }
+__setup("l2cr=", ppc_setup_l2cr);
X
X void __init ppc_init(void)
X {
@@ -683,6 +687,9 @@
X extern char *klimit;
X extern void do_init_bootmem(void);
X
+ /* so udelay does something sensible, assume <= 1000 bogomips */
+ loops_per_sec = 500000000;
+
X #ifdef CONFIG_ALL_PPC
X feature_init();
X #endif
@@ -737,6 +744,7 @@
X if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
X
X paging_init();
+ sort_exception_table();
X }
X
X void ppc_generic_ide_fix_driveid(struct hd_driveid *id)
diff -u --recursive --new-file v2.4.0-test8/linux/arch/ppc/kernel/signal.c linux/arch/ppc/kernel/signal.c
--- v2.4.0-test8/linux/arch/ppc/kernel/signal.c Sun Sep 3 11:50:26 2000
+++ linux/arch/ppc/kernel/signal.c Sun Sep 17 09:48:07 2000
@@ -154,7 +154,7 @@
X }
X
X
-asmlinkage int
+int
X sys_sigaltstack(const stack_t *uss, stack_t *uoss)
X {
X struct pt_regs *regs = (struct pt_regs *) &uss;
@@ -232,7 +232,7 @@
X * Each of these things must be a multiple of 16 bytes in size.
X *
X */
-asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
+int sys_rt_sigreturn(struct pt_regs *regs)
X {
X struct rt_sigframe *rt_sf;
X struct sigcontext_struct sigctx;
@@ -301,7 +301,6 @@
X return ret;
X
X badframe:
- lock_kernel();
X do_exit(SIGSEGV);
X }
X
@@ -351,7 +350,6 @@
X printk("badframe in setup_rt_frame, regs=%p frame=%p newsp=%lx\n",
X regs, frame, newsp);
X #endif
- lock_kernel();
X do_exit(SIGSEGV);
X }
X
@@ -418,7 +416,6 @@
X return ret;
X
X badframe:
- lock_kernel();
X do_exit(SIGSEGV);
X }
X
@@ -460,7 +457,6 @@
X printk("badframe in setup_frame, regs=%p frame=%p newsp=%lx\n",
X regs, frame, newsp);
X #endif
- lock_kernel();
X do_exit(SIGSEGV);
X }
X
@@ -541,7 +537,6 @@
X regs, frame, *newspp);
X printk("sc=%p sig=%d ka=%p info=%p oldset=%p\n", sc, sig, ka, info, oldset);
X #endif
- lock_kernel();
X do_exit(SIGSEGV);
X }
X
@@ -645,7 +640,6 @@
X /* FALLTHRU */
X
X default:
- lock_kernel();
X sigaddset(&current->pending.signal, signr);
X recalc_sigpending(current);
X current->flags |= PF_SIGNALED;
@@ -663,6 +657,7 @@
X
X /* Whee! Actually deliver the signal. */
X handle_signal(signr, ka, &info, oldset, regs, &newsp, frame);
+ break;
X }
X
X if (regs->trap == 0x0C00 /* System Call! */ &&
diff -u --recursive --new-file v2.4.0-test8/linux/arch/ppc/kernel/smp.c linux/arch/ppc/kernel/smp.c
--- v2.4.0-test8/linux/arch/ppc/kernel/smp.c Tue Sep 5 13:50:02 2000
+++ linux/arch/ppc/kernel/smp.c Sun Sep 17 09:48:07 2000
@@ -62,72 +62,62 @@
X int start_secondary(void *);
X extern int cpu_idle(void *unused);
X u_int openpic_read(volatile u_int *addr);
+void smp_call_function_interrupt(void);
+void smp_message_pass(int target, int msg, unsigned long data, int wait);
X
+/* register for interrupting the primary processor on the powersurge */
+/* N.B. this is actually the ethernet ROM! */
+#define PSURGE_PRI_INTR 0xf3019000
X /* register for interrupting the secondary processor on the powersurge */
-#define PSURGE_INTR ((volatile unsigned *)0xf80000c0)
+#define PSURGE_SEC_INTR 0xf80000c0
+/* register for storing the start address for the secondary processor */
+#define PSURGE_START 0xf2800000
+/* virtual addresses for the above */
+volatile u32 *psurge_pri_intr;
+volatile u32 *psurge_sec_intr;
+volatile u32 *psurge_start;
+
+/* Since OpenPIC has only 4 IPIs, we use slightly different message numbers. */
+#define PPC_MSG_CALL_FUNCTION 0
+#define PPC_MSG_RESCHEDULE 1
+#define PPC_MSG_INVALIDATE_TLB 2
+#define PPC_MSG_XMON_BREAK 3
+
+static inline void set_tb(unsigned int upper, unsigned int lower)
+{
+ mtspr(SPRN_TBWU, upper);
+ mtspr(SPRN_TBWL, lower);
+}
X
X void smp_local_timer_interrupt(struct pt_regs * regs)
X {
X int cpu = smp_processor_id();
- extern void update_one_process(struct task_struct *,unsigned long,
- unsigned long,unsigned long,int);
- if (!--prof_counter[cpu]) {
- int user=0,system=0;
- struct task_struct * p = current;
-
- /*
- * After doing the above, we need to make like
- * a normal interrupt - otherwise timer interrupts
- * ignore the global interrupt lock, which is the
- * WrongThing (tm) to do.
- */
-
- if (user_mode(regs))
- user=1;
- else
- system=1;
-
- if (p->pid) {
- update_one_process(p, 1, user, system, cpu);
-
- p->counter -= 1;
- if (p->counter <= 0) {
- p->counter = 0;
- current->need_resched = 1;
- }
- if (p->nice > 0) {
- kstat.cpu_nice += user;
- kstat.per_cpu_nice[cpu] += user;
- } else {
- kstat.cpu_user += user;
- kstat.per_cpu_user[cpu] += user;
- }
-
- kstat.cpu_system += system;
- kstat.per_cpu_system[cpu] += system;
X
- }
+ if (!--prof_counter[cpu]) {
+ update_process_times(user_mode(regs));
X prof_counter[cpu]=prof_multiplier[cpu];
X }
X }
X
-void smp_message_recv(int msg)
+void smp_message_recv(int msg, struct pt_regs *regs)
X {
X ipi_count++;
X
- switch( msg )
- {
- case MSG_STOP_CPU:
- __cli();
- while (1) ;
+ switch( msg ) {
+ case PPC_MSG_CALL_FUNCTION:
+ smp_call_function_interrupt();
X break;
- case MSG_RESCHEDULE:
+ case PPC_MSG_RESCHEDULE:
X current->need_resched = 1;
X break;
- case MSG_INVALIDATE_TLB:
+ case PPC_MSG_INVALIDATE_TLB:
X _tlbia();
- case 0xf0f0: /* pmac syncing time bases - just return */
X break;
+#ifdef CONFIG_XMON
+ case PPC_MSG_XMON_BREAK:
+ xmon(regs);
+ break;
+#endif /* CONFIG_XMON */
X default:
X printk("SMP %d: smp_message_recv(): unknown msg %d\n",
X smp_processor_id(), msg);
@@ -142,25 +132,38 @@
X * smp_message[].
X *
X * This is because don't have several IPI's on the PowerSurge even though
- * we do on the chrp. It would be nice to use actual IPI's such as with openpic
- * rather than this.
+ * we do on the chrp. It would be nice to use actual IPI's such as with
+ * openpic rather than this.
X * -- Cort
X */
X int pmac_smp_message[NR_CPUS];
-void pmac_smp_message_recv(void)
+void pmac_smp_message_recv(struct pt_regs *regs)
X {
- int msg = pmac_smp_message[smp_processor_id()];
-
+ int cpu = smp_processor_id();
+ int msg;
+
X /* clear interrupt */
- out_be32(PSURGE_INTR, ~0);
-
- /* make sure msg is for us */
- if ( msg == -1 ) return;
+ if (cpu == 1)
+ out_be32(psurge_sec_intr, ~0);
+
+ if (smp_num_cpus < 2)
+ return;
+
+ /* make sure there is a message there */
+ msg = pmac_smp_message[cpu];
+ if (msg == 0)
+ return;
X
- smp_message_recv(msg);
-
X /* reset message */
- pmac_smp_message[smp_processor_id()] = -1;
+ pmac_smp_message[cpu] = 0;
+
+ smp_message_recv(msg - 1, regs);
+}
+
+void
+pmac_primary_intr(int irq, void *d, struct pt_regs *regs)
+{
+ pmac_smp_message_recv(regs);
X }
X
X /*
@@ -171,7 +174,7 @@
X void smp_send_tlb_invalidate(int cpu)
X {
X if ( (_get_PVR()>>16) == 8 )
- smp_message_pass(MSG_ALL_BUT_SELF, MSG_INVALIDATE_TLB, 0, 0);
+ smp_message_pass(MSG_ALL_BUT_SELF, PPC_MSG_INVALIDATE_TLB, 0, 0);
X }
X
X void smp_send_reschedule(int cpu)
@@ -187,18 +190,135 @@
X */
X /* This is only used if `cpu' is running an idle task,
X so it will reschedule itself anyway... */
- smp_message_pass(cpu, MSG_RESCHEDULE, 0, 0);
+ smp_message_pass(cpu, PPC_MSG_RESCHEDULE, 0, 0);
+}
+
+#ifdef CONFIG_XMON
+void smp_send_xmon_break(int cpu)
+{
+ smp_message_pass(cpu, PPC_MSG_XMON_BREAK, 0, 0);
+}
+#endif /* CONFIG_XMON */
+
+static void stop_this_cpu(void *dummy)
+{
+ __cli();
+ while (1)
+ ;
X }
X
X void smp_send_stop(void)
X {
- smp_message_pass(MSG_ALL_BUT_SELF, MSG_STOP_CPU, 0, 0);
+ smp_call_function(stop_this_cpu, NULL, 1, 0);
+ smp_num_cpus = 1;
+}
+
+/*
+ * Structure and data for smp_call_function(). This is designed to minimise
+ * static memory requirements. It also looks cleaner.
+ * Stolen from the i386 version.
+ */
+static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
+
+static volatile struct call_data_struct {
+ void (*func) (void *info);
+ void *info;
+ atomic_t started;
+ atomic_t finished;
+ int wait;
+} *call_data = NULL;
+
+/*
+ * this function sends a 'generic call function' IPI to all other CPUs
+ * in the system.
+ */
+
+int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
+ int wait)
+/*
+ * [SUMMARY] Run a function on all other CPUs.
+ * <func> The function to run. This must be fast and non-blocking.
+ * <info> An arbitrary pointer to pass to the function.
+ * <nonatomic> currently unused.
+ * <wait> If true, wait (atomically) until function has completed on other CPUs.
+ * [RETURNS] 0 on success, else a negative status code. Does not return until
+ * remote CPUs are nearly ready to execute <<func>> or are or have executed.
+ *
+ * You must not call this function with disabled interrupts or from a
+ * hardware interrupt handler, you may call it from a bottom half handler.
+ */
+{
+ struct call_data_struct data;
+ int ret = -1, cpus = smp_num_cpus-1;
+ int timeout;
+
+ if (!cpus)
+ return 0;
+
+ data.func = func;
+ data.info = info;
+ atomic_set(&data.started, 0);
+ data.wait = wait;
+ if (wait)
+ atomic_set(&data.finished, 0);
+
+ spin_lock_bh(&call_lock);
+ call_data = &data;
+ /* Send a message to all other CPUs and wait for them to respond */
+ smp_message_pass(MSG_ALL_BUT_SELF, PPC_MSG_CALL_FUNCTION, 0, 0);
+
+ /* Wait for response */
+ timeout = 1000000;
+ while (atomic_read(&data.started) != cpus) {
+ if (--timeout == 0) {
+ printk("smp_call_function on cpu %d: other cpus not responding (%d)\n",
+ smp_processor_id(), atomic_read(&data.started));
+ goto out;
+ }
+ barrier();
+ udelay(1);
+ }
+
+ if (wait) {
+ timeout = 1000000;
+ while (atomic_read(&data.finished) != cpus) {
+ if (--timeout == 0) {
+ printk("smp_call_function on cpu %d: other cpus not finishing (%d/%d)\n",
+ smp_processor_id(), atomic_read(&data.finished), atomic_read(&data.started));
+ goto out;
+ }
+ barrier();
+ udelay(1);
+ }
+ }
+ ret = 0;
+
+ out:
+ spin_unlock_bh(&call_lock);
+ return ret;
+}
+
+void smp_call_function_interrupt(void)
+{
+ void (*func) (void *info) = call_data->func;
+ void *info = call_data->info;
+ int wait = call_data->wait;
+
+ /*
+ * Notify initiating CPU that I've grabbed the data and am
+ * about to execute the function
+ */
+ atomic_inc(&call_data->started);
+ /*
+ * At this point the info structure may be out of scope unless wait==1
+ */
+ (*func)(info);
+ if (wait)
+ atomic_inc(&call_data->finished);
X }
X
X void smp_message_pass(int target, int msg, unsigned long data, int wait)
X {
- int i;
-
X if ( !(_machine & (_MACH_Pmac|_MACH_chrp|_MACH_prep|_MACH_gemini)) )
X return;
X
@@ -212,31 +332,29 @@
X * the recipient won't know the message was destined
X * for it. -- Cort
X */
- for ( i = 0; i <= smp_num_cpus ; i++ )
- pmac_smp_message[i] = -1;
- switch( target )
- {
- case MSG_ALL:
- pmac_smp_message[smp_processor_id()] = msg;
- /* fall through */
- case MSG_ALL_BUT_SELF:
- for ( i = 0 ; i < smp_num_cpus ; i++ )
- if ( i != smp_processor_id () )
- pmac_smp_message[i] = msg;
- break;
- default:
- pmac_smp_message[target] = msg;
- break;
+ if (smp_processor_id() == 0) {
+ /* primary cpu */
+ if (target == 1 || target == MSG_ALL_BUT_SELF
+ || target == MSG_ALL) {
+ pmac_smp_message[1] = msg + 1;
+ /* interrupt secondary processor */
+ out_be32(psurge_sec_intr, ~0);
+ out_be32(psurge_sec_intr, 0);
+ }
+ } else {
+ /* secondary cpu */
+ if (target == 0 || target == MSG_ALL_BUT_SELF
+ || target == MSG_ALL) {
+ pmac_smp_message[0] = msg + 1;
+ /* interrupt primary processor */
+ in_be32(psurge_pri_intr);
+ }
+ }
+ if (target == smp_processor_id() || target == MSG_ALL) {
+ /* sending a message to ourself */
+ /* XXX maybe we shouldn't do this if ints are off */
+ smp_message_recv(msg, NULL);
X }
- /* interrupt secondary processor */
- out_be32(PSURGE_INTR, ~0);
- out_be32(PSURGE_INTR, 0);
- /*
- * Assume for now that the secondary doesn't send
- * IPI's -- Cort
- */
- /* interrupt primary */
- /**(volatile unsigned long *)(0xf3019000);*/
X break;
X case _MACH_chrp:
X case _MACH_prep:
@@ -261,7 +379,7 @@
X #else /* CONFIG_POWER4 */
X /* for now, only do reschedule messages
X since we only have one IPI */
- if (msg != MSG_RESCHEDULE)
+ if (msg != PPC_MSG_RESCHEDULE)
X break;
X for (i = 0; i < smp_num_cpus; ++i) {
X if (target == MSG_ALL || target == i
@@ -319,7 +437,10 @@
X {
X case _MACH_Pmac:
X /* assume powersurge board - 2 processors -- Cort */
- cpu_nr = 2;
+ cpu_nr = 2;
+ psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4);
+ psurge_sec_intr = ioremap(PSURGE_SEC_INTR, 4);
+ psurge_start = ioremap(PSURGE_START, 4);
X break;
X case _MACH_chrp:
X if (OpenPIC)
@@ -370,13 +491,11 @@
X {
X case _MACH_Pmac:
X /* setup entry point of secondary processor */
- *(volatile unsigned long *)(0xf2800000) =
- (unsigned long)__secondary_start_psurge-KERNELBASE;
- eieio();
+ out_be32(psurge_start, __pa(__secondary_start_psurge));
X /* interrupt secondary to begin executing code */
- out_be32(PSURGE_INTR, ~0);
+ out_be32(psurge_sec_intr, ~0);
X udelay(1);
- out_be32(PSURGE_INTR, 0);
+ out_be32(psurge_sec_intr, 0);
X break;
X case _MACH_chrp:
X *(unsigned long *)KERNELBASE = i;
@@ -399,9 +518,6 @@
X if ( cpu_callin_map[i] )
X {
X printk("Processor %d found.\n", i);
- /* this sync's the decr's -- Cort */
- if ( _machine == _MACH_Pmac )
- set_dec(decrementer_count);
X smp_num_cpus++;
X } else {
X printk("Processor %d is stuck.\n", i);
@@ -415,9 +531,25 @@
X {
X /* reset the entry point so if we get another intr we won't
X * try to startup again */
- *(volatile unsigned long *)(0xf2800000) = 0x100;
- /* send interrupt to other processors to start decr's on all cpus */
- smp_message_pass(1,0xf0f0, 0, 0);
+ out_be32(psurge_start, 0x100);
+ if (request_irq(30, pmac_primary_intr, 0, "primary IPI", 0))
+ printk(KERN_ERR "Couldn't get primary IPI interrupt");
+ /*
+ * The decrementers of both cpus are frozen at this point
+ * until we give the secondary cpu another interrupt.
+ * We set them both to decrementer_count and then send
+ * the interrupt. This should get the decrementers
+ * synchronized.
+ * -- paulus.
+ */
+ set_dec(tb_ticks_per_jiffy);
+ if ((_get_PVR() >> 16) != 1) {
+ set_tb(0, 0); /* set timebase if not 601 */
+ last_jiffy_stamp(0) = 0;
+ }
+ out_be32(psurge_sec_intr, ~0);
+ udelay(1);
+ out_be32(psurge_sec_intr, 0);
X }
X }
X
@@ -447,8 +579,11 @@
X void __init smp_callin(void)
X {
X smp_store_cpu_info(current->processor);
- set_dec(decrementer_count);
-
+ set_dec(tb_ticks_per_jiffy);
+ if (_machine == _MACH_Pmac && (_get_PVR() >> 16) != 1) {
+ set_tb(0, 0); /* set timebase if not 601 */
+ last_jiffy_stamp(current->processor) = 0;
+ }
X init_idle();
X cpu_callin_map[current->processor] = 1;
X
diff -u --recursive --new-file v2.4.0-test8/linux/arch/ppc/kernel/syscalls.c linux/arch/ppc/kernel/syscalls.c
--- v2.4.0-test8/linux/arch/ppc/kernel/syscalls.c Tue Jul 18 15:03:56 2000
+++ linux/arch/ppc/kernel/syscalls.c Sun Sep 17 09:48:07 2000
@@ -45,7 +45,7 @@
X {
X }
X
-asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on)
+int sys_ioperm(unsigned long from, unsigned long num, int on)
X {
X printk(KERN_ERR "sys_ioperm()\n");
X return -EIO;
@@ -74,7 +74,7 @@
X *
X * This is really horribly ugly.
X */
-asmlinkage int
+int
X sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth)
X {
X int version, ret;
@@ -172,7 +172,7 @@
X * sys_pipe() is the normal C calling standard for creating
X * a pipe. It's not the way unix traditionally does this, though.
X */
-asmlinkage int sys_pipe(int *fildes)
+int sys_pipe(int *fildes)
X {
X int fd[2];
X int error;
@@ -185,19 +185,19 @@
X return error;
X }
X
-asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, off_t offset)
+unsigned long sys_mmap(unsigned long addr, size_t len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, off_t offset)
X {
X struct file * file = NULL;
X int ret = -EBADF;
X
+ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
X if (!(flags & MAP_ANONYMOUS)) {
X if (!(file = fget(fd)))
X goto out;
X }
X
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
X down(&current->mm->mmap_sem);
X ret = do_mmap(file, addr, len, prot, flags, offset);
X up(&current->mm->mmap_sem);
@@ -207,7 +207,7 @@
X return ret;
X }
X
-extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+extern int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
X
X /*
X * Due to some executables calling the wrong select we sometimes
@@ -215,7 +215,7 @@
X * (a single ptr to them all args passed) then calls
X * sys_select() with the appropriate args. -- Cort
X */
-asmlinkage int
+int
X ppc_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval *tvp)
X {
X if ( (unsigned long)n >= 4096 )
@@ -232,14 +232,14 @@
X return sys_select(n, inp, outp, exp, tvp);
X }
X
-asmlinkage int sys_pause(void)
+int sys_pause(void)
X {
X current->state = TASK_INTERRUPTIBLE;
X schedule();
X return -ERESTARTNOHAND;
X }
X
-asmlinkage int sys_uname(struct old_utsname * name)
+int sys_uname(struct old_utsname * name)
X {
X int err = -EFAULT;
X
@@ -250,7 +250,7 @@
X return err;
X }
X
-asmlinkage int sys_olduname(struct oldold_utsname * name)
+int sys_olduname(struct oldold_utsname * name)
X {
X int error;
X
diff -u --recursive --new-file v2.4.0-test8/linux/arch/ppc/kernel/time.c linux/arch/ppc/kernel/time.c
--- v2.4.0-test8/linux/arch/ppc/kernel/time.c Thu Jul 13 09:42:50 2000
+++ linux/arch/ppc/kernel/time.c Sun Sep 17 09:48:07 2000
@@ -6,6 +6,27 @@
X * Paul Mackerras' version and mine for PReP and Pmac.
X * MPC8xx/MBX changes by Dan Malek (dma...@jlc.net).
X *
+ * First round of bugfixes by Gabriel Paubert (pau...@iram.es)
+ * to make clock more stable (2.4.0-test5). The only thing
+ * that this code assumes is that the timebases have been synchronized
+ * by firmware on SMP and are never stopped (never do sleep
+ * on SMP then, nap and doze are OK).
+ *
+ * TODO (not necessarily in this file):
+ * - improve precision and reproducibility of timebase frequency
+ * measurement at boot time.
+ * - get rid of xtime_lock for gettimeofday (generic kernel problem
+ * to be implemented on all architectures for SMP scalability and
+ * eventually implementing gettimeofday without entering the kernel).
+ * - put all time/clock related variables in a single structure
+ * to minimize number of cache lines touched by gettimeofday()
+ * - for astronomical applications: add a new function to get
+ * non ambiguous timestamps even around leap seconds. This needs
+ * a new timestamp format and a good name.
+ *
+ *
+ * The following comment is partially obsolete (at least the long wait
+ * is no more a valid reason):
X * Since the MPC8xx has a programmable interrupt timer, I decided to
X * use that rather than the decrementer. Two reasons: 1.) the clock
X * frequency is low, causing 2.) a long wait in the timer interrupt
@@ -49,18 +70,32 @@
X void smp_local_timer_interrupt(struct pt_regs *);
X
X /* keep track of when we need to update the rtc */
-time_t last_rtc_update = 0;
+time_t last_rtc_update;
X extern rwlock_t xtime_lock;
X
X /* The decrementer counts down by 128 every 128ns on a 601. */
X #define DECREMENTER_COUNT_601 (1000000000 / HZ)
-#define COUNT_PERIOD_NUM_601 1
-#define COUNT_PERIOD_DEN_601 1000
X
-unsigned decrementer_count; /* count value for 1e6/HZ microseconds */
-unsigned count_period_num; /* 1 decrementer count equals */
-unsigned count_period_den; /* count_period_num / count_period_den us */
-unsigned long last_tb;
+unsigned tb_ticks_per_jiffy;
+unsigned tb_to_us;
+unsigned tb_last_stamp;
+
+extern unsigned long wall_jiffies;
+
+static long time_offset;
+
+/* Timer interrupt helper function */
+static inline int tb_delta(unsigned *jiffy_stamp) {
+ int delta;
+ if (__USE_RTC()) {
+ delta = get_rtcl();
+ if (delta < *jiffy_stamp) *jiffy_stamp -= 1000000000;
+ delta -= *jiffy_stamp;
+ } else {
+ delta = get_tbl() - *jiffy_stamp;
+ }
+ return delta;
+}
X
X /*
X * timer_interrupt - gets called when the decrementer overflows,
@@ -69,88 +104,56 @@
X */
X int timer_interrupt(struct pt_regs * regs)
X {
- int dval, d;
-#if 0
- unsigned long flags;
-#endif
+ int next_dec;
X unsigned long cpu = smp_processor_id();
-
+ unsigned jiffy_stamp = last_jiffy_stamp(cpu);
+
X hardirq_enter(cpu);
-#ifdef CONFIG_SMP
- {
- unsigned int loops = 100000000;
- while (test_bit(0, &global_irq_lock)) {
- if (smp_processor_id() == global_irq_holder) {
- printk("uh oh, interrupt while we hold global irq lock!\n");
-#ifdef CONFIG_XMON
- xmon(0);
-#endif
- break;
- }
- if (loops-- == 0) {
- printk("do_IRQ waiting for irq lock (holder=%d)\n", global_irq_holder);
-#ifdef CONFIG_XMON
- xmon(0);
-#endif
- }
- }
- }
-#endif /* CONFIG_SMP */
X
- dval = get_dec();
- /*
- * Wait for the decrementer to change, then jump
- * in and add decrementer_count to its value
- * (quickly, before it changes again!)
- */
- while ((d = get_dec()) == dval)
- ;
- asm volatile("mftb %0" : "=r" (last_tb) );
- /*
- * Don't play catchup between the call to time_init()
- * and sti() in init/main.c.
- *
- * This also means if we're delayed for > HZ
- * we lose those ticks. If we're delayed for > HZ
- * then we have something wrong anyway, though.
- *
- * -- Cort
- */
- if ( d < (-1*decrementer_count) )
- d = 0;
- set_dec(d + decrementer_count);
- if ( !smp_processor_id() )
- {
+ do {
+ jiffy_stamp += tb_ticks_per_jiffy;
+ if (smp_processor_id()) continue;
+ /* We are in an interrupt, no need to save/restore flags */
+ write_lock(&xtime_lock);
+ tb_last_stamp = jiffy_stamp;
X do_timer(regs);
-#if 0
- /* -- BenH -- I'm removing this for now since it can cause various
- * troubles with local-time RTCs. Now that we have a
- * /dev/rtc that uses ppc_md.set_rtc_time() on mac, it
- * should be possible to program the RTC from userland
- * in all cases.
- */
+
X /*
- * update the rtc when needed
+ * update the rtc when needed, this should be performed on the
+ * right fraction of a second. Half or full second ?
+ * Full second works on mk48t59 clocks, others need testing.
+ * Note that this update is basically only used through
+ * the adjtimex system calls. Setting the HW clock in
+ * any other way is a /dev/rtc and userland business.
+ * This is still wrong by -0.5/+1.5 jiffies because of the
+ * timer interrupt resolution and possible delay, but here we
+ * hit a quantization limit which can only be solved by higher
+ * resolution timers and decoupling time management from timer
+ * interrupts. This is also wrong on the clocks
+ * which require being written at the half second boundary.
+ * We should have an rtc call that only sets the minutes and
+ * seconds like on Intel to avoid problems with non UTC clocks.
X */
- read_lock_irqsave(&xtime_lock, flags);
- if ( (time_status & STA_UNSYNC) &&
- ((xtime.tv_sec > last_rtc_update + 60) ||
- (xtime.tv_sec < last_rtc_update)) )
- {
- if (ppc_md.set_rtc_time(xtime.tv_sec) == 0)
- last_rtc_update = xtime.tv_sec;
+ if ( (time_status & STA_UNSYNC) == 0 &&
+ xtime.tv_sec - last_rtc_update >= 659 &&
+ abs(xtime.tv_usec - (1000000-1000000/HZ)) < 500000/HZ &&
+ jiffies - wall_jiffies == 1) {
+ if (ppc_md.set_rtc_time(xtime.tv_sec+1 + time_offset) == 0)
+ last_rtc_update = xtime.tv_sec+1;
X else
- /* do it again in 60 s */
- last_rtc_update = xtime.tv_sec;
+ /* Try again one minute later */
+ last_rtc_update += 60;
X }
- read_unlock_irqrestore(&xtime_lock, flags);
-#endif
- }
+ write_unlock(&xtime_lock);
+ } while((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) < 0);
+ set_dec(next_dec);
+ last_jiffy_stamp(cpu) = jiffy_stamp;
+
X #ifdef CONFIG_SMP
X smp_local_timer_interrupt(regs);
X #endif
X
- if ( ppc_md.heartbeat && !ppc_md.heartbeat_count--)
+ if (ppc_md.heartbeat && !ppc_md.heartbeat_count--)
X ppc_md.heartbeat();
X
X hardirq_exit(cpu);
@@ -162,106 +165,138 @@
X */
X void do_gettimeofday(struct timeval *tv)
X {
- unsigned long flags, diff;
+ unsigned long flags;
+ unsigned delta, lost_ticks, usec, sec;
X
- save_flags(flags);
- cli();
X read_lock_irqsave(&xtime_lock, flags);
- *tv = xtime;
+ sec = xtime.tv_sec;
+ usec = xtime.tv_usec;
+ delta = tb_ticks_since(tb_last_stamp);
+#ifdef CONFIG_SMP
+ /* As long as timebases are not in sync, gettimeofday can only
+ * have jiffy resolution on SMP.
+ */
+ if (_machine != _MACH_Pmac)
+ delta = 0;
+#endif /* CONFIG_SMP */
+ lost_ticks = jiffies - wall_jiffies;
X read_unlock_irqrestore(&xtime_lock, flags);
- /* XXX we don't seem to have the decrementers synced properly yet */
-#ifndef CONFIG_SMP
- asm volatile("mftb %0" : "=r" (diff) );
- diff -= last_tb;
- tv->tv_usec += diff * count_period_num / count_period_den;
- tv->tv_sec += tv->tv_usec / 1000000;
- tv->tv_usec = tv->tv_usec % 1000000;
-#endif
-
- restore_flags(flags);
+
+ usec += mulhwu(tb_to_us, tb_ticks_per_jiffy * lost_ticks + delta);
+ while (usec > 1000000) {
+ sec++;
+ usec -= 1000000;
+ }
+ tv->tv_sec = sec;
+ tv->tv_usec = usec;
X }
X
X void do_settimeofday(struct timeval *tv)
X {
X unsigned long flags;
- int frac_tick;
-
- last_rtc_update = 0; /* so the rtc gets updated soon */
-
- frac_tick = tv->tv_usec % (1000000 / HZ);
- save_flags(flags);
- cli();
+ int tb_delta, new_usec, new_sec;
+
X write_lock_irqsave(&xtime_lock, flags);
- xtime.tv_sec = tv->tv_sec;
- xtime.tv_usec = tv->tv_usec - frac_tick;
- write_unlock_irqrestore(&xtime_lock, flags);
- set_dec(frac_tick * count_period_den / count_period_num);
+ /* Updating the RTC is not the job of this code. If the time is
+ * stepped under NTP, the RTC will be update after STA_UNSYNC
+ * is cleared. Tool like clock/hwclock either copy the RTC
+ * to the system time, in which case there is no point in writing
+ * to the RTC again, or write to the RTC but then they don't call
+ * settimeofday to perform this operation. Note also that
+ * we don't touch the decrementer since:
+ * a) it would lose timer interrupt synchronization on SMP
+ * (if it is working one day)
+ * b) it could make one jiffy spuriously shorter or longer
+ * which would introduce another source of uncertainty potentially
+ * harmful to relatively short timers.
+ */
+
+ /* This works perfectly on SMP only if the tb are in sync but
+ * guarantees an error < 1 jiffy even if they are off by eons,
+ * still reasonable when gettimeofday resolution is 1 jiffy.
+ */
+ tb_delta = tb_ticks_since(last_jiffy_stamp(smp_processor_id()));
+ tb_delta += (jiffies - wall_jiffies) * tb_ticks_per_jiffy;
+ new_sec = tv->tv_sec;
+ new_usec = tv->tv_usec - mulhwu(tb_to_us, tb_delta);
+ while (new_usec <0) {
+ new_sec--;
+ new_usec += 1000000;
+ }
+ xtime.tv_usec = new_usec;
+ xtime.tv_sec = new_sec;
+
+ /* In case of a large backwards jump in time with NTP, we want the
+ * clock to be updated as soon as the PLL is again in lock.
+ */
+ last_rtc_update = new_sec - 658;
+
X time_adjust = 0; /* stop active adjtime() */
X time_status |= STA_UNSYNC;
X time_state = TIME_ERROR; /* p. 24, (a) */
X time_maxerror = NTP_PHASE_LIMIT;
X time_esterror = NTP_PHASE_LIMIT;
- restore_flags(flags);
+ write_unlock_irqrestore(&xtime_lock, flags);
X }
X
X
X void __init time_init(void)
X {
+ time_t sec, old_sec;
+ unsigned old_stamp, stamp, elapsed;
+ /* This function is only called on the boot processor */
X unsigned long flags;
+
X if (ppc_md.time_init != NULL)
- {
- ppc_md.time_init();
- }
+ time_offset = ppc_md.time_init();
X
- if ((_get_PVR() >> 16) == 1) {
+ if (__USE_RTC()) {
X /* 601 processor: dec counts down by 128 every 128ns */
- decrementer_count = DECREMENTER_COUNT_601;
- count_period_num = COUNT_PERIOD_NUM_601;
- count_period_den = COUNT_PERIOD_DEN_601;
- } else if (!smp_processor_id()) {
+ tb_ticks_per_jiffy = DECREMENTER_COUNT_601;
+ /* mulhwu_scale_factor(1000000000, 1000000) is 0x418937 */
+ tb_to_us = 0x418937;
+ } else {
X ppc_md.calibrate_decr();
X }
X
+ /* Now that the decrementer is calibrated, it can be used in case the
+ * clock is stuck, but the fact that we have to handle the 601
+ * makes things more complex. Repeatedly read the RTC until the
+ * next second boundary to try to achieve some precision...
+ */
+ stamp = get_native_tbl();
+ sec = ppc_md.get_rtc_time();
+ elapsed = 0;
+ do {
+ old_stamp = stamp;
+ old_sec = sec;
+ stamp = get_native_tbl();
+ if (__USE_RTC() && stamp < old_stamp) old_stamp -= 1000000000;
+ elapsed += stamp - old_stamp;
+ sec = ppc_md.get_rtc_time();
+ } while ( sec == old_sec && elapsed < 2*HZ*tb_ticks_per_jiffy);
+ if (sec==old_sec) {
+ printk("Warning: real time clock seems stuck!\n");
+ }
X write_lock_irqsave(&xtime_lock, flags);
- xtime.tv_sec = ppc_md.get_rtc_time();
+ xtime.tv_sec = sec;
+ last_jiffy_stamp(0) = tb_last_stamp = stamp;
X xtime.tv_usec = 0;
+ /* No update now, we just read the time from the RTC ! */
+ last_rtc_update = xtime.tv_sec;
X write_unlock_irqrestore(&xtime_lock, flags);
+ /* Not exact, but the timer interrupt takes care of this */
+ set_dec(tb_ticks_per_jiffy);
X
- set_dec(decrementer_count);
- /* allow setting the time right away */
- last_rtc_update = 0;
-}
-
-/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
- * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
- * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
- *
- * [For the Julian calendar (which was used in Russia before 1917,
- * Britain & colonies before 1752, anywhere else before 1582,
- * and is still in use by some communities) leave out the
- * -year/100+year/400 terms, and add 10.]
- *
- * This algorithm was first published by Gauss (I think).
- *
- * WARNING: this function will overflow on 2106-02-07 06:28:16 on
- * machines were long is 32-bit! (However, as time_t is signed, we
- * will already get problems at other places on 2038-01-19 03:14:08)
- */
-unsigned long mktime(unsigned int year, unsigned int mon,
- unsigned int day, unsigned int hour,
- unsigned int min, unsigned int sec)
-{
-
- if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */
- mon += 12; /* Puts Feb last since it has leap day */
- year -= 1;
- }
- return (((
- (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
- year*365 - 719499
- )*24 + hour /* now have hours */
- )*60 + min /* now have minutes */
- )*60 + sec; /* finally seconds */
+ /* If platform provided a timezone (pmac), we correct the time
+ * using do_sys_settimeofday() which in turn calls warp_clock()
+ */
+ if (time_offset) {
+ struct timezone tz;
+ tz.tz_minuteswest = -time_offset / 60;
+ tz.tz_dsttime = 0;
+ do_sys_settimeofday(NULL, &tz);
+ }
X }
X
X #define TICK_SIZE tick
@@ -354,3 +389,31 @@
X */
X GregorianDay(tm);
X }
+
+/* Auxiliary function to compute scaling factors */
+/* Actually the choice of a timebase running at 1/4 the of the bus
+ * frequency giving resolution of a few tens of nanoseconds is quite nice.
+ * It makes this computation very precise (27-28 bits typically) which
+ * is optimistic considering the stability of most processor clock
+ * oscillators and the precision with which the timebase frequency
+ * is measured but does not harm.
+ */
+unsigned mulhwu_scale_factor(unsigned inscale, unsigned outscale) {
+ unsigned mlt=0, tmp, err;
+ /* No concern for performance, it's done once: use a stupid
+ * but safe and compact method to find the multiplier.
+ */
+ for (tmp = 1U<<31; tmp != 0; tmp >>= 1) {
+ if (mulhwu(inscale, mlt|tmp) < outscale) mlt|=tmp;
+ }
+ /* We might still be off by 1 for the best approximation.
+ * A side effect of this is that if outscale is too large
+ * the returned value will be zero.
+ * Many corner cases have been checked and seem to work,
+ * some might have been forgotten in the test however.
+ */
+ err = inscale*(mlt+1);
+ if (err <= inscale/2) mlt++;
+ return mlt;
+}
+
diff -u --recursive --new-file v2.4.0-test8/linux/arch/ppc/kernel/traps.c linux/arch/ppc/kernel/traps.c
--- v2.4.0-test8/linux/arch/ppc/kernel/traps.c Mon May 15 14:53:30 2000
+++ linux/arch/ppc/kernel/traps.c Sun Sep 17 09:48:07 2000
@@ -87,45 +87,76 @@
X void
X MachineCheckException(struct pt_regs *regs)
X {
- if ( !user_mode(regs) )
- {
-#if defined(CONFIG_8xx) && defined(CONFIG_PCI)
- /* the qspan pci read routines can cause machine checks -- Cort */
- bad_page_fault(regs, regs->dar);
+#ifdef CONFIG_ALL_PPC
+ unsigned long fixup;
+#endif /* CONFIG_ALL_PPC */
+
+ if (user_mode(regs)) {
+ _exception(SIGSEGV, regs);
X return;
+ }
+
+#if defined(CONFIG_8xx) && defined(CONFIG_PCI)
+ /* the qspan pci read routines can cause machine checks -- Cort */
+ bad_page_fault(regs, regs->dar);
+ return;
X #endif
X #if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
- if (debugger_fault_handler) {
- debugger_fault_handler(regs);
- return;
- }
+ if (debugger_fault_handler) {
+ debugger_fault_handler(regs);
+ return;
+ }
X #endif
- printk("Machine check in kernel mode.\n");
- printk("Caused by (from SRR1=%lx): ", regs->msr);
- switch (regs->msr & 0xF0000) {
- case 0x80000:
- printk("Machine check signal\n");
- break;
- case 0x40000:
- printk("Transfer error ack signal\n");
- break;
- case 0x20000:
- printk("Data parity error signal\n");
- break;
- case 0x10000:
- printk("Address parity error signal\n");
- break;
- default:
- printk("Unknown values in msr\n");
+
+#ifdef CONFIG_ALL_PPC
+ /*
+ * I/O accesses can cause machine checks on powermacs.
+ * Check if the NIP corresponds to the address of a sync
+ * instruction for which there is an entry in the exception
+ * table.
+ */
+ if (regs->msr & (0x80000 | 0x40000)
+ && (fixup = search_exception_table(regs->nip)) != 0) {
+ /*
+ * Check that it's a sync instruction.
+ * As the address is in the exception table
+ * we should be able to read the instr there.
+ */
+ if (*(unsigned int *)regs->nip == 0x7c0004ac) {
+ unsigned int lsi = ((unsigned int *)regs->nip)[-1];
+ int rb = (lsi >> 11) & 0x1f;
+ printk(KERN_DEBUG "%s bad port %lx at %lx\n",
+ (lsi & 0x100)? "OUT to": "IN from",
+ regs->gpr[rb] - _IO_BASE, regs->nip);
+ regs->nip = fixup;
+ return;
X }
- show_regs(regs);
+ }
+#endif /* CONFIG_ALL_PPC */
+ printk("Machine check in kernel mode.\n");
+ printk("Caused by (from SRR1=%lx): ", regs->msr);
+ switch (regs->msr & 0xF0000) {
+ case 0x80000:
+ printk("Machine check signal\n");
+ break;
+ case 0x40000:
+ printk("Transfer error ack signal\n");
+ break;
+ case 0x20000:
+ printk("Data parity error signal\n");
+ break;
+ case 0x10000:
+ printk("Address parity error signal\n");
+ break;
+ default:
+ printk("Unknown values in msr\n");
+ }
+ show_regs(regs);
X #if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
- debugger(regs);
+ debugger(regs);
X #endif
- print_backtrace((unsigned long *)regs->gpr[1]);
- panic("machine check");
- }
- _exception(SIGSEGV, regs);
+ print_backtrace((unsigned long *)regs->gpr[1]);
+ panic("machine check");
X }
X
X void
@@ -166,6 +197,46 @@
X _exception(SIGTRAP, regs);
X }
X
+/* Illegal instruction emulation support. Originally written to
+ * provide the PVR to user applications using the mfspr rd, PVR.
+ * Return non-zero if we can't emulate, or EFAULT if the associated
+ * memory access caused an access fault. Return zero on success.
+ *
+ * There are a couple of ways to do this, either "decode" the instruction
+ * or directly match lots of bits. In this case, matching lots of
+ * bits is faster and easier.
+ *
+ */
+#define INST_MFSPR_PVR 0x7c1f42a6
+#define INST_MFSPR_PVR_MASK 0xfc1fffff
+
+static int
+emulate_instruction(struct pt_regs *regs)
+{
+ uint instword;
+ uint rd;
+ uint retval;
+
+ retval = EFAULT;
+
+ if (!user_mode(regs))
+ return retval;
+
+ if (get_user(instword, (uint *)(regs->nip)))
+ return retval;
+
+ /* Emulate the mfspr rD, PVR.
+ */
+ if ((instword & INST_MFSPR_PVR_MASK) == INST_MFSPR_PVR) {
+ rd = (instword >> 21) & 0x1f;
+ regs->gpr[rd] = _get_PVR();
+ retval = 0;
+ }
+ if (retval == 0)
+ regs->nip += 4;
+ return(retval);
+}
+
X void
X ProgramCheckException(struct pt_regs *regs)
X {
@@ -193,7 +264,14 @@
X #endif
X _exception(SIGTRAP, regs);
X } else {
- _exception(SIGILL, regs);
+ /* Try to emulate it if we should. */
+ int errcode;
+ if ((errcode = emulate_instruction(regs))) {
+ if (errcode == EFAULT)
+ _exception(SIGBUS, regs);
+ else
+ _exception(SIGILL, regs);
+ }
X }
X #endif
X }
diff -u --recursive --new-file v2.4.0-test8/linux/arch/ppc/kernel/walnut_setup.c linux/arch/ppc/kernel/walnut_setup.c
--- v2.4.0-test8/linux/arch/ppc/kernel/walnut_setup.c Thu Jul 13 09:42:51 2000
+++ linux/arch/ppc/kernel/walnut_setup.c Sun Sep 17 09:48:07 2000
@@ -226,10 +226,11 @@
X /*
X * Document me.
X */
-void __init
+long __init
X walnut_time_init(void)
X {
X /* XXX - Implement me */
+ return 0;
X }
X
X /*
diff -u --recursive --new-file v2.4.0-test8/linux/arch/ppc/kernel/xics.c linux/arch/ppc/kernel/xics.c
--- v2.4.0-test8/linux/arch/ppc/kernel/xics.c Mon Jun 19 17:59:36 2000
+++ linux/arch/ppc/kernel/xics.c Sun Sep 17 09:48:07 2000
@@ -166,7 +166,7 @@
X void xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
X {
X qirr_info(smp_processor_id()) = 0xff;
- smp_message_recv(MSG_RESCHEDULE);
+ smp_message_recv(MSG_RESCHEDULE, regs);
X }
X
X void xics_cause_IPI(int cpu)
diff -u --recursive --new-file v2.4.0-test8/linux/arch/ppc/lib/string.S linux/arch/ppc/lib/string.S
--- v2.4.0-test8/linux/arch/ppc/lib/string.S Sun Feb 13 10:47:01 2000
+++ linux/arch/ppc/lib/string.S Tue Sep 19 08:31:53 2000
@@ -9,13 +9,74 @@
X * 2 of the License, or (at your option) any later version.
X */
X #include "../kernel/ppc_asm.tmpl"
+#include <linux/config.h>
X #include <asm/processor.h>
X #include <asm/errno.h>
X
-CACHELINE_BYTES = 32
-LG_CACHELINE_BYTES = 5
-CACHELINE_MASK = 0x1f
-CACHELINE_WORDS = 8
+#if defined(CONFIG_4xx) || defined(CONFIG_8xx)
+#define CACHE_LINE_SIZE 16
+#define LG_CACHE_LINE_SIZE 4
+#define MAX_COPY_PREFETCH 1
+#elif !defined(CONFIG_PPC64BRIDGE)
+#define CACHE_LINE_SIZE 32
+#define LG_CACHE_LINE_SIZE 5
+#define MAX_COPY_PREFETCH 4
+#else
+#define CACHE_LINE_SIZE 128
+#define LG_CACHE_LINE_SIZE 7
+#define MAX_COPY_PREFETCH 1
+#endif /* CONFIG_4xx || CONFIG_8xx */
+
+#define COPY_16_BYTES \
+ lwz r7,4(r4); \
+ lwz r8,8(r4); \
+ lwz r9,12(r4); \
+ lwzu r10,16(r4); \
+ stw r7,4(r6); \
+ stw r8,8(r6); \
+ stw r9,12(r6); \
+ stwu r10,16(r6)
+
+#define COPY_16_BYTES_WITHEX(n) \
+8 ## n ## 0: \
+ lwz r7,4(r4); \
+8 ## n ## 1: \
+ lwz r8,8(r4); \
+8 ## n ## 2: \
+ lwz r9,12(r4); \
+8 ## n ## 3: \
+ lwzu r10,16(r4); \
+8 ## n ## 4: \
+ stw r7,4(r6); \
+8 ## n ## 5: \
+ stw r8,8(r6); \
+8 ## n ## 6: \
+ stw r9,12(r6); \
+8 ## n ## 7: \
+ stwu r10,16(r6)
+
+#define COPY_16_BYTES_EXCODE(n) \
+9 ## n ## 0: \
+ addi r5,r5,-(16 * n); \
+ b 104f; \
+9 ## n ## 1: \
+ addi r5,r5,-(16 * n); \
+ b 105f; \
+.section __ex_table,"a"; \
+ .align 2; \
+ .long 8 ## n ## 0b,9 ## n ## 0b; \
+ .long 8 ## n ## 1b,9 ## n ## 0b; \
+ .long 8 ## n ## 2b,9 ## n ## 0b; \
+ .long 8 ## n ## 3b,9 ## n ## 0b; \
+ .long 8 ## n ## 4b,9 ## n ## 1b; \
+ .long 8 ## n ## 5b,9 ## n ## 1b; \
+ .long 8 ## n ## 6b,9 ## n ## 1b; \
+ .long 8 ## n ## 7b,9 ## n ## 1b; \
+.text
+
+CACHELINE_BYTES = CACHE_LINE_SIZE
+LG_CACHELINE_BYTES = LG_CACHE_LINE_SIZE
+CACHELINE_MASK = (CACHE_LINE_SIZE-1)
X
X .globl strcpy
X strcpy:
@@ -105,7 +166,14 @@
X bdnz 4b
X 3: mtctr r9
X li r7,4
+#if !defined(CONFIG_8xx)
X 10: dcbz r7,r6
+#else
+10: stw r4, 4(r6)
+ stw r4, 8(r6)
+ stw r4, 12(r6)
+ stw r4, 16(r6)
+#endif
X addi r6,r6,CACHELINE_BYTES
X bdnz 10b
X clrlwi r5,r8,32-LG_CACHELINE_BYTES
@@ -202,23 +270,24 @@
X li r11,4
X mtctr r0
X beq 63f
-53: dcbz r11,r6
- lwz r7,4(r4)
- lwz r8,8(r4)
- lwz r9,12(r4)
- lwzu r10,16(r4)
- stw r7,4(r6)
- stw r8,8(r6)
- stw r9,12(r6)
- stwu r10,16(r6)
- lwz r7,4(r4)
- lwz r8,8(r4)
- lwz r9,12(r4)
- lwzu r10,16(r4)
- stw r7,4(r6)
SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi
echo 'End of part 015'
echo 'File patch-2.4.0-test9 is continued in part 016'
echo "016" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part016

#!/bin/sh -x
# this is part 016 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 016; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

- stw r8,8(r6)
- stw r9,12(r6)
- stwu r10,16(r6)

+53:
+#if !defined(CONFIG_8xx)
+ dcbz r11,r6
+#endif
+ COPY_16_BYTES
+#if CACHE_LINE_SIZE >= 32
+ COPY_16_BYTES
+#if CACHE_LINE_SIZE >= 64
+ COPY_16_BYTES
+ COPY_16_BYTES
+#if CACHE_LINE_SIZE >= 128
+ COPY_16_BYTES
+ COPY_16_BYTES
+ COPY_16_BYTES
+ COPY_16_BYTES
+#endif
+#endif
+#endif
X bdnz 53b
X
X 63: srwi. r0,r5,2
@@ -380,25 +449,59 @@
X 58: srwi. r0,r5,LG_CACHELINE_BYTES /* # complete cachelines */
X clrlwi r5,r5,32-LG_CACHELINE_BYTES
X li r11,4
- mtctr r0


X beq 63f
-53: dcbz r11,r6

-10: lwz r7,4(r4)
-11: lwz r8,8(r4)
-12: lwz r9,12(r4)
-13: lwzu r10,16(r4)
-14: stw r7,4(r6)
-15: stw r8,8(r6)
-16: stw r9,12(r6)
-17: stwu r10,16(r6)
-20: lwz r7,4(r4)
-21: lwz r8,8(r4)
-22: lwz r9,12(r4)
-23: lwzu r10,16(r4)
-24: stw r7,4(r6)
-25: stw r8,8(r6)
-26: stw r9,12(r6)
-27: stwu r10,16(r6)
+
+#if !defined(CONFIG_8xx)
+ /* Here we decide how far ahead to prefetch the source */
+#if MAX_COPY_PREFETCH > 1
+ /* Heuristically, for large transfers we prefetch
+ MAX_COPY_PREFETCH cachelines ahead. For small transfers
+ we prefetch 1 cacheline ahead. */
+ cmpwi r0,MAX_COPY_PREFETCH
+ li r7,1
+ li r3,4
+ ble 111f
+ li r7,MAX_COPY_PREFETCH
+111: mtctr r7
+112: dcbt r3,r4
+ addi r3,r3,CACHELINE_BYTES
+ bdnz 112b
+#else /* MAX_COPY_PREFETCH == 1 */
+ li r3,CACHELINE_BYTES + 4
+ dcbt r11,r4
+#endif /* MAX_COPY_PREFETCH */
+#endif /* CONFIG_8xx */
+
+ mtctr r0
+53:
+#if !defined(CONFIG_8xx)
+ dcbt r3,r4
+ dcbz r11,r6
+#endif
+/* had to move these to keep extable in order */
+ .section __ex_table,"a"
+ .align 2
+ .long 70b,100f
+ .long 71b,101f
+ .long 72b,102f
+ .long 73b,103f
+ .long 53b,105f
+ .text
+/* the main body of the cacheline loop */
+ COPY_16_BYTES_WITHEX(0)
+#if CACHE_LINE_SIZE >= 32
+ COPY_16_BYTES_WITHEX(1)
+#if CACHE_LINE_SIZE >= 64
+ COPY_16_BYTES_WITHEX(2)
+ COPY_16_BYTES_WITHEX(3)
+#if CACHE_LINE_SIZE >= 128
+ COPY_16_BYTES_WITHEX(4)
+ COPY_16_BYTES_WITHEX(5)
+ COPY_16_BYTES_WITHEX(6)
+ COPY_16_BYTES_WITHEX(7)
+#endif
+#endif
+#endif
X bdnz 53b
X
X 63: srwi. r0,r5,2
@@ -434,15 +537,31 @@
X 103: li r4,1
X 91: li r3,2
X b 99f
-/* read fault in 2nd half of cacheline loop */
-106: addi r5,r5,-16
-/* read fault in 1st half of cacheline loop */
+
+/*
+ * this stuff handles faults in the cacheline loop and branches to either
+ * 104f (if in read part) or 105f (if in write part), after updating r5
+ */
+ COPY_16_BYTES_EXCODE(0)
+#if CACHE_LINE_SIZE >= 32
+ COPY_16_BYTES_EXCODE(1)
+#if CACHE_LINE_SIZE >= 64
+ COPY_16_BYTES_EXCODE(2)
+ COPY_16_BYTES_EXCODE(3)
+#if CACHE_LINE_SIZE >= 128
+ COPY_16_BYTES_EXCODE(4)
+ COPY_16_BYTES_EXCODE(5)
+ COPY_16_BYTES_EXCODE(6)
+ COPY_16_BYTES_EXCODE(7)
+#endif
+#endif
+#endif
+
+/* read fault in cacheline loop */
X 104: li r4,0
X b 92f
-/* write fault in 2nd half of cacheline loop */
-107: addi r5,r5,-16
X /* fault on dcbz (effectively a write fault) */
-/* or write fault in 1st half of cacheline loop */
+/* or write fault in cacheline loop */
X 105: li r4,1
X 92: li r3,LG_CACHELINE_BYTES
X b 99f
@@ -485,36 +604,15 @@
X bdnz 114b
X 120: blr
X
-.section __ex_table,"a"
+ .section __ex_table,"a"
X .align 2
- .long 70b,100b
- .long 71b,101b
- .long 72b,102b
- .long 73b,103b
- .long 53b,105b
- .long 10b,104b
- .long 11b,104b
- .long 12b,104b
- .long 13b,104b
- .long 14b,105b
- .long 15b,105b
- .long 16b,105b
- .long 17b,105b
- .long 20b,106b
- .long 21b,106b
- .long 22b,106b
- .long 23b,106b
- .long 24b,107b
- .long 25b,107b
- .long 26b,107b
- .long 27b,107b
X .long 30b,108b
X .long 31b,109b
X .long 40b,110b
X .long 41b,111b
X .long 112b,120b
X .long 114b,120b
-.text
+ .text
X
X .globl __clear_user
X __clear_user:
@@ -546,12 +644,13 @@
X blr
X 99: li r3,-EFAULT
X blr
-.section __ex_table,"a"
+
+ .section __ex_table,"a"
X .align 2
X .long 11b,99b
X .long 1b,99b
X .long 8b,99b
-.text
+ .text
X
X .globl __strncpy_from_user
X __strncpy_from_user:
@@ -570,10 +669,11 @@
X blr
X 99: li r3,-EFAULT
X blr
-.section __ex_table,"a"
+
+ .section __ex_table,"a"
X .align 2
X .long 1b,99b
-.text
+ .text
X
X /* r3 = str, r4 = len (> 0), r5 = top (highest addr) */
X .globl __strnlen_user
@@ -596,6 +696,7 @@
X blr
X 99: li r3,0 /* bad address, return 0 */
X blr
-.section __ex_table,"a"
+
+ .section __ex_table,"a"
X .align 2
X .long 1b,99b
diff -u --recursive --new-file v2.4.0-test8/linux/arch/ppc/mbxboot/misc.c linux/arch/ppc/mbxboot/misc.c
--- v2.4.0-test8/linux/arch/ppc/mbxboot/misc.c Thu Jul 13 09:42:51 2000
+++ linux/arch/ppc/mbxboot/misc.c Sun Sep 17 09:48:07 2000
@@ -269,6 +269,11 @@
X */
X #ifdef CONFIG_MBX
X cmd_line = (char *)(load_addr - 0x10000);
+
+ /* To be like everyone else, we need one too, although this
+ * board information is passed from the boot rom.
+ */
+ bp->bi_baudrate = 9600;
X #else
X cmd_line = (char *)(0x200000);
X #endif
diff -u --recursive --new-file v2.4.0-test8/linux/arch/ppc/mm/extable.c linux/arch/ppc/mm/extable.c
--- v2.4.0-test8/linux/arch/ppc/mm/extable.c Wed Nov 10 22:18:39 1999
+++ linux/arch/ppc/mm/extable.c Tue Sep 19 08:31:53 2000
@@ -4,11 +4,47 @@
X * from linux/arch/i386/mm/extable.c
X */
X
+#include <linux/config.h>
X #include <linux/module.h>
X #include <asm/uaccess.h>
X
-extern const struct exception_table_entry __start___ex_table[];
-extern const struct exception_table_entry __stop___ex_table[];
+extern struct exception_table_entry __start___ex_table[];
+extern struct exception_table_entry __stop___ex_table[];
+
+/*
+ * The exception table needs to be sorted because we use the macros
+ * which put things into the exception table in a variety of segments
+ * such as the prep, pmac, chrp, etc. segments as well as the init
+ * segment and the main kernel text segment.
+ */
+static inline void
+sort_ex_table(struct exception_table_entry *start,
+ struct exception_table_entry *finish)
+{
+ struct exception_table_entry el, *p, *q;
+
+ /* insertion sort */
+ for (p = start + 1; p < finish; ++p) {
+ /* start .. p-1 is sorted */
+ if (p[0].insn < p[-1].insn) {
+ /* move element p down to its right place */
+ el = *p;
+ q = p;
+ do {
+ /* el comes before q[-1], move q[-1] up one */
+ q[0] = q[-1];
+ --q;
+ } while (q > start && el.insn < q[-1].insn);
+ *q = el;
+ }
+ }
+}
+
+void
+sort_exception_table(void)
+{
+ sort_ex_table(__start___ex_table, __stop___ex_table);
+}
X
X static inline unsigned long
X search_one_table(const struct exception_table_entry *first,
@@ -36,25 +72,21 @@
X {
X unsigned long ret;
X
-#if 1 /*ndef CONFIG_MODULES*/
+#ifndef CONFIG_MODULES
X /* There is only the kernel to search. */
X ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
X if (ret) return ret;
X #else
X /* The kernel is the last "module" -- no need to treat it special. */
X struct module *mp;
- read_lock(&modlist_lock);
X for (mp = module_list; mp != NULL; mp = mp->next) {
X if (mp->ex_table_start == NULL)
X continue;
X ret = search_one_table(mp->ex_table_start,
X mp->ex_table_end - 1, addr);
- if (ret) {
- read_unlock(&modlist_lock);
+ if (ret)
X return ret;
- }
X }
- read_unlock(&modlist_lock);
X #endif
X
X return 0;
diff -u --recursive --new-file v2.4.0-test8/linux/arch/ppc/mm/fault.c linux/arch/ppc/mm/fault.c
--- v2.4.0-test8/linux/arch/ppc/mm/fault.c Mon Jun 19 17:59:37 2000
+++ linux/arch/ppc/mm/fault.c Sun Sep 17 09:48:07 2000
@@ -67,7 +67,7 @@
X #if defined(CONFIG_4xx)
X int is_write = error_code & ESR_DST;
X #else
- int is_write = error_code & 0x02000000;
+ int is_write = 0;
X
X /*
X * Fortunately the bit assignments in SRR1 for an instruction
@@ -77,6 +77,8 @@
X */
X if (regs->trap == 0x400)
X error_code &= 0x48200000;
+ else
+ is_write = error_code & 0x02000000;
X #endif /* CONFIG_4xx */
X
X #if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
diff -u --recursive --new-file v2.4.0-test8/linux/arch/ppc/mm/init.c linux/arch/ppc/mm/init.c
--- v2.4.0-test8/linux/arch/ppc/mm/init.c Mon Aug 7 21:02:27 2000
+++ linux/arch/ppc/mm/init.c Sun Sep 17 09:48:07 2000
@@ -36,6 +36,7 @@
X #include <linux/delay.h>
X #include <linux/openpic.h>
X #include <linux/bootmem.h>
+#include <linux/highmem.h>
X #ifdef CONFIG_BLK_DEV_INITRD
X #include <linux/blk.h> /* for initrd_* */
X #endif
@@ -69,15 +70,20 @@
X #include "4xx_tlb.h"
X #endif
X
+#define MAX_LOW_MEM (640 << 20)
+
X #define PGTOKB(pages) (((pages) * PAGE_SIZE) >> 10)
X
X int prom_trashed;
X atomic_t next_mmu_context;
X unsigned long *end_of_DRAM;
+unsigned long total_memory;
+unsigned long total_lowmem;
X int mem_init_done;
X int init_bootmem_done;
X int boot_mapsize;
X unsigned long totalram_pages = 0;
+unsigned long totalhigh_pages = 0;
X extern pgd_t swapper_pg_dir[];
X extern char _start[], _end[];
X extern char etext[], _stext[];
@@ -98,22 +104,26 @@
X #ifndef CONFIG_SMP
X struct pgtable_cache_struct quicklists;
X #endif
+#ifdef CONFIG_HIGHMEM
+pte_t *kmap_pte;
+pgprot_t kmap_prot;
+#endif
X
X void MMU_init(void);
X static void *MMU_get_page(void);
-unsigned long *prep_find_end_of_memory(void);
-unsigned long *pmac_find_end_of_memory(void);
-unsigned long *apus_find_end_of_memory(void);
-unsigned long *gemini_find_end_of_memory(void);
-extern unsigned long *find_end_of_memory(void);
+unsigned long prep_find_end_of_memory(void);
+unsigned long pmac_find_end_of_memory(void);
+unsigned long apus_find_end_of_memory(void);
+unsigned long gemini_find_end_of_memory(void);
+extern unsigned long find_end_of_memory(void);
X #ifdef CONFIG_8xx
-unsigned long *m8xx_find_end_of_memory(void);
+unsigned long m8xx_find_end_of_memory(void);
X #endif /* CONFIG_8xx */
X #ifdef CONFIG_4xx
-unsigned long *oak_find_end_of_memory(void);
+unsigned long oak_find_end_of_memory(void);
X #endif
X #ifdef CONFIG_8260
-unsigned long *m8260_find_end_of_memory(void);
+unsigned long m8260_find_end_of_memory(void);
X #endif /* CONFIG_8260 */
X static void mapin_ram(void);
X void map_page(unsigned long va, unsigned long pa, int flags);
@@ -269,6 +279,7 @@
X int i,free = 0,total = 0,reserved = 0;
X int shared = 0, cached = 0;
X struct task_struct *p;
+ int highmem = 0;
X
X printk("Mem-info:\n");
X show_free_areas();
@@ -276,6 +287,8 @@
X i = max_mapnr;
X while (i-- > 0) {
X total++;
+ if (PageHighMem(mem_map+i))
+ highmem++;
X if (PageReserved(mem_map+i))
X reserved++;
X else if (PageSwapCache(mem_map+i))
@@ -286,6 +299,7 @@
X shared += atomic_read(&mem_map[i].count) - 1;
X }
X printk("%d pages of RAM\n",total);
+ printk("%d pages of HIGHMEM\n", highmem);
X printk("%d free pages\n",free);
X printk("%d reserved pages\n",reserved);
X printk("%d pages shared\n",shared);
@@ -354,6 +368,8 @@
X continue;
X val->sharedram += atomic_read(&mem_map[i].count) - 1;
X }
+ val->totalhigh = totalhigh_pages;
+ val->freehigh = nr_free_highpages();
X val->mem_unit = PAGE_SIZE;
X }
X
@@ -443,7 +459,8 @@
X
X void iounmap(void *addr)
X {
- /* XXX todo */
+ if (addr > high_memory && (unsigned long) addr < ioremap_bot)
+ vfree((void *) (PAGE_MASK & (unsigned long) addr));
X }
X
X unsigned long iopa(unsigned long addr)
@@ -476,7 +493,7 @@
X {
X pmd_t *pd, oldpd;
X pte_t *pg;
-
+
X /* Use upper 10 bits of VA to index the first level map */
X pd = pmd_offset(pgd_offset_k(va), va);
X oldpd = *pd;
@@ -516,6 +533,7 @@
X flush_hash_segments(0xd, 0xffffff);
X #else
X __clear_user(Hash, Hash_size);
+ _tlbia();
X #ifdef CONFIG_SMP
X smp_send_tlb_invalidate(0);


X #endif /* CONFIG_SMP */

@@ -610,6 +628,13 @@
X }
X #endif /* CONFIG_8xx */
X
+void flush_page_to_ram(struct page *page)
+{
+ unsigned long vaddr = kmap(page);
+ __flush_page_to_ram(vaddr);
+ kunmap(page);
+}
+
X #if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
X static void get_mem_prop(char *, struct mem_pieces *);
X
@@ -722,7 +747,7 @@
X if (align && align < max_size)
X max_size = align;
X
- tot = (unsigned long)end_of_DRAM - KERNELBASE;
+ tot = total_lowmem;
X for (bl = 128<<10; bl < max_size; bl <<= 1) {
X if (bl * 2 > tot)
X break;
@@ -745,6 +770,8 @@
X for (i = 0; i < phys_mem.n_regions; ++i) {
X v = (ulong)__va(phys_mem.regions[i].address);
X p = phys_mem.regions[i].address;
+ if (p >= total_lowmem)
+ break;
X for (s = 0; s < phys_mem.regions[i].size; s += PAGE_SIZE) {
X /* On the MPC8xx, we want the page shared so we
X * don't get ASID compares on kernel space.
@@ -766,6 +793,8 @@
X map_page(v, p, f);
X v += PAGE_SIZE;
X p += PAGE_SIZE;
+ if (p >= total_lowmem)


+ break;
X }
X }
X }

@@ -788,77 +817,42 @@
X return p;
X }
X
-void __init free_initmem(void)
+static void free_sec(unsigned long start, unsigned long end, const char *name)
X {
- unsigned long a;
- unsigned long num_freed_pages = 0, num_prep_pages = 0,
- num_pmac_pages = 0, num_openfirmware_pages = 0,
- num_apus_pages = 0, num_chrp_pages = 0;
-#define FREESEC(START,END,CNT) do { \
- a = (unsigned long)(&START); \
- for (; a < (unsigned long)(&END); a += PAGE_SIZE) { \
- clear_bit(PG_reserved, &virt_to_page(a)->flags); \
- set_page_count(virt_to_page(a), 1); \
- free_page(a); \
- CNT++; \
- } \
-} while (0)
-
- FREESEC(__init_begin,__init_end,num_freed_pages);
- switch (_machine)
- {
- case _MACH_Pmac:
- FREESEC(__apus_begin,__apus_end,num_apus_pages);
- FREESEC(__prep_begin,__prep_end,num_prep_pages);
- FREESEC(__chrp_begin,__chrp_end,num_chrp_pages);
- break;
- case _MACH_chrp:
- FREESEC(__apus_begin,__apus_end,num_apus_pages);
- FREESEC(__pmac_begin,__pmac_end,num_pmac_pages);
- FREESEC(__prep_begin,__prep_end,num_prep_pages);
- break;
- case _MACH_prep:
- FREESEC(__apus_begin,__apus_end,num_apus_pages);
- FREESEC(__pmac_begin,__pmac_end,num_pmac_pages);
- FREESEC(__chrp_begin,__chrp_end,num_chrp_pages);
- break;
- case _MACH_mbx:
- FREESEC(__apus_begin,__apus_end,num_apus_pages);
- FREESEC(__pmac_begin,__pmac_end,num_pmac_pages);
- FREESEC(__prep_begin,__prep_end,num_prep_pages);
- FREESEC(__chrp_begin,__chrp_end,num_chrp_pages);
- break;
- case _MACH_apus:
- FREESEC(__pmac_begin,__pmac_end,num_pmac_pages);
- FREESEC(__prep_begin,__prep_end,num_prep_pages);
- FREESEC(__chrp_begin,__chrp_end,num_chrp_pages);
- break;
- case _MACH_gemini:
- FREESEC(__apus_begin,__apus_end,num_apus_pages);
- FREESEC(__pmac_begin,__pmac_end,num_pmac_pages);
- FREESEC(__prep_begin,__prep_end,num_prep_pages);
- FREESEC(__chrp_begin,__chrp_end,num_chrp_pages);
- break;
- }
+ unsigned long cnt = 0;
X
- if ( !have_of )
- FREESEC( __openfirmware_begin, __openfirmware_end,
- num_openfirmware_pages );
-
- printk ("Freeing unused kernel memory: %ldk init",
- PGTOKB(num_freed_pages));
+ while (start < end) {
+ clear_bit(PG_reserved, &virt_to_page(start)->flags);
+ set_page_count(virt_to_page(start), 1);
+ free_page(start);
+ cnt++;
+ start += PAGE_SIZE;
+ }
+ if (cnt)
+ printk(" %ldk %s", PGTOKB(cnt), name);
+}
X
- if ( num_prep_pages )
- printk(" %ldk prep", PGTOKB(num_prep_pages));
- if ( num_chrp_pages )
- printk(" %ldk chrp", PGTOKB(num_chrp_pages));
- if ( num_pmac_pages )
- printk(" %ldk pmac", PGTOKB(num_pmac_pages));
- if ( num_openfirmware_pages )
- printk(" %ldk open firmware", PGTOKB(num_openfirmware_pages));
- if ( num_apus_pages )
- printk(" %ldk apus", PGTOKB(num_apus_pages));
- printk("\n");
+void free_initmem(void)
+{
+#define FREESEC(TYPE) \
+ free_sec((unsigned long)(&__ ## TYPE ## _begin), \
+ (unsigned long)(&__ ## TYPE ## _end), \
+ #TYPE);
+
+ printk ("Freeing unused kernel memory:");
+ FREESEC(init);


+ if (_machine != _MACH_Pmac)

+ FREESEC(pmac);
+ if (_machine != _MACH_chrp)
+ FREESEC(chrp);
+ if (_machine != _MACH_prep)
+ FREESEC(prep);
+ if (_machine != _MACH_apus)
+ FREESEC(apus);
+ if (!have_of)
+ FREESEC(openfirmware);
+ printk("\n");
+#undef FREESEC
X }
X
X #ifdef CONFIG_BLK_DEV_INITRD
@@ -909,7 +903,8 @@
X * at KERNELBASE.
X */
X
- end_of_DRAM = oak_find_end_of_memory();
+ total_memory = total_lowmem = oak_find_end_of_memory();
+ end_of_DRAM = __va(total_memory);
X mapin_ram();
X
X /*
@@ -939,23 +934,33 @@
X if ( ppc_md.progress ) ppc_md.progress("MMU:enter", 0x111);
X #ifndef CONFIG_8xx
X if (have_of)
- end_of_DRAM = pmac_find_end_of_memory();
+ total_memory = pmac_find_end_of_memory();
X #ifdef CONFIG_APUS
X else if (_machine == _MACH_apus )
- end_of_DRAM = apus_find_end_of_memory();
+ total_memory = apus_find_end_of_memory();
X #endif
X #ifdef CONFIG_GEMINI
X else if ( _machine == _MACH_gemini )
- end_of_DRAM = gemini_find_end_of_memory();
+ total_memory = gemini_find_end_of_memory();
X #endif /* CONFIG_GEMINI */
X #if defined(CONFIG_8260)
X else
- end_of_DRAM = m8260_find_end_of_memory();
+ total_memory = m8260_find_end_of_memory();
X #else
X else /* prep */
- end_of_DRAM = prep_find_end_of_memory();
+ total_memory = prep_find_end_of_memory();
X #endif
X
+ total_lowmem = total_memory;
+#ifdef CONFIG_HIGHMEM
+ if (total_lowmem > MAX_LOW_MEM) {
+ total_lowmem = MAX_LOW_MEM;
+ mem_pieces_remove(&phys_avail, total_lowmem,
+ total_memory - total_lowmem, 0);
+ }
+#endif /* CONFIG_HIGHMEM */
+ end_of_DRAM = __va(total_lowmem);
+
X if ( ppc_md.progress ) ppc_md.progress("MMU:hash init", 0x300);
X hash_init();
X #ifndef CONFIG_PPC64BRIDGE
@@ -995,7 +1000,7 @@
X #endif
X break;
X case _MACH_Pmac:
- ioremap_base = 0xf8000000;
+ ioremap_base = 0xfe000000;
X break;
X case _MACH_apus:
X /* Map PPC exception vectors. */
@@ -1022,7 +1027,15 @@
X #endif /* CONFIG_POWER4 */
X #else /* CONFIG_8xx */
X
- end_of_DRAM = m8xx_find_end_of_memory();
+ total_memory = total_lowmem = m8xx_find_end_of_memory();
+#ifdef CONFIG_HIGHMEM
+ if (total_lowmem > MAX_LOW_MEM) {
+ total_lowmem = MAX_LOW_MEM;
+ mem_pieces_remove(&phys_avail, total_lowmem,
+ total_memory - total_lowmem, 0);
+ }
+#endif /* CONFIG_HIGHMEM */
+ end_of_DRAM = __va(total_lowmem);
X
X /* Map in all of RAM starting at KERNELBASE */
X mapin_ram();
@@ -1055,7 +1068,7 @@
X if ( ppc_md.progress ) ppc_md.progress("MMU:exit", 0x211);
X #ifdef CONFIG_BOOTX_TEXT
X /* Must be done last, or ppc_md.progress will die */
- if (_machine == _MACH_Pmac)
+ if (_machine == _MACH_Pmac || _machine == _MACH_chrp)
X map_bootx_text();
X #endif
X }
@@ -1092,7 +1105,7 @@
X start = PAGE_ALIGN(start);
X
X boot_mapsize = init_bootmem(start >> PAGE_SHIFT,
- __pa(end_of_DRAM) >> PAGE_SHIFT);
+ total_lowmem >> PAGE_SHIFT);
X
X /* remove the bootmem bitmap from the available memory */
X mem_pieces_remove(&phys_avail, start, boot_mapsize, 1);
@@ -1105,47 +1118,6 @@
X init_bootmem_done = 1;
X }
X
-#if 0
-/*
- * Find some memory for setup_arch to return.
- * We use the largest chunk of available memory as the area
- * that setup_arch returns, making sure that there are at
- * least 32 pages unused before this for MMU_get_page to use.
- */
-unsigned long __init find_available_memory(void)
-{
- int i, rn;
- unsigned long a, free;
- unsigned long start, end;
-
- if (_machine == _MACH_mbx) {
- /* Return the first, not the last region, because we
- * may not yet have properly initialized the additonal
- * memory DIMM.
- */
- a = PAGE_ALIGN(phys_avail.regions[0].address);
- avail_start = (unsigned long) __va(a);
- return avail_start;
- }
-
- rn = 0;
- for (i = 1; i < phys_avail.n_regions; ++i)
- if (phys_avail.regions[i].size > phys_avail.regions[rn].size)
- rn = i;
- free = 0;
- for (i = 0; i < rn; ++i) {
- start = phys_avail.regions[i].address;
- end = start + phys_avail.regions[i].size;
- free += (end & PAGE_MASK) - PAGE_ALIGN(start);
- }
- a = PAGE_ALIGN(phys_avail.regions[rn].address);
- if (free < 32 * PAGE_SIZE)
- a += 32 * PAGE_SIZE - free;
- avail_start = (unsigned long) __va(a);
- return avail_start;
-}
-#endif /* 0 */
-
X /*
X * paging_init() sets up the page tables - in fact we've already done this.
X */
@@ -1153,6 +1125,14 @@
X {
X unsigned long zones_size[MAX_NR_ZONES], i;
X
+#ifdef CONFIG_HIGHMEM
+ map_page(PKMAP_BASE, 0, 0); /* XXX gross */
+ pkmap_page_table = pte_offset(pmd_offset(pgd_offset_k(PKMAP_BASE), PKMAP_BASE), PKMAP_BASE);
+ map_page(KMAP_FIX_BEGIN, 0, 0); /* XXX gross */
+ kmap_pte = pte_offset(pmd_offset(pgd_offset_k(KMAP_FIX_BEGIN), KMAP_FIX_BEGIN), KMAP_FIX_BEGIN);
+ kmap_prot = PAGE_KERNEL;
+#endif /* CONFIG_HIGHMEM */
+
X /*
X * Grab some memory for bad_page and bad_pagetable to use.
X */
@@ -1162,9 +1142,14 @@
X /*
X * All pages are DMA-able so we put them all in the DMA zone.
X */
- zones_size[0] = ((unsigned long)end_of_DRAM - KERNELBASE) >> PAGE_SHIFT;
+ zones_size[ZONE_DMA] = total_lowmem >> PAGE_SHIFT;
X for (i = 1; i < MAX_NR_ZONES; i++)
X zones_size[i] = 0;
+
+#ifdef CONFIG_HIGHMEM
+ zones_size[ZONE_HIGHMEM] = (total_memory - total_lowmem) >> PAGE_SHIFT;
+#endif /* CONFIG_HIGHMEM */
+
X free_area_init(zones_size);
X }
X
@@ -1176,7 +1161,17 @@
X int codepages = 0;
X int datapages = 0;
X int initpages = 0;
+#ifdef CONFIG_HIGHMEM
+ unsigned long highmem_mapnr;
+
+ highmem_mapnr = total_lowmem >> PAGE_SHIFT;
+ highmem_start_page = mem_map + highmem_mapnr;
+ max_mapnr = total_memory >> PAGE_SHIFT;
+ totalram_pages += max_mapnr - highmem_mapnr;
+#else
X max_mapnr = max_low_pfn;
+#endif /* CONFIG_HIGHMEM */
+
X high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
X num_physpages = max_mapnr; /* RAM is assumed contiguous */
X
@@ -1217,11 +1212,28 @@
X datapages++;
X }
X
- printk("Memory: %luk available (%dk kernel code, %dk data, %dk init) [%08x,%08lx]\n",
+#ifdef CONFIG_HIGHMEM
+ {
+ unsigned long pfn;
+
+ for (pfn = highmem_mapnr; pfn < max_mapnr; ++pfn) {
+ struct page *page = mem_map + pfn;
+
+ ClearPageReserved(page);
+ set_bit(PG_highmem, &page->flags);
+ atomic_set(&page->count, 1);
+ __free_page(page);
+ totalhigh_pages++;
+ }
+ totalram_pages += totalhigh_pages;
+ }
+#endif /* CONFIG_HIGHMEM */
+
+ printk("Memory: %luk available (%dk kernel code, %dk data, %dk init, %ldk highmem)\n",
X (unsigned long)nr_free_pages()<< (PAGE_SHIFT-10),
X codepages<< (PAGE_SHIFT-10), datapages<< (PAGE_SHIFT-10),
X initpages<< (PAGE_SHIFT-10),
- PAGE_OFFSET, (unsigned long) end_of_DRAM);
+ (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)));
X mem_init_done = 1;
X }
X
@@ -1234,7 +1246,7 @@
X * Our text, data, bss use something over 1MB, starting at 0.
X * Open Firmware may be using 1MB at the 4MB point.
X */
-unsigned long __init *pmac_find_end_of_memory(void)
+unsigned long __init pmac_find_end_of_memory(void)
X {
X unsigned long a, total;
X unsigned long ram_limit = 0xe0000000 - KERNELBASE;
@@ -1279,7 +1291,7 @@
X
X set_phys_avail(&phys_mem);
X
- return __va(total);
+ return total;
X }
X #endif /* CONFIG_ALL_PPC */
X
@@ -1290,7 +1302,7 @@
X * this will likely stay separate from the pmac.


X * -- Cort
X */

-unsigned long __init *prep_find_end_of_memory(void)
+unsigned long __init prep_find_end_of_memory(void)
X {
X unsigned long total;
X total = res->TotalMemory;
@@ -1308,15 +1320,15 @@
X mem_pieces_append(&phys_mem, 0, total);
X set_phys_avail(&phys_mem);
X
- return (__va(total));
+ return (total);
X }
X #endif /* defined(CONFIG_ALL_PPC) */
X
X
X #if defined(CONFIG_GEMINI)
-unsigned long __init *gemini_find_end_of_memory(void)
+unsigned long __init gemini_find_end_of_memory(void)
X {
- unsigned long total, *ret;
+ unsigned long total;
X unsigned char reg;
X
X reg = readb(GEMINI_MEMCFG);
@@ -1327,9 +1339,8 @@
X phys_mem.regions[0].size = total;
X phys_mem.n_regions = 1;
X
- ret = __va(phys_mem.regions[0].size);
X set_phys_avail(&phys_mem);
- return ret;
+ return phys_mem.regions[0].size;
X }
X #endif /* defined(CONFIG_GEMINI) */
X
@@ -1337,10 +1348,9 @@
X /*
X * Same hack as 8xx.
X */
-unsigned long __init *m8260_find_end_of_memory(void)
+unsigned long __init m8260_find_end_of_memory(void)
X {
X bd_t *binfo;
- unsigned long *ret;
X extern unsigned char __res[];
X
X binfo = (bd_t *)__res;
@@ -1349,15 +1359,14 @@
X phys_mem.regions[0].size = binfo->bi_memsize;
X phys_mem.n_regions = 1;
X
- ret = __va(phys_mem.regions[0].size);
X set_phys_avail(&phys_mem);
- return ret;
+ return phys_mem.regions[0].size;
X }
X #endif /* CONFIG_8260 */
X
X #ifdef CONFIG_APUS
X #define HARDWARE_MAPPED_SIZE (512*1024)
-unsigned long __init *apus_find_end_of_memory(void)
+unsigned long __init apus_find_end_of_memory(void)
X {
X int shadow = 0;
X
@@ -1421,7 +1430,7 @@
X the PowerUP board. Other system memory is horrible slow in
X comparison. The user can use other memory for swapping
X using the z2ram device. */
- return __va(memory[0].addr + memory[0].size);
+ return memory[0].addr + memory[0].size;
X }
X #endif /* CONFIG_APUS */
X
@@ -1484,7 +1493,7 @@
X /* Find some memory for the hash table. */
X if ( Hash_size ) {
X Hash = mem_pieces_find(Hash_size, Hash_size);
- /*__clear_user(Hash, Hash_size);*/
+ cacheable_memzero(Hash, Hash_size);
X } else
X Hash = 0;


X #endif /* CONFIG_PPC64BRIDGE */

@@ -1544,10 +1553,9 @@
X * functions in the image just to get prom_init, all we really need right
X * now is the initialization of the physical memory region.
X */
-unsigned long __init *m8xx_find_end_of_memory(void)
+unsigned long __init m8xx_find_end_of_memory(void)
X {
X bd_t *binfo;
- unsigned long *ret;
X extern unsigned char __res[];
X
X binfo = (bd_t *)__res;
@@ -1555,12 +1563,9 @@
X phys_mem.regions[0].address = 0;
X phys_mem.regions[0].size = binfo->bi_memsize;
X phys_mem.n_regions = 1;
-
- ret = __va(phys_mem.regions[0].address+
- phys_mem.regions[0].size);
X
X set_phys_avail(&phys_mem);
- return ret;
+ return phys_mem.regions[0].address + phys_mem.regions[0].size;
X }
X #endif /* !CONFIG_4xx && !CONFIG_8xx */
X
@@ -1569,7 +1574,7 @@
X * Return the virtual address representing the top of physical RAM
X * on the Oak board.
X */
-unsigned long __init *
+unsigned long __init
X oak_find_end_of_memory(void)
X {
X extern unsigned char __res[];
@@ -1580,12 +1585,9 @@
X phys_mem.regions[0].address = 0;
X phys_mem.regions[0].size = bip->bi_memsize;
X phys_mem.n_regions = 1;
-
- ret = __va(phys_mem.regions[0].address +
- phys_mem.regions[0].size);
X
X set_phys_avail(&phys_mem);
- return (ret);
+ return (phys_mem.regions[0].address + phys_mem.regions[0].size);
X }
X #endif
X
diff -u --recursive --new-file v2.4.0-test8/linux/arch/ppc/xmon/start.c linux/arch/ppc/xmon/start.c
--- v2.4.0-test8/linux/arch/ppc/xmon/start.c Mon Jun 19 17:59:37 2000
+++ linux/arch/ppc/xmon/start.c Sun Sep 17 09:48:07 2000
@@ -8,6 +8,7 @@
X #include <asm/page.h>
X #include <linux/adb.h>
X #include <linux/pmu.h>
+#include <linux/cuda.h>
X #include <linux/kernel.h>
X #include <asm/prom.h>
X #include <asm/bootx.h>
@@ -67,6 +68,12 @@
X use_screen = 1;
X }
X #endif
+#ifdef CONFIG_ADB_CUDA
+ if (!via_modem && disp_bi ) {
+ prom_drawstring("xmon uses screen and keyboard\n");
+ use_screen = 1;
+ }
+#endif
X #endif
X
X #ifdef CHRP_ESCC
@@ -100,6 +107,10 @@
X /* should already be mapped by the kernel boot */
X sccc = (volatile unsigned char *) (isa_io_base + 0x3fd);
X sccd = (volatile unsigned char *) (isa_io_base + 0x3f8);
+ if (xmon_use_sccb) {
+ sccc -= 0x100;
+ sccd -= 0x100;
+ }
X TXRDY = 0x20;
X RXRDY = 1;
X }
@@ -109,6 +120,19 @@
X
X void xmon_init_scc(void);
X extern void pmu_poll(void);
+extern void cuda_poll(void);
+
+static inline void do_poll_adb(void)
+{
+#ifdef CONFIG_ADB_PMU
+ if (sys_ctrler == SYS_CTRLER_PMU)
+ pmu_poll();
+#endif /* CONFIG_ADB_PMU */
+#ifdef CONFIG_ADB_CUDA
+ if (sys_ctrler == SYS_CTRLER_CUDA)
+ cuda_poll();
+#endif /* CONFIG_ADB_CUDA */
+}
X
X int
X xmon_write(void *handle, void *ptr, int nb)
@@ -128,12 +152,8 @@
X xmon_init_scc();
X ct = 0;
X for (i = 0; i < nb; ++i) {
- while ((*sccc & TXRDY) == 0) {
-#ifdef CONFIG_ADB_PMU
- if (sys_ctrler == SYS_CTRLER_PMU)
- pmu_poll();
-#endif /* CONFIG_ADB_PMU */
- }
+ while ((*sccc & TXRDY) == 0)
+ do_poll_adb();
X c = p[i];
X if (c == '\n' && !ct) {
X c = '\r';
@@ -189,9 +209,7 @@
X prom_drawchar('\b');
X t = 200000;
X }
-#ifdef CONFIG_ADB_PMU
- pmu_poll();
-#endif /* CONFIG_ADB_PMU */
+ do_poll_adb();
X } while (xmon_adb_keycode == -1);
X k = xmon_adb_keycode;
X if (on)
@@ -230,14 +248,9 @@
X xmon_init_scc();
X for (i = 0; i < nb; ++i) {
X while ((*sccc & RXRDY) == 0)
-#ifdef CONFIG_ADB_PMU
- if (sys_ctrler == SYS_CTRLER_PMU)
- pmu_poll();
-#else
- ;
-#endif /* CONFIG_ADB_PMU */
+ do_poll_adb();
X buf_access();
- *p++ = *sccd;
+ *p++ = *sccd;
X }
X return i;
X }
@@ -246,10 +259,7 @@
X xmon_read_poll(void)
X {
X if ((*sccc & RXRDY) == 0) {
-#ifdef CONFIG_ADB_PMU
- if (sys_ctrler == SYS_CTRLER_PMU)
- pmu_poll();
-#endif /* CONFIG_ADB_PMU */
+ do_poll_adb();
X return -1;
X }
X buf_access();
@@ -490,4 +500,20 @@
X }
X *p = 0;
X return str;
+}
+
+void
+xmon_enter(void)
+{
+#ifdef CONFIG_ADB_PMU
+ pmu_suspend();
+#endif
+}
+
+void
+xmon_leave(void)
+{
+#ifdef CONFIG_ADB_PMU
+ pmu_resume();
+#endif
X }
diff -u --recursive --new-file v2.4.0-test8/linux/arch/ppc/xmon/xmon.c linux/arch/ppc/xmon/xmon.c
--- v2.4.0-test8/linux/arch/ppc/xmon/xmon.c Thu Jul 13 09:42:51 2000
+++ linux/arch/ppc/xmon/xmon.c Sun Sep 17 09:48:07 2000
@@ -6,15 +6,23 @@
X #include <linux/config.h>
X #include <linux/errno.h>
X #include <linux/sched.h>
+#include <linux/smp.h>
X #include <asm/ptrace.h>
X #include <asm/string.h>
X #include <asm/prom.h>
+#include <asm/bitops.h>
X #include "nonstdio.h"
X #include "privinst.h"
X
X #define scanhex xmon_scanhex
X #define skipbl xmon_skipbl
X
+#ifdef CONFIG_SMP
+static unsigned long cpus_in_xmon = 0;
+static unsigned long got_xmon = 0;
+static volatile int take_xmon = -1;


+#endif /* CONFIG_SMP */
+

X static unsigned adrs;
X static int size = 1;
X static unsigned ndump = 64;
@@ -84,6 +92,9 @@
X static struct bpt *at_breakpoint(unsigned pc);
X static void bpt_cmds(void);
X static void cacheflush(void);
+#ifdef CONFIG_SMP
+static void cpu_cmd(void);
+#endif /* CONFIG_SMP */
X #if 0 /* Makes compile with -Wall */
X static char *pretty_print_addr(unsigned long addr);
X static char *lookup_name(unsigned long addr);
@@ -96,8 +107,18 @@
X extern int setjmp(u_int *);
X extern void longjmp(u_int *, int);
X
+extern void xmon_enter(void);
+extern void xmon_leave(void);
+
X #define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
X
+#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
+ || ('a' <= (c) && (c) <= 'f') \
+ || ('A' <= (c) && (c) <= 'F'))
+#define isalnum(c) (('0' <= (c) && (c) <= '9') \
+ || ('a' <= (c) && (c) <= 'z') \
+ || ('A' <= (c) && (c) <= 'Z'))
+
X static char *help_string = "\
X Commands:\n\
X d dump bytes\n\
@@ -117,10 +138,12 @@
X x exit monitor\n\
X ";
X
-static int xmon_trace;
+static int xmon_trace[NR_CPUS];
X #define SSTEP 1 /* stepping because of 's' command */
X #define BRSTEP 2 /* stepping over breakpoint */
X
+static struct pt_regs *xmon_regs[NR_CPUS];
+
X void
X xmon(struct pt_regs *excp)
X {
@@ -143,27 +166,52 @@
X
X msr = get_msr();
X set_msr(msr & ~0x8000); /* disable interrupts */
- remove_bpts();
+ xmon_regs[smp_processor_id()] = excp;
+ xmon_enter();
X excprint(excp);
+#ifdef CONFIG_SMP
+ if (test_and_set_bit(smp_processor_id(), &cpus_in_xmon))
+ for (;;)
+ ;
+ while (test_and_set_bit(0, &got_xmon)) {
+ if (take_xmon == smp_processor_id()) {
+ take_xmon = -1;
+ break;
+ }
+ }
+ /*
+ * XXX: breakpoints are removed while any cpu is in xmon
+ */
+#endif /* CONFIG_SMP */
+ remove_bpts();
X cmd = cmds(excp);
X if (cmd == 's') {
- xmon_trace = SSTEP;
+ xmon_trace[smp_processor_id()] = SSTEP;
X excp->msr |= 0x400;
X } else if (at_breakpoint(excp->nip)) {
- xmon_trace = BRSTEP;
+ xmon_trace[smp_processor_id()] = BRSTEP;
X excp->msr |= 0x400;
X } else {
- xmon_trace = 0;
+ xmon_trace[smp_processor_id()] = 0;
X insert_bpts();
X }
+ xmon_leave();
+ xmon_regs[smp_processor_id()] = 0;
+#ifdef CONFIG_SMP
+ clear_bit(0, &got_xmon);
+ clear_bit(smp_processor_id(), &cpus_in_xmon);
+#endif /* CONFIG_SMP */
X set_msr(msr); /* restore interrupt enable */
X }
X
X void
X xmon_irq(int irq, void *d, struct pt_regs *regs)
X {
+ unsigned long flags;
+ save_flags(flags);cli();
X printf("Keyboard interrupt\n");
X xmon(regs);
+ restore_flags(flags);
X }
X
X int
@@ -178,7 +226,7 @@
X --bp->count;
X remove_bpts();
X excprint(regs);
- xmon_trace = BRSTEP;
+ xmon_trace[smp_processor_id()] = BRSTEP;
X regs->msr |= 0x400;
X } else {
X xmon(regs);
@@ -189,10 +237,10 @@
X int
X xmon_sstep(struct pt_regs *regs)
X {
- if (!xmon_trace)
+ if (!xmon_trace[smp_processor_id()])
X return 0;
- if (xmon_trace == BRSTEP) {
- xmon_trace = 0;
+ if (xmon_trace[smp_processor_id()] == BRSTEP) {
+ xmon_trace[smp_processor_id()] = 0;
X insert_bpts();
X } else {
X xmon(regs);
@@ -207,7 +255,7 @@
X --dabr.count;
X remove_bpts();
X excprint(regs);
- xmon_trace = BRSTEP;
+ xmon_trace[smp_processor_id()] = BRSTEP;
X regs->msr |= 0x400;
X } else {
X dabr.instr = regs->nip;
@@ -223,7 +271,7 @@
X --iabr.count;
X remove_bpts();
X excprint(regs);
- xmon_trace = BRSTEP;
+ xmon_trace[smp_processor_id()] = BRSTEP;
X regs->msr |= 0x400;
X } else {
X xmon(regs);
@@ -264,6 +312,7 @@
X bp->address);
X bp->enabled = 0;
X }
+ store_inst((void *) bp->address);
X }
X #if !defined(CONFIG_8xx) && !defined(CONFIG_POWER4)
X if (dabr.enabled)
@@ -293,6 +342,7 @@
X && mwrite(bp->address, &bp->instr, 4) != 4)
X printf("Couldn't remove breakpoint at %x\n",
X bp->address);
+ store_inst((void *) bp->address);
X }
X }
X
@@ -306,6 +356,9 @@
X
X last_cmd = NULL;
X for(;;) {
+#ifdef CONFIG_SMP
+ printf("%d:", smp_processor_id());
+#endif /* CONFIG_SMP */
X printf("mon> ");
X fflush(stdout);
X flush_input();
@@ -383,12 +436,67 @@
X case 'b':
X bpt_cmds();
X break;
- case 'c':
+ case 'C':
X csum();
X break;
+#ifdef CONFIG_SMP
+ case 'c':
+ cpu_cmd();
+ break;


+#endif /* CONFIG_SMP */
+ }

+ }
+}
+
+#ifdef CONFIG_SMP
+static void cpu_cmd(void)
+{
+ unsigned cpu;
+ int timeout;
+ int cmd;
+
+ cmd = inchar();
+ if (cmd == 'i') {
+ /* interrupt other cpu(s) */
+ cpu = MSG_ALL_BUT_SELF;
+ scanhex(&cpu);
+ smp_send_xmon_break(cpu);
+ return;
+ }
+ termch = cmd;
+ if (!scanhex(&cpu)) {
+ /* print cpus waiting or in xmon */
+ printf("cpus stopped:");
+ for (cpu = 0; cpu < NR_CPUS; ++cpu) {
+ if (test_bit(cpu, &cpus_in_xmon)) {
+ printf(" %d", cpu);
+ if (cpu == smp_processor_id())
+ printf("*", cpu);
+ }
+ }
+ printf("\n");
+ return;
+ }
+ /* try to switch to cpu specified */
+ take_xmon = cpu;
+ timeout = 10000000;
+ while (take_xmon >= 0) {


+ if (--timeout == 0) {

+ /* yes there's a race here */
+ take_xmon = -1;
+ printf("cpu %u didn't take control\n", cpu);
+ return;
+ }
+ }
+ /* now have to wait to be given control back */
+ while (test_and_set_bit(0, &got_xmon)) {
+ if (take_xmon == smp_processor_id()) {
+ take_xmon = -1;


+ break;
X }
X }
X }

+#endif /* CONFIG_SMP */
X
X static unsigned short fcstab[256] = {
X 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
@@ -551,6 +659,8 @@
X extern char lost_irq_ret, do_bottom_half_ret, do_signal_ret;
X extern char ret_from_except;
X
+ printf("backtrace:\n");
+
X if (excp != NULL)
X sp = excp->gpr[1];
X else
@@ -592,6 +702,9 @@
X void
X excprint(struct pt_regs *fp)
X {
+#ifdef CONFIG_SMP
+ printf("cpu %d: ", smp_processor_id());
+#endif /* CONFIG_SMP */
X printf("vector: %x at pc = %x",
X fp->trap, fp->nip);
X printf(", lr = %x, msr = %x, sp = %x [%x]\n",
@@ -1163,9 +1276,6 @@
X return c;
X }
X
-#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
- || ('a' <= (c) && (c) <= 'f') \
- || ('A' <= (c) && (c) <= 'F'))
X void
X dump()
X {
@@ -1402,6 +1512,16 @@
X return c;
X }
X
+#define N_PTREGS 44
+static char *regnames[N_PTREGS] = {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+ "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", "mq",
+ "trap", "dar", "dsisr", "res"
+};
+
X int
X scanhex(vp)
X unsigned *vp;
@@ -1410,6 +1530,36 @@
X unsigned v;
X
X c = skipbl();
+ if (c == '%') {
+ /* parse register name */
+ char regname[8];
+ int i;
+
+ for (i = 0; i < sizeof(regname) - 1; ++i) {
+ c = inchar();
+ if (!isalnum(c)) {
+ termch = c;
+ break;
+ }
+ regname[i] = c;
+ }
+ regname[i] = 0;
+ for (i = 0; i < N_PTREGS; ++i) {
+ if (strcmp(regnames[i], regname) == 0) {
+ unsigned *rp = (unsigned *)
+ xmon_regs[smp_processor_id()];
+ if (rp == NULL) {
+ printf("regs not available\n");
+ return 0;
+ }
+ *vp = rp[i];
+ return 1;
+ }
+ }
+ printf("invalid register name '%%%s'\n", regname);


+ return 0;
+ }
+

X d = hexdigit(c);
X if( d == EOF ){
X termch = c;
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sh/boot/compressed/Makefile linux/arch/sh/boot/compressed/Makefile
--- v2.4.0-test8/linux/arch/sh/boot/compressed/Makefile Wed Aug 9 13:59:04 2000
+++ linux/arch/sh/boot/compressed/Makefile Mon Oct 2 11:57:33 2000
@@ -36,7 +36,7 @@
X $(OBJCOPY) -R .empty_zero_page $(SYSTEM) $$tmppiggy; \
X gzip -f -9 < $$tmppiggy > $$tmppiggy.gz; \
X echo "SECTIONS { .data : { input_len = .; LONG(input_data_end - input_data) input_data = .; *(.data) input_data_end = .; }}" > $$tmppiggy.lnk; \
- $(LD) -r -o piggy.o -b binary $$tmppiggy.gz -b elf32-shl -T $$tmppiggy.lnk; \
+ $(LD) -r -o piggy.o -b binary $$tmppiggy.gz -b elf32-sh-linux -T $$tmppiggy.lnk; \
X rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk
X
X clean:
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sh/config.in linux/arch/sh/config.in
--- v2.4.0-test8/linux/arch/sh/config.in Wed Aug 9 13:59:04 2000
+++ linux/arch/sh/config.in Tue Sep 19 10:57:30 2000
@@ -123,6 +123,8 @@
X
X source drivers/block/Config.in
X
+source drivers/md/Config.in
+
X if [ "$CONFIG_NET" = "y" ]; then
X source net/Config.in
X fi
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sh/kernel/entry.S linux/arch/sh/kernel/entry.S
--- v2.4.0-test8/linux/arch/sh/kernel/entry.S Fri Aug 11 14:29:05 2000
+++ linux/arch/sh/kernel/entry.S Mon Oct 2 11:57:34 2000
@@ -14,7 +14,12 @@
X #include <linux/linkage.h>
X #include <linux/config.h>
X
-#define COMPAT_OLD_SYSCALL_ABI 1
+
+/*
+ * Define this to turn on compatibility with the previous
+ * system call ABI. This feature is not properly maintained.
+ */
+#undef COMPAT_OLD_SYSCALL_ABI
X
X ! NOTE:
X ! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address
@@ -28,6 +33,12 @@
X * NOTE: This code handles signal-recognition, which happens every time
X * after a timer-interrupt and after each system call.
X *
+ * NOTE: This code uses a convention that instructions in the delay slot
+ * of a transfer-control instruction are indented by an extra space, thus:
+ *
+ * jmp @$k0 ! control-transfer instruction
+ * ldc $k1, $ssr ! delay slot
+ *
X * Stack layout in 'ret_from_syscall':
X * ptrace needs to have all regs on the stack.
X * if the order here is changed, it needs to be
@@ -58,6 +69,7 @@
X PF_USEDFPU = 0x00100000
X
X ENOSYS = 38
+EINVAL = 22
X
X #if defined(__sh3__)
X TRA = 0xffffffd0
@@ -76,7 +88,14 @@
X #endif
X
X /* Offsets to the stack */
-R0 = 0 /* Return value */
+R0 = 0 /* Return value. New ABI also arg4 */
+R1 = 4 /* New ABI: arg5 */
+R2 = 8 /* New ABI: arg6 */
+R3 = 12 /* New ABI: syscall_nr */
+R4 = 16 /* New ABI: arg0 */
+R5 = 20 /* New ABI: arg1 */
+R6 = 24 /* New ABI: arg2 */
+R7 = 28 /* New ABI: arg3 */
X SP = (15*4)
X SR = (16*4+8)
X SYSCALL_NR = (16*4+6*4)
@@ -132,7 +151,6 @@
X tlb_miss_load:
X mov.l 2f, $r0
X mov.l @$r0, $r6
- STI()
X mov $r15, $r4
X mov.l 1f, $r0
X jmp @$r0
@@ -142,7 +160,6 @@
X tlb_miss_store:
X mov.l 2f, $r0
X mov.l @$r0, $r6
- STI()
X mov $r15, $r4
X mov.l 1f, $r0
X jmp @$r0
@@ -152,7 +169,6 @@
X initial_page_write:
X mov.l 2f, $r0
X mov.l @$r0, $r6
- STI()
X mov $r15, $r4
X mov.l 1f, $r0
X jmp @$r0
@@ -162,7 +178,6 @@
X tlb_protection_violation_load:
X mov.l 2f, $r0
X mov.l @$r0, $r6
- STI()
X mov $r15, $r4
X mov.l 1f, $r0
X jmp @$r0
@@ -172,14 +187,13 @@
X tlb_protection_violation_store:
X mov.l 2f, $r0
X mov.l @$r0, $r6
- STI()
X mov $r15, $r4
X mov.l 1f, $r0
X jmp @$r0
X mov #1, $r5
X
X .align 2
-1: .long SYMBOL_NAME(do_page_fault)
+1: .long SYMBOL_NAME(__do_page_fault)
X 2: .long MMU_TEA
X
X #if defined(CONFIG_DEBUG_KERNEL_WITH_GDB_STUB) || defined(CONFIG_SH_STANDARD_BIOS)
@@ -249,9 +263,6 @@
X .align 2
X 1: .long SYMBOL_NAME(do_exception_error)
X
-badsys: mov #-ENOSYS, $r0
- rts ! go to ret_from_syscall..
- mov.l $r0, @(R0,$r15)
X
X !
X !
@@ -291,7 +302,7 @@
X */
X
X system_call:
- mov.l 1f, $r9
+ mov.l __TRA, $r9
X mov.l @$r9, $r8
X !
X ! Is the trap argument >= 0x20? (TRA will be >= 0x80)
@@ -304,122 +315,160 @@
X mov #SYSCALL_NR, $r14
X add $r15, $r14
X !
- mov #0x40, $r9
X #ifdef COMPAT_OLD_SYSCALL_ABI
+ mov #0x40, $r9
X cmp/hs $r9, $r8
- mov $r0, $r10
- bf/s 0f
- mov $r0, $r9
+ bf/s old_abi_system_call
+ nop
X #endif
X ! New Syscall ABI
X add #-0x40, $r8
X shlr2 $r8
X shll8 $r8
- shll8 $r8
+ shll8 $r8 ! $r8 = num_args<<16
X mov $r3, $r10
X or $r8, $r10 ! Encode syscall # and # of arguments
- !
- mov $r3, $r9
- mov #0, $r8
-0:
X mov.l $r10, @$r14 ! set syscall_nr
X STI()
- mov.l __n_sys, $r10
- cmp/hs $r10, $r9
- bt badsys
X !
-#ifdef COMPAT_OLD_SYSCALL_ABI
- ! Build the stack frame if TRA > 0
- mov $r8, $r10
- cmp/pl $r10
- bf 0f
- mov.l @(SP,$r15), $r0 ! get original stack
-7: add #-4, $r10
-4: mov.l @($r0,$r10), $r1 ! May cause address error exception..
- mov.l $r1, @-$r15
- cmp/pl $r10
- bt 7b
-#endif
-0: stc $k_current, $r11
- mov.l @(tsk_ptrace,$r11), $r10 ! Is it trace?
+ stc $k_current, $r11
+ mov.l @(tsk_ptrace,$r11), $r10 ! Is current PTRACE_SYSCALL'd?
X mov #PT_TRACESYS, $r11
X tst $r11, $r10
X bt 5f
- ! Trace system call
- mov #-ENOSYS, $r11
- mov.l $r11, @(R0,$r15)
- ! Push up $R0--$R2, and $R4--$R7
- mov.l $r0, @-$r15
- mov.l $r1, @-$r15
- mov.l $r2, @-$r15
- mov.l $r4, @-$r15
- mov.l $r5, @-$r15
- mov.l $r6, @-$r15
- mov.l $r7, @-$r15
- !
- mov.l 2f, $r11
- jsr @$r11
+ ! Yes it is traced.
+ mov.l __syscall_trace, $r11 ! Call syscall_trace() which notifies
+ jsr @$r11 ! superior (will chomp $R[0-7])
X nop
- ! Pop down $R0--$R2, and $R4--$R7
- mov.l @$r15+, $r7
- mov.l @$r15+, $r6
- mov.l @$r15+, $r5
- mov.l @$r15+, $r4
- mov.l @$r15+, $r2
- mov.l @$r15+, $r1
- mov.l @$r15+, $r0
- !
+ ! Reload $R0-$R4 from kernel stack, where the
+ ! parent may have modified them using
+ ! ptrace(POKEUSR). (Note that $R0-$R2 are
+ ! used by the system call handler directly
+ ! from the kernel stack anyway, so don't need
+ ! to be reloaded here.) This allows the parent
+ ! to rewrite system calls and args on the fly.
+ mov.l @(R4,$r15), $r4 ! arg0
+ mov.l @(R5,$r15), $r5
+ mov.l @(R6,$r15), $r6
+ mov.l @(R7,$r15), $r7 ! arg3
+ mov.l @(R3,$r15), $r3 ! syscall_nr
+ ! Arrange for syscall_trace() to be called
+ ! again as the system call returns.
X mov.l __syscall_ret_trace, $r10
X bra 6f
X lds $r10, $pr
- !
+ ! No it isn't traced.
+ ! Arrange for normal system call return.
X 5: mov.l __syscall_ret, $r10
X lds $r10, $pr
- !
-6: mov $r9, $r10
- shll2 $r10 ! x4
+ ! Call the system call handler through the table.
+ ! (both normal and ptrace'd)
+ ! First check for bad syscall number
+6: mov $r3, $r9
+ mov.l __n_sys, $r10
+ cmp/hs $r10, $r9
+ bf 2f
+ ! Bad syscall number
+ rts ! go to syscall_ret or syscall_ret_trace
+ mov #-ENOSYS, $r0
+ ! Good syscall number
+2: shll2 $r9 ! x4
X mov.l __sct, $r11
- add $r11, $r10
- mov.l @$r10, $r11
- jmp @$r11
+ add $r11, $r9
+ mov.l @$r9, $r11
+ jmp @$r11 ! jump to specific syscall handler
X nop
X
X ! In case of trace
- .align 2
-3:
-#ifdef COMPAT_OLD_SYSCALL_ABI
- add $r8, $r15 ! pop off the arguments
-#endif
+syscall_ret_trace:
X mov.l $r0, @(R0,$r15) ! save the return value
- mov.l 2f, $r1
+ mov.l __syscall_trace, $r1
X mova SYMBOL_NAME(ret_from_syscall), $r0
- jmp @$r1
- lds $r0, $pr
- .align 2
-1: .long TRA
-2: .long SYMBOL_NAME(syscall_trace)
-__n_sys: .long NR_syscalls
-__sct: .long SYMBOL_NAME(sys_call_table)
-__syscall_ret_trace:
- .long 3b
-__syscall_ret:
- .long SYMBOL_NAME(syscall_ret)
+ jmp @$r1 ! Call syscall_trace() which notifies superior
+ lds $r0, $pr ! Then return to ret_from_syscall()
+
+
X
X #ifdef COMPAT_OLD_SYSCALL_ABI
+! Handle old ABI system call.
+! Note that ptrace(SYSCALL) is not supported for the old ABI.
+! At this point:
+! $r0, $r4-7 as per ABI
+! $r8 = value of TRA register (= num_args<<2)
+! $r14 = points to SYSCALL_NR in stack frame
+old_abi_system_call:
+ mov $r0, $r9 ! Save system call number in $r9
+ ! ! arrange for return which pops stack
+ mov.l __old_abi_syscall_ret, $r10
+ lds $r10, $pr
+ ! Build the stack frame if TRA > 0
+ mov $r8, $r10
+ cmp/pl $r10
+ bf 0f
+ mov.l @(SP,$r15), $r0 ! get original user stack
+7: add #-4, $r10
+4: mov.l @($r0,$r10), $r1 ! May cause address error exception..
+ mov.l $r1, @-$r15
+ cmp/pl $r10
+ bt 7b
+0:
+ mov.l $r9, @$r14 ! set syscall_nr
+ STI()
+ ! Call the system call handler through the table.
+ ! First check for bad syscall number
+ mov.l __n_sys, $r10
+ cmp/hs $r10, $r9
+ bf 2f
+ ! Bad syscall number
+ rts ! return to old_abi_syscall_ret
+ mov #-ENOSYS, $r0
+ ! Good syscall number
+2: shll2 $r9 ! x4
+ mov.l __sct, $r11
+ add $r11, $r9
+ mov.l @$r9, $r11
+ jmp @$r11 ! call specific syscall handler,
+ nop
+
+ .align 2
+__old_abi_syscall_ret:
+ .long old_abi_syscall_ret
+
+ ! This code gets called on address error exception when copying
+ ! syscall arguments from user stack to kernel stack. It is
+ ! supposed to return -EINVAL through old_abi_syscall_ret, but it
+ ! appears to have been broken for a long time in that the $r0
+ ! return value will be saved into the kernel stack relative to $r15
+ ! but the value of $r15 is not correct partway through the loop.
+ ! So the user prog is returned its old $r0 value, not -EINVAL.
+ ! Greg Banks 28 Aug 2000.
X .section .fixup,"ax"
X fixup_syscall_argerr:
+ ! First get $r15 back to
X rts
- mov.l 1f, $r0
-1: .long -22 ! -EINVAL
-.previous
+ mov #-EINVAL, $r0
+ .previous
X
X .section __ex_table, "a"
X .align 2
X .long 4b,fixup_syscall_argerr
-.previous
+ .previous
X #endif
X
X .align 2
+__TRA: .long TRA
+__syscall_trace:
+ .long SYMBOL_NAME(syscall_trace)
+__n_sys:.long NR_syscalls
+__sct: .long SYMBOL_NAME(sys_call_table)
+__syscall_ret_trace:
+ .long syscall_ret_trace
+__syscall_ret:
+ .long SYMBOL_NAME(syscall_ret)
+
+
+
+ .align 2
X reschedule:
X mova SYMBOL_NAME(ret_from_syscall), $r0
X mov.l 1f, $r1
@@ -454,10 +503,12 @@
X .long 0xffffff0f ! ~(IMASK)
X
X .align 2
-syscall_ret:
X #ifdef COMPAT_OLD_SYSCALL_ABI
+old_abi_syscall_ret:
X add $r8, $r15 ! pop off the arguments
+ /* fall through */
X #endif
+syscall_ret:
X mov.l $r0, @(R0,$r15) ! save the return value
X /* fall through */
X
@@ -707,7 +758,7 @@
X #endif
X 8: /* User space to kernel */
X mov #0x20, $k1
- shll8 $k1 ! $k1 <= 8192
+ shll8 $k1 ! $k1 <= 8192 == THREAD_SIZE
X add $current, $k1
X mov $k1, $r15 ! change to kernel stack
X !
@@ -1107,6 +1158,7 @@
X .long SYMBOL_NAME(sys_mincore)
X .long SYMBOL_NAME(sys_madvise)
X .long SYMBOL_NAME(sys_getdents64) /* 220 */
+ .long SYMBOL_NAME(sys_fcntl64)
X
X /*
X * NOTE!! This doesn't have to be exact - we just have
@@ -1114,7 +1166,7 @@
X * entries. Don't panic if you notice that this hasn't
X * been shrunk every time we add a new system call.
X */
- .rept NR_syscalls-220
+ .rept NR_syscalls-221
X .long SYMBOL_NAME(sys_ni_syscall)
X .endr
X
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sh/kernel/head.S linux/arch/sh/kernel/head.S
--- v2.4.0-test8/linux/arch/sh/kernel/head.S Mon Apr 24 13:54:17 2000
+++ linux/arch/sh/kernel/head.S Mon Oct 2 11:57:34 2000
@@ -21,9 +21,9 @@
X .long 0x00360000 /* INITRD_START */
X .long 0x000a0000 /* INITRD_SIZE */
X .long 0
+ .balign 4096,0,4096
X
X .text
- .balign 4096,0,4096
X /*
X * Condition at the entry of _stext:
X *
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sh/kernel/io.c linux/arch/sh/kernel/io.c
--- v2.4.0-test8/linux/arch/sh/kernel/io.c Thu Aug 10 13:03:25 2000
+++ linux/arch/sh/kernel/io.c Mon Oct 2 11:57:34 2000
@@ -1,5 +1,5 @@
X /*
- * linux/arch/sh/kernel/io_generic.c
+ * linux/arch/sh/kernel/io.c
X *
X * Copyright (C) 2000 Stuart Menefy
X *
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sh/kernel/irq_imask.c linux/arch/sh/kernel/irq_imask.c
--- v2.4.0-test8/linux/arch/sh/kernel/irq_imask.c Wed Aug 9 13:59:04 2000
+++ linux/arch/sh/kernel/irq_imask.c Mon Oct 2 11:57:34 2000
@@ -41,7 +41,7 @@
X
X static unsigned int startup_imask_irq(unsigned int irq)
X {
- enable_imask_irq(irq);
+ /* Nothing to do */
X return 0; /* never anything pending */
X }
X
@@ -71,7 +71,8 @@
X "ldc %0, $sr\n"
X "1:"
X : "=&z" (__dummy)
- : "r" (~0xf0), "r" (ip << 4));
+ : "r" (~0xf0), "r" (ip << 4)
+ : "t");
X }
X
X static void disable_imask_irq(unsigned int irq)
@@ -103,7 +104,7 @@
X
X static void shutdown_imask_irq(unsigned int irq)
X {
- disable_imask_irq(irq);
+ /* Nothing to do */
X }
X
X void make_imask_irq(unsigned int irq)
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sh/kernel/irq_ipr.c linux/arch/sh/kernel/irq_ipr.c
--- v2.4.0-test8/linux/arch/sh/kernel/irq_ipr.c Wed Aug 9 13:59:04 2000
+++ linux/arch/sh/kernel/irq_ipr.c Mon Oct 2 11:57:34 2000
@@ -128,12 +128,14 @@
X #ifdef SCIF_ERI_IRQ
X make_ipr_irq(SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
X make_ipr_irq(SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
+ make_ipr_irq(SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
X make_ipr_irq(SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
X #endif
X
X #ifdef IRDA_ERI_IRQ
X make_ipr_irq(IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
X make_ipr_irq(IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
+ make_ipr_irq(IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
X make_ipr_irq(IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
X #endif
X
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sh/kernel/process.c linux/arch/sh/kernel/process.c
--- v2.4.0-test8/linux/arch/sh/kernel/process.c Tue Sep 5 13:50:01 2000
+++ linux/arch/sh/kernel/process.c Mon Oct 2 11:57:34 2000
@@ -136,11 +136,12 @@
X */
X int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
X { /* Don't use this in BL=1(cli). Or else, CPU resets! */
- register unsigned long __sc0 __asm__ ("$r3") = __NR_clone;
- register unsigned long __sc4 __asm__ ("$r4") = (long) flags | CLONE_VM;
- register unsigned long __sc5 __asm__ ("$r5") = 0;
- register unsigned long __sc8 __asm__ ("$r8") = (long) arg;
- register unsigned long __sc9 __asm__ ("$r9") = (long) fn;
+ register unsigned long __sc0 __asm__ ("r0");
+ register unsigned long __sc3 __asm__ ("r3") = __NR_clone;
+ register unsigned long __sc4 __asm__ ("r4") = (long) flags | CLONE_VM;
+ register unsigned long __sc5 __asm__ ("r5") = 0;
+ register unsigned long __sc8 __asm__ ("r8") = (long) arg;
+ register unsigned long __sc9 __asm__ ("r9") = (long) fn;
X
X __asm__("trapa #0x12\n\t" /* Linux/SH system call */
X "tst #0xff, $r0\n\t" /* child or parent? */
@@ -148,13 +149,13 @@
X "jsr @$r9\n\t" /* call fn */
X " mov $r8, $r4\n\t" /* push argument */
X "mov $r0, $r4\n\t" /* return value to arg of exit */
- "mov %2, $r3\n\t" /* exit */
+ "mov %1, $r3\n\t" /* exit */
X "trapa #0x11\n"
X "1:"
X : "=z" (__sc0)
- : "0" (__sc0), "i" (__NR_exit),
- "r" (__sc4), "r" (__sc5), "r" (__sc8), "r" (__sc9)
- : "memory");
+ : "i" (__NR_exit), "r" (__sc3), "r" (__sc4), "r" (__sc5),
+ "r" (__sc8), "r" (__sc9)
+ : "memory", "t");
X return __sc0;
X }
X
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sh/kernel/setup_cqreek.c linux/arch/sh/kernel/setup_cqreek.c
--- v2.4.0-test8/linux/arch/sh/kernel/setup_cqreek.c Thu Aug 10 13:03:25 2000
+++ linux/arch/sh/kernel/setup_cqreek.c Mon Oct 2 11:57:34 2000
@@ -1,4 +1,4 @@
-/* $Id: setup_cqreek.c,v 1.1 2000/08/05 06:25:23 gniibe Exp $
+/* $Id: setup_cqreek.c,v 1.5 2000/09/18 05:51:24 gniibe Exp $
X *
X * arch/sh/kernel/setup_cqreek.c
X *
@@ -44,15 +44,24 @@
X return ISA_OFFSET + port;
X }
X
+struct cqreek_irq_data {
+ unsigned short mask_port; /* Port of Interrupt Mask Register */
+ unsigned short stat_port; /* Port of Interrupt Status Register */
+ unsigned short bit; /* Value of the bit */
+};
+static struct cqreek_irq_data cqreek_irq_data[NR_IRQS];
+
X static void disable_cqreek_irq(unsigned int irq)


X {
X unsigned long flags;

X unsigned short mask;
+ unsigned short mask_port = cqreek_irq_data[irq].mask_port;
+ unsigned short bit = cqreek_irq_data[irq].bit;
X
X save_and_cli(flags);
X /* Disable IRQ */
- mask = inw(BRIDGE_ISA_INTR_MASK) & ~(1 << irq);
- outw_p(mask, BRIDGE_ISA_INTR_MASK);
+ mask = inw(mask_port) & ~bit;
+ outw_p(mask, mask_port);
X restore_flags(flags);
X }
X
@@ -60,32 +69,29 @@
X {
X unsigned long flags;
X unsigned short mask;
+ unsigned short mask_port = cqreek_irq_data[irq].mask_port;
+ unsigned short bit = cqreek_irq_data[irq].bit;
X
X save_and_cli(flags);
X /* Enable IRQ */
- mask = inw(BRIDGE_ISA_INTR_MASK) | (1 << irq);
- outw_p(mask, BRIDGE_ISA_INTR_MASK);
+ mask = inw(mask_port) | bit;
+ outw_p(mask, mask_port);
X restore_flags(flags);
X }
X
-#define CLEAR_AT_ACCEPT
-
X static void mask_and_ack_cqreek(unsigned int irq)
X {
- inw(BRIDGE_ISA_INTR_STAT);
+ unsigned short stat_port = cqreek_irq_data[irq].stat_port;
+ unsigned short bit = cqreek_irq_data[irq].bit;
+
+ inw(stat_port);
X disable_cqreek_irq(irq);
-#ifdef CLEAR_AT_ACCEPT
X /* Clear IRQ (it might be edge IRQ) */
- outw_p((1<<irq), BRIDGE_ISA_INTR_STAT);
-#endif
+ outw_p(bit, stat_port);
X }
X
X static void end_cqreek_irq(unsigned int irq)
X {
-#ifndef CLEAR_AT_ACCEPT
- /* Clear IRQ (it might be edge IRQ) */
- outw_p((1<<irq), BRIDGE_ISA_INTR_STAT);
-#endif
X enable_cqreek_irq(irq);
X }
X
@@ -101,7 +107,7 @@
X }
X
X static struct hw_interrupt_type cqreek_irq_type = {
- "CQREEK-IRQ",
+ "CqREEK-IRQ",
X startup_cqreek_irq,
X shutdown_cqreek_irq,
X enable_cqreek_irq,
@@ -116,10 +122,24 @@
X What we really need is virtualized IRQ and demultiplexer like HP600 port */
X void __init init_cqreek_IRQ(void)
X {
- if (has_ide)
- make_ipr_irq(14, IDE_OFFSET+BRIDGE_IDE_INTR_LVL, 0, 0x0f-14);
+ if (has_ide) {
+ cqreek_irq_data[14].mask_port = BRIDGE_IDE_INTR_MASK;
+ cqreek_irq_data[14].stat_port = BRIDGE_IDE_INTR_STAT;
+ cqreek_irq_data[14].bit = 1;
+
+ irq_desc[14].handler = &cqreek_irq_type;
+ irq_desc[14].status = IRQ_DISABLED;
+ irq_desc[14].action = 0;
+ irq_desc[14].depth = 1;
+
+ disable_cqreek_irq(14);
+ }
X
X if (has_isa) {
+ cqreek_irq_data[10].mask_port = BRIDGE_ISA_INTR_MASK;
+ cqreek_irq_data[10].stat_port = BRIDGE_ISA_INTR_STAT;
+ cqreek_irq_data[10].bit = (1 << 10);
+
X /* XXX: Err... we may need demultiplexer for ISA irq... */
X irq_desc[10].handler = &cqreek_irq_type;
X irq_desc[10].status = IRQ_DISABLED;
@@ -135,10 +155,17 @@
X */
X void __init setup_cqreek(void)
X {
+ extern void disable_hlt(void);
X int i;
X /* udelay is not available at setup time yet... */
X #define DELAY() do {for (i=0; i<10000; i++) ctrl_inw(0xa0000000);} while(0)
X
+ /*
+ * XXX: I don't know the reason, but it becomes so fragile with
+ * "sleep", so we need to stop sleeping.
+ */
+ disable_hlt();
+
X if ((inw (BRIDGE_FEATURE) & 1)) { /* We have IDE interface */
X outw_p(0, BRIDGE_IDE_INTR_LVL);
X outw_p(0, BRIDGE_IDE_INTR_MASK);
@@ -219,7 +246,6 @@
X mv_init_arch: setup_cqreek,
X mv_init_irq: init_cqreek_IRQ,
X
- mv_port2addr: cqreek_port2addr,
X mv_isa_port2addr: cqreek_port2addr,
X };
X ALIAS_MV(cqreek)
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sh/kernel/sh_bios.c linux/arch/sh/kernel/sh_bios.c
--- v2.4.0-test8/linux/arch/sh/kernel/sh_bios.c Wed Aug 9 13:59:04 2000
+++ linux/arch/sh/kernel/sh_bios.c Mon Oct 2 11:57:34 2000
@@ -1,4 +1,4 @@
-/* $Id: sh_bios.c,v 1.2 2000/07/26 04:37:32 gniibe Exp $
+/* $Id: sh_bios.c,v 1.3 2000/09/30 03:43:30 gniibe Exp $
X *
X * linux/arch/sh/kernel/sh_bios.c
X * C interface for trapping into the standard LinuxSH BIOS.
@@ -20,11 +20,11 @@
X
X static __inline__ long sh_bios_call(long func, long arg0, long arg1, long arg2, long arg3)
X {
- register long r0 __asm__("$r0") = func;
- register long r4 __asm__("$r4") = arg0;
- register long r5 __asm__("$r5") = arg1;
- register long r6 __asm__("$r6") = arg2;
- register long r7 __asm__("$r7") = arg3;
+ register long r0 __asm__("r0") = func;
+ register long r4 __asm__("r4") = arg0;
+ register long r5 __asm__("r5") = arg1;
+ register long r6 __asm__("r6") = arg2;
+ register long r7 __asm__("r7") = arg3;
X __asm__ __volatile__("trapa #0x3f"
X : "=z" (r0)
X : "0" (r0), "r" (r4), "r" (r5), "r" (r6), "r" (r7)
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sh/kernel/sh_ksyms.c linux/arch/sh/kernel/sh_ksyms.c


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 016'
echo 'File patch-2.4.0-test9 is continued in part 017'
echo "017" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part017

#!/bin/sh -x
# this is part 017 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 017; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

--- v2.4.0-test8/linux/arch/sh/kernel/sh_ksyms.c Fri Jul 21 14:21:06 2000
+++ linux/arch/sh/kernel/sh_ksyms.c Mon Oct 2 11:57:34 2000
@@ -17,6 +17,7 @@
X #include <asm/hardirq.h>
X #include <asm/delay.h>
X #include <asm/irq.h>
+#include <asm/pgtable.h>
X
X extern void dump_thread(struct pt_regs *, struct user *);
X extern int dump_fpu(elf_fpregset_t *);
@@ -35,7 +36,35 @@
X EXPORT_SYMBOL(strtok);
X EXPORT_SYMBOL(strpbrk);
X EXPORT_SYMBOL(strstr);
+EXPORT_SYMBOL(strlen);
+
+/* mem exports */
+EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(memset);
+EXPORT_SYMBOL(memmove);
+
+/* this is not provided by arch/sh/lib/*.S but is
+ potentially needed by modules (af_packet.o/unix.o
+ use memcmp, for instance) */
+EXPORT_SYMBOL(memcmp);
X
X #ifdef CONFIG_VT
X EXPORT_SYMBOL(screen_info);
+#endif
+
+
+#define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL_NOVERS(name)
+
+/* These symbols are generated by the compiler itself */
+#ifdef __SH4__
+
+DECLARE_EXPORT(__udivsi3_i4);
+DECLARE_EXPORT(__sdivsi3_i4);
+DECLARE_EXPORT(__movstr_i4_even);
+DECLARE_EXPORT(__movstr_i4_odd);
+DECLARE_EXPORT(__ashrdi3);
+DECLARE_EXPORT(__ashldi3);
+
+/* needed by some modules */
+EXPORT_SYMBOL(flush_dcache_page);
X #endif
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sh/kernel/time.c linux/arch/sh/kernel/time.c
--- v2.4.0-test8/linux/arch/sh/kernel/time.c Wed Aug 9 13:59:04 2000
+++ linux/arch/sh/kernel/time.c Mon Oct 2 11:57:34 2000
@@ -274,37 +274,6 @@
X write_unlock(&xtime_lock);
X }
X

-/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
- * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
- * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
- *
- * [For the Julian calendar (which was used in Russia before 1917,
- * Britain & colonies before 1752, anywhere else before 1582,
- * and is still in use by some communities) leave out the
- * -year/100+year/400 terms, and add 10.]
- *
- * This algorithm was first published by Gauss (I think).
- *
- * WARNING: this function will overflow on 2106-02-07 06:28:16 on
- * machines were long is 32-bit! (However, as time_t is signed, we
- * will already get problems at other places on 2038-01-19 03:14:08)
- */

-static inline unsigned long mktime(unsigned int year, unsigned int mon,


- unsigned int day, unsigned int hour,
- unsigned int min, unsigned int sec)
-{
- if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */
- mon += 12; /* Puts Feb last since it has leap day */
- year -= 1;
- }
- return (((
- (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
- year*365 - 719499
- )*24 + hour /* now have hours */
- )*60 + min /* now have minutes */
- )*60 + sec; /* finally seconds */

-}
-
X static unsigned long get_rtc_time(void)
X {
X unsigned int sec, min, hr, wk, day, mon, yr, yr100;
@@ -373,7 +342,8 @@
X "bt/s 1b\n\t"
X " add #1,%0"
X : "=r"(count), "=z" (__dummy)
- : "0" (0), "1" (0));
+ : "0" (0), "1" (0)
+ : "t");
X cli();
X /*
X * SH-3:
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sh/kernel/traps.c linux/arch/sh/kernel/traps.c
--- v2.4.0-test8/linux/arch/sh/kernel/traps.c Mon Apr 24 13:54:17 2000
+++ linux/arch/sh/kernel/traps.c Mon Oct 2 11:57:34 2000
@@ -131,9 +131,16 @@
X
X asm("mov $r15, %0" : "=r" (start));
X asm("stc $r7_bank, %0" : "=r" (end));
- end += 8192;
+ end += 8192/4;
X
X printk("%08lx:%08lx\n", (unsigned long)start, (unsigned long)end);
- for (p=start; p < end; p++)
- printk("%08lx\n", *p);
+ for (p=start; p < end; p++) {
+ extern long _text, _etext;
+ unsigned long v=*p;
+
+ if ((v >= (unsigned long )&_text)
+ && (v <= (unsigned long )&_etext)) {
+ printk("%08lx\n", v);
+ }
+ }
X }
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sh/lib/checksum.S linux/arch/sh/lib/checksum.S
--- v2.4.0-test8/linux/arch/sh/lib/checksum.S Wed Aug 9 13:59:04 2000
+++ linux/arch/sh/lib/checksum.S Mon Oct 2 11:57:34 2000
@@ -159,14 +159,14 @@
X * them all but there's no guarantee.
X */
X
-#define SRC(y...) \
- 9999: y; \
+#define SRC(x,y) \
+ 9999: x,y; \
X .section __ex_table, "a"; \
X .long 9999b, 6001f ; \
X .previous
X
-#define DST(y...) \
- 9999: y; \
+#define DST(x,y) \
+ 9999: x,y; \
X .section __ex_table, "a"; \
X .long 9999b, 6002f ; \
X .previous
@@ -276,7 +276,7 @@
X DST( mov.l r1,@r5 )
X add #4,r5
X
-SRC( mov.l @r4+,r0 )
+SRC( mov.l @r4+,r0 )
X SRC( mov.l @r4+,r1 )
X addc r0,r7
X DST( mov.l r0,@r5 )
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sh/mm/cache.c linux/arch/sh/mm/cache.c
--- v2.4.0-test8/linux/arch/sh/mm/cache.c Wed Aug 9 13:59:04 2000
+++ linux/arch/sh/mm/cache.c Mon Oct 2 11:57:34 2000
@@ -64,9 +64,9 @@
X #define CACHE_IC_WAY_SHIFT 13
X #define CACHE_OC_ENTRY_SHIFT 5
X #define CACHE_IC_ENTRY_SHIFT 5
-#define CACHE_OC_ENTRY_MASK 0x3fe0
-#define CACHE_OC_ENTRY_PHYS_MASK 0x0fe0
-#define CACHE_IC_ENTRY_MASK 0x1fe0
+#define CACHE_OC_ENTRY_MASK 0x3fe0
+#define CACHE_OC_ENTRY_PHYS_MASK 0x0fe0
+#define CACHE_IC_ENTRY_MASK 0x1fe0
X #define CACHE_IC_NUM_ENTRIES 256
X #define CACHE_OC_NUM_ENTRIES 512
X #define CACHE_OC_NUM_WAYS 1
@@ -92,7 +92,8 @@
X addr = CACHE_OC_ADDRESS_ARRAY|(j<<CACHE_OC_WAY_SHIFT)|
X (i<<CACHE_OC_ENTRY_SHIFT);
X data = ctrl_inl(addr);
- if (data & CACHE_UPDATED) {
+ if ((data & (CACHE_UPDATED|CACHE_VALID))
+ == (CACHE_UPDATED|CACHE_VALID)) {
X data &= ~CACHE_UPDATED;
X ctrl_outl(data, addr);
X }
@@ -114,17 +115,25 @@
X */
X addr0 = CACHE_OC_ADDRESS_ARRAY + (3 << 12);
X addr1 = CACHE_OC_ADDRESS_ARRAY + (1 << 12);
+
+ /* First, write back & invalidate */
X data0 = ctrl_inl(addr0);
- data0 ^= 0x00000001;
- ctrl_outl(data0,addr0);
+ ctrl_outl(data0&~(CACHE_VALID|CACHE_UPDATED), addr0);
+ data1 = ctrl_inl(addr1);
+ ctrl_outl(data1&~(CACHE_VALID|CACHE_UPDATED), addr1);
+
+ /* Next, check if there's shadow or not */
+ data0 = ctrl_inl(addr0);
+ data0 ^= CACHE_VALID;
+ ctrl_outl(data0, addr0);
X data1 = ctrl_inl(addr1);
- data2 = data1 ^ 0x00000001;
- ctrl_outl(data2,addr1);
+ data2 = data1 ^ CACHE_VALID;
+ ctrl_outl(data2, addr1);
X data3 = ctrl_inl(addr0);
X
- /* Invaliate them, in case the cache has been enabled already. */
- ctrl_outl(data0&~0x00000001, addr0);
- ctrl_outl(data2&~0x00000001, addr1);
+ /* Lastly, invaliate them. */
+ ctrl_outl(data0&~CACHE_VALID, addr0);
+ ctrl_outl(data2&~CACHE_VALID, addr1);
X back_to_P1();
X
X if (data0 == data1 && data2 == data3) { /* Shadow */
@@ -150,8 +159,6 @@
X detect_cpu_and_cache_system();
X
X ccr = ctrl_inl(CCR);
- if (ccr == CCR_CACHE_VAL)
- return;
X jump_to_P2();
X if (ccr & CCR_CACHE_ENABLE)
X /*
@@ -380,29 +387,114 @@
X }
X
X /*
+ * Write-back & invalidate the cache.
+ *
X * After accessing the memory from kernel space (P1-area), we need to
- * write back the cache line to maintain DMA coherency.
+ * write back the cache line.
X *
X * We search the D-cache to see if we have the entries corresponding to
X * the page, and if found, write back them.
X */
+void __flush_page_to_ram(void *kaddr)
+{
+ unsigned long phys, addr, data, i;
+
+ /* Physical address of this page */
+ phys = PHYSADDR(kaddr);
+
+ jump_to_P2();
+ /* Loop all the D-cache */
+ for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) {
+ addr = CACHE_OC_ADDRESS_ARRAY| (i<<CACHE_OC_ENTRY_SHIFT);
+ data = ctrl_inl(addr);
+ if ((data & CACHE_VALID) && (data&PAGE_MASK) == phys) {
+ data &= ~(CACHE_UPDATED|CACHE_VALID);
+ ctrl_outl(data, addr);
+ }
+ }
+ back_to_P1();
+}
+
X void flush_page_to_ram(struct page *pg)
X {
+ unsigned long phys;
+
+ /* Physical address of this page */
+ phys = (pg - mem_map)*PAGE_SIZE + __MEMORY_START;
+ __flush_page_to_ram(phys_to_virt(phys));
+}
+
+/*
+ * Check entries of the I-cache & D-cache of the page.
+ * (To see "alias" issues)
+ */
+void check_cache_page(struct page *pg)
+{
X unsigned long phys, addr, data, i;
+ unsigned long kaddr;
+ unsigned long cache_line_index;
+ int bingo = 0;
X
X /* Physical address of this page */
X phys = (pg - mem_map)*PAGE_SIZE + __MEMORY_START;
+ kaddr = phys + PAGE_OFFSET;
+ cache_line_index = (kaddr&CACHE_OC_ENTRY_MASK)>>CACHE_OC_ENTRY_SHIFT;
X
X jump_to_P2();
X /* Loop all the D-cache */
X for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) {
X addr = CACHE_OC_ADDRESS_ARRAY| (i<<CACHE_OC_ENTRY_SHIFT);
X data = ctrl_inl(addr);
- if ((data & CACHE_UPDATED) && (data&PAGE_MASK) == phys) {
- data &= ~CACHE_UPDATED;
+ if ((data & (CACHE_UPDATED|CACHE_VALID))
+ == (CACHE_UPDATED|CACHE_VALID)
+ && (data&PAGE_MASK) == phys) {
+ data &= ~(CACHE_VALID|CACHE_UPDATED);
X ctrl_outl(data, addr);
+ if ((i^cache_line_index)&0x180)
+ bingo = 1;
+ }
+ }
+
+ cache_line_index &= 0xff;
+ /* Loop all the I-cache */
+ for (i=0; i<CACHE_IC_NUM_ENTRIES; i++) {
+ addr = CACHE_IC_ADDRESS_ARRAY| (i<<CACHE_IC_ENTRY_SHIFT);
+ data = ctrl_inl(addr);
+ if ((data & CACHE_VALID) && (data&PAGE_MASK) == phys) {
+ data &= ~CACHE_VALID;
+ ctrl_outl(data, addr);
+ if (((i^cache_line_index)&0x80))
+ bingo = 2;
X }
X }
X back_to_P1();
+
+ if (bingo) {
+ extern void dump_stack(void);
+
+ if (bingo ==1)
+ printk("BINGO!\n");
+ else
+ printk("Bingo!\n");
+ dump_stack();
+ printk("--------------------\n");
+ }
+}
+
+/* Page is 4K, OC size is 16K, there are four lines. */
+#define CACHE_ALIAS 0x00003000
+
+void clear_user_page(void *to, unsigned long address)
+{
+ clear_page(to);
+ if (((address ^ (unsigned long)to) & CACHE_ALIAS))
+ __flush_page_to_ram(to);
+}
+
+void copy_user_page(void *to, void *from, unsigned long address)
+{
+ copy_page(to, from);
+ if (((address ^ (unsigned long)to) & CACHE_ALIAS))
+ __flush_page_to_ram(to);
X }
X #endif
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sh/mm/fault.c linux/arch/sh/mm/fault.c
--- v2.4.0-test8/linux/arch/sh/mm/fault.c Wed Aug 9 13:59:04 2000
+++ linux/arch/sh/mm/fault.c Mon Oct 2 11:57:34 2000
@@ -28,9 +28,9 @@
X #include <asm/mmu_context.h>
X
X extern void die(const char *,struct pt_regs *,long);
-static void __flush_tlb_page(struct mm_struct *mm, unsigned long page);
+static void __flush_tlb_page(unsigned long asid, unsigned long page);
X #if defined(__SH4__)
-static void __flush_tlb_phys(struct mm_struct *mm, unsigned long phys);
+static void __flush_tlb_phys(unsigned long phys);


X #endif
X
X /*

@@ -85,42 +85,6 @@


X return 0;
X }
X

-static void handle_vmalloc_fault(struct mm_struct *mm, unsigned long address)
-{
- pgd_t *dir;
- pmd_t *pmd;
- pte_t *pte;
- pte_t entry;
-
- dir = pgd_offset_k(address);
- pmd = pmd_offset(dir, address);
- if (pmd_none(*pmd)) {
- printk(KERN_ERR "vmalloced area %08lx bad\n", address);
- return;
- }
- if (pmd_bad(*pmd)) {
- pmd_ERROR(*pmd);
- pmd_clear(pmd);
- return;
- }
- pte = pte_offset(pmd, address);
- entry = *pte;
- if (pte_none(entry) || !pte_present(entry) || !pte_write(entry)) {
- printk(KERN_ERR "vmalloced area %08lx bad\n", address);
- return;
- }
-
-#if defined(__SH4__)
- /*
- * ITLB is not affected by "ldtlb" instruction.
- * So, we need to flush the entry by ourselves.
- */
- if (mm)
- __flush_tlb_page(mm, address&PAGE_MASK);
-#endif
- update_mmu_cache(NULL, address, entry);
-}
-
X /*
X * This routine handles page faults. It determines the address,
X * and the problem, and then passes it off to one of the appropriate
@@ -138,11 +102,6 @@
X tsk = current;
X mm = tsk->mm;
X
- if (address >= VMALLOC_START && address < VMALLOC_END) {
- handle_vmalloc_fault(mm, address);
- return;
- }
-
X /*
X * If we're in an interrupt or have no user
X * context, we must not take the fault..
@@ -272,6 +231,67 @@
X goto no_context;
X }
X
+static int __do_page_fault1(struct pt_regs *regs, unsigned long writeaccess,
+ unsigned long address)
+{
+ pgd_t *dir;
+ pmd_t *pmd;
+ pte_t *pte;
+ pte_t entry;
+
+ if (address >= VMALLOC_START && address < VMALLOC_END)
+ /* We can change the implementation of P3 area pte entries.
+ set_pgdir and such. */
+ dir = pgd_offset_k(address);
+ else
+ dir = pgd_offset(current->mm, address);
+
+ pmd = pmd_offset(dir, address);
+ if (pmd_none(*pmd))
+ return 1;
+ if (pmd_bad(*pmd)) {
+ pmd_ERROR(*pmd);
+ pmd_clear(pmd);
+ return 1;
+ }
+ pte = pte_offset(pmd, address);
+ entry = *pte;
+ if (pte_none(entry) || !pte_present(entry)
+ || (writeaccess && !pte_write(entry)))
+ return 1;
+
+ if (writeaccess)
+ entry = pte_mkdirty(entry);
+ entry = pte_mkyoung(entry);
+#if defined(__SH4__)
+ /*
+ * ITLB is not affected by "ldtlb" instruction.
+ * So, we need to flush the entry by ourselves.
+ */
+ __flush_tlb_page(get_asid(), address&PAGE_MASK);
+#endif
+ set_pte(pte, entry);
+ update_mmu_cache(NULL, address, entry);


+ return 0;
+}
+

+/*
+ * Called with interrupt disabled.
+ */
+asmlinkage void __do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
+ unsigned long address)
+{
+ /*
+ * XXX: Could you please implement this (calling __do_page_fault1)
+ * in assembler language in entry.S?
+ */
+ if (__do_page_fault1(regs, writeaccess, address) == 0)
+ /* Done. */
+ return;
+ sti();
+ do_page_fault(regs, writeaccess, address);
+}
+
X void update_mmu_cache(struct vm_area_struct * vma,
X unsigned long address, pte_t pte)
X {
@@ -282,28 +302,30 @@
X save_and_cli(flags);
X
X #if defined(__SH4__)
- if (vma && (vma->vm_flags & VM_SHARED)) {
+ if (pte_shared(pte)) {
X struct page *pg;
X
X pteval = pte_val(pte);
X pteval &= PAGE_MASK; /* Physicall page address */
- __flush_tlb_phys(vma->vm_mm, pteval);
+ __flush_tlb_phys(pteval);
X pg = virt_to_page(__va(pteval));
X flush_dcache_page(pg);
X }
X #endif
X
- /* Set PTEH register */
- if (vma) {
- pteaddr = (address & MMU_VPN_MASK) |
- (vma->vm_mm->context & MMU_CONTEXT_ASID_MASK);
- ctrl_outl(pteaddr, MMU_PTEH);
+ /* Ptrace may call this routine. */
+ if (vma && current->active_mm != vma->vm_mm) {
+ restore_flags(flags);
+ return;
X }
X
+ /* Set PTEH register */
+ pteaddr = (address & MMU_VPN_MASK) | get_asid();
+ ctrl_outl(pteaddr, MMU_PTEH);
+
X /* Set PTEL register */
X pteval = pte_val(pte);
X pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
- pteval |= _PAGE_FLAGS_HARDWARE_DEFAULT; /* add default flags */
X ctrl_outl(pteval, MMU_PTEL);
X
X /* Load the TLB */
@@ -311,24 +333,16 @@
X restore_flags(flags);
X }
X
-static void __flush_tlb_page(struct mm_struct *mm, unsigned long page)
+static void __flush_tlb_page(unsigned long asid, unsigned long page)
X {
- unsigned long addr, data, asid;
- unsigned long saved_asid = MMU_NO_ASID;
-
- if (mm->context == NO_CONTEXT)
- return;
-
- asid = mm->context & MMU_CONTEXT_ASID_MASK;
- if (mm != current->mm) {
- saved_asid = get_asid();
- /*
- * We need to set ASID of the target entry to flush,
- * because TLB is indexed by (ASID and PAGE).
- */
- set_asid(asid);
- }
+ unsigned long addr, data;
X
+ /*
+ * NOTE: PTEH.ASID should be set to this MM
+ * _AND_ we need to write ASID to the array.
+ *
+ * It would be simple if we didn't need to set PTEH.ASID...
+ */
X #if defined(__sh3__)
X addr = MMU_TLB_ADDRESS_ARRAY |(page & 0x1F000)| MMU_PAGE_ASSOC_BIT;
X data = (page & 0xfffe0000) | asid; /* VALID bit is off */
@@ -340,12 +354,10 @@
X ctrl_outl(data, addr);
X back_to_P1();
X #endif
- if (saved_asid != MMU_NO_ASID)
- set_asid(saved_asid);
X }
X
X #if defined(__SH4__)
-static void __flush_tlb_phys(struct mm_struct *mm, unsigned long phys)
+static void __flush_tlb_phys(unsigned long phys)
X {
X int i;
X unsigned long addr, data;
@@ -373,12 +385,22 @@
X
X void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
X {
- unsigned long flags;
+ if (vma->vm_mm && vma->vm_mm->context != NO_CONTEXT) {
+ unsigned long flags;
+ unsigned long asid;
+ unsigned long saved_asid = MMU_NO_ASID;
X
- if (vma->vm_mm) {
+ asid = vma->vm_mm->context & MMU_CONTEXT_ASID_MASK;
X page &= PAGE_MASK;
+
X save_and_cli(flags);
- __flush_tlb_page(vma->vm_mm, page);
+ if (vma->vm_mm != current->mm) {
+ saved_asid = get_asid();
+ set_asid(asid);
+ }
+ __flush_tlb_page(asid, page);
+ if (saved_asid != MMU_NO_ASID)
+ set_asid(saved_asid);
X restore_flags(flags);
X }
X }
@@ -397,13 +419,22 @@
X if (mm == current->mm)
X activate_context(mm);
X } else {
+ unsigned long asid = mm->context&MMU_CONTEXT_ASID_MASK;
+ unsigned long saved_asid = MMU_NO_ASID;
+
X start &= PAGE_MASK;
X end += (PAGE_SIZE - 1);
X end &= PAGE_MASK;
+ if (mm != current->mm) {
+ saved_asid = get_asid();
+ set_asid(asid);
+ }
X while (start < end) {
- __flush_tlb_page(mm, start);
+ __flush_tlb_page(asid, start);
X start += PAGE_SIZE;
X }
+ if (saved_asid != MMU_NO_ASID)
+ set_asid(saved_asid);
X }
X restore_flags(flags);
X }
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sh/mm/init.c linux/arch/sh/mm/init.c
--- v2.4.0-test8/linux/arch/sh/mm/init.c Thu Sep 7 08:44:50 2000
+++ linux/arch/sh/mm/init.c Mon Oct 2 11:57:34 2000
@@ -241,6 +241,7 @@
X
X /* clear the zero-page */
X memset(empty_zero_page, 0, PAGE_SIZE);
+ flush_page_to_ram(virt_to_page(empty_zero_page));
X
X /* this will put all low memory onto the freelists */
X totalram_pages += free_all_bootmem();
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sh/vmlinux.lds.S linux/arch/sh/vmlinux.lds.S
--- v2.4.0-test8/linux/arch/sh/vmlinux.lds.S Wed Aug 9 13:59:04 2000
+++ linux/arch/sh/vmlinux.lds.S Mon Oct 2 11:57:34 2000
@@ -4,9 +4,9 @@
X */
X #include <linux/config.h>
X #ifdef CONFIG_CPU_LITTLE_ENDIAN
-OUTPUT_FORMAT("elf32-shl", "elf32-shl", "elf32-shl")
+OUTPUT_FORMAT("elf32-sh-linux", "elf32-sh-linux", "elf32-sh-linux")
X #else
-OUTPUT_FORMAT("elf32-sh", "elf32-sh", "elf32-sh")
+OUTPUT_FORMAT("elf32-shbig-linux", "elf32-shbig-linux", "elf32-shbig-linux")
X #endif
X OUTPUT_ARCH(sh)
X ENTRY(_start)
@@ -89,6 +89,7 @@
X /DISCARD/ : {
X *(.text.exit)
X *(.data.exit)
+ *(.exitcall.exit)
X }
X
X /* Stabs debugging sections. */
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sparc/config.in linux/arch/sparc/config.in
--- v2.4.0-test8/linux/arch/sparc/config.in Wed Aug 23 09:30:13 2000
+++ linux/arch/sparc/config.in Tue Sep 19 10:59:52 2000
@@ -94,15 +94,7 @@
X # bool ' LVM information in proc filesystem' CONFIG_LVM_PROC_FS Y
X #fi
X
-tristate 'Multiple devices driver support' CONFIG_BLK_DEV_MD
-dep_tristate ' Linear (append) mode' CONFIG_MD_LINEAR $CONFIG_BLK_DEV_MD
-dep_tristate ' RAID-0 (striping) mode' CONFIG_MD_RAID0 $CONFIG_BLK_DEV_MD
-dep_tristate ' RAID-1 (mirroring) mode' CONFIG_MD_RAID1 $CONFIG_BLK_DEV_MD
-#dep_tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5 $CONFIG_BLK_DEV_MD
-#if [ "$CONFIG_MD_LINEAR" = "y" -o "$CONFIG_MD_RAID0" = "y" -o "$CONFIG_MD_RAID1" = "y" -o "$CONFIG_MD_RAID5" = "y" ]; then
-# bool ' Boot support' CONFIG_MD_BOOT
-# bool ' Auto Detect support' CONFIG_AUTODETECT_RAID
-#fi
+include drivers/md/Config.in
X
X tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
X if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sparc/kernel/pcic.c linux/arch/sparc/kernel/pcic.c
--- v2.4.0-test8/linux/arch/sparc/kernel/pcic.c Thu Sep 7 08:32:00 2000
+++ linux/arch/sparc/kernel/pcic.c Tue Oct 3 09:24:41 2000
@@ -1,4 +1,4 @@
-/* $Id: pcic.c,v 1.17 2000/09/05 06:49:44 anton Exp $
+/* $Id: pcic.c,v 1.18 2000/09/25 06:09:12 anton Exp $
X * pcic.c: Sparc/PCI controller support
X *
X * Copyright (C) 1998 V. Roganov and G. Raiko
@@ -35,11 +35,6 @@
X
X #ifndef CONFIG_PCI
X
-int pcibios_present(void)
-{
- return 0;
-}
-
X asmlinkage int sys_pciconfig_read(unsigned long bus,
X unsigned long dfn,
X unsigned long off,
@@ -976,7 +971,6 @@
X if(!suser())
X return -EPERM;
X
- lock_kernel();
X switch(len) {
X case 1:
X err = get_user(ubyte, (unsigned char *)buf);
@@ -1004,7 +998,6 @@
X break;
X
X };
- unlock_kernel();
X
X return err;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sparc/kernel/sparc-stub.c linux/arch/sparc/kernel/sparc-stub.c
--- v2.4.0-test8/linux/arch/sparc/kernel/sparc-stub.c Mon Jan 3 12:01:31 2000
+++ linux/arch/sparc/kernel/sparc-stub.c Sun Oct 1 20:35:15 2000
@@ -123,7 +123,7 @@
X */
X #define BUFMAX 2048
X
-static int initialized = 0; /* !0 means we've been initialized */
+static int initialized; /* !0 means we've been initialized */
X
X static const char hexchars[]="0123456789abcdef";
X
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sparc/kernel/time.c linux/arch/sparc/kernel/time.c
--- v2.4.0-test8/linux/arch/sparc/kernel/time.c Mon Jun 19 17:59:38 2000
+++ linux/arch/sparc/kernel/time.c Sun Sep 17 10:01:49 2000
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.56 2000/06/13 22:51:28 anton Exp $
+/* $Id: time.c,v 1.57 2000/09/16 07:33:45 davem Exp $
X * linux/arch/sparc/kernel/time.c
X *
X * Copyright (C) 1995 David S. Miller (da...@caip.rutgers.edu)
@@ -147,37 +147,6 @@
X last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
X }
X write_unlock(&xtime_lock);


-}
-
-/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
- * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
- * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
- *
- * [For the Julian calendar (which was used in Russia before 1917,
- * Britain & colonies before 1752, anywhere else before 1582,
- * and is still in use by some communities) leave out the
- * -year/100+year/400 terms, and add 10.]
- *
- * This algorithm was first published by Gauss (I think).
- *
- * WARNING: this function will overflow on 2106-02-07 06:28:16 on
- * machines were long is 32-bit! (However, as time_t is signed, we
- * will already get problems at other places on 2038-01-19 03:14:08)
- */

-static inline unsigned long mktime(unsigned int year, unsigned int mon,


- unsigned int day, unsigned int hour,
- unsigned int min, unsigned int sec)
-{
- if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */
- mon += 12; /* Puts Feb last since it has leap day */
- year -= 1;
- }
- return (((
- (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
- year*365 - 719499
- )*24 + hour /* now have hours */
- )*60 + min /* now have minutes */
- )*60 + sec; /* finally seconds */

X }
X
X /* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sparc64/boot/piggyback.c linux/arch/sparc64/boot/piggyback.c
--- v2.4.0-test8/linux/arch/sparc64/boot/piggyback.c Wed Jul 16 19:22:50 1997
+++ linux/arch/sparc64/boot/piggyback.c Tue Oct 3 09:24:41 2000
@@ -1,4 +1,4 @@
-/* $Id: piggyback.c,v 1.1 1997/07/11 11:05:26 jj Exp $
+/* $Id: piggyback.c,v 1.2 2000/09/19 14:34:39 anton Exp $
X Simple utility to make a single-image install kernel with initial ramdisk
X for Sparc64 tftpbooting without need to set up nfs.
X
@@ -50,9 +50,9 @@
X map = fopen (argv[2], "r");
X if (!map) die(argv[2]);
X while (fgets (buffer, 1024, map)) {
- if (!strcmp (buffer + 19, "start\n"))
+ if (!strcmp (buffer + 19, "_start\n"))
X start = strtoul (buffer + 8, NULL, 16);
- else if (!strcmp (buffer + 19, "end\n"))
+ else if (!strcmp (buffer + 19, "_end\n"))
X end = strtoul (buffer + 8, NULL, 16);
X }
X fclose (map);
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sparc64/config.in linux/arch/sparc64/config.in
--- v2.4.0-test8/linux/arch/sparc64/config.in Wed Aug 23 09:30:13 2000
+++ linux/arch/sparc64/config.in Tue Sep 19 10:59:52 2000
@@ -94,15 +94,7 @@
X # bool ' LVM information in proc filesystem' CONFIG_LVM_PROC_FS Y
X #fi
X
-tristate 'Multiple devices driver support' CONFIG_BLK_DEV_MD
-dep_tristate ' Linear (append) mode' CONFIG_MD_LINEAR $CONFIG_BLK_DEV_MD
-dep_tristate ' RAID-0 (striping) mode' CONFIG_MD_RAID0 $CONFIG_BLK_DEV_MD
-dep_tristate ' RAID-1 (mirroring) mode' CONFIG_MD_RAID1 $CONFIG_BLK_DEV_MD
-#dep_tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5 $CONFIG_BLK_DEV_MD
-#if [ "$CONFIG_MD_LINEAR" = "y" -o "$CONFIG_MD_RAID0" = "y" -o "$CONFIG_MD_RAID1" = "y" -o "$CONFIG_MD_RAID5" = "y" ]; then
-# bool ' Boot support' CONFIG_MD_BOOT
-# bool ' Auto Detect support' CONFIG_AUTODETECT_RAID
-#fi
+include drivers/md/Config.in
X
X tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
X if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sparc64/kernel/auxio.c linux/arch/sparc64/kernel/auxio.c
--- v2.4.0-test8/linux/arch/sparc64/kernel/auxio.c Mon Dec 20 22:05:52 1999
+++ linux/arch/sparc64/kernel/auxio.c Tue Oct 3 09:24:41 2000
@@ -18,6 +18,7 @@
X #include <asm/sbus.h>
X #include <asm/ebus.h>
X #include <asm/fhc.h>
+#include <asm/starfire.h>
X
X /* Probe and map in the Auxiliary I/O register */
X unsigned long auxio_register = 0;
@@ -55,7 +56,7 @@
X return;
X }
X #endif
- if(central_bus) {
+ if(central_bus || this_is_starfire) {
X auxio_register = 0UL;
X return;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sparc64/kernel/central.c linux/arch/sparc64/kernel/central.c
--- v2.4.0-test8/linux/arch/sparc64/kernel/central.c Mon Dec 20 22:05:52 1999
+++ linux/arch/sparc64/kernel/central.c Tue Oct 3 09:24:41 2000
@@ -1,4 +1,4 @@
-/* $Id: central.c,v 1.13 1999/12/01 10:44:43 davem Exp $
+/* $Id: central.c,v 1.14 2000/09/21 06:25:14 anton Exp $
X * central.c: Central FHC driver for Sunfire/Starfire/Wildfire.
X *
X * Copyright (C) 1997, 1999 David S. Miller (da...@redhat.com)


@@ -15,6 +15,7 @@
X

X #include <asm/page.h>
X #include <asm/fhc.h>
+#include <asm/starfire.h>
X
X struct linux_central *central_bus = NULL;
X struct linux_fhc *fhc_list = NULL;
@@ -254,9 +255,8 @@
X
X cnode = prom_finddevice("/central");
X if(cnode == 0 || cnode == -1) {
- extern void starfire_check(void);
-
- starfire_check();
+ if (this_is_starfire)
+ starfire_cpu_setup();
X return;
X }
X
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sparc64/kernel/entry.S linux/arch/sparc64/kernel/entry.S
--- v2.4.0-test8/linux/arch/sparc64/kernel/entry.S Thu Sep 7 08:32:00 2000
+++ linux/arch/sparc64/kernel/entry.S Fri Sep 8 17:55:17 2000
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.119 2000/09/06 00:45:01 davem Exp $
+/* $Id: entry.S,v 1.120 2000/09/08 13:58:12 jj Exp $
X * arch/sparc64/kernel/entry.S: Sparc64 trap low-level entry points.
X *
X * Copyright (C) 1995,1997 David S. Miller (da...@caip.rutgers.edu)
@@ -940,8 +940,8 @@
X
X 1: b,pt %xcc, ret_sys_call
X ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0], %o0
-sparc_exit: rdpr %otherwin, %g1
- wrpr %g0, (PSTATE_RMO | PSTATE_PEF | PSTATE_PRIV), %pstate
+sparc_exit: wrpr %g0, (PSTATE_RMO | PSTATE_PEF | PSTATE_PRIV), %pstate
+ rdpr %otherwin, %g1
X rdpr %cansave, %g3
X add %g3, %g1, %g3
X wrpr %g3, 0x0, %cansave
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sparc64/kernel/irq.c linux/arch/sparc64/kernel/irq.c
--- v2.4.0-test8/linux/arch/sparc64/kernel/irq.c Thu Sep 7 08:32:00 2000
+++ linux/arch/sparc64/kernel/irq.c Tue Oct 3 09:24:41 2000
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.93 2000/08/31 10:00:39 anton Exp $
+/* $Id: irq.c,v 1.94 2000/09/21 06:27:10 anton Exp $
X * irq.c: UltraSparc IRQ handling/init/registry.
X *
X * Copyright (C) 1997 David S. Miller (da...@caip.rutgers.edu)
@@ -31,6 +31,7 @@
X #include <asm/smp.h>
X #include <asm/hardirq.h>
X #include <asm/softirq.h>
+#include <asm/starfire.h>
X
X /* Internal flag, should not be visible elsewhere at all. */
X #define SA_IMAP_MASKED 0x100
@@ -123,7 +124,6 @@
X /* Now these are always passed a true fully specified sun4u INO. */
X void enable_irq(unsigned int irq)
X {
- extern int this_is_starfire;
X struct ino_bucket *bucket = __bucket(irq);
X unsigned long imap;
X unsigned long tid;
@@ -139,9 +139,6 @@
X : "i" (ASI_UPA_CONFIG));
X tid = ((tid & UPA_CONFIG_MID) << 9);
X } else {
- extern unsigned int starfire_translate(unsigned long imap,
- unsigned int upaid);
-
X tid = (starfire_translate(imap, current->processor) << 26);
X }
X
@@ -715,7 +712,6 @@
X struct ino_bucket *bp, *nbp;


X int cpu = smp_processor_id();

X #ifdef CONFIG_SMP
- extern int this_is_starfire;
X int should_forward = (this_is_starfire == 0 &&
X irq < 10 &&
X current->pid != 0);
@@ -1029,7 +1025,6 @@
X #ifdef CONFIG_SMP
X static int retarget_one_irq(struct irqaction *p, int goal_cpu)
X {
- extern int this_is_starfire;
X struct ino_bucket *bucket = __bucket(p->mask);
X unsigned long imap = bucket->imap;
X unsigned int tid;
@@ -1041,9 +1036,6 @@
X if(this_is_starfire == 0) {
X tid = __cpu_logical_map[goal_cpu] << 26;
X } else {
- extern unsigned int starfire_translate(unsigned long imap,
- unsigned int upaid);
-
X tid = (starfire_translate(imap, __cpu_logical_map[goal_cpu]) << 26);
X }
X upa_writel(IMAP_VALID | (tid & IMAP_TID), imap);
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sparc64/kernel/pci.c linux/arch/sparc64/kernel/pci.c
--- v2.4.0-test8/linux/arch/sparc64/kernel/pci.c Thu Sep 7 08:32:00 2000
+++ linux/arch/sparc64/kernel/pci.c Tue Oct 3 09:24:41 2000
@@ -24,7 +24,6 @@
X
X #ifndef CONFIG_PCI
X /* A "nop" PCI implementation. */
-int pcibios_present(void) { return 0; }
X asmlinkage int sys_pciconfig_read(unsigned long bus, unsigned long dfn,
X unsigned long off, unsigned long len,
X unsigned char *buf)
@@ -316,7 +315,6 @@


X goto out;
X }
X

- lock_kernel();
X switch(len) {
X case 1:
X err = get_user(byte, (u8 *)buf);
@@ -344,7 +342,6 @@
X break;
X
X };
- unlock_kernel();
X
X out:
X return err;
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sparc64/kernel/pci_psycho.c linux/arch/sparc64/kernel/pci_psycho.c
--- v2.4.0-test8/linux/arch/sparc64/kernel/pci_psycho.c Mon Apr 24 13:59:58 2000
+++ linux/arch/sparc64/kernel/pci_psycho.c Tue Oct 3 09:24:41 2000
@@ -1,4 +1,4 @@
-/* $Id: pci_psycho.c,v 1.16 2000/04/15 10:06:16 davem Exp $
+/* $Id: pci_psycho.c,v 1.17 2000/09/21 06:25:14 anton Exp $
X * pci_psycho.c: PSYCHO/U2P specific PCI controller support.
X *
X * Copyright (C) 1997, 1998, 1999 David S. Miller (da...@caipfs.rutgers.edu)
@@ -15,6 +15,7 @@
X #include <asm/pbm.h>
X #include <asm/iommu.h>
X #include <asm/irq.h>
+#include <asm/starfire.h>
X
X #include "pci_impl.h"
X
@@ -1254,8 +1255,6 @@
X
X static void __init psycho_iommu_init(struct pci_controller_info *p)
X {
- extern int this_is_starfire;
- extern void *starfire_hookup(int);
X unsigned long tsbbase, i;
X u64 control;
X
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sparc64/kernel/sbus.c linux/arch/sparc64/kernel/sbus.c
--- v2.4.0-test8/linux/arch/sparc64/kernel/sbus.c Fri Apr 14 09:37:09 2000
+++ linux/arch/sparc64/kernel/sbus.c Tue Oct 3 09:24:41 2000
@@ -1,4 +1,4 @@
-/* $Id: sbus.c,v 1.11 2000/04/14 09:13:04 davem Exp $
+/* $Id: sbus.c,v 1.12 2000/09/21 06:25:14 anton Exp $
X * sbus.c: UltraSparc SBUS controller support.
X *
X * Copyright (C) 1999 David S. Miller (da...@redhat.com)
@@ -18,6 +18,7 @@
X #include <asm/cache.h>
X #include <asm/dma.h>
X #include <asm/irq.h>
+#include <asm/starfire.h>
X
X #include "iommu_common.h"
X
@@ -1151,15 +1152,10 @@
X upa_writeq(control, iommu->sbus_control_reg);
X
X /* Now some Xfire specific grot... */
- {
- extern void *starfire_hookup(int);
- extern int this_is_starfire;
-
- if (this_is_starfire)
- sbus->starfire_cookie = starfire_hookup(sbus->portid);
- else
- sbus->starfire_cookie = NULL;
- }
+ if (this_is_starfire)
+ sbus->starfire_cookie = starfire_hookup(sbus->portid);
+ else
+ sbus->starfire_cookie = NULL;
X
X sysio_register_error_handlers(sbus);
X }
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sparc64/kernel/setup.c linux/arch/sparc64/kernel/setup.c
--- v2.4.0-test8/linux/arch/sparc64/kernel/setup.c Wed Jul 26 18:36:44 2000
+++ linux/arch/sparc64/kernel/setup.c Tue Oct 3 09:24:41 2000
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.55 2000/07/24 14:13:13 anton Exp $
+/* $Id: setup.c,v 1.56 2000/09/21 06:29:01 anton Exp $
X * linux/arch/sparc64/kernel/setup.c
X *
X * Copyright (C) 1995,1996 David S. Miller (da...@caip.rutgers.edu)
@@ -37,6 +37,7 @@
X #include <asm/pgtable.h>
X #include <asm/idprom.h>
X #include <asm/head.h>
+#include <asm/starfire.h>
X
X #ifdef CONFIG_IP_PNP
X #include <net/ipconfig.h>
@@ -478,6 +479,9 @@
X #elif defined(CONFIG_PROM_CONSOLE)
X conswitchp = &prom_con;
X #endif
+
+ /* Work out if we are starfire early on */
+ check_if_starfire();
X
X boot_flags_init(*cmdline_p);
X
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sparc64/kernel/starfire.c linux/arch/sparc64/kernel/starfire.c
--- v2.4.0-test8/linux/arch/sparc64/kernel/starfire.c Mon Jan 31 23:37:19 2000
+++ linux/arch/sparc64/kernel/starfire.c Tue Oct 3 09:24:41 2000
@@ -1,7 +1,8 @@
-/* $Id: starfire.c,v 1.5 2000/01/31 04:59:12 davem Exp $
+/* $Id: starfire.c,v 1.7 2000/09/22 23:02:13 davem Exp $
X * starfire.c: Starfire/E10000 support.
X *
X * Copyright (C) 1998 David S. Miller (da...@redhat.com)
+ * Copyright (C) 2000 Anton Blanchard (an...@linuxcare.com)
X */
X
X #include <linux/kernel.h>
@@ -11,23 +12,31 @@
X #include <asm/oplib.h>
X #include <asm/smp.h>
X #include <asm/upa.h>
+#include <asm/starfire.h>
X
-/* A few places around the kernel check this to see if
+/*
+ * A few places around the kernel check this to see if
X * they need to call us to do things in a Starfire specific
X * way.
X */
X int this_is_starfire = 0;
X
-void starfire_check(void)
+void check_if_starfire(void)
X {
X int ssnode = prom_finddevice("/ssp-serial");
+ if(ssnode != 0 && ssnode != -1)
+ this_is_starfire = 1;
+}
X
- if(ssnode != 0 && ssnode != -1) {
+void starfire_cpu_setup(void)
+{
+ if (this_is_starfire) {
+/* We do this in starfire_translate - Anton */
+#if 0
X int i;
X
- this_is_starfire = 1;
-
- /* Now must fixup cpu MIDs. OBP gave us a logical
+ /*
+ * Now must fixup cpu MIDs. OBP gave us a logical
X * linear cpuid number, not the real upaid.
X */
X for(i = 0; i < linux_num_cpus; i++) {
@@ -39,6 +48,7 @@
X
X linux_cpus[i].mid = mid;
X }
+#endif
X }
X }
X
@@ -47,7 +57,8 @@
X return upa_readl(0x1fff40000d0UL);
X }
X
-/* Each Starfire board has 32 registers which perform translation
+/*
+ * Each Starfire board has 32 registers which perform translation
X * and delivery of traditional interrupt packets into the extended
X * Starfire hardware format. Essentially UPAID's now have 2 more
X * bits than in all previous Sun5 systems.
@@ -82,6 +93,9 @@
X for(i = 0; i < 32; i++) {
X p->imap_slots[i] = 0UL;
X p->tregs[i] = treg_base + (i * 0x10UL);
+ /* Lets play it safe and not overwrite existing mappings */
+ if (upa_readl(p->tregs[i]) != 0)
+ p->imap_slots[i] = 0xdeadbeaf;
X }
X p->upaid = upaid;
X p->next = sflist;
@@ -116,6 +130,12 @@
X panic("Lucy in the sky....");
X }
X p->imap_slots[i] = imap;
+
+ /* map to real upaid */
+ upaid = (((upaid & 0x3c) << 1) |
+ ((upaid & 0x40) >> 4) |
+ (upaid & 0x3));
+
X upa_writel(upaid, p->tregs[i]);
X
X return i;
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sparc64/kernel/sys_sparc32.c linux/arch/sparc64/kernel/sys_sparc32.c
--- v2.4.0-test8/linux/arch/sparc64/kernel/sys_sparc32.c Wed Aug 23 09:30:13 2000
+++ linux/arch/sparc64/kernel/sys_sparc32.c Sun Sep 17 10:01:49 2000
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc32.c,v 1.163 2000/08/22 10:09:10 jj Exp $
+/* $Id: sys_sparc32.c,v 1.164 2000/09/14 10:42:47 davem Exp $
X * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
X *
X * Copyright (C) 1997,1998 Jakub Jelinek (j...@sunsite.mff.cuni.cz)
@@ -1621,7 +1621,7 @@
X
X static void *do_ncp_super_data_conv(void *raw_data)
X {
- struct ncp_mount_data *n = (struct ncp_mount_data *)raw_data;
+ struct ncp_mount_data news, *n = &news;
X struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data;
X
X n->dir_mode = n32->dir_mode;
@@ -1631,6 +1631,7 @@
X memmove (n->mounted_vol, n32->mounted_vol, (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int)));
X n->wdog_pid = n32->wdog_pid;
X n->mounted_uid = low2highuid(n32->mounted_uid);
+ memcpy(raw_data, n, sizeof(struct ncp_mount_data));
X return raw_data;
X }
X
@@ -1645,7 +1646,7 @@
X
X static void *do_smb_super_data_conv(void *raw_data)
X {
- struct smb_mount_data *s = (struct smb_mount_data *)raw_data;
+ struct smb_mount_data news, *s = &news;
X struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;
X
X s->version = s32->version;
@@ -1654,6 +1655,7 @@
X s->gid = low2highgid(s32->gid);
X s->file_mode = s32->file_mode;
X s->dir_mode = s32->dir_mode;
+ memcpy(raw_data, s, sizeof(struct smb_mount_data));
X return raw_data;
X }
X
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sparc64/kernel/time.c linux/arch/sparc64/kernel/time.c
--- v2.4.0-test8/linux/arch/sparc64/kernel/time.c Tue Jul 11 15:46:08 2000
+++ linux/arch/sparc64/kernel/time.c Tue Oct 3 09:24:41 2000
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.28 2000/07/11 02:21:12 davem Exp $
+/* $Id: time.c,v 1.32 2000/09/22 23:02:13 davem Exp $
X * time.c: UltraSparc timer and TOD clock support.
X *
X * Copyright (C) 1997 David S. Miller (da...@caip.rutgers.edu)
@@ -30,6 +30,7 @@
X #include <asm/fhc.h>
X #include <asm/pbm.h>
X #include <asm/ebus.h>
+#include <asm/starfire.h>
X

X extern rwlock_t xtime_lock;
X

@@ -177,37 +178,6 @@
X }
X #endif
X

-/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
- * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
- * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
- *
- * [For the Julian calendar (which was used in Russia before 1917,
- * Britain & colonies before 1752, anywhere else before 1582,
- * and is still in use by some communities) leave out the
- * -year/100+year/400 terms, and add 10.]
- *
- * This algorithm was first published by Gauss (I think).
- *
- * WARNING: this function will overflow on 2106-02-07 06:28:16 on
- * machines were long is 32-bit! (However, as time_t is signed, we
- * will already get problems at other places on 2038-01-19 03:14:08)
- */

-static inline unsigned long mktime(unsigned int year, unsigned int mon,


- unsigned int day, unsigned int hour,
- unsigned int min, unsigned int sec)
-{
- if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */
- mon += 12; /* Puts Feb last since it has leap day */
- year -= 1;
- }
- return (((
- (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
- year*365 - 719499
- )*24 + hour /* now have hours */
- )*60 + min /* now have minutes */
- )*60 + sec; /* finally seconds */

-}
-
X /* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */
X static void __init kick_start_clock(void)
X {
@@ -336,6 +306,20 @@
X struct linux_ebus *ebus = NULL;
X #endif
X
+
+ if (this_is_starfire) {
+ /* davem suggests we keep this within the 4M locked kernel image */
+ static char obp_gettod[256];
+ static u32 unix_tod;
+
+ sprintf(obp_gettod, "h# %08x unix-gettod",
+ (unsigned int) (long) &unix_tod);
+ prom_feval(obp_gettod);
+ xtime.tv_sec = unix_tod;
+ xtime.tv_usec = 0;
+ return;
+ }
+
X __save_and_cli(flags);
X
X if(central_bus != NULL) {
@@ -504,6 +488,9 @@


X
X void do_settimeofday(struct timeval *tv)
X {

+ if (this_is_starfire)
+ return;
+
X write_lock_irq(&xtime_lock);
X
X tv->tv_usec -= do_gettimeoffset();
@@ -527,7 +514,10 @@
X unsigned long regs = mstk48t02_regs;
X u8 tmp;
X
- /* Not having a register set can lead to trouble. */
+ /*
+ * Not having a register set can lead to trouble.
+ * Also starfire doesnt have a tod clock.
+ */
X if (!regs)
X return -1;
X
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sparc64/lib/rwlock.S linux/arch/sparc64/lib/rwlock.S
--- v2.4.0-test8/linux/arch/sparc64/lib/rwlock.S Thu Mar 16 11:40:17 2000
+++ linux/arch/sparc64/lib/rwlock.S Fri Sep 8 17:55:17 2000
@@ -1,4 +1,4 @@
-/* $Id: rwlock.S,v 1.3 2000/03/16 16:44:38 davem Exp $
+/* $Id: rwlock.S,v 1.4 2000/09/09 00:00:34 davem Exp $
X * rwlocks.S: These things are too big to do inline.
X *
X * Copyright (C) 1999 David S. Miller (da...@redhat.com)
@@ -30,54 +30,38 @@
X cmp %g5, %g7
X be,pt %xcc, 99b
X membar #StoreLoad | #StoreStore
- b,a,pt %xcc, __read_unlock
+ ba,a,pt %xcc, __read_unlock
X
X __read_wait_for_writer:
X ldsw [%o0], %g5
X brlz,pt %g5, __read_wait_for_writer
X membar #LoadLoad
- b,a,pt %xcc, 4b
-__write_wait_for_writer:
- ldsw [%o0], %g5
- brlz,pt %g5, __write_wait_for_writer
+ ba,a,pt %xcc, 4b
+__write_wait_for_any:
+ lduw [%o0], %g5
+ brnz,pt %g5, __write_wait_for_any
X membar #LoadLoad
- b,a,pt %xcc, 4f
-
- /* Similarly, 2 cache lines for non-contention write locks. */
+ ba,a,pt %xcc, 4f
X
X .align 64
X .globl __write_unlock
X __write_unlock: /* %o0 = lock_ptr */
- sethi %hi(0x80000000), %g2
-1: lduw [%o0], %g5
- andn %g5, %g2, %g7
- cas [%o0], %g5, %g7
- cmp %g5, %g7
- be,pt %icc, 99b
- membar #StoreLoad | #StoreStore
- b,a,pt %xcc, 1b
+ membar #LoadStore | #StoreStore
+ retl
+ stw %g0, [%o0]
X
X .globl __write_lock
X __write_lock: /* %o0 = lock_ptr */
X sethi %hi(0x80000000), %g2
-1: ldsw [%o0], %g5
-4: brnz,pn %g5, 5f
- or %g5, %g2, %g7
+
+1: lduw [%o0], %g5
+ brnz,pn %g5, __write_wait_for_any
+4: or %g5, %g2, %g7
X cas [%o0], %g5, %g7
+
X cmp %g5, %g7
X be,pt %icc, 99b
X membar #StoreLoad | #StoreStore
-
- b,a,pt %xcc, 1b
-5: brlz %g5, __write_wait_for_writer
- or %g5, %g2, %g7
- cas [%o0], %g5, %g7
- cmp %g5, %g7
- bne,pn %icc, 5b
-8: ldsw [%o0], %g5
- cmp %g5, %g2
- be,pn %icc, 99b
- membar #LoadLoad
- b,a,pt %xcc, 99b
+ ba,a,pt %xcc, 1b
X rwlock_impl_end:
X
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sparc64/mm/fault.c linux/arch/sparc64/mm/fault.c
--- v2.4.0-test8/linux/arch/sparc64/mm/fault.c Sat Aug 12 12:08:50 2000
+++ linux/arch/sparc64/mm/fault.c Sun Sep 17 10:01:50 2000
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.50 2000/08/11 03:00:13 davem Exp $
+/* $Id: fault.c,v 1.51 2000/09/14 06:22:32 anton Exp $
X * arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc.
X *
X * Copyright (C) 1996 David S. Miller (da...@caip.rutgers.edu)
@@ -145,7 +145,7 @@
X
X if (!insn) {
X if (regs->tstate & TSTATE_PRIV) {
- if (regs->tpc & 0x3)
+ if (!regs->tpc || (regs->tpc & 0x3))
X goto cannot_handle;
X insn = *(unsigned int *)regs->tpc;
X } else {
diff -u --recursive --new-file v2.4.0-test8/linux/arch/sparc64/mm/init.c linux/arch/sparc64/mm/init.c
--- v2.4.0-test8/linux/arch/sparc64/mm/init.c Thu Sep 7 08:44:50 2000
+++ linux/arch/sparc64/mm/init.c Tue Oct 3 09:24:41 2000
@@ -1,4 +1,4 @@
-/* $Id: init.c,v 1.154 2000/08/09 00:00:15 davem Exp $
+/* $Id: init.c,v 1.156 2000/09/21 06:34:48 anton Exp $
X * arch/sparc64/mm/init.c
X *
X * Copyright (C) 1996-1999 David S. Miller (da...@caip.rutgers.edu)
@@ -29,6 +29,7 @@
X #include <asm/mmu_context.h>
X #include <asm/vaddrs.h>
X #include <asm/dma.h>
+#include <asm/starfire.h>
X
X extern void device_scan(void);
X
@@ -200,7 +201,7 @@
X
X for (i = 0; i < n; i++) {
X unsigned long vaddr;
-
+
X if (trans[i].virt >= 0xf0000000 && trans[i].virt < 0x100000000) {
X for (vaddr = trans[i].virt;
X vaddr < trans[i].virt + trans[i].size;
@@ -808,7 +809,6 @@
X unsigned long bootmap_pfn, bytes_avail, size;
X int i;
X
-
X bytes_avail = 0UL;
X for (i = 0; sp_banks[i].num_bytes != 0; i++) {
X end_of_phys_memory = sp_banks[i].base_addr +
@@ -999,12 +999,7 @@
X */
X {
X extern void setup_tba(int);
- int is_starfire = prom_finddevice("/ssp-serial");
- if (is_starfire != 0 && is_starfire != -1)
- is_starfire = 1;
- else
- is_starfire = 0;
- setup_tba(is_starfire);
+ setup_tba(this_is_starfire);
X }
X
X inherit_locked_prom_mappings(1);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/Makefile linux/drivers/Makefile
--- v2.4.0-test8/linux/drivers/Makefile Tue Aug 22 11:41:14 2000
+++ linux/drivers/Makefile Wed Sep 27 14:14:34 2000
@@ -1,205 +1,59 @@
X #
X # Makefile for the Linux kernel device drivers.
X #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (not a .c file).
+# 15 Sep 2000, Christoph Hellwig <h...@caldera.de>
+# Rewritten to use lists instead of if-statements.
X #
-# Note 2! The CFLAGS definitions are now in the main makefile.
X
-SUB_DIRS := block char net parport sound misc media
-MOD_SUB_DIRS := $(SUB_DIRS)
-ALL_SUB_DIRS := $(SUB_DIRS) pci sgi ide scsi sbus cdrom isdn pnp i2o \
- ieee1394 macintosh video dio zorro fc4 \
- usb nubus tc atm pcmcia i2c telephony \
- acpi mtd input
-
-ifdef CONFIG_DIO
-SUB_DIRS += dio
-MOD_SUB_DIRS += dio
-endif
-
-ifdef CONFIG_PCI
-SUB_DIRS += pci
-endif
-
-ifeq ($(CONFIG_PCMCIA),y)
-SUB_DIRS += pcmcia
-else
- ifeq ($(CONFIG_PCMCIA),m)
- MOD_SUB_DIRS += pcmcia
- endif
-endif
-
-ifdef CONFIG_MTD
-SUB_DIRS += mtd
-MOD_SUB_DIRS += mtd
-endif
-
-ifdef CONFIG_SBUS
-SUB_DIRS += sbus
-MOD_SUB_DIRS += sbus
-endif
-
-ifdef CONFIG_ZORRO
-SUB_DIRS += zorro
-endif
-
-ifdef CONFIG_NUBUS
-SUB_DIRS += nubus
-endif
-
-ifdef CONFIG_TC
-SUB_DIRS += tc
-endif
-
-ifdef CONFIG_VT
-SUB_DIRS += video
-MOD_SUB_DIRS += video
-endif
-
-ifdef CONFIG_MAC
-SUB_DIRS += macintosh
-MOD_SUB_DIRS += macintosh
-endif
-
-ifdef CONFIG_PPC
-SUB_DIRS += macintosh
-MOD_SUB_DIRS += macintosh
-endif
-
-ifeq ($(CONFIG_USB),y)
-SUB_DIRS += usb
-MOD_SUB_DIRS += usb
-else
- ifeq ($(CONFIG_USB),m)
- MOD_SUB_DIRS += usb
- endif
-endif
-
-ifeq ($(CONFIG_INPUT),y)
-SUB_DIRS += input
-MOD_SUB_DIRS += input
-else
- ifeq ($(CONFIG_INPUT),m)
- MOD_SUB_DIRS += input
- endif
-endif
-
-ifeq ($(CONFIG_PHONE),y)
-SUB_DIRS += telephony
-MOD_SUB_DIRS += telephony
-else
- ifeq ($(CONFIG_PHONE),m)
- MOD_SUB_DIRS += telephony
- endif
-endif
-
-ifdef CONFIG_SGI
-SUB_DIRS += sgi
-MOD_SUB_DIRS += sgi
-endif
-
-ifeq ($(CONFIG_I2O),y)
-SUB_DIRS += i2o
-MOD_SUB_DIRS += i2o
-else
- ifeq ($(CONFIG_I2O),m)
- MOD_SUB_DIRS += i2o
- endif
-endif
-
-# If CONFIG_IDE is set, the core of ATA support will be added to the kernel,
-# but some of the low-level things may also be modules.
-ifeq ($(CONFIG_IDE),y)
-SUB_DIRS += ide
-MOD_SUB_DIRS += ide
-else
- ifeq ($(CONFIG_IDE),m)
- MOD_SUB_DIRS += ide
- endif
-endif
-
-# If CONFIG_SCSI is set, the core of SCSI support will be added to the kernel,
-# but some of the low-level things may also be modules.
-ifeq ($(CONFIG_SCSI),y)
-SUB_DIRS += scsi
-MOD_SUB_DIRS += scsi
-else
- ifeq ($(CONFIG_SCSI),m)
- MOD_SUB_DIRS += scsi
- endif
-endif
-
-ifeq ($(CONFIG_IEEE1394),y)
-SUB_DIRS += ieee1394
-MOD_SUB_DIRS += ieee1394
-else
- ifeq ($(CONFIG_IEEE1394),m)
- MOD_SUB_DIRS += ieee1394
- endif
-endif
-
-ifeq ($(CONFIG_PNP),y)
-SUB_DIRS += pnp
-MOD_SUB_DIRS += pnp
-else
- ifeq ($(CONFIG_PNP),m)
- MOD_SUB_DIRS += pnp
- endif
-endif
-
-ifneq ($(CONFIG_CD_NO_IDESCSI)$(CONFIG_BLK_DEV_IDECD)$(CONFIG_BLK_DEV_SR)$(CONFIG_PARIDE_PCD),)
-SUB_DIRS += cdrom
-MOD_SUB_DIRS += cdrom
-endif
-
-ifeq ($(CONFIG_ISDN),y)
-SUB_DIRS += isdn
-MOD_SUB_DIRS += isdn
-else
- ifeq ($(CONFIG_ISDN),m)
- MOD_SUB_DIRS += isdn
- endif
-endif
-
-ifdef CONFIG_ATM
-SUB_DIRS += atm
-MOD_SUB_DIRS += atm
-endif
-
-ifeq ($(CONFIG_FC4),y)
-SUB_DIRS += fc4
-MOD_SUB_DIRS += fc4
-else
- ifeq ($(CONFIG_FC4),m)
- MOD_SUB_DIRS += fc4
- endif
-endif
-
-# When MOD_LIST_NAME is set, make will try to add $(MOD_SUB_DIRS).o to
-# modules/MOD_LIST_NAME. We don't have hamradio.o and Linus
-# sort of insisted on making hamradio/ a subdirectory of drivers/net/.
-# #FIXME# MOD_LIST_NAME doesn't exist any more -- does this comment
-# #FIXME# still mean anything?
-
-ifeq ($(CONFIG_HAMRADIO),y)
- SUB_DIRS += net/hamradio
- MOD_SUB_DIRS += net/hamradio
-endif
-
-ifeq ($(CONFIG_I2C),y)
-SUB_DIRS += i2c
-MOD_SUB_DIRS += i2c
-else
- ifeq ($(CONFIG_I2C),m)
- MOD_SUB_DIRS += i2c
- endif
-endif
-
-ifeq ($(CONFIG_ACPI),y)
-SUB_DIRS += acpi
-MOD_SUB_DIRS += acpi
-endif
+
+mod-subdirs := dio mtd sbus video macintosh usb input telephony sgi i2o ide \
+ scsi md ieee1394 pnp isdn atm fc4 net/hamradio i2c acpi
+
+subdir-y := block char net parport sound misc media cdrom
+subdir-m := $(subdir-y)
+
+
+subdir-$(CONFIG_DIO) += dio
+subdir-$(CONFIG_PCI) += pci
+subdir-$(CONFIG_PCMCIA) += pcmcia
+subdir-$(CONFIG_MTD) += mtd
+subdir-$(CONFIG_SBUS) += sbus
+subdir-$(CONFIG_ZORRO) += zorro
+subdir-$(CONFIG_NUBUS) += nubus
+subdir-$(CONFIG_TC) += tc
+subdir-$(CONFIG_VT) += video
+subdir-$(CONFIG_MAC) += macintosh
+subdir-$(CONFIG_ALL_PPC) += macintosh
+subdir-$(CONFIG_USB) += usb
+subdir-$(CONFIG_INPUT) += input
+subdir-$(CONFIG_PHONE) += telephony
+subdir-$(CONFIG_SGI) += sgi
+subdir-$(CONFIG_I2O) += i2o
+subdir-$(CONFIG_IDE) += ide
+subdir-$(CONFIG_SCSI) += scsi
+subdir-$(CONFIG_MD) += md
+subdir-$(CONFIG_IEEE1394) += ieee1394
+subdir-$(CONFIG_PNP) += pnp
+subdir-$(CONFIG_ISDN) += isdn
+subdir-$(CONFIG_ATM) += atm
+subdir-$(CONFIG_FC4) += fc4
+
+# CONFIG_HAMRADIO can be set without CONFIG_NETDEVICE being set -- ch
+subdir-$(CONFIG_HAMRADIO) += net/hamradio
+subdir-$(CONFIG_I2C) += i2c
+subdir-$(CONFIG_ACPI) += acpi
+
+
+# Subdirectories that should be entered when MAKING_MODULES=1, even if set to 'y'.
+both-m := $(filter $(mod-subdirs), $(subdir-y))
+
+# Translate to Rules.make lists.
+SUB_DIRS := $(subdir-y)
+MOD_SUB_DIRS := $(sort $(subdir-m) $(both-m))
+ALL_SUB_DIRS := $(sort $(subdir-y) $(subdir-m) $(subdir-n) $(subdir-))
+
+# net/hamradio is already in ALL_SUB_DIRS of drivers/net/Makefile
+ALL_SUB_DIRS := $(filter-out net/hamradio, $(ALL_SUB_DIRS))
X
X include $(TOPDIR)/Rules.make
+
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/block/fd1772.c linux/drivers/acorn/block/fd1772.c
--- v2.4.0-test8/linux/drivers/acorn/block/fd1772.c Sun Aug 13 09:54:15 2000
+++ linux/drivers/acorn/block/fd1772.c Sun Oct 1 20:35:15 2000
@@ -198,7 +198,7 @@
X #define MAX_DISK_SIZE 720
X
X static int floppy_sizes[256];
-static int floppy_blocksizes[256] = {0,};
+static int floppy_blocksizes[256];
X
X /* current info on each unit */
X static struct archy_floppy_struct {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/block/mfmhd.c linux/drivers/acorn/block/mfmhd.c
--- v2.4.0-test8/linux/drivers/acorn/block/mfmhd.c Mon Feb 28 14:16:37 2000
+++ linux/drivers/acorn/block/mfmhd.c Mon Sep 18 15:15:21 2000
@@ -124,7 +124,7 @@
X #include <asm/dma.h>
X #include <asm/hardware.h>
X #include <asm/ecard.h>
-#include <asm/ioc.h>
+#include <asm/hardware/ioc.h>
X
X /*
X * This sort of stuff should be in a header file shared with ide.c, hd.c, xd.c etc
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/char/Makefile linux/drivers/acorn/char/Makefile
--- v2.4.0-test8/linux/drivers/acorn/char/Makefile Sun Aug 13 09:54:15 2000
+++ linux/drivers/acorn/char/Makefile Mon Sep 18 15:15:21 2000


@@ -28,19 +28,15 @@
X

X obj-arc := keyb_arc.o
X obj-rpc := keyb_ps2.o
+obj-clps7500 := keyb_ps2.o defkeymap-acorn.o
X
X obj-$(CONFIG_RPCMOUSE) += mouse_rpc.o
X obj-$(CONFIG_ATOMWIDE_SERIAL) += serial-atomwide.o
X obj-$(CONFIG_DUALSP_SERIAL) += serial-dualsp.o
-obj-$(CONFIG_ARCH_ACORN) += defkeymap-acorn.o
+obj-$(CONFIG_ARCH_ACORN) += defkeymap-acorn.o i2c.o pcf8583.o
X
X # Do the i2c and rtc last
X obj-y += $(obj-$(MACHINE))
-
-# CL-PS7500 does not have these devices.
-ifneq ($(CONFIG_ARCH_CLPS7500),y)
-obj-y += i2c.o pcf8583.o
-endif
X
X O_OBJS := $(filter-out $(export-objs), $(obj-y))
X OX_OBJS := $(filter $(export-objs), $(obj-y))
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/char/defkeymap-acorn.c linux/drivers/acorn/char/defkeymap-acorn.c
--- v2.4.0-test8/linux/drivers/acorn/char/defkeymap-acorn.c Mon Jun 26 12:04:42 2000
+++ linux/drivers/acorn/char/defkeymap-acorn.c Mon Sep 18 15:15:21 2000
@@ -1,9 +1,12 @@
X /*
- * linux/arch/arm/drivers/char/defkeymap.c
+ * linux/drivers/acorn/char/defkeymap.c
X *
- * Copyright (C) 1995, 1996 Russell King
+ * Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X */
-
X #include <linux/types.h>
X #include <linux/keyboard.h>
X #include <linux/kd.h>
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/char/i2c.c linux/drivers/acorn/char/i2c.c
--- v2.4.0-test8/linux/drivers/acorn/char/i2c.c Sun Feb 6 17:45:25 2000
+++ linux/drivers/acorn/char/i2c.c Mon Sep 18 15:15:21 2000
@@ -1,11 +1,15 @@
X /*
- * linux/drivers/acorn/char/i2c.c
+ * linux/drivers/acorn/char/i2c.c
X *
- * Copyright (C) 2000 Russell King
+ * Copyright (C) 2000 Russell King
X *
- * ARM IOC/IOMD i2c driver.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X *
- * On Acorn machines, the following i2c devices are on the bus:
+ * ARM IOC/IOMD i2c driver.
+ *
+ * On Acorn machines, the following i2c devices are on the bus:
X * - PCF8583 real time clock & static RAM
X */
X #include <linux/init.h>
@@ -15,7 +19,7 @@
X
X #include <asm/hardware.h>
X #include <asm/io.h>
-#include <asm/ioc.h>
+#include <asm/hardware/ioc.h>
X #include <asm/system.h>
X
X #include "pcf8583.h"
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/char/keyb_arc.c linux/drivers/acorn/char/keyb_arc.c
--- v2.4.0-test8/linux/drivers/acorn/char/keyb_arc.c Wed Aug 9 14:11:11 2000
+++ linux/drivers/acorn/char/keyb_arc.c Mon Sep 18 15:15:21 2000
@@ -1,13 +1,18 @@
X /*
- * linux/arch/arm/drivers/char1/keyb_arc.c
+ * linux/drivers/acorn/char/keyb_arc.c
X *
- * Acorn keyboard driver for ARM Linux.
+ * Copyright (C) 2000 Russell King
X *
- * The Acorn keyboard appears to have a ***very*** buggy reset protocol -
- * every reset behaves differently. We try to get round this by attempting
- * a few things...
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Acorn keyboard driver for ARM Linux.
+ *
+ * The Acorn keyboard appears to have a ***very*** buggy reset protocol -
+ * every reset behaves differently. We try to get round this by attempting
+ * a few things...
X */
-
X #include <linux/config.h>
X #include <linux/sched.h>
X #include <linux/interrupt.h>
@@ -28,8 +33,8 @@
X #include <asm/bitops.h>
X #include <asm/keyboard.h>
X #include <asm/irq.h>
-#include <asm/ioc.h>
X #include <asm/hardware.h>
+#include <asm/hardware/ioc.h>
X
X #include "../../char/busmouse.h"


X
@@ -424,14 +429,11 @@

X {
X unsigned long flags;
X

- save_flags_cli (flags);
X if (request_irq (IRQ_KEYBOARDTX, a5kkbd_tx, 0, "keyboard", NULL) != 0)
X panic("Could not allocate keyboard transmit IRQ!");
- disable_irq (IRQ_KEYBOARDTX);
+ (void)inb(IOC_KARTRX);
X if (request_irq (IRQ_KEYBOARDRX, a5kkbd_rx, 0, "keyboard", NULL) != 0)
X panic("Could not allocate keyboard receive IRQ!");
- (void)inb(IOC_KARTRX);
- restore_flags (flags);
X
X a5kkbd_sendbyte (HRST); /* send HRST (expect HRST) */
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/char/keyb_ps2.c linux/drivers/acorn/char/keyb_ps2.c
--- v2.4.0-test8/linux/drivers/acorn/char/keyb_ps2.c Wed Aug 9 14:11:11 2000
+++ linux/drivers/acorn/char/keyb_ps2.c Mon Sep 18 15:15:21 2000
@@ -1,11 +1,16 @@
X /*
- * linux/arch/arm/drivers/block/keyb_ps2.c
+ * linux/drivers/acorn/char/keyb_ps2.c
X *
- * Keyboard driver for RPC ARM Linux.
+ * Copyright (C) 2000 Russell King
X *
- * Note!!! This driver talks directly to the keyboard.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Keyboard driver for RiscPC ARM Linux.
+ *
+ * Note!!! This driver talks directly to the keyboard.
X */
-
X #include <linux/config.h>
X #include <linux/sched.h>
X #include <linux/interrupt.h>
@@ -25,7 +30,7 @@
X #include <asm/irq.h>
X #include <asm/hardware.h>
X #include <asm/io.h>
-#include <asm/iomd.h>
+#include <asm/hardware/iomd.h>
X #include <asm/system.h>
X
X extern struct tasklet_struct keyboard_tasklet;
@@ -326,20 +331,15 @@
X
X int __init ps2kbd_init_hw(void)
X {
- unsigned long flags;
-
X /* Reset the keyboard state machine. */
X outb(0, IOMD_KCTRL);
X outb(8, IOMD_KCTRL);
X
- save_flags_cli (flags);
+ (void)IOMD_KARTRX;
X if (request_irq (IRQ_KEYBOARDRX, ps2kbd_rx, 0, "keyboard", NULL) != 0)
X panic("Could not allocate keyboard receive IRQ!");
X if (request_irq (IRQ_KEYBOARDTX, ps2kbd_tx, 0, "keyboard", NULL) != 0)
X panic("Could not allocate keyboard transmit IRQ!");
- disable_irq (IRQ_KEYBOARDTX);
- (void)IOMD_KARTRX;
- restore_flags (flags);
X
X return 0;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/char/mouse_rpc.c linux/drivers/acorn/char/mouse_rpc.c
--- v2.4.0-test8/linux/drivers/acorn/char/mouse_rpc.c Tue Jun 20 07:24:52 2000
+++ linux/drivers/acorn/char/mouse_rpc.c Mon Sep 18 15:15:21 2000
@@ -1,12 +1,16 @@
X /*
- * linux/drivers/char/mouse_rpc.c
+ * linux/drivers/char/mouse_rpc.c
X *
- * Copyright (C) 1996-1998 Russell King
+ * Copyright (C) 1996-1998 Russell King
X *
- * This handles the Acorn RiscPCs mouse. We basically have a couple
- * of hardware registers that track the sensor count for the X-Y movement
- * and another register holding the button state. On every VSYNC interrupt
- * we read the complete state and then work out if something has changed.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This handles the Acorn RiscPCs mouse. We basically have a couple


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 017'
echo 'File patch-2.4.0-test9 is continued in part 018'
echo "018" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part019

#!/bin/sh -x
# this is part 019 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 019; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ *
+ * RETURN: Length
+ *
+ * DESCRIPTION: Returns the length of the input string
+ *
+ ******************************************************************************/
+
+
+NATIVE_UINT
+acpi_cm_strlen (
+ const NATIVE_CHAR *string)
+{
+ NATIVE_UINT length = 0;
+
+
+ /* Count the string until a null is encountered */
+
+ while (*string) {
+ length++;
+ string++;
+ }
+
+ return (length);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: strcpy
+ *
+ * PARAMETERS: Dst_string - Target of the copy
+ * Src_string - The source string to copy
+ *
+ * RETURN: Dst_string
+ *
+ * DESCRIPTION: Copy a null terminated string
+ *
+ ******************************************************************************/
+
+NATIVE_CHAR *
+acpi_cm_strcpy (
+ NATIVE_CHAR *dst_string,
+ const NATIVE_CHAR *src_string)
+{
+ NATIVE_CHAR *string = dst_string;
+
+
+ /* Move bytes brute force */
+
+ while (*src_string) {
+ *string = *src_string;
+
+ string++;
+ src_string++;
+ }
+
+ /* Null terminate */
+
+ *string = 0;
+
+ return (dst_string);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: strncpy
+ *
+ * PARAMETERS: Dst_string - Target of the copy
+ * Src_string - The source string to copy
+ * Count - Maximum # of bytes to copy
+ *
+ * RETURN: Dst_string
+ *
+ * DESCRIPTION: Copy a null terminated string, with a maximum length
+ *
+ ******************************************************************************/
+
+NATIVE_CHAR *
+acpi_cm_strncpy (
+ NATIVE_CHAR *dst_string,
+ const NATIVE_CHAR *src_string,
+ NATIVE_UINT count)
+{
+ NATIVE_CHAR *string = dst_string;
+
+
+ /* Copy the string */
+
+ for (string = dst_string;
+ count && (count--, (*string++ = *src_string++)); )
+ {;}
+
+ /* Pad with nulls if necessary */
+
+ while (count--) {
+ *string = 0;
+ string++;
+ }
+
+ /* Return original pointer */
+
+ return (dst_string);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: strcmp
+ *
+ * PARAMETERS: String1 - First string
+ * String2 - Second string
+ *
+ * RETURN: Index where strings mismatched, or 0 if strings matched
+ *
+ * DESCRIPTION: Compare two null terminated strings
+ *
+ ******************************************************************************/
+
+u32
+acpi_cm_strcmp (
+ const NATIVE_CHAR *string1,
+ const NATIVE_CHAR *string2)
+{
+
+
+ for ( ; (*string1 == *string2); string2++) {
+ if (!*string1++) {
+ return (0);
+ }
+ }
+
+
+ return ((unsigned char) *string1 - (unsigned char) *string2);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: strncmp
+ *
+ * PARAMETERS: String1 - First string
+ * String2 - Second string
+ * Count - Maximum # of bytes to compare
+ *
+ * RETURN: Index where strings mismatched, or 0 if strings matched
+ *
+ * DESCRIPTION: Compare two null terminated strings, with a maximum length
+ *
+ ******************************************************************************/
+
+u32
+acpi_cm_strncmp (
+ const NATIVE_CHAR *string1,
+ const NATIVE_CHAR *string2,
+ NATIVE_UINT count)
+{
+
+
+ for ( ; count-- && (*string1 == *string2); string2++) {
+ if (!*string1++) {
+ return (0);
+ }
+ }
+
+ return ((count == -1) ? 0 : ((unsigned char) *string1 -
+ (unsigned char) *string2));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Strcat
+ *
+ * PARAMETERS: Dst_string - Target of the copy
+ * Src_string - The source string to copy
+ *
+ * RETURN: Dst_string
+ *
+ * DESCRIPTION: Append a null terminated string to a null terminated string
+ *
+ ******************************************************************************/
+
+NATIVE_CHAR *
+acpi_cm_strcat (
+ NATIVE_CHAR *dst_string,
+ const NATIVE_CHAR *src_string)
+{
+ NATIVE_CHAR *string;
+
+
+ /* Find end of the destination string */
+
+ for (string = dst_string; *string++; ) { ; }
+
+ /* Concatinate the string */
+
+ for (--string; (*string++ = *src_string++); ) { ; }
+
+ return (dst_string);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: strncat
+ *
+ * PARAMETERS: Dst_string - Target of the copy
+ * Src_string - The source string to copy
+ * Count - Maximum # of bytes to copy
+ *
+ * RETURN: Dst_string
+ *
+ * DESCRIPTION: Append a null terminated string to a null terminated string,
+ * with a maximum count.
+ *
+ ******************************************************************************/
+
+NATIVE_CHAR *
+acpi_cm_strncat (
+ NATIVE_CHAR *dst_string,
+ const NATIVE_CHAR *src_string,
+ NATIVE_UINT count)
+{
+ NATIVE_CHAR *string;
+
+
+ if (count) {
+ /* Find end of the destination string */
+
+ for (string = dst_string; *string++; ) { ; }
+
+ /* Concatinate the string */
+
+ for (--string; (*string++ = *src_string++) && --count; ) { ; }
+
+ /* Null terminate if necessary */
+
+ if (!count) {
+ *string = 0;
+ }
+ }
+
+ return (dst_string);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: memcpy
+ *
+ * PARAMETERS: Dest - Target of the copy
+ * Src - Source buffer to copy
+ * Count - Number of bytes to copy
+ *
+ * RETURN: Dest
+ *
+ * DESCRIPTION: Copy arbitrary bytes of memory
+ *
+ ******************************************************************************/
+
+void *
+acpi_cm_memcpy (
+ void *dest,
+ const void *src,
+ NATIVE_UINT count)
+{
+ NATIVE_CHAR *new = (NATIVE_CHAR *) dest;
+ NATIVE_CHAR *old = (NATIVE_CHAR *) src;
+
+
+ while (count) {
+ *new = *old;
+ new++;
+ old++;
+ count--;
+ }
+
+ return (dest);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: memset
+ *
+ * PARAMETERS: Dest - Buffer to set
+ * Value - Value to set each byte of memory
+ * Count - Number of bytes to set
+ *
+ * RETURN: Dest
+ *
+ * DESCRIPTION: Initialize a buffer to a known value.
+ *
+ ******************************************************************************/
+
+void *
+acpi_cm_memset (
+ void *dest,
+ u32 value,
+ NATIVE_UINT count)
+{
+ NATIVE_CHAR *new = (NATIVE_CHAR *) dest;
+
+
+ while (count) {
+ *new = (char) value;
+ new++;
+ count--;
+ }
+
+ return (dest);
+}
+
+
+#define NEGATIVE 1
+#define POSITIVE 0
+
+
+#define _XA 0x00 /* extra alphabetic - not supported */
+#define _XS 0x40 /* extra space */
+#define _BB 0x00 /* BEL, BS, etc. - not supported */
+#define _CN 0x20 /* CR, FF, HT, NL, VT */
+#define _DI 0x04 /* '0'-'9' */
+#define _LO 0x02 /* 'a'-'z' */
+#define _PU 0x10 /* punctuation */
+#define _SP 0x08 /* space */
+#define _UP 0x01 /* 'A'-'Z' */
+#define _XD 0x80 /* '0'-'9', 'A'-'F', 'a'-'f' */
+
+const u8 _ctype[257] = {
+ _CN, /* 0x0 0. */
+ _CN, /* 0x1 1. */
+ _CN, /* 0x2 2. */
+ _CN, /* 0x3 3. */
+ _CN, /* 0x4 4. */
+ _CN, /* 0x5 5. */
+ _CN, /* 0x6 6. */
+ _CN, /* 0x7 7. */
+ _CN, /* 0x8 8. */
+ _CN|_SP, /* 0x9 9. */
+ _CN|_SP, /* 0xA 10. */
+ _CN|_SP, /* 0xB 11. */
+ _CN|_SP, /* 0xC 12. */
+ _CN|_SP, /* 0xD 13. */
+ _CN, /* 0xE 14. */
+ _CN, /* 0xF 15. */
+ _CN, /* 0x10 16. */
+ _CN, /* 0x11 17. */
+ _CN, /* 0x12 18. */
+ _CN, /* 0x13 19. */
+ _CN, /* 0x14 20. */
+ _CN, /* 0x15 21. */
+ _CN, /* 0x16 22. */
+ _CN, /* 0x17 23. */
+ _CN, /* 0x18 24. */
+ _CN, /* 0x19 25. */
+ _CN, /* 0x1A 26. */
+ _CN, /* 0x1B 27. */
+ _CN, /* 0x1C 28. */
+ _CN, /* 0x1D 29. */
+ _CN, /* 0x1E 30. */
+ _CN, /* 0x1F 31. */
+ _XS|_SP, /* 0x20 32. ' ' */
+ _PU, /* 0x21 33. '!' */
+ _PU, /* 0x22 34. '"' */
+ _PU, /* 0x23 35. '#' */
+ _PU, /* 0x24 36. '$' */
+ _PU, /* 0x25 37. '%' */
+ _PU, /* 0x26 38. '&' */
+ _PU, /* 0x27 39. ''' */
+ _PU, /* 0x28 40. '(' */
+ _PU, /* 0x29 41. ')' */
+ _PU, /* 0x2A 42. '*' */
+ _PU, /* 0x2B 43. '+' */
+ _PU, /* 0x2C 44. ',' */
+ _PU, /* 0x2D 45. '-' */
+ _PU, /* 0x2E 46. '.' */
+ _PU, /* 0x2F 47. '/' */
+ _XD|_DI, /* 0x30 48. '0' */
+ _XD|_DI, /* 0x31 49. '1' */
+ _XD|_DI, /* 0x32 50. '2' */
+ _XD|_DI, /* 0x33 51. '3' */
+ _XD|_DI, /* 0x34 52. '4' */
+ _XD|_DI, /* 0x35 53. '5' */
+ _XD|_DI, /* 0x36 54. '6' */
+ _XD|_DI, /* 0x37 55. '7' */
+ _XD|_DI, /* 0x38 56. '8' */
+ _XD|_DI, /* 0x39 57. '9' */
+ _PU, /* 0x3A 58. ':' */
+ _PU, /* 0x3B 59. ';' */
+ _PU, /* 0x3C 60. '<' */
+ _PU, /* 0x3D 61. '=' */
+ _PU, /* 0x3E 62. '>' */
+ _PU, /* 0x3F 63. '?' */
+ _PU, /* 0x40 64. '@' */
+ _XD|_UP, /* 0x41 65. 'A' */
+ _XD|_UP, /* 0x42 66. 'B' */
+ _XD|_UP, /* 0x43 67. 'C' */
+ _XD|_UP, /* 0x44 68. 'D' */
+ _XD|_UP, /* 0x45 69. 'E' */
+ _XD|_UP, /* 0x46 70. 'F' */
+ _UP, /* 0x47 71. 'G' */
+ _UP, /* 0x48 72. 'H' */
+ _UP, /* 0x49 73. 'I' */
+ _UP, /* 0x4A 74. 'J' */
+ _UP, /* 0x4B 75. 'K' */
+ _UP, /* 0x4C 76. 'L' */
+ _UP, /* 0x4D 77. 'M' */
+ _UP, /* 0x4E 78. 'N' */
+ _UP, /* 0x4F 79. 'O' */
+ _UP, /* 0x50 80. 'P' */
+ _UP, /* 0x51 81. 'Q' */
+ _UP, /* 0x52 82. 'R' */
+ _UP, /* 0x53 83. 'S' */
+ _UP, /* 0x54 84. 'T' */
+ _UP, /* 0x55 85. 'U' */
+ _UP, /* 0x56 86. 'V' */
+ _UP, /* 0x57 87. 'W' */
+ _UP, /* 0x58 88. 'X' */
+ _UP, /* 0x59 89. 'Y' */
+ _UP, /* 0x5A 90. 'Z' */
+ _PU, /* 0x5B 91. '[' */
+ _PU, /* 0x5C 92. '\' */
+ _PU, /* 0x5D 93. ']' */
+ _PU, /* 0x5E 94. '^' */
+ _PU, /* 0x5F 95. '_' */
+ _PU, /* 0x60 96. '`' */
+ _XD|_LO, /* 0x61 97. 'a' */
+ _XD|_LO, /* 0x62 98. 'b' */
+ _XD|_LO, /* 0x63 99. 'c' */
+ _XD|_LO, /* 0x64 100. 'd' */
+ _XD|_LO, /* 0x65 101. 'e' */
+ _XD|_LO, /* 0x66 102. 'f' */
+ _LO, /* 0x67 103. 'g' */
+ _LO, /* 0x68 104. 'h' */
+ _LO, /* 0x69 105. 'i' */
+ _LO, /* 0x6A 106. 'j' */
+ _LO, /* 0x6B 107. 'k' */
+ _LO, /* 0x6C 108. 'l' */
+ _LO, /* 0x6D 109. 'm' */
+ _LO, /* 0x6E 110. 'n' */
+ _LO, /* 0x6F 111. 'o' */
+ _LO, /* 0x70 112. 'p' */
+ _LO, /* 0x71 113. 'q' */
+ _LO, /* 0x72 114. 'r' */
+ _LO, /* 0x73 115. 's' */
+ _LO, /* 0x74 116. 't' */
+ _LO, /* 0x75 117. 'u' */
+ _LO, /* 0x76 118. 'v' */
+ _LO, /* 0x77 119. 'w' */
+ _LO, /* 0x78 120. 'x' */
+ _LO, /* 0x79 121. 'y' */
+ _LO, /* 0x7A 122. 'z' */
+ _PU, /* 0x7B 123. '{' */
+ _PU, /* 0x7C 124. '|' */
+ _PU, /* 0x7D 125. '}' */
+ _PU, /* 0x7E 126. '~' */
+ _CN, /* 0x7F 127. */
+
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x80 to 0x8F */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x90 to 0x9F */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xA0 to 0xAF */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xB0 to 0xBF */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xC0 to 0xCF */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xD0 to 0xDF */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xE0 to 0xEF */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* 0xF0 to 0x100 */
+};
+
+#define IS_UPPER(c) (_ctype[(unsigned char)(c)] & (_UP))
+#define IS_LOWER(c) (_ctype[(unsigned char)(c)] & (_LO))
+#define IS_DIGIT(c) (_ctype[(unsigned char)(c)] & (_DI))
+#define IS_SPACE(c) (_ctype[(unsigned char)(c)] & (_SP))
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_cm_to_upper
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION: Convert character to uppercase
+ *
+ ******************************************************************************/
+
+u32
+acpi_cm_to_upper (
+ u32 c)
+{
+
+ return (IS_LOWER(c) ? ((c)-0x20) : (c));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_cm_to_lower
+ *
+ * PARAMETERS:
+ *
+ * RETURN:
+ *
+ * DESCRIPTION: Convert character to lowercase
+ *
+ ******************************************************************************/
+
+u32
+acpi_cm_to_lower (
+ u32 c)
+{
+
+ return (IS_UPPER(c) ? ((c)+0x20) : (c));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: strupr
+ *
+ * PARAMETERS: Src_string - The source string to convert to
+ *
+ * RETURN: Src_string
+ *
+ * DESCRIPTION: Convert string to uppercase
+ *
+ ******************************************************************************/
+
+NATIVE_CHAR *
+acpi_cm_strupr (
+ NATIVE_CHAR *src_string)
+{
+ NATIVE_CHAR *string;
+
+
+ /* Walk entire string, uppercasing the letters */
+
+ for (string = src_string; *string; ) {
+ *string = (char) acpi_cm_to_upper (*string);
+ string++;
+ }
+
+
+ return (src_string);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: strstr
+ *
+ * PARAMETERS: String1 -
+ * String2
+ *
+ * RETURN:
+ *
+ * DESCRIPTION: Checks if String2 occurs in String1. This is not really a
+ * full implementation of strstr, only sufficient for command
+ * matching
+ *
+ ******************************************************************************/
+
+NATIVE_CHAR *
+acpi_cm_strstr (
+ NATIVE_CHAR *string1,
+ NATIVE_CHAR *string2)
+{
+ NATIVE_CHAR *string;
+
+
+ if (acpi_cm_strlen (string2) > acpi_cm_strlen (string1)) {
+ return (NULL);
+ }
+
+ /* Walk entire string, uppercasing the letters */
+
+ for (string = string1; *string2; ) {
+ if (*string2 != *string) {
+ return (NULL);
+ }
+
+ string2++;
+ string++;
+ }
+
+
+ return (string1);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: strtoul
+ *
+ * PARAMETERS: String - Null terminated string
+ * Terminater - Where a pointer to the terminating byte is returned
+ * Base - Radix of the string
+ *
+ * RETURN: Converted value
+ *
+ * DESCRIPTION: Convert a string into an unsigned value.
+ *
+ ******************************************************************************/
+
+u32
+acpi_cm_strtoul (
+ const NATIVE_CHAR *string,
+ NATIVE_CHAR **terminator,
+ u32 base)
+{
+ u32 converted = 0;
+ u32 index;
+ u32 sign;
+ const NATIVE_CHAR *string_start;
+ u32 return_value = 0;
+ ACPI_STATUS status = AE_OK;
+
+
+ /*
+ * Save the value of the pointer to the buffer's first
+ * character, save the current errno value, and then
+ * skip over any white space in the buffer:
+ */
+ string_start = string;
+ while (IS_SPACE (*string) || *string == '\t') {
+ ++string;
+ }
+
+ /*
+ * The buffer may contain an optional plus or minus sign.
+ * If it does, then skip over it but remember what is was:
+ */
+ if (*string == '-') {
+ sign = NEGATIVE;
+ ++string;
+ }
+
+ else if (*string == '+') {
+ ++string;
+ sign = POSITIVE;
+ }
+
+ else {
+ sign = POSITIVE;
+ }
+
+ /*
+ * If the input parameter Base is zero, then we need to
+ * determine if it is octal, decimal, or hexadecimal:
+ */
+ if (base == 0) {
+ if (*string == '0') {
+ if (acpi_cm_to_lower (*(++string)) == 'x') {
+ base = 16;
+ ++string;
+ }
+
+ else {
+ base = 8;
+ }
+ }
+
+ else {
+ base = 10;
+ }
+ }
+
+ else if (base < 2 || base > 36) {
+ /*
+ * The specified Base parameter is not in the domain of
+ * this function:
+ */
+ goto done;
+ }
+
+ /*
+ * For octal and hexadecimal bases, skip over the leading
+ * 0 or 0x, if they are present.
+ */
+ if (base == 8 && *string == '0') {
+ string++;
+ }
+
+ if (base == 16 &&
+ *string == '0' &&
+ acpi_cm_to_lower (*(++string)) == 'x')
+ {
+ string++;
+ }
+
+
+ /*
+ * Main loop: convert the string to an unsigned long:
+ */
+ while (*string) {
+ if (IS_DIGIT (*string)) {
+ index = *string - '0';
+ }
+
+ else {
+ index = acpi_cm_to_upper (*string);
+ if (IS_UPPER (index)) {
+ index = index - 'A' + 10;
+ }
+
+ else {
+ goto done;
+ }
+ }
+
+ if (index >= base) {
+ goto done;
+ }
+
+ /*
+ * Check to see if value is out of range:
+ */
+
+ if (return_value > ((ACPI_UINT32_MAX - (u32) index) /
+ (u32) base))
+ {
+ status = AE_ERROR;
+ return_value = 0L; /* reset */
+ }
+
+ else {
+ return_value *= base;
+ return_value += index;
+ converted = 1;
+ }
+
+ ++string;
+ }
+
+done:
+ /*
+ * If appropriate, update the caller's pointer to the next
+ * unconverted character in the buffer.
+ */
+ if (terminator) {
+ if (converted == 0 && return_value == 0L && string != NULL) {
+ *terminator = (NATIVE_CHAR *) string_start;
+ }
+
+ else {
+ *terminator = (NATIVE_CHAR *) string;
+ }
+ }
+
+ if (status == AE_ERROR) {
+ return_value = ACPI_UINT32_MAX;
+ }
+
+ /*
+ * If a minus sign was present, then "the conversion is negated":
+ */
+ if (sign == NEGATIVE) {
+ return_value = (ACPI_UINT32_MAX - return_value) + 1;
+ }
+
+ return (return_value);
+}
+
+#endif /* ACPI_USE_SYSTEM_CLIBRARY */
+
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/common/cmcopy.c linux/drivers/acpi/common/cmcopy.c
--- v2.4.0-test8/linux/drivers/acpi/common/cmcopy.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/common/cmcopy.c Fri Sep 15 14:30:29 2000
@@ -1,6 +1,7 @@
X /******************************************************************************
X *
X * Module Name: cmcopy - Internal to external object translation utilities
+ * $Revision: 56 $
X *
X *****************************************************************************/
X
@@ -24,17 +25,17 @@
X
X
X #include "acpi.h"
-#include "interp.h"
-#include "namesp.h"
+#include "acinterp.h"
+#include "acnamesp.h"
X
X
X #define _COMPONENT MISCELLANEOUS
- MODULE_NAME ("cmcopy");
+ MODULE_NAME ("cmcopy")
X
X
X typedef struct search_st
X {
- ACPI_OBJECT_INTERNAL *internal_obj;
+ ACPI_OPERAND_OBJECT *internal_obj;
X u32 index;
X ACPI_OBJECT *external_obj;
X
@@ -64,13 +65,13 @@
X
X ACPI_STATUS
X acpi_cm_build_external_simple_object (
- ACPI_OBJECT_INTERNAL *internal_obj,
+ ACPI_OPERAND_OBJECT *internal_obj,
X ACPI_OBJECT *external_obj,
X u8 *data_space,
X u32 *buffer_space_used)
X {
X u32 length = 0;
- char *source_ptr = NULL;
+ u8 *source_ptr = NULL;
X
X
X /*
@@ -103,8 +104,8 @@
X
X length = internal_obj->string.length;
X external_obj->string.length = internal_obj->string.length;
- external_obj->string.pointer = (char *) data_space;
- source_ptr = internal_obj->string.pointer;
+ external_obj->string.pointer = (NATIVE_CHAR *) data_space;
+ source_ptr = (u8 *) internal_obj->string.pointer;
X break;
X
X
@@ -113,7 +114,7 @@
X length = internal_obj->buffer.length;
X external_obj->buffer.length = internal_obj->buffer.length;
X external_obj->buffer.pointer = data_space;
- source_ptr = (char *) internal_obj->buffer.pointer;
+ source_ptr = (u8 *) internal_obj->buffer.pointer;
X break;
X
X
@@ -132,7 +133,7 @@
X */
X
X external_obj->type = ACPI_TYPE_ANY;
- external_obj->reference.handle = internal_obj->reference.nte;
+ external_obj->reference.handle = internal_obj->reference.node;
X break;
X
X
@@ -142,10 +143,10 @@
X internal_obj->processor.proc_id;
X
X external_obj->processor.pblk_address =
- internal_obj->processor.pblk_address;
+ internal_obj->processor.address;
X
X external_obj->processor.pblk_length =
- internal_obj->processor.pblk_length;
+ internal_obj->processor.length;
X break;
X
X case ACPI_TYPE_POWER:


@@ -200,7 +201,7 @@
X

X ACPI_STATUS
X acpi_cm_build_external_package_object (
- ACPI_OBJECT_INTERNAL *internal_obj,
+ ACPI_OPERAND_OBJECT *internal_obj,
X u8 *buffer,
X u32 *space_used)
X {
@@ -211,7 +212,7 @@
X u32 length = 0;
X u32 this_index;
X u32 object_space;
- ACPI_OBJECT_INTERNAL *this_internal_obj;
+ ACPI_OPERAND_OBJECT *this_internal_obj;
X ACPI_OBJECT *this_external_obj;
X PKG_SEARCH_INFO *level_ptr;
X
@@ -256,7 +257,7 @@
X while (1) {
X this_index = level_ptr->index;
X this_internal_obj =
- (ACPI_OBJECT_INTERNAL *)
+ (ACPI_OPERAND_OBJECT *)
X level_ptr->internal_obj->package.elements[this_index];
X this_external_obj =
X (ACPI_OBJECT *)
@@ -264,10 +265,11 @@
X
X
X /*
- * Check for 1) Null object -- OK, this can happen if package
+ * Check for
+ * 1) Null object -- OK, this can happen if package
X * element is never initialized
- * 2) Not an internal object - can be an NTE instead
- * 3) Any internal object other than a package.
+ * 2) Not an internal object - can be Node instead
+ * 3) Any internal object other than a package.
X *
X * The more complex package case is handled later
X */
@@ -367,8 +369,6 @@
X level_ptr->index = 0;
X }
X }
-
- return (AE_OK);
X }
X
X
@@ -388,7 +388,7 @@
X
X ACPI_STATUS
X acpi_cm_build_external_object (
- ACPI_OBJECT_INTERNAL *internal_obj,
+ ACPI_OPERAND_OBJECT *internal_obj,
X ACPI_BUFFER *ret_buffer)
X {
X ACPI_STATUS status;
@@ -446,7 +446,7 @@
X ACPI_STATUS
X acpi_cm_build_internal_simple_object (
X ACPI_OBJECT *external_obj,
- ACPI_OBJECT_INTERNAL *internal_obj)
+ ACPI_OPERAND_OBJECT *internal_obj)
X {
X
X
@@ -508,18 +508,17 @@
X
X ACPI_STATUS
X acpi_cm_build_internal_package_object (
- ACPI_OBJECT_INTERNAL *internal_obj,
+ ACPI_OPERAND_OBJECT *internal_obj,
X u8 *buffer,
X u32 *space_used)
X {
X u8 *free_space;
X ACPI_OBJECT *external_obj;
X u32 current_depth = 0;
- ACPI_STATUS status = AE_OK;
X u32 length = 0;
X u32 this_index;
X u32 object_space = 0;
- ACPI_OBJECT_INTERNAL *this_internal_obj;
+ ACPI_OPERAND_OBJECT *this_internal_obj;
X ACPI_OBJECT *this_external_obj;
X PKG_SEARCH_INFO *level_ptr;
X
@@ -562,7 +561,7 @@
X while (1) {
X this_index = level_ptr->index;
X
- this_internal_obj = (ACPI_OBJECT_INTERNAL *)
+ this_internal_obj = (ACPI_OPERAND_OBJECT *)
X &level_ptr->internal_obj->package.elements[this_index];
X
X this_external_obj = (ACPI_OBJECT *)
@@ -605,17 +604,6 @@
X } /* if object is a package */
X
X else {
-/* Status = Acpi_cm_build_simple_object(This_internal_obj,
- This_external_obj, Free_space,
- &Object_space);
-*/
- if (status != AE_OK) {
- /*
- * Failure get out
- */
- return (status);
- }
-
X free_space += object_space;
X length += object_space;
X
@@ -651,13 +639,6 @@
X }
X } /* else object is NOT a package */
X } /* while (1) */
-
-
- /*
- * We'll never get here, but the compiler whines about
- * return value
- */
- return (AE_OK);
X }
X
X
@@ -677,7 +658,7 @@
X ACPI_STATUS
X acpi_cm_build_internal_object (
X ACPI_OBJECT *external_obj,
- ACPI_OBJECT_INTERNAL *internal_obj)
+ ACPI_OPERAND_OBJECT *internal_obj)
X {
X ACPI_STATUS status;
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/common/cmdebug.c linux/drivers/acpi/common/cmdebug.c
--- v2.4.0-test8/linux/drivers/acpi/common/cmdebug.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/common/cmdebug.c Fri Sep 15 14:30:29 2000
@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *
X * Module Name: cmdebug - Debug print routines
+ * $Revision: 60 $
X *
X *****************************************************************************/
X
@@ -27,7 +27,7 @@
X #include "acpi.h"
X
X #define _COMPONENT MISCELLANEOUS
- MODULE_NAME ("cmdebug");
+ MODULE_NAME ("cmdebug")
X
X
X /*****************************************************************************
@@ -41,16 +41,16 @@
X ****************************************************************************/
X
X
-s32
+u32
X get_debug_level (void)
X {
X
- return acpi_dbg_level;
+ return (acpi_dbg_level);
X }
X
X void
X set_debug_level (
- s32 new_debug_level)
+ u32 new_debug_level)
X {
X
X acpi_dbg_level = new_debug_level;
@@ -75,10 +75,10 @@
X
X void
X function_trace (
- char *module_name,
- s32 line_number,
- s32 component_id,
- char *function_name)
+ NATIVE_CHAR *module_name,
+ u32 line_number,
+ u32 component_id,
+ NATIVE_CHAR *function_name)
X {
X
X acpi_gbl_nesting_level++;
@@ -109,10 +109,10 @@
X
X void
X function_trace_ptr (
- char *module_name,
- s32 line_number,
- s32 component_id,
- char *function_name,
+ NATIVE_CHAR *module_name,
+ u32 line_number,
+ u32 component_id,
+ NATIVE_CHAR *function_name,
X void *pointer)
X {
X
@@ -142,11 +142,11 @@
X
X void
X function_trace_str (
- char *module_name,
- s32 line_number,
- s32 component_id,
- char *function_name,
- char *string)
+ NATIVE_CHAR *module_name,
+ u32 line_number,
+ u32 component_id,
+ NATIVE_CHAR *function_name,
+ NATIVE_CHAR *string)
X {
X
X acpi_gbl_nesting_level++;
@@ -175,16 +175,16 @@
X
X void
X function_trace_u32 (
- char *module_name,
- s32 line_number,
- s32 component_id,
- char *function_name,
+ NATIVE_CHAR *module_name,
+ u32 line_number,
+ u32 component_id,
+ NATIVE_CHAR *function_name,
X u32 integer)
X {
X
X acpi_gbl_nesting_level++;
X debug_print (module_name, line_number, component_id, TRACE_FUNCTIONS,
- " %2.2ld Entered Function: %s, 0x%l_x\n",
+ " %2.2ld Entered Function: %s, 0x%lX\n",
X acpi_gbl_nesting_level, function_name, integer);
X }
X
@@ -207,10 +207,10 @@
X
X void
X function_exit (
- char *module_name,
- s32 line_number,
- s32 component_id,
- char *function_name)
+ NATIVE_CHAR *module_name,
+ u32 line_number,
+ u32 component_id,
+ NATIVE_CHAR *function_name)
X {
X
X debug_print (module_name, line_number, component_id, TRACE_FUNCTIONS,
@@ -240,30 +240,19 @@
X
X void
X function_status_exit (
- char *module_name,
- s32 line_number,
- s32 component_id,
- char *function_name,
+ NATIVE_CHAR *module_name,
+ u32 line_number,
+ u32 component_id,
+ NATIVE_CHAR *function_name,
X ACPI_STATUS status)
X {
X
- if (status > ACPI_MAX_STATUS) {
- debug_print (module_name, line_number, component_id,
- TRACE_FUNCTIONS,
- " %2.2ld Exiting Function: %s, [Unknown Status] 0x%X\n",
- acpi_gbl_nesting_level,
- function_name,
- status);
- }
-
- else {
- debug_print (module_name, line_number, component_id,
- TRACE_FUNCTIONS,
- " %2.2ld Exiting Function: %s, %s\n",
- acpi_gbl_nesting_level,
- function_name,
- acpi_cm_format_exception (status));
- }
+ debug_print (module_name, line_number, component_id,
+ TRACE_FUNCTIONS,
+ " %2.2ld Exiting Function: %s, %s\n",
+ acpi_gbl_nesting_level,
+ function_name,
+ acpi_cm_format_exception (status));
X
X acpi_gbl_nesting_level--;
X }
@@ -288,10 +277,10 @@
X
X void
X function_value_exit (
- char *module_name,
- s32 line_number,
- s32 component_id,
- char *function_name,
+ NATIVE_CHAR *module_name,
+ u32 line_number,
+ u32 component_id,
+ NATIVE_CHAR *function_name,
X NATIVE_UINT value)
X {
X
@@ -322,11 +311,11 @@
X
X void
X function_ptr_exit (
- char *module_name,
- s32 line_number,
- s32 component_id,
- char *function_name,
- char *ptr)
+ NATIVE_CHAR *module_name,
+ u32 line_number,
+ u32 component_id,
+ NATIVE_CHAR *function_name,
+ u8 *ptr)
X {
X
X debug_print (module_name, line_number, component_id, TRACE_FUNCTIONS,
@@ -357,11 +346,11 @@
X
X void
X debug_print (
- char *module_name,
- s32 line_number,
- s32 component_id,
- s32 print_level,
- char *format,
+ NATIVE_CHAR *module_name,
+ u32 line_number,
+ u32 component_id,
+ u32 print_level,
+ NATIVE_CHAR *format,
X ...)
X {
X va_list args;
@@ -397,8 +386,8 @@
X
X void
X debug_print_prefix (
- char *module_name,
- s32 line_number)
+ NATIVE_CHAR *module_name,
+ u32 line_number)
X {
X
X
@@ -421,7 +410,7 @@
X
X void
X debug_print_raw (
- char *format,
+ NATIVE_CHAR *format,
X ...)
X {
X va_list args;
@@ -451,10 +440,10 @@
X
X void
X acpi_cm_dump_buffer (
- char *buffer,
+ u8 *buffer,
X u32 count,
X u32 display,
- s32 component_id)
+ u32 component_id)
X {
X u32 i = 0;
X u32 j;
@@ -477,7 +466,7 @@
X while (i < count) {
X /* Print current offset */
X
- acpi_os_printf ("%05_x ", i);
+ acpi_os_printf ("%05X ", i);
X
X
X /* Print 16 hex chars */
@@ -488,7 +477,7 @@
X return;
X }
X
- /* Make sure that the char doesn't get sign-extended! */
+ /* Make sure that the s8 doesn't get sign-extended! */
X
X switch (display)
X {
@@ -496,7 +485,7 @@
X
X default:
X
- acpi_os_printf ("%02_x ",
+ acpi_os_printf ("%02X ",
X *((u8 *) &buffer[i + j]));
X j += 1;
X break;
@@ -506,7 +495,7 @@
X
X MOVE_UNALIGNED16_TO_32 (&temp32,
X &buffer[i + j]);
- acpi_os_printf ("%04_x ", temp32);
+ acpi_os_printf ("%04X ", temp32);
X j += 2;
X break;
X
@@ -515,7 +504,7 @@
X
X MOVE_UNALIGNED32_TO_32 (&temp32,
X &buffer[i + j]);
- acpi_os_printf ("%08_x ", temp32);
+ acpi_os_printf ("%08X ", temp32);
X j += 4;
X break;
X
@@ -524,11 +513,11 @@
X
X MOVE_UNALIGNED32_TO_32 (&temp32,
X &buffer[i + j]);
- acpi_os_printf ("%08_x", temp32);
+ acpi_os_printf ("%08X", temp32);
X
X MOVE_UNALIGNED32_TO_32 (&temp32,
X &buffer[i + j + 4]);
- acpi_os_printf ("%08_x ", temp32);
+ acpi_os_printf ("%08X ", temp32);
X j += 8;
X break;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/common/cmdelete.c linux/drivers/acpi/common/cmdelete.c
--- v2.4.0-test8/linux/drivers/acpi/common/cmdelete.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/common/cmdelete.c Fri Sep 15 14:30:29 2000
@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *
X * Module Name: cmdelete - object deletion and reference count utilities
+ * $Revision: 53 $
X *
X *****************************************************************************/
X
@@ -25,13 +25,13 @@
X
X
X #include "acpi.h"
-#include "interp.h"
-#include "namesp.h"
-#include "tables.h"
-#include "parser.h"
+#include "acinterp.h"
+#include "acnamesp.h"
+#include "actables.h"
+#include "acparser.h"
X
X #define _COMPONENT MISCELLANEOUS
- MODULE_NAME ("cmdelete");
+ MODULE_NAME ("cmdelete")
X
X
X /******************************************************************************
@@ -49,7 +49,7 @@
X
X void
X acpi_cm_delete_internal_obj (
- ACPI_OBJECT_INTERNAL *object)
+ ACPI_OPERAND_OBJECT *object)
X {
X void *obj_pointer = NULL;
X
@@ -110,14 +110,7 @@
X
X case ACPI_TYPE_METHOD:
X
- /* Delete parse tree if it exists */
-
- if (object->method.parser_op) {
- acpi_ps_delete_parse_tree (object->method.parser_op);
- object->method.parser_op = NULL;
- }
-
- /* Delete semaphore if it exists */
+ /* Delete the method semaphore if it exists */
X
X if (object->method.semaphore) {
X acpi_os_delete_semaphore (object->method.semaphore);
@@ -146,7 +139,7 @@
X /* Only delete the object if it was dynamically allocated */
X
X
- if (!(object->common.flags & AO_STATIC_ALLOCATION)) {
+ if (!(object->common.flags & AOPOBJ_STATIC_ALLOCATION)) {
X acpi_cm_delete_object_desc (object);
X
X }
@@ -170,9 +163,9 @@
X
X ACPI_STATUS
X acpi_cm_delete_internal_object_list (
- ACPI_OBJECT_INTERNAL **obj_list)
+ ACPI_OPERAND_OBJECT **obj_list)
X {
- ACPI_OBJECT_INTERNAL **internal_obj;
+ ACPI_OPERAND_OBJECT **internal_obj;
X
X
X /* Walk the null-terminated internal list */
@@ -220,8 +213,8 @@
X
X void
X acpi_cm_update_ref_count (
- ACPI_OBJECT_INTERNAL *object,
- s32 action)
+ ACPI_OPERAND_OBJECT *object,
+ u32 action)
X {
X u16 count;
X u16 new_count;
@@ -308,23 +301,23 @@
X * DESCRIPTION: Increment the object reference count
X *
X * Object references are incremented when:
- * 1) An object is added as a value in an Name Table Entry (NTE)
+ * 1) An object is attached to a Node (namespace object)
X * 2) An object is copied (all subobjects must be incremented)
X *
X * Object references are decremented when:
- * 1) An object is removed from an NTE
+ * 1) An object is detached from an Node
X *
X ******************************************************************************/
X
X ACPI_STATUS
X acpi_cm_update_object_reference (
- ACPI_OBJECT_INTERNAL *object,
+ ACPI_OPERAND_OBJECT *object,
X u16 action)
X {
X ACPI_STATUS status;
X u32 i;
- ACPI_OBJECT_INTERNAL *next;
- ACPI_OBJECT_INTERNAL *new;
+ ACPI_OPERAND_OBJECT *next;
+ ACPI_OPERAND_OBJECT *new;
X ACPI_GENERIC_STATE *state_list = NULL;
X ACPI_GENERIC_STATE *state;
X
@@ -381,9 +374,9 @@
X
X /* Must walk list of address handlers */
X
- next = object->addr_handler.link;
+ next = object->addr_handler.next;
X while (next) {
- new = next->addr_handler.link;
+ new = next->addr_handler.next;
X acpi_cm_update_ref_count (next, action);
X
X next = new;
@@ -512,7 +505,7 @@
X
X void
X acpi_cm_add_reference (
- ACPI_OBJECT_INTERNAL *object)
+ ACPI_OPERAND_OBJECT *object)
X {
X
X
@@ -549,7 +542,7 @@
X
X void
X acpi_cm_remove_reference (
- ACPI_OBJECT_INTERNAL *object)
+ ACPI_OPERAND_OBJECT *object)
X {
X
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/common/cmeval.c linux/drivers/acpi/common/cmeval.c
--- v2.4.0-test8/linux/drivers/acpi/common/cmeval.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/common/cmeval.c Fri Sep 15 14:30:29 2000
@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *
X * Module Name: cmeval - Object evaluation
+ * $Revision: 14 $
X *
X *****************************************************************************/
X
@@ -25,19 +25,19 @@
X
X
X #include "acpi.h"
-#include "namesp.h"
-#include "interp.h"
+#include "acnamesp.h"
+#include "acinterp.h"
X
X
X #define _COMPONENT MISCELLANEOUS
- MODULE_NAME ("cmeval");
+ MODULE_NAME ("cmeval")
X
X
X /****************************************************************************
X *
X * FUNCTION: Acpi_cm_evaluate_numeric_object
X *
- * PARAMETERS: Acpi_device - NTE for the device
+ * PARAMETERS: Device_node - Node for the device
X * *Address - Where the value is returned
X *
X * RETURN: Status
@@ -51,17 +51,17 @@
X
X ACPI_STATUS
X acpi_cm_evaluate_numeric_object (
- char *object_name,
- ACPI_NAMED_OBJECT *acpi_device,
+ NATIVE_CHAR *object_name,
+ ACPI_NAMESPACE_NODE *device_node,
X u32 *address)
X {
- ACPI_OBJECT_INTERNAL *obj_desc;
+ ACPI_OPERAND_OBJECT *obj_desc;
X ACPI_STATUS status;
X
X
X /* Execute the method */
X
- status = acpi_ns_evaluate_relative (acpi_device, object_name, NULL, &obj_desc);
+ status = acpi_ns_evaluate_relative (device_node, object_name, NULL, &obj_desc);
X if (ACPI_FAILURE (status)) {
X
X return (status);
@@ -99,7 +99,7 @@
X *
X * FUNCTION: Acpi_cm_execute_HID
X *
- * PARAMETERS: Acpi_device - NTE for the device
+ * PARAMETERS: Device_node - Node for the device
X * *Hid - Where the HID is returned
X *
X * RETURN: Status
@@ -113,16 +113,16 @@
X
X ACPI_STATUS
X acpi_cm_execute_HID (
- ACPI_NAMED_OBJECT *acpi_device,
+ ACPI_NAMESPACE_NODE *device_node,
X DEVICE_ID *hid)
X {
- ACPI_OBJECT_INTERNAL *obj_desc;
+ ACPI_OPERAND_OBJECT *obj_desc;
X ACPI_STATUS status;
X
X
X /* Execute the method */
X
- status = acpi_ns_evaluate_relative (acpi_device,
+ status = acpi_ns_evaluate_relative (device_node,
X METHOD_NAME__HID, NULL, &obj_desc);
X if (ACPI_FAILURE (status)) {
X
@@ -176,7 +176,7 @@
X *
X * FUNCTION: Acpi_cm_execute_UID
X *
- * PARAMETERS: Acpi_device - NTE for the device
+ * PARAMETERS: Device_node - Node for the device
X * *Uid - Where the UID is returned
X *
X * RETURN: Status
@@ -190,16 +190,16 @@
X
X ACPI_STATUS
X acpi_cm_execute_UID (
- ACPI_NAMED_OBJECT *acpi_device,
+ ACPI_NAMESPACE_NODE *device_node,
X DEVICE_ID *uid)
X {
- ACPI_OBJECT_INTERNAL *obj_desc;
+ ACPI_OPERAND_OBJECT *obj_desc;
X ACPI_STATUS status;
X
X
X /* Execute the method */
X
- status = acpi_ns_evaluate_relative (acpi_device,
+ status = acpi_ns_evaluate_relative (device_node,
X METHOD_NAME__UID, NULL, &obj_desc);
X if (ACPI_FAILURE (status)) {
X
@@ -251,7 +251,7 @@
X *
X * FUNCTION: Acpi_cm_execute_STA
X *
- * PARAMETERS: Acpi_device - NTE for the device
+ * PARAMETERS: Device_node - Node for the device
X * *Flags - Where the status flags are returned
X *
X * RETURN: Status
@@ -265,16 +265,16 @@
X
X ACPI_STATUS
X acpi_cm_execute_STA (
- ACPI_NAMED_OBJECT *acpi_device,
+ ACPI_NAMESPACE_NODE *device_node,
X u32 *flags)
X {
- ACPI_OBJECT_INTERNAL *obj_desc;
+ ACPI_OPERAND_OBJECT *obj_desc;
X ACPI_STATUS status;
X
X
X /* Execute the method */
X
- status = acpi_ns_evaluate_relative (acpi_device,
+ status = acpi_ns_evaluate_relative (device_node,
X METHOD_NAME__STA, NULL, &obj_desc);
X if (ACPI_FAILURE (status)) {
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/common/cmglobal.c linux/drivers/acpi/common/cmglobal.c
--- v2.4.0-test8/linux/drivers/acpi/common/cmglobal.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/common/cmglobal.c Fri Sep 15 14:30:29 2000
@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *
X * Module Name: cmglobal - Global variables for the ACPI subsystem
+ * $Revision: 99 $
X *
X *****************************************************************************/
X
@@ -26,13 +26,13 @@
X #define DEFINE_ACPI_GLOBALS
X
X #include "acpi.h"
-#include "events.h"
-#include "namesp.h"
-#include "interp.h"
+#include "acevents.h"
+#include "acnamesp.h"
+#include "acinterp.h"
X
X
X #define _COMPONENT MISCELLANEOUS
- MODULE_NAME ("cmglobal");
+ MODULE_NAME ("cmglobal")
X
X
X /******************************************************************************
@@ -126,31 +126,25 @@
X NSP_NEWSCOPE | NSP_LOCAL, /* 13 Thermal */
X NSP_NORMAL, /* 14 Buffer_field */
X NSP_NORMAL, /* 15 Ddb_handle */
- NSP_NORMAL, /* 16 reserved */
- NSP_NORMAL, /* 17 reserved */
- NSP_NORMAL, /* 18 reserved */
- NSP_NORMAL, /* 19 reserved */
- NSP_NORMAL, /* 20 reserved */
- NSP_NORMAL, /* 21 reserved */
- NSP_NORMAL, /* 22 reserved */
- NSP_NORMAL, /* 23 reserved */
- NSP_NORMAL, /* 24 reserved */
- NSP_NORMAL, /* 25 Def_field */
- NSP_NORMAL, /* 26 Bank_field */
- NSP_NORMAL, /* 27 Index_field */
- NSP_NORMAL, /* 28 Def_field_defn */
- NSP_NORMAL, /* 29 Bank_field_defn */
- NSP_NORMAL, /* 30 Index_field_defn */
- NSP_NORMAL, /* 31 If */
- NSP_NORMAL, /* 32 Else */
- NSP_NORMAL, /* 33 While */
- NSP_NEWSCOPE, /* 34 Scope */
- NSP_LOCAL, /* 35 Def_any */
- NSP_NORMAL, /* 36 Reference */
- NSP_NORMAL, /* 37 Alias */
- NSP_NORMAL, /* 38 Notify */
- NSP_NORMAL, /* 39 Address Handler */
- NSP_NORMAL /* 40 Invalid */
+ NSP_NORMAL, /* 16 Debug Object */
+ NSP_NORMAL, /* 17 Def_field */
+ NSP_NORMAL, /* 18 Bank_field */
+ NSP_NORMAL, /* 19 Index_field */
+ NSP_NORMAL, /* 20 Reference */
+ NSP_NORMAL, /* 21 Alias */
+ NSP_NORMAL, /* 22 Notify */
+ NSP_NORMAL, /* 23 Address Handler */
+ NSP_NORMAL, /* 24 Def_field_defn */
+ NSP_NORMAL, /* 25 Bank_field_defn */
+ NSP_NORMAL, /* 26 Index_field_defn */
+ NSP_NORMAL, /* 27 If */
+ NSP_NORMAL, /* 28 Else */
+ NSP_NORMAL, /* 29 While */
+ NSP_NEWSCOPE, /* 30 Scope */
+ NSP_LOCAL, /* 31 Def_any */
+ NSP_NORMAL, /* 32 Method Arg */
+ NSP_NORMAL, /* 33 Method Local */
+ NSP_NORMAL /* 34 Invalid */
X };
X
X
@@ -204,11 +198,11 @@
X if ((type < INTERNAL_TYPE_BEGIN) ||
X (type > INTERNAL_TYPE_MAX))
X {
- return FALSE;
+ return (FALSE);
X }
X }
X
- return TRUE;
+ return (TRUE);
X }
X
X
@@ -224,16 +218,60 @@
X *
X ****************************************************************************/
X
-char *
+NATIVE_CHAR *
X acpi_cm_format_exception (
X ACPI_STATUS status)
X {
+ NATIVE_CHAR *exception = "UNKNOWN_STATUS";
+ ACPI_STATUS sub_status;
+
+
+ sub_status = (status & ~AE_CODE_MASK);
+
X
- if (status > ACPI_MAX_STATUS) {
- return "UNKNOWN_STATUS";
+ switch (status & AE_CODE_MASK)
+ {
+ case AE_CODE_ENVIRONMENTAL:
+
+ if (sub_status <= AE_CODE_ENV_MAX) {
+ exception = acpi_gbl_exception_names_env [sub_status];
+ }
+ break;
+
+ case AE_CODE_PROGRAMMER:
+
+ if (sub_status <= AE_CODE_PGM_MAX) {
+ exception = acpi_gbl_exception_names_pgm [sub_status -1];
+ }
+ break;
+
+ case AE_CODE_ACPI_TABLES:
+
+ if (sub_status <= AE_CODE_TBL_MAX) {
+ exception = acpi_gbl_exception_names_tbl [sub_status -1];
+ }
+ break;
+
+ case AE_CODE_AML:
+
+ if (sub_status <= AE_CODE_AML_MAX) {
+ exception = acpi_gbl_exception_names_aml [sub_status -1];
+ }
+ break;
+
+ case AE_CODE_CONTROL:
+
+ if (sub_status <= AE_CODE_CTRL_MAX) {
+ exception = acpi_gbl_exception_names_ctrl [sub_status -1];
+ }
+ break;
+
+ default:
+ break;
X }
X
- return (acpi_gbl_exception_names [status]);
+
+ return (exception);
X }
X
X
@@ -389,6 +427,11 @@
X acpi_gbl_parse_cache_requests = 0;
X acpi_gbl_parse_cache_hits = 0;
X
+ acpi_gbl_ext_parse_cache = NULL;
+ acpi_gbl_ext_parse_cache_depth = 0;
+ acpi_gbl_ext_parse_cache_requests = 0;
+ acpi_gbl_ext_parse_cache_hits = 0;
+
X acpi_gbl_object_cache = NULL;
X acpi_gbl_object_cache_depth = 0;
X acpi_gbl_object_cache_requests = 0;
@@ -402,7 +445,7 @@
X /* Interpreter */
X
X acpi_gbl_buf_seq = 0;
- acpi_gbl_named_object_err = FALSE;
+ acpi_gbl_node_err = FALSE;
X
X /* Parser */
X
@@ -418,18 +461,15 @@
X
X /* Namespace */
X
- acpi_gbl_root_name_table.next_table = NULL;
- acpi_gbl_root_name_table.parent_entry = NULL;
- acpi_gbl_root_name_table.parent_table = NULL;
-
- acpi_gbl_root_object = acpi_gbl_root_name_table.entries;
-
- acpi_gbl_root_object->name = ACPI_ROOT_NAME;
- acpi_gbl_root_object->data_type = ACPI_DESC_TYPE_NAMED;
- acpi_gbl_root_object->type = ACPI_TYPE_ANY;
- acpi_gbl_root_object->this_index = 0;
- acpi_gbl_root_object->child_table = NULL;
- acpi_gbl_root_object->object = NULL;
+ acpi_gbl_root_node = NULL;
+
+ acpi_gbl_root_node_struct.name = ACPI_ROOT_NAME;
+ acpi_gbl_root_node_struct.data_type = ACPI_DESC_TYPE_NAMED;
+ acpi_gbl_root_node_struct.type = ACPI_TYPE_ANY;
+ acpi_gbl_root_node_struct.child = NULL;
+ acpi_gbl_root_node_struct.peer = NULL;
+ acpi_gbl_root_node_struct.object = NULL;
+ acpi_gbl_root_node_struct.flags = ANOBJ_END_OF_PEER_LIST;
X
X /* Memory allocation metrics - compiled out in non-debug mode. */
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/common/cminit.c linux/drivers/acpi/common/cminit.c
--- v2.4.0-test8/linux/drivers/acpi/common/cminit.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/common/cminit.c Fri Sep 15 14:30:29 2000
@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *
X * Module Name: cminit - Common ACPI subsystem initialization
+ * $Revision: 79 $
X *
X *****************************************************************************/
X
@@ -25,14 +25,14 @@
X
X
X #include "acpi.h"
-#include "hardware.h"
-#include "namesp.h"
-#include "events.h"
-#include "parser.h"
-#include "dispatch.h"
+#include "achware.h"
+#include "acnamesp.h"
+#include "acevents.h"
+#include "acparser.h"
+#include "acdispat.h"
X
X #define _COMPONENT MISCELLANEOUS
- MODULE_NAME ("cminit");
+ MODULE_NAME ("cminit")
X
X
X /*******************************************************************************
@@ -52,7 +52,7 @@
X
X void
X acpi_cm_facp_register_error (
- char *register_name,
+ NATIVE_CHAR *register_name,
X u32 value)
X {
X
@@ -77,7 +77,7 @@
X acpi_cm_hardware_initialize (void)
X {
X ACPI_STATUS status = AE_OK;
- s32 index;
+ u32 index;
X
X
X /* Are we running on the actual hardware */
@@ -351,8 +351,9 @@
X acpi_ps_delete_parse_cache ();
X
X /* Debug only - display leftover memory allocation, if any */
-
+#ifdef ENABLE_DEBUGGER
X acpi_cm_dump_current_allocations (ACPI_UINT32_MAX, NULL);
+#endif
X
X BREAKPOINT3;
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/common/cmobject.c linux/drivers/acpi/common/cmobject.c
--- v2.4.0-test8/linux/drivers/acpi/common/cmobject.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/common/cmobject.c Fri Sep 15 14:30:29 2000
@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *
X * Module Name: cmobject - ACPI object create/delete/size/cache routines
+ * $Revision: 27 $
X *
X *****************************************************************************/
X
@@ -25,14 +25,14 @@
X
X
X #include "acpi.h"
-#include "interp.h"
-#include "namesp.h"
-#include "tables.h"
+#include "acinterp.h"
+#include "acnamesp.h"
+#include "actables.h"
X #include "amlcode.h"
X
X
X #define _COMPONENT MISCELLANEOUS
- MODULE_NAME ("cmobject");
+ MODULE_NAME ("cmobject")
X
X
X /******************************************************************************
@@ -57,14 +57,14 @@
X *
X ******************************************************************************/
X
-ACPI_OBJECT_INTERNAL *
+ACPI_OPERAND_OBJECT *
X _cm_create_internal_object (
- char *module_name,
- s32 line_number,
- s32 component_id,
+ NATIVE_CHAR *module_name,
+ u32 line_number,
+ u32 component_id,
X OBJECT_TYPE_INTERNAL type)
X {
- ACPI_OBJECT_INTERNAL *object;
+ ACPI_OPERAND_OBJECT *object;
X
X
X /* Allocate the raw object descriptor */
@@ -79,7 +79,6 @@
X /* Save the object type in the object descriptor */
X
X object->common.type = type;
- object->common.size = (u8) sizeof (ACPI_OBJECT_INTERNAL);
X
X /* Init the reference count */
X
@@ -88,10 +87,6 @@
X /* Any per-type initialization should go here */
X
X
- /* Memory allocation metrics - compiled out in non debug mode. */
-
- INCREMENT_OBJECT_METRICS (sizeof (ACPI_OBJECT_INTERNAL));
-
X return (object);
X }
X
@@ -102,7 +97,7 @@
X *
X * PARAMETERS: Operand - Object to be validated
X *
- * RETURN: Validate a pointer to be an ACPI_OBJECT_INTERNAL
+ * RETURN: Validate a pointer to be an ACPI_OPERAND_OBJECT
X *
X *****************************************************************************/
X
@@ -114,13 +109,13 @@
X /* Check for a null pointer */
X
X if (!object) {
- return FALSE;
+ return (FALSE);
X }
X
X /* Check for a pointer within one of the ACPI tables */
X
X if (acpi_tb_system_table_pointer (object)) {
- return FALSE;
+ return (FALSE);
X }
X
X /* Check the descriptor type field */
@@ -131,13 +126,13 @@
X
X
X
- return FALSE;
+ return (FALSE);
X }
X
X
- /* The object appears to be a valid ACPI_OBJECT_INTERNAL */
+ /* The object appears to be a valid ACPI_OPERAND_OBJECT */
X
- return TRUE;
+ return (TRUE);
X }
X
X
@@ -159,11 +154,11 @@
X
X void *
X _cm_allocate_object_desc (
- char *module_name,
- s32 line_number,
- s32 component_id)
+ NATIVE_CHAR *module_name,
+ u32 line_number,
+ u32 component_id)
X {
- ACPI_OBJECT_INTERNAL *object;
+ ACPI_OPERAND_OBJECT *object;
X
X
X acpi_cm_acquire_mutex (ACPI_MTX_CACHES);
@@ -176,8 +171,8 @@
X /* There is an object available, use it */
X
X object = acpi_gbl_object_cache;
- acpi_gbl_object_cache = object->common.next;
- object->common.next = NULL;
+ acpi_gbl_object_cache = object->cache.next;
+ object->cache.next = NULL;
X
X acpi_gbl_object_cache_hits++;
X acpi_gbl_object_cache_depth--;
@@ -192,9 +187,8 @@
X
X /* Attempt to allocate new descriptor */
X
- object = _cm_callocate (sizeof (ACPI_OBJECT_INTERNAL), component_id,
+ object = _cm_callocate (sizeof (ACPI_OPERAND_OBJECT), component_id,
X module_name, line_number);
-
X if (!object) {
X /* Allocation failed */
X
@@ -203,6 +197,10 @@
X
X return (NULL);
X }
+
+ /* Memory allocation metrics - compiled out in non debug mode. */
+
+ INCREMENT_OBJECT_METRICS (sizeof (ACPI_OPERAND_OBJECT));
X }
X
X /* Mark the descriptor type */
@@ -227,19 +225,19 @@
X
X void
X acpi_cm_delete_object_desc (
- ACPI_OBJECT_INTERNAL *object)
+ ACPI_OPERAND_OBJECT *object)
X {
X
X
- /* Object must be an ACPI_OBJECT_INTERNAL */
+ /* Make sure that the object isn't already in the cache */
X
- if (object->common.data_type != ACPI_DESC_TYPE_INTERNAL) {
+ if (object->common.data_type == (ACPI_DESC_TYPE_INTERNAL | ACPI_CACHED_OBJECT)) {
X return;
X }
X
- /* Make sure that the object isn't already in the cache */
+ /* Object must be an ACPI_OPERAND_OBJECT */
X
- if (object->common.next) {
+ if (object->common.data_type != ACPI_DESC_TYPE_INTERNAL) {
X return;
X }
X
@@ -251,7 +249,7 @@
X * Memory allocation metrics. Call the macro here since we only
X * care about dynamically allocated objects.
X */
- DECREMENT_OBJECT_METRICS (acpi_gbl_object_cache->common.size);
+ DECREMENT_OBJECT_METRICS (sizeof (ACPI_OPERAND_OBJECT));
X
X acpi_cm_free (object);
X return;
@@ -261,17 +259,18 @@
X
X /* Clear the entire object. This is important! */
X
- MEMSET (object, 0, sizeof (ACPI_OBJECT_INTERNAL));
- object->common.data_type = ACPI_DESC_TYPE_INTERNAL;
+ MEMSET (object, 0, sizeof (ACPI_OPERAND_OBJECT));
+ object->common.data_type = ACPI_DESC_TYPE_INTERNAL | ACPI_CACHED_OBJECT;
X
X /* Put the object at the head of the global cache list */
X
- object->common.next = acpi_gbl_object_cache;
+ object->cache.next = acpi_gbl_object_cache;
X acpi_gbl_object_cache = object;
X acpi_gbl_object_cache_depth++;
X
X
X acpi_cm_release_mutex (ACPI_MTX_CACHES);
+ return;
X }
X
X
@@ -292,7 +291,7 @@
X acpi_cm_delete_object_cache (
X void)
X {
- ACPI_OBJECT_INTERNAL *next;
+ ACPI_OPERAND_OBJECT *next;
X
X
X /* Traverse the global cache list */
@@ -300,17 +299,18 @@
X while (acpi_gbl_object_cache) {
X /* Delete one cached state object */
X
- next = acpi_gbl_object_cache->common.next;
- acpi_gbl_object_cache->common.next = NULL;
+ next = acpi_gbl_object_cache->cache.next;
+ acpi_gbl_object_cache->cache.next = NULL;
X
X /*
X * Memory allocation metrics. Call the macro here since we only
X * care about dynamically allocated objects.
X */
- DECREMENT_OBJECT_METRICS (acpi_gbl_object_cache->common.size);
+ DECREMENT_OBJECT_METRICS (sizeof (ACPI_OPERAND_OBJECT));
X
X acpi_cm_free (acpi_gbl_object_cache);
X acpi_gbl_object_cache = next;
+ acpi_gbl_object_cache_depth--;
X }
X
X return;
@@ -333,7 +333,7 @@
X
X void
X acpi_cm_init_static_object (
- ACPI_OBJECT_INTERNAL *obj_desc)
+ ACPI_OPERAND_OBJECT *obj_desc)
X {
X
X
@@ -345,12 +345,12 @@
X /*
X * Clear the entire descriptor
X */
- MEMSET ((void *) obj_desc, 0, sizeof (ACPI_OBJECT_INTERNAL));
+ MEMSET ((void *) obj_desc, 0, sizeof (ACPI_OPERAND_OBJECT));
X
X
X /*
X * Initialize the header fields
- * 1) This is an ACPI_OBJECT_INTERNAL descriptor
+ * 1) This is an ACPI_OPERAND_OBJECT descriptor
X * 2) The size is the full object (worst case)
X * 3) The flags field indicates static allocation
X * 4) Reference count starts at one (not really necessary since the
@@ -358,8 +358,7 @@
X */
X
X obj_desc->common.data_type = ACPI_DESC_TYPE_INTERNAL;
- obj_desc->common.size = sizeof (ACPI_OBJECT_INTERNAL);
- obj_desc->common.flags = AO_STATIC_ALLOCATION;
+ obj_desc->common.flags = AOPOBJ_STATIC_ALLOCATION;
X obj_desc->common.reference_count = 1;


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 019'
echo 'File patch-2.4.0-test9 is continued in part 020'
echo "020" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part018

#!/bin/sh -x
# this is part 018 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 018; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ * of hardware registers that track the sensor count for the X-Y movement
+ * and another register holding the button state. On every VSYNC interrupt
+ * we read the complete state and then work out if something has changed.
X */
X #include <linux/module.h>
X #include <linux/sched.h>
@@ -17,7 +21,7 @@
X #include <asm/hardware.h>
X #include <asm/irq.h>


X #include <asm/io.h>
-#include <asm/iomd.h>
+#include <asm/hardware/iomd.h>
X

X #include "../../char/busmouse.h"
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/char/pcf8583.c linux/drivers/acorn/char/pcf8583.c
--- v2.4.0-test8/linux/drivers/acorn/char/pcf8583.c Sun Feb 6 17:45:25 2000
+++ linux/drivers/acorn/char/pcf8583.c Mon Sep 18 15:15:21 2000
@@ -1,11 +1,14 @@
X /*
- * linux/drivers/i2c/pcf8583.c
+ * linux/drivers/acorn/char/pcf8583.c


X *
- * Copyright (C) 2000 Russell King
+ * Copyright (C) 2000 Russell King
X *

- * Driver for PCF8583 RTC & RAM chip


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Driver for PCF8583 RTC & RAM chip
X */
-
X #include <linux/i2c.h>
X #include <linux/malloc.h>
X #include <linux/string.h>
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/char/pcf8583.h linux/drivers/acorn/char/pcf8583.h
--- v2.4.0-test8/linux/drivers/acorn/char/pcf8583.h Sun Feb 6 17:45:25 2000
+++ linux/drivers/acorn/char/pcf8583.h Mon Sep 18 15:15:21 2000
@@ -1,3 +1,12 @@
+/*
+ * linux/drivers/acorn/char/pcf8583.h
+ *


+ * Copyright (C) 2000 Russell King

+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

+ */
X struct rtc_tm {
X unsigned char cs;
X unsigned char secs;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/char/serial-atomwide.c linux/drivers/acorn/char/serial-atomwide.c
--- v2.4.0-test8/linux/drivers/acorn/char/serial-atomwide.c Thu Dec 2 15:41:02 1999
+++ linux/drivers/acorn/char/serial-atomwide.c Mon Sep 18 15:15:22 2000
@@ -1,14 +1,17 @@
X /*
- * linux/arch/arm/drivers/char/serial-atomwide.c
+ * linux/arch/arm/drivers/char/serial-atomwide.c
X *
- * Copyright (c) 1996 Russell King.
+ * Copyright (C) 1996 Russell King.
X *
- * Changelog:
- * 02-05-1996 RMK Created
- * 07-05-1996 RMK Altered for greater number of cards.
- * 30-07-1996 RMK Now uses generic card code.


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Changelog:
+ * 02-05-1996 RMK Created
+ * 07-05-1996 RMK Altered for greater number of cards.
+ * 30-07-1996 RMK Now uses generic card code.
X */
-
X #define MY_CARD_LIST { MANU_ATOMWIDE, PROD_ATOMWIDE_3PSERIAL }
X #define MY_NUMPORTS 3
X #define MY_BAUD_BASE (7372800 / 16)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/char/serial-card.c linux/drivers/acorn/char/serial-card.c
--- v2.4.0-test8/linux/drivers/acorn/char/serial-card.c Thu Dec 2 15:41:02 1999
+++ linux/drivers/acorn/char/serial-card.c Mon Sep 18 15:15:22 2000
@@ -1,7 +1,11 @@
X /*
- * linux/arch/arm/drivers/char/serial-card.c
+ * linux/drivers/acorn/char/serial-card.c
X *
- * Copyright (c) 1996-1999 Russell King.
+ * Copyright (C) 1996-1999 Russell King.


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

X *
X * A generic handler of serial expansion cards that use 16550s or
X * the like.
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/char/serial-dualsp.c linux/drivers/acorn/char/serial-dualsp.c
--- v2.4.0-test8/linux/drivers/acorn/char/serial-dualsp.c Thu Dec 2 15:41:02 1999
+++ linux/drivers/acorn/char/serial-dualsp.c Mon Sep 18 15:15:22 2000
@@ -1,10 +1,14 @@
X /*
- * linux/arch/arm/drivers/char/serial-dualsp.c
+ * linux/drivers/acorn/char/serial-dualsp.c
X *
- * Copyright (c) 1996 Russell King.
+ * Copyright (C) 1996 Russell King.
X *
- * Changelog:
- * 30-07-1996 RMK Created


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Changelog:
+ * 30-07-1996 RMK Created
X */
X #define MY_CARD_LIST { MANU_SERPORT, PROD_SERPORT_DSPORT }
X #define MY_NUMPORTS 2
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/net/ether1.c linux/drivers/acorn/net/ether1.c
--- v2.4.0-test8/linux/drivers/acorn/net/ether1.c Tue Jul 11 11:12:23 2000
+++ linux/drivers/acorn/net/ether1.c Mon Sep 18 15:15:22 2000
@@ -1,13 +1,14 @@
X /*
- * linux/arch/arm/drivers/net/ether1.c
+ * linux/drivers/acorn/net/ether1.c
X *
- * (C) Copyright 1996-2000 Russell King
+ * Copyright (C) 1996-2000 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

+ *
+ * Acorn ether1 driver (82586 chip) for Acorn machines
X *
- * Acorn ether1 driver (82586 chip)
- * for Acorn machines
- */
-
-/*
X * We basically keep two queues in the cards memory - one for transmit
X * and one for receive. Each has a head and a tail. The head is where
X * we/the chip adds packets to be transmitted/received, and the tail
@@ -15,9 +16,7 @@
X * Both of these queues are circular, and since the chip is running
X * all the time, we have to be careful when we modify the pointers etc
X * so that the buffer memory contents is valid all the time.
- */
-
-/*
+ *
X * Change log:
X * 1.00 RMK Released
X * 1.01 RMK 19/03/1996 Transfers the last odd byte onto/off of the card now.
@@ -132,135 +131,128 @@
X * This routine is essentially an optimised memcpy from the card's
X * onboard RAM to kernel memory.
X */
-static inline void *
-ether1_inswb (unsigned int addr, void *data, unsigned int len)
-{
- int used;
-
- addr = ioaddr(addr);
-
- __asm__ __volatile__(
- "subs %3, %3, #2
- bmi 2f
-1: ldr %0, [%1], #4
- strb %0, [%2], #1
- mov %0, %0, lsr #8
- strb %0, [%2], #1
- subs %3, %3, #2
- bmi 2f
- ldr %0, [%1], #4
- strb %0, [%2], #1
- mov %0, %0, lsr #8
- strb %0, [%2], #1
- subs %3, %3, #2
- bmi 2f
- ldr %0, [%1], #4
- strb %0, [%2], #1
- mov %0, %0, lsr #8
- strb %0, [%2], #1
- subs %3, %3, #2
- bmi 2f
- ldr %0, [%1], #4
- strb %0, [%2], #1
- mov %0, %0, lsr #8
- strb %0, [%2], #1
- subs %3, %3, #2
- bpl 1b
-2: adds %3, %3, #1
- ldreqb %0, [%1]
- streqb %0, [%2]"
- : "=&r" (used), "=&r" (addr), "=&r" (data), "=&r" (len)
- : "1" (addr), "2" (data), "3" (len));
-
- return data;
-}
-
-static inline void *
-ether1_outswb (unsigned int addr, void *data, unsigned int len)
-{
- int used;
-
- addr = ioaddr(addr);
-
- __asm__ __volatile__(
- "subs %3, %3, #2
- bmi 2f
-1: ldr %0, [%2], #2
- mov %0, %0, lsl #16
- orr %0, %0, %0, lsr #16
- str %0, [%1], #4
- subs %3, %3, #2
- bmi 2f
- ldr %0, [%2], #2
- mov %0, %0, lsl #16
- orr %0, %0, %0, lsr #16
- str %0, [%1], #4
- subs %3, %3, #2
- bmi 2f
- ldr %0, [%2], #2
- mov %0, %0, lsl #16
- orr %0, %0, %0, lsr #16
- str %0, [%1], #4
- subs %3, %3, #2
- bmi 2f
- ldr %0, [%2], #2
- mov %0, %0, lsl #16
- orr %0, %0, %0, lsr #16
- str %0, [%1], #4
- subs %3, %3, #2
- bpl 1b
-2: adds %3, %3, #1
- ldreqb %0, [%2]
- streqb %0, [%1]"
- : "=&r" (used), "=&r" (addr), "=&r" (data), "=&r" (len)
- : "1" (addr), "2" (data), "3" (len));
-
- return data;
-}
-
-
X static void
X ether1_writebuffer (struct net_device *dev, void *data, unsigned int start, unsigned int length)
X {
- unsigned int page, thislen, offset;
+ unsigned int page, thislen, offset, addr;
X
X offset = start & 4095;
+ page = start >> 12;
+ addr = ioaddr(ETHER1_RAM + (offset >> 1));
X
- for (page = start >> 12; length; page++) {
- outb (page, REG_PAGE);
- if (offset + length > 4096) {
- length -= 4096 - offset;
- thislen = 4096 - offset;
- } else {
- thislen = length;
- length = 0;
- }
-
- data = ether1_outswb (ETHER1_RAM + (offset >> 1), data, thislen);
- offset = 0;
- }
+ if (offset + length > 4096)
+ thislen = 4096 - offset;
+ else
+ thislen = length;
+
+ do {
+ int used;
+
+ outb(page, REG_PAGE);
+ length -= thislen;
+
+ __asm__ __volatile__(
+ "subs %3, %3, #2
+ bmi 2f
+1: ldr %0, [%1], #2
+ mov %0, %0, lsl #16
+ orr %0, %0, %0, lsr #16
+ str %0, [%2], #4
+ subs %3, %3, #2
+ bmi 2f
+ ldr %0, [%1], #2
+ mov %0, %0, lsl #16
+ orr %0, %0, %0, lsr #16
+ str %0, [%2], #4
+ subs %3, %3, #2
+ bmi 2f
+ ldr %0, [%1], #2
+ mov %0, %0, lsl #16
+ orr %0, %0, %0, lsr #16
+ str %0, [%2], #4
+ subs %3, %3, #2
+ bmi 2f
+ ldr %0, [%1], #2
+ mov %0, %0, lsl #16
+ orr %0, %0, %0, lsr #16
+ str %0, [%2], #4
+ subs %3, %3, #2
+ bpl 1b
+2: adds %3, %3, #1
+ ldreqb %0, [%1]
+ streqb %0, [%2]"
+ : "=&r" (used), "=&r" (data)
+ : "r" (addr), "r" (thislen), "1" (data));
+
+ addr = ioaddr(ETHER1_RAM);
+
+ thislen = length;
+ if (thislen > 4096)
+ thislen = 4096;
+ page++;
+ } while (thislen);


X }
X
X static void

X ether1_readbuffer (struct net_device *dev, void *data, unsigned int start, unsigned int length)
X {
- unsigned int page, thislen, offset;
+ unsigned int page, thislen, offset, addr;
X
X offset = start & 4095;
+ page = start >> 12;
+ addr = ioaddr(ETHER1_RAM + (offset >> 1));
X
- for (page = start >> 12; length; page++) {
- outb (page, REG_PAGE);
- if (offset + length > 4096) {
- length -= 4096 - offset;
- thislen = 4096 - offset;
- } else {
- thislen = length;
- length = 0;
- }
-
- data = ether1_inswb (ETHER1_RAM + (offset >> 1), data, thislen);
- offset = 0;
- }
+ if (offset + length > 4096)
+ thislen = 4096 - offset;
+ else
+ thislen = length;
+
+ do {
+ int used;
+
+ outb(page, REG_PAGE);
+ length -= thislen;
+
+ __asm__ __volatile__(
+ "subs %3, %3, #2
+ bmi 2f
+1: ldr %0, [%2], #4
+ strb %0, [%1], #1
+ mov %0, %0, lsr #8
+ strb %0, [%1], #1
+ subs %3, %3, #2
+ bmi 2f
+ ldr %0, [%2], #4
+ strb %0, [%1], #1
+ mov %0, %0, lsr #8
+ strb %0, [%1], #1
+ subs %3, %3, #2
+ bmi 2f
+ ldr %0, [%2], #4
+ strb %0, [%1], #1
+ mov %0, %0, lsr #8
+ strb %0, [%1], #1
+ subs %3, %3, #2
+ bmi 2f
+ ldr %0, [%2], #4
+ strb %0, [%1], #1
+ mov %0, %0, lsr #8
+ strb %0, [%1], #1
+ subs %3, %3, #2
+ bpl 1b
+2: adds %3, %3, #1
+ ldreqb %0, [%2]
+ streqb %0, [%1]"
+ : "=&r" (used), "=&r" (data)
+ : "r" (addr), "r" (thislen), "1" (data));
+
+ addr = ioaddr(ETHER1_RAM);
+
+ thislen = length;
+ if (thislen > 4096)
+ thislen = 4096;
+ page++;
+ } while (thislen);
X }
X
X static int __init
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/net/ether1.h linux/drivers/acorn/net/ether1.h
--- v2.4.0-test8/linux/drivers/acorn/net/ether1.h Tue Jul 11 11:12:23 2000
+++ linux/drivers/acorn/net/ether1.h Mon Sep 18 15:15:22 2000
@@ -1,9 +1,13 @@
X /*
- * linux/arch/arm/drivers/net/ether1.h
+ * linux/drivers/acorn/net/ether1.h
X *
- * network driver for Acorn Ether1 cards.
+ * Copyright (C) 1996 Russell King
X *
- * (c) 1996 Russell King


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Network driver for Acorn Ether1 cards.
X */
X
X #ifndef _LINUX_ether1_H
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/net/ether3.c linux/drivers/acorn/net/ether3.c
--- v2.4.0-test8/linux/drivers/acorn/net/ether3.c Tue Jul 11 11:12:23 2000
+++ linux/drivers/acorn/net/ether3.c Mon Sep 18 15:15:22 2000
@@ -1,5 +1,11 @@
X /*
- * linux/drivers/net/ether3.c
+ * linux/drivers/acorn/net/ether3.c
+ *
+ * Copyright (C) 1995-2000 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X *

X * SEEQ nq8005 ethernet driver for Acorn/ANT Ether3 card
X * for Acorn machines
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/net/ether3.h linux/drivers/acorn/net/ether3.h
--- v2.4.0-test8/linux/drivers/acorn/net/ether3.h Tue Jul 11 11:12:23 2000
+++ linux/drivers/acorn/net/ether3.h Mon Sep 18 15:15:22 2000
@@ -1,7 +1,13 @@
X /*
- * linux/drivers/net/ether3.h
+ * linux/drivers/acorn/net/ether3.h
X *
- * network driver for Acorn/ANT Ether3 cards
+ * Copyright (C) 1995-2000 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

+ *
+ * network driver for Acorn/ANT Ether3 cards
X */
X
X #ifndef _LINUX_ether3_H
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/net/etherh.c linux/drivers/acorn/net/etherh.c
--- v2.4.0-test8/linux/drivers/acorn/net/etherh.c Tue Jun 20 07:24:52 2000
+++ linux/drivers/acorn/net/etherh.c Mon Oct 2 14:22:40 2000
@@ -1,13 +1,17 @@
X /*
- * linux/drivers/net/etherh.c
+ * linux/drivers/acorn/net/etherh.c
+ *


+ * Copyright (C) 2000 Russell King

+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X *

X * NS8390 ANT etherh specific driver
X * For Acorn machines
X *
X * Thanks to I-Cubed for information on their cards.
X *
- * By Russell King.
- *
X * Changelog:
X * 08-12-1996 RMK 1.00 Created
X * RMK 1.03 Added support for EtherLan500 cards
@@ -63,7 +67,7 @@
X MODULE_AUTHOR("Russell King");
X MODULE_DESCRIPTION("i3 EtherH driver");
X
-static char *version __initdata =
+static char version[] __initdata =
X "etherh [500/600/600A] ethernet driver (c) 2000 R.M.King v1.07\n";
X
X #define ETHERH500_DATAPORT 0x200 /* MEMC */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/scsi/acornscsi-io.S linux/drivers/acorn/scsi/acornscsi-io.S
--- v2.4.0-test8/linux/drivers/acorn/scsi/acornscsi-io.S Sun Jan 11 16:45:53 1998
+++ linux/drivers/acorn/scsi/acornscsi-io.S Mon Sep 18 15:15:22 2000
@@ -1,4 +1,10 @@
-@ linux/arch/arm/drivers/scsi/acornscsi-io.S: Acorn SCSI card IO
+/*
+ * linux/drivers/acorn/scsi/acornscsi-io.S: Acorn SCSI card IO


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

+ */
X #include <linux/linkage.h>
X
X #include <asm/assembler.h>
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/scsi/acornscsi.c linux/drivers/acorn/scsi/acornscsi.c
--- v2.4.0-test8/linux/drivers/acorn/scsi/acornscsi.c Thu Nov 11 16:57:30 1999
+++ linux/drivers/acorn/scsi/acornscsi.c Mon Sep 18 15:15:22 2000
@@ -1,9 +1,13 @@
X /*
- * linux/arch/arm/drivers/scsi/acornscsi.c
+ * linux/drivers/acorn/scsi/acornscsi.c
X *
X * Acorn SCSI 3 driver
X * By R.M.King.
X *


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

+ *
X * Abandoned using the Select and Transfer command since there were
X * some nasty races between our software and the target devices that
X * were not easy to solve, and the device errata had a lot of entries
@@ -2621,7 +2625,7 @@
X {
X enum res_abort res = res_not_running;
X
- if (queue_removecmd(&host->queues.issue, SCpnt)) {
+ if (queue_remove_cmd(&host->queues.issue, SCpnt)) {
X /*
X * The command was on the issue queue, and has not been
X * issued yet. We can remove the command from the queue,
@@ -2632,7 +2636,7 @@
X printk("on issue queue ");
X //#endif
X res = res_success;
- } else if (queue_removecmd(&host->queues.disconnected, SCpnt)) {
+ } else if (queue_remove_cmd(&host->queues.disconnected, SCpnt)) {
X /*
X * The command was on the disconnected queue. Simply
X * acknowledge the abort condition, and when the target
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/scsi/acornscsi.h linux/drivers/acorn/scsi/acornscsi.h
--- v2.4.0-test8/linux/drivers/acorn/scsi/acornscsi.h Sun Apr 2 17:28:21 2000
+++ linux/drivers/acorn/scsi/acornscsi.h Mon Sep 18 15:15:22 2000
@@ -1,7 +1,13 @@
X /*
- * Acorn SCSI driver
+ * linux/drivers/acorn/scsi/acornscsi.h
X *
- * Copyright (C) 1997 Russell King
+ * Copyright (C) 1997 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

+ *
+ * Acorn SCSI driver
X */
X #ifndef ACORNSCSI_H
X #define ACORNSCSI_H
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/scsi/arxescsi.c linux/drivers/acorn/scsi/arxescsi.c
--- v2.4.0-test8/linux/drivers/acorn/scsi/arxescsi.c Fri May 12 11:21:20 2000
+++ linux/drivers/acorn/scsi/arxescsi.c Mon Sep 18 15:15:22 2000
@@ -17,7 +17,6 @@
X * (arxescsi_pseudo_dma_write)
X * 02-04-2000 RMK 0.1.1 Updated for new error handling code.
X */
-
X #include <linux/module.h>
X #include <linux/blk.h>
X #include <linux/kernel.h>
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/scsi/cumana_2.c linux/drivers/acorn/scsi/cumana_2.c
--- v2.4.0-test8/linux/drivers/acorn/scsi/cumana_2.c Sun Apr 2 17:28:22 2000
+++ linux/drivers/acorn/scsi/cumana_2.c Mon Sep 18 15:15:22 2000
@@ -1,18 +1,21 @@
X /*
- * linux/arch/arm/drivers/scsi/cumana_2.c
+ * linux/drivers/acorn/scsi/cumana_2.c
X *
- * Copyright (C) 1997-2000 Russell King
+ * Copyright (C) 1997-2000 Russell King
X *
- * Changelog:
- * 30-08-1997 RMK 0.0.0 Created, READONLY version.
- * 22-01-1998 RMK 0.0.1 Updated to 2.1.80.
- * 15-04-1998 RMK 0.0.1 Only do PIO if FAS216 will allow it.
- * 02-05-1998 RMK 0.0.2 Updated & added DMA support.
- * 27-06-1998 RMK Changed asm/delay.h to linux/delay.h
- * 18-08-1998 RMK 0.0.3 Fixed synchronous transfer depth.
- * 02-04-2000 RMK 0.0.4 Updated for new error handling code.


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Changelog:
+ * 30-08-1997 RMK 0.0.0 Created, READONLY version.
+ * 22-01-1998 RMK 0.0.1 Updated to 2.1.80.
+ * 15-04-1998 RMK 0.0.1 Only do PIO if FAS216 will allow it.
+ * 02-05-1998 RMK 0.0.2 Updated & added DMA support.
+ * 27-06-1998 RMK Changed asm/delay.h to linux/delay.h
+ * 18-08-1998 RMK 0.0.3 Fixed synchronous transfer depth.
+ * 02-04-2000 RMK 0.0.4 Updated for new error handling code.
X */
-
X #include <linux/module.h>
X #include <linux/blk.h>
X #include <linux/kernel.h>
@@ -23,6 +26,7 @@
X #include <linux/unistd.h>
X #include <linux/stat.h>
X #include <linux/delay.h>
+#include <linux/pci.h>
X
X #include <asm/dma.h>
X #include <asm/ecard.h>
@@ -151,15 +155,6 @@
X fas216_intr(host);
X }
X
-static void
-cumanascsi_2_invalidate(char *addr, long len, fasdmadir_t direction)
-{
- if (direction == DMA_OUT)
- dma_cache_wback((unsigned long)addr, (unsigned long)len);
- else
- dma_cache_inv((unsigned long)addr, (unsigned long)len);
-}
-
X /* Prototype: fasdmatype_t cumanascsi_2_dma_setup(host, SCpnt, direction, min_type)
X * Purpose : initialises DMA/PIO
X * Params : host - host
@@ -179,33 +174,30 @@
X
X if (dmach != NO_DMA &&
X (min_type == fasdma_real_all || SCp->this_residual >= 512)) {
- int buf;
+ int bufs = SCp->buffers_residual;
+ int pci_dir, dma_dir, alatch_dir;
+
+ if (bufs)
+ memcpy(info->sg + 1, SCp->buffer + 1,
+ sizeof(struct scatterlist) * bufs);
+ info->sg[0].address = SCp->ptr;
+ info->sg[0].length = SCp->this_residual;
+
+ if (direction == DMA_OUT)
+ pci_dir = PCI_DMA_TODEVICE,
+ dma_dir = DMA_MODE_WRITE,
+ alatch_dir = ALATCH_DMA_OUT;
+ else
+ pci_dir = PCI_DMA_FROMDEVICE,
+ dma_dir = DMA_MODE_READ,
+ alatch_dir = ALATCH_DMA_IN;
X
- for (buf = 1; buf <= SCp->buffers_residual &&
- buf < NR_SG; buf++) {
- info->dmasg[buf].address = __virt_to_bus(
- (unsigned long)SCp->buffer[buf].address);
- info->dmasg[buf].length = SCp->buffer[buf].length;
-
- cumanascsi_2_invalidate(SCp->buffer[buf].address,
- SCp->buffer[buf].length,
- direction);
- }
-
- info->dmasg[0].address = __virt_to_phys((unsigned long)SCp->ptr);
- info->dmasg[0].length = SCp->this_residual;
- cumanascsi_2_invalidate(SCp->ptr,
- SCp->this_residual, direction);
+ pci_map_sg(NULL, info->sg, bufs + 1, pci_dir);
X
X disable_dma(dmach);
- set_dma_sg(dmach, info->dmasg, buf);
- if (direction == DMA_OUT) {
- outb(ALATCH_DMA_OUT, info->alatch);
- set_dma_mode(dmach, DMA_MODE_WRITE);
- } else {
- outb(ALATCH_DMA_IN, info->alatch);
- set_dma_mode(dmach, DMA_MODE_READ);
- }
+ set_dma_sg(dmach, info->sg, bufs + 1);
+ outb(alatch_dir, info->alatch);
+ set_dma_mode(dmach, dma_dir);
X enable_dma(dmach);
X outb(ALATCH_ENA_DMA, info->alatch);
X outb(ALATCH_DIS_BIT32, info->alatch);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/scsi/cumana_2.h linux/drivers/acorn/scsi/cumana_2.h
--- v2.4.0-test8/linux/drivers/acorn/scsi/cumana_2.h Fri May 12 11:21:20 2000
+++ linux/drivers/acorn/scsi/cumana_2.h Mon Sep 18 15:15:22 2000
@@ -1,7 +1,13 @@
X /*
- * Cumana SCSI II driver
+ * linux/drivers/acorn/scsi/cumana_2.h
X *
- * Copyright (C) 1997-2000 Russell King
+ * Copyright (C) 1997-2000 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

+ *
+ * Cumana SCSI II driver
X */
X #ifndef CUMANA_2_H
X #define CUMANA_2_H
@@ -76,7 +82,7 @@
X unsigned int alatch; /* Control register */
X unsigned int terms; /* Terminator state */
X unsigned int dmaarea; /* Pseudo DMA area */
- dmasg_t dmasg[NR_SG]; /* Scatter DMA list */
+ struct scatterlist sg[NR_SG]; /* Scatter DMA list */
X } CumanaScsi2_Info;
X
X #define CSTATUS_IRQ (1 << 0)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/scsi/eesox.c linux/drivers/acorn/scsi/eesox.c
--- v2.4.0-test8/linux/drivers/acorn/scsi/eesox.c Sun Apr 2 17:28:22 2000
+++ linux/drivers/acorn/scsi/eesox.c Mon Sep 18 15:15:22 2000
@@ -1,24 +1,27 @@
X /*
- * linux/arch/arm/drivers/scsi/eesox.c
+ * linux/drivers/acorn/scsi/eesox.c
X *
- * Copyright (C) 1997-2000 Russell King
+ * Copyright (C) 1997-2000 Russell King
X *
- * This driver is based on experimentation. Hence, it may have made
- * assumptions about the particular card that I have available, and
- * may not be reliable!


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X *

- * Changelog:
- * 01-10-1997 RMK Created, READONLY version
- * 15-02-1998 RMK READ/WRITE version
+ * This driver is based on experimentation. Hence, it may have made
+ * assumptions about the particular card that I have available, and
+ * may not be reliable!
+ *
+ * Changelog:
+ * 01-10-1997 RMK Created, READONLY version
+ * 15-02-1998 RMK READ/WRITE version
X * added DMA support and hardware definitions
- * 14-03-1998 RMK Updated DMA support
+ * 14-03-1998 RMK Updated DMA support
X * Added terminator control
- * 15-04-1998 RMK Only do PIO if FAS216 will allow it.
- * 27-06-1998 RMK Changed asm/delay.h to linux/delay.h
- * 02-04-2000 RMK 0.0.3 Fixed NO_IRQ/NO_DMA problem, updated for new
+ * 15-04-1998 RMK Only do PIO if FAS216 will allow it.
+ * 27-06-1998 RMK Changed asm/delay.h to linux/delay.h
+ * 02-04-2000 RMK 0.0.3 Fixed NO_IRQ/NO_DMA problem, updated for new
X * error handling code.
X */
-
X #include <linux/module.h>
X #include <linux/blk.h>
X #include <linux/kernel.h>
@@ -29,6 +32,7 @@
X #include <linux/unistd.h>
X #include <linux/stat.h>
X #include <linux/delay.h>
+#include <linux/pci.h>
X
X #include <asm/io.h>
X #include <asm/irq.h>
@@ -157,15 +161,6 @@
X fas216_intr(host);
X }
X
-static void
-eesoxscsi_invalidate(char *addr, long len, fasdmadir_t direction)
-{
- if (direction == DMA_OUT)
- dma_cache_wback((unsigned long)addr, (unsigned long)len);
- else
- dma_cache_inv((unsigned long)addr, (unsigned long)len);
-}
-
X /* Prototype: fasdmatype_t eesoxscsi_dma_setup(host, SCpnt, direction, min_type)
X * Purpose : initialises DMA/PIO
X * Params : host - host
@@ -183,29 +178,27 @@
X
X if (dmach != NO_DMA &&
X (min_type == fasdma_real_all || SCp->this_residual >= 512)) {
- int buf;
+ int bufs = SCp->buffers_residual;
+ int pci_dir, dma_dir;
+
+ if (bufs)
+ memcpy(info->sg + 1, SCp->buffer + 1,
+ sizeof(struct scatterlist) * bufs);
+ info->sg[0].address = SCp->ptr;
+ info->sg[0].length = SCp->this_residual;
+
+ if (direction == DMA_OUT)
+ pci_dir = PCI_DMA_TODEVICE,
+ dma_dir = DMA_MODE_WRITE;
+ else
+ pci_dir = PCI_DMA_FROMDEVICE,
+ dma_dir = DMA_MODE_READ;
X
- for(buf = 1; buf <= SCp->buffers_residual &&
- buf < NR_SG; buf++) {
- info->dmasg[buf].address = __virt_to_bus(
- (unsigned long)SCp->buffer[buf].address);
- info->dmasg[buf].length = SCp->buffer[buf].length;
-
- eesoxscsi_invalidate(SCp->buffer[buf].address,
- SCp->buffer[buf].length,
- direction);
- }
-
- info->dmasg[0].address = __virt_to_phys((unsigned long)SCp->ptr);
- info->dmasg[0].length = SCp->this_residual;
- eesoxscsi_invalidate(SCp->ptr,
- SCp->this_residual, direction);
+ pci_map_sg(NULL, info->sg, bufs + 1, pci_dir);
X
X disable_dma(dmach);
- set_dma_sg(dmach, info->dmasg, buf);
- set_dma_mode(dmach,
- direction == DMA_OUT ? DMA_MODE_WRITE :
- DMA_MODE_READ);
+ set_dma_sg(dmach, info->sg, bufs + 1);
+ set_dma_mode(dmach, dma_dir);
X enable_dma(dmach);
X return fasdma_real_all;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/scsi/eesox.h linux/drivers/acorn/scsi/eesox.h
--- v2.4.0-test8/linux/drivers/acorn/scsi/eesox.h Sun Apr 2 17:28:22 2000
+++ linux/drivers/acorn/scsi/eesox.h Mon Sep 18 15:15:22 2000
@@ -1,7 +1,13 @@
X /*
- * EESOX SCSI driver
+ * linux/drivers/acorn/scsi/eesox.h
X *
- * Copyright (C) 1997-2000 Russell King
+ * Copyright (C) 1997-2000 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

+ *
+ * EESOX SCSI driver
X */
X #ifndef EESOXSCSI_H
X #define EESOXSCSI_H
@@ -76,7 +82,7 @@
X struct control control;
X
X unsigned int dmaarea; /* Pseudo DMA area */
- dmasg_t dmasg[NR_SG]; /* Scatter DMA list */
+ struct scatterlist sg[NR_SG]; /* Scatter DMA list */
X } EESOXScsi_Info;
X
X #endif /* HOSTS_C */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/scsi/fas216.c linux/drivers/acorn/scsi/fas216.c
--- v2.4.0-test8/linux/drivers/acorn/scsi/fas216.c Wed Aug 9 14:11:11 2000
+++ linux/drivers/acorn/scsi/fas216.c Mon Sep 18 15:15:22 2000
@@ -1,7 +1,11 @@
X /*
- * linux/arch/arm/drivers/scsi/fas216.c
+ * linux/arch/arm/drivers/scsi/fas216.c
X *
- * Copyright (C) 1997-2000 Russell King
+ * Copyright (C) 1997-2000 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X *

X * Based on information in qlogicfas.c by Tom Zerucha, Michael Griffith, and
X * other sources, including:
@@ -33,7 +37,6 @@
X * Todo:
X * - allow individual devices to enable sync xfers.
X */
-
X #include <linux/module.h>
X #include <linux/blk.h>
X #include <linux/kernel.h>
@@ -2177,7 +2180,7 @@
X {
X enum res_abort res = res_failed;
X
- if (queue_removecmd(&info->queues.issue, SCpnt)) {
+ if (queue_remove_cmd(&info->queues.issue, SCpnt)) {
X /*
X * The command was on the issue queue, and has not been
X * issued yet. We can remove the command from the queue,
@@ -2187,7 +2190,7 @@
X printk("on issue queue ");
X
X res = res_success;
- } else if (queue_removecmd(&info->queues.disconnected, SCpnt)) {
+ } else if (queue_remove_cmd(&info->queues.disconnected, SCpnt)) {
X /*
X * The command was on the disconnected queue. We must
X * reconnect with the device if possible, and send it
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/scsi/fas216.h linux/drivers/acorn/scsi/fas216.h
--- v2.4.0-test8/linux/drivers/acorn/scsi/fas216.h Sun Apr 2 17:28:22 2000
+++ linux/drivers/acorn/scsi/fas216.h Mon Sep 18 15:15:22 2000
@@ -1,7 +1,13 @@
X /*
- * FAS216 generic driver
+ * linux/drivers/acorn/scsi/fas216.h
X *
- * Copyright (C) 1997-2000 Russell King
+ * Copyright (C) 1997-2000 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

+ *
+ * FAS216 generic driver
X */
X #ifndef FAS216_H
X #define FAS216_H
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/scsi/msgqueue.c linux/drivers/acorn/scsi/msgqueue.c
--- v2.4.0-test8/linux/drivers/acorn/scsi/msgqueue.c Thu Jun 17 01:11:35 1999
+++ linux/drivers/acorn/scsi/msgqueue.c Mon Sep 18 15:15:22 2000
@@ -1,9 +1,14 @@
X /*
- * drivers/acorn/scsi/msgqueue.c: message queue handling
+ * linux/drivers/acorn/scsi/msgqueue.c
X *
- * Copyright (C) 1997-1998 Russell King
+ * Copyright (C) 1997-1998 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

+ *
+ * message queue handling
X */
-
X #include <linux/module.h>
X #include <linux/kernel.h>
X #include <linux/stddef.h>
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/scsi/msgqueue.h linux/drivers/acorn/scsi/msgqueue.h
--- v2.4.0-test8/linux/drivers/acorn/scsi/msgqueue.h Sun Apr 2 17:28:22 2000
+++ linux/drivers/acorn/scsi/msgqueue.h Mon Sep 18 15:15:22 2000
@@ -1,7 +1,13 @@
X /*
- * msgqueue.h: message queue handling
+ * linux/drivers/acorn/scsi/msgqueue.h
X *
- * Copyright (C) 1997 Russell King
+ * Copyright (C) 1997 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

+ *
+ * message queue handling
X */
X #ifndef MSGQUEUE_H
X #define MSGQUEUE_H
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/scsi/powertec.c linux/drivers/acorn/scsi/powertec.c
--- v2.4.0-test8/linux/drivers/acorn/scsi/powertec.c Sun Apr 2 17:28:22 2000
+++ linux/drivers/acorn/scsi/powertec.c Mon Sep 18 15:15:22 2000
@@ -1,7 +1,11 @@
X /*
- * linux/arch/arm/drivers/scsi/powertec.c
+ * linux/drivers/acorn/scsi/powertec.c
X *
- * Copyright (C) 1997-2000 Russell King
+ * Copyright (C) 1997-2000 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X *

X * This driver is based on experimentation. Hence, it may have made
X * assumptions about the particular card that I have available, and
@@ -15,7 +19,6 @@
X * 27-06-1998 RMK Changed asm/delay.h to linux/delay.h
X * 02-04-2000 RMK Updated for new error handling code.
X */
-
X #include <linux/module.h>
X #include <linux/blk.h>
X #include <linux/kernel.h>
@@ -26,6 +29,7 @@
X #include <linux/unistd.h>
X #include <linux/stat.h>
X #include <linux/delay.h>
+#include <linux/pci.h>
X
X #include <asm/dma.h>
X #include <asm/ecard.h>
@@ -147,15 +151,6 @@
X fas216_intr(host);
X }
X
-static void
-powertecscsi_invalidate(char *addr, long len, fasdmadir_t direction)
-{
- if (direction == DMA_OUT)
- dma_cache_wback((unsigned long)addr, (unsigned long)len);
- else
- dma_cache_inv((unsigned long)addr, (unsigned long)len);
-}
-
X /* Prototype: fasdmatype_t powertecscsi_dma_setup(host, SCpnt, direction, min_type)
X * Purpose : initialises DMA/PIO
X * Params : host - host
@@ -173,29 +168,27 @@
X
X if (dmach != NO_DMA &&
X (min_type == fasdma_real_all || SCp->this_residual >= 512)) {
- int buf;
+ int bufs = SCp->buffers_residual;
+ int pci_dir, dma_dir;
+
+ if (bufs)
+ memcpy(info->sg + 1, SCp->buffer + 1,
+ sizeof(struct scatterlist) * bufs);
+ info->sg[0].address = SCp->ptr;
+ info->sg[0].length = SCp->this_residual;
+
+ if (direction == DMA_OUT)
+ pci_dir = PCI_DMA_TODEVICE,
+ dma_dir = DMA_MODE_WRITE;
+ else
+ pci_dir = PCI_DMA_FROMDEVICE,
+ dma_dir = DMA_MODE_READ;
X
- for (buf = 1; buf <= SCp->buffers_residual &&
- buf < NR_SG; buf++) {
- info->dmasg[buf].address = __virt_to_bus(
- (unsigned long)SCp->buffer[buf].address);
- info->dmasg[buf].length = SCp->buffer[buf].length;
-
- powertecscsi_invalidate(SCp->buffer[buf].address,
- SCp->buffer[buf].length,
- direction);
- }
-
- info->dmasg[0].address = __virt_to_phys((unsigned long)SCp->ptr);
- info->dmasg[0].length = SCp->this_residual;
- powertecscsi_invalidate(SCp->ptr,
- SCp->this_residual, direction);
+ pci_map_sg(NULL, info->sg, bufs + 1, pci_dir);
X
X disable_dma(dmach);
- set_dma_sg(dmach, info->dmasg, buf);
- set_dma_mode(dmach,
- direction == DMA_OUT ? DMA_MODE_WRITE :
- DMA_MODE_READ);
+ set_dma_sg(dmach, info->sg, bufs + 1);
+ set_dma_mode(dmach, dma_dir);
X enable_dma(dmach);
X return fasdma_real_all;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/scsi/powertec.h linux/drivers/acorn/scsi/powertec.h
--- v2.4.0-test8/linux/drivers/acorn/scsi/powertec.h Sun Apr 2 17:28:22 2000
+++ linux/drivers/acorn/scsi/powertec.h Mon Sep 18 15:15:22 2000
@@ -1,7 +1,13 @@
X /*
- * PowerTec SCSI driver
+ * linux/drivers/acorn/scsi/powertec.h
X *
- * Copyright (C) 1997-2000 Russell King
+ * Copyright (C) 1997-2000 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

+ *
+ * PowerTec SCSI driver
X */
X #ifndef POWERTECSCSI_H
X #define POWERTECSCSI_H
@@ -74,7 +80,7 @@
X } control;
X
X /* other info... */
- dmasg_t dmasg[NR_SG]; /* Scatter DMA list */
+ struct scatterlist sg[NR_SG]; /* Scatter DMA list */
X } PowerTecScsi_Info;
X
X #endif /* HOSTS_C */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/scsi/queue.c linux/drivers/acorn/scsi/queue.c
--- v2.4.0-test8/linux/drivers/acorn/scsi/queue.c Thu Jun 17 01:11:35 1999
+++ linux/drivers/acorn/scsi/queue.c Mon Sep 18 15:15:22 2000
@@ -1,40 +1,57 @@
X /*
- * queue.c: queue handling primitives
+ * linux/drivers/acorn/scsi/queue.c: queue handling primitives
X *
- * (c) 1997 Russell King
+ * Copyright (C) 1997-2000 Russell King
X *
- * Changelog:
- * 15-Sep-1997 RMK Created.
- * 11-Oct-1997 RMK Corrected problem with queue_remove_exclude


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Changelog:
+ * 15-Sep-1997 RMK Created.
+ * 11-Oct-1997 RMK Corrected problem with queue_remove_exclude
X * not updating internal linked list properly
X * (was causing commands to go missing).
+ * 30-Aug-2000 RMK Use Linux list handling and spinlocks
X */
-
-#define SECTOR_SIZE 512
-
X #include <linux/module.h>
X #include <linux/blk.h>
X #include <linux/kernel.h>
X #include <linux/string.h>
X #include <linux/malloc.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
X
X #include "../../scsi/scsi.h"
X
X MODULE_AUTHOR("Russell King");
X MODULE_DESCRIPTION("SCSI command queueing");
X
+#define DEBUG
+
X typedef struct queue_entry {
- struct queue_entry *next;
- struct queue_entry *prev;
- unsigned long magic;
+ struct list_head list;
X Scsi_Cmnd *SCpnt;
+#ifdef DEBUG
+ unsigned long magic;
+#endif
X } QE_t;
X
+#ifdef DEBUG
X #define QUEUE_MAGIC_FREE 0xf7e1c9a3
X #define QUEUE_MAGIC_USED 0xf7e1cc33
X
+#define SET_MAGIC(q,m) ((q)->magic = (m))
+#define BAD_MAGIC(q,m) ((q)->magic != (m))
+#else
+#define SET_MAGIC(q,m) do { } while (0)
+#define BAD_MAGIC(q,m) (0)
+#endif
+
X #include "queue.h"
X
+#define NR_QE 32
+
X /*
X * Function: void queue_initialise (Queue_t *queue)
X * Purpose : initialise a queue
@@ -42,24 +59,29 @@
X */
X int queue_initialise (Queue_t *queue)
X {
- unsigned int nqueues;
+ unsigned int nqueues = NR_QE;
X QE_t *q;
X
- queue->alloc = queue->free = q = (QE_t *) kmalloc (SECTOR_SIZE, GFP_KERNEL);
+ spin_lock_init(&queue->queue_lock);
+ INIT_LIST_HEAD(&queue->head);
+ INIT_LIST_HEAD(&queue->free);
+
+ /*
+ * If life was easier, then SCpnt would have a
+ * host-available list head, and we wouldn't
+ * need to keep free lists or allocate this
+ * memory.
+ */
+ queue->alloc = q = kmalloc(sizeof(QE_t) * nqueues, GFP_KERNEL);
X if (q) {
- nqueues = SECTOR_SIZE / sizeof (QE_t);
-
X for (; nqueues; q++, nqueues--) {
- q->next = q + 1;
- q->prev = NULL;
- q->magic = QUEUE_MAGIC_FREE;
+ SET_MAGIC(q, QUEUE_MAGIC_FREE);
X q->SCpnt = NULL;
+ list_add(&q->list, &queue->free);
X }
- q -= 1;
- q->next = NULL;
X }
X
- return q != NULL;
+ return queue->alloc != NULL;
X }
X
X /*
@@ -69,103 +91,69 @@
X */
X void queue_free (Queue_t *queue)
X {
+ if (!list_empty(&queue->head))
+ printk(KERN_WARNING "freeing non-empty queue %p\n", queue);
X if (queue->alloc)
- kfree (queue->alloc);
+ kfree(queue->alloc);
X }
X
X
X /*
- * Function: int queue_add_cmd_ordered (Queue_t *queue, Scsi_Cmnd *SCpnt)
+ * Function: int queue_add_cmd(Queue_t *queue, Scsi_Cmnd *SCpnt, int head)
X * Purpose : Add a new command onto a queue, adding REQUEST_SENSE to head.
X * Params : queue - destination queue
X * SCpnt - command to add
+ * head - add command to head of queue
X * Returns : 0 on error, !0 on success
X */
-int queue_add_cmd_ordered (Queue_t *queue, Scsi_Cmnd *SCpnt)
+int __queue_add(Queue_t *queue, Scsi_Cmnd *SCpnt, int head)


X {
X unsigned long flags;

+ struct list_head *l;
X QE_t *q;
+ int ret = 0;
X
- save_flags_cli (flags);
- q = queue->free;
- if (q)
- queue->free = q->next;
-
- if (q) {
- if (q->magic != QUEUE_MAGIC_FREE) {
- restore_flags (flags);
- panic ("scsi queues corrupted - queue entry not free");
- }
-
- q->magic = QUEUE_MAGIC_USED;
- q->SCpnt = SCpnt;
-
- if (SCpnt->cmnd[0] == REQUEST_SENSE) { /* request_sense gets put on the queue head */
- if (queue->head) {
- q->prev = NULL;
- q->next = queue->head;
- queue->head->prev = q;
- queue->head = q;
- } else {
- q->next = q->prev = NULL;
- queue->head = queue->tail = q;
- }
- } else { /* others get put on the tail */
- if (queue->tail) {
- q->next = NULL;
- q->prev = queue->tail;
- queue->tail->next = q;
- queue->tail = q;
- } else {
- q->next = q->prev = NULL;
- queue->head = queue->tail = q;
- }
- }
- }
- restore_flags (flags);
-
- return q != NULL;
+ spin_lock_irqsave(&queue->queue_lock, flags);
+ if (list_empty(&queue->free))
+ goto empty;
+
+ l = queue->free.next;
+ list_del(l);
+
+ q = list_entry(l, QE_t, list);
+ if (BAD_MAGIC(q, QUEUE_MAGIC_FREE))
+ BUG();
+
+ SET_MAGIC(q, QUEUE_MAGIC_USED);
+ q->SCpnt = SCpnt;
+
+ if (head)
+ list_add(l, &queue->head);
+ else
+ list_add_tail(l, &queue->head);
+
+ ret = 1;
+empty:
+ spin_unlock_irqrestore(&queue->queue_lock, flags);
+ return ret;
X }
X
-/*
- * Function: int queue_add_cmd_tail (Queue_t *queue, Scsi_Cmnd *SCpnt)
- * Purpose : Add a new command onto a queue, adding onto tail of list
- * Params : queue - destination queue
- * SCpnt - command to add
- * Returns : 0 on error, !0 on success
- */
-int queue_add_cmd_tail (Queue_t *queue, Scsi_Cmnd *SCpnt)
+static Scsi_Cmnd *__queue_remove(Queue_t *queue, struct list_head *ent)


X {
- unsigned long flags;

X QE_t *q;
X
- save_flags_cli (flags);
- q = queue->free;
- if (q)
- queue->free = q->next;
-
- if (q) {
- if (q->magic != QUEUE_MAGIC_FREE) {
- restore_flags (flags);
- panic ("scsi queues corrupted - queue entry not free");
- }
-
- q->magic = QUEUE_MAGIC_USED;
- q->SCpnt = SCpnt;
+ /*
+ * Move the entry from the "used" list onto the "free" list
+ */
+ list_del(ent);
+ q = list_entry(ent, QE_t, list);
+ if (BAD_MAGIC(q, QUEUE_MAGIC_USED))
+ BUG();
X
- if (queue->tail) {
- q->next = NULL;
- q->prev = queue->tail;
- queue->tail->next = q;
- queue->tail = q;
- } else {
- q->next = q->prev = NULL;
- queue->head = queue->tail = q;
- }
- }
- restore_flags (flags);
+ SET_MAGIC(q, QUEUE_MAGIC_FREE);
+ list_add(ent, &queue->free);
X
- return q != NULL;
+ return q->SCpnt;
X }
X
X /*
@@ -175,50 +163,21 @@
X * exclude - bit array of target&lun which is busy
X * Returns : Scsi_Cmnd if successful (and a reference), or NULL if no command available
X */
-Scsi_Cmnd *queue_remove_exclude (Queue_t *queue, unsigned char *exclude)
+Scsi_Cmnd *queue_remove_exclude(Queue_t *queue, void *exclude)


X {
X unsigned long flags;

- Scsi_Cmnd *SCpnt;
- QE_t *q, *prev;
+ struct list_head *l;
+ Scsi_Cmnd *SCpnt = NULL;
X
- save_flags_cli (flags);
- for (q = queue->head, prev = NULL; q; q = q->next) {
- if (exclude && !test_bit (q->SCpnt->target * 8 + q->SCpnt->lun, exclude))
+ spin_lock_irqsave(&queue->queue_lock, flags);
+ list_for_each(l, &queue->head) {
+ QE_t *q = list_entry(l, QE_t, list);
+ if (!test_bit(q->SCpnt->target * 8 + q->SCpnt->lun, exclude)) {
+ SCpnt = __queue_remove(queue, l);
X break;
- prev = q;
- }
-
- if (q) {
- if (q->magic != QUEUE_MAGIC_USED) {
- restore_flags (flags);
- panic ("q_remove_exclude: scsi queues corrupted - queue entry not used");
- }
- if (q->prev != prev)
- panic ("q_remove_exclude: scsi queues corrupted - q->prev != prev");
-
- if (!prev) {
- queue->head = q->next;
- if (queue->head)
- queue->head->prev = NULL;
- else
- queue->tail = NULL;
- } else {
- prev->next = q->next;
- if (prev->next)
- prev->next->prev = prev;
- else
- queue->tail = prev;
X }
-
- SCpnt = q->SCpnt;
-
- q->next = queue->free;
- queue->free = q;
- q->magic = QUEUE_MAGIC_FREE;
- } else
- SCpnt = NULL;
-
- restore_flags (flags);
+ }
+ spin_unlock_irqrestore(&queue->queue_lock, flags);
X
X return SCpnt;
X }
@@ -229,35 +188,15 @@
X * Params : queue - queue to remove command from
X * Returns : Scsi_Cmnd if successful (and a reference), or NULL if no command available
X */
-Scsi_Cmnd *queue_remove (Queue_t *queue)
+Scsi_Cmnd *queue_remove(Queue_t *queue)


X {
X unsigned long flags;

- Scsi_Cmnd *SCpnt;
- QE_t *q;
-
- save_flags_cli (flags);
- q = queue->head;
- if (q) {
- queue->head = q->next;
- if (queue->head)
- queue->head->prev = NULL;
- else
- queue->tail = NULL;
-
- if (q->magic != QUEUE_MAGIC_USED) {
- restore_flags (flags);
- panic ("scsi queues corrupted - queue entry not used");
- }
-
- SCpnt = q->SCpnt;
+ Scsi_Cmnd *SCpnt = NULL;
X
- q->next = queue->free;
- queue->free = q;
- q->magic = QUEUE_MAGIC_FREE;
- } else
- SCpnt = NULL;
-
- restore_flags (flags);
+ spin_lock_irqsave(&queue->queue_lock, flags);
+ if (!list_empty(&queue->head))
+ SCpnt = __queue_remove(queue, queue->head.next);
+ spin_unlock_irqrestore(&queue->queue_lock, flags);
X
X return SCpnt;
X }
@@ -274,50 +213,19 @@
X Scsi_Cmnd *queue_remove_tgtluntag (Queue_t *queue, int target, int lun, int tag)


X {
X unsigned long flags;

- Scsi_Cmnd *SCpnt;
- QE_t *q, *prev;
+ struct list_head *l;
+ Scsi_Cmnd *SCpnt = NULL;
X
- save_flags_cli (flags);
- for (q = queue->head, prev = NULL; q; q = q->next) {
- if (q->SCpnt->target == target &&
- q->SCpnt->lun == lun &&
- q->SCpnt->tag == tag)
+ spin_lock_irqsave(&queue->queue_lock, flags);
+ list_for_each(l, &queue->head) {
+ QE_t *q = list_entry(l, QE_t, list);
+ if (q->SCpnt->target == target && q->SCpnt->lun == lun &&
+ q->SCpnt->tag == tag) {
+ SCpnt = __queue_remove(queue, l);
X break;
-
- prev = q;
- }
-
- if (q) {
- if (q->magic != QUEUE_MAGIC_USED) {
- restore_flags (flags);
- panic ("q_remove_tgtluntag: scsi queues corrupted - queue entry not used");
- }
- if (q->prev != prev)
- panic ("q_remove_tgtluntag: scsi queues corrupted - q->prev != prev");
-
- if (!prev) {
- queue->head = q->next;
- if (queue->head)
- queue->head->prev = NULL;
- else
- queue->tail = NULL;
- } else {
- prev->next = q->next;
- if (prev->next)
- prev->next->prev = prev;
- else
- queue->tail = prev;
X }
-
- SCpnt = q->SCpnt;
-
- q->magic = QUEUE_MAGIC_FREE;
- q->next = queue->free;
- queue->free = q;
- } else
- SCpnt = NULL;
-
- restore_flags (flags);
+ }
+ spin_unlock_irqrestore(&queue->queue_lock, flags);
X
X return SCpnt;
X }
@@ -333,96 +241,58 @@
X */
X int queue_probetgtlun (Queue_t *queue, int target, int lun)
X {
- QE_t *q;
-
- for (q = queue->head; q; q = q->next)
- if (q->SCpnt->target == target &&
- q->SCpnt->lun == lun)
- break;
-
- return q != NULL;
-}
-
-/*
- * Function: int queue_cmdonqueue (queue, SCpnt)
- * Purpose : check to see if we have a command on the queue
- * Params : queue - queue to look in
- * SCpnt - command to find
- * Returns : 0 if not found, != 0 if found
- */
-int queue_cmdonqueue (Queue_t *queue, Scsi_Cmnd *SCpnt)
-{
- QE_t *q;
+ unsigned long flags;
+ struct list_head *l;
+ int found = 0;
X
- for (q = queue->head; q; q = q->next)
- if (q->SCpnt == SCpnt)
+ spin_lock_irqsave(&queue->queue_lock, flags);
+ list_for_each(l, &queue->head) {
+ QE_t *q = list_entry(l, QE_t, list);
+ if (q->SCpnt->target == target && q->SCpnt->lun == lun) {
+ found = 1;
X break;
+ }
+ }
+ spin_unlock_irqrestore(&queue->queue_lock, flags);
X
- return q != NULL;
+ return found;
X }
X
X /*
- * Function: int queue_removecmd (Queue_t *queue, Scsi_Cmnd *SCpnt)
+ * Function: int queue_remove_cmd(Queue_t *queue, Scsi_Cmnd *SCpnt)
X * Purpose : remove a specific command from the queues
X * Params : queue - queue to look in
X * SCpnt - command to find
X * Returns : 0 if not found
X */
-int queue_removecmd (Queue_t *queue, Scsi_Cmnd *SCpnt)
+int queue_remove_cmd(Queue_t *queue, Scsi_Cmnd *SCpnt)


X {
X unsigned long flags;

- QE_t *q, *prev;
+ struct list_head *l;
+ int found = 0;
X
- save_flags_cli (flags);
- for (q = queue->head, prev = NULL; q; q = q->next) {
- if (q->SCpnt == SCpnt)
+ spin_lock_irqsave(&queue->queue_lock, flags);
+ list_for_each(l, &queue->head) {
+ QE_t *q = list_entry(l, QE_t, list);
+ if (q->SCpnt == SCpnt) {
+ __queue_remove(queue, l);
+ found = 1;
X break;
-
- prev = q;
- }
-
- if (q) {
- if (q->magic != QUEUE_MAGIC_USED) {
- restore_flags (flags);
- panic ("q_removecmd: scsi queues corrupted - queue entry not used");
X }
- if (q->prev != prev)
- panic ("q_removecmd: scsi queues corrupted - q->prev != prev");
-
- if (!prev) {
- queue->head = q->next;
- if (queue->head)
- queue->head->prev = NULL;
- else
- queue->tail = NULL;
- } else {
- prev->next = q->next;
- if (prev->next)
- prev->next->prev = prev;
- else
- queue->tail = prev;
- }
-
- q->magic = QUEUE_MAGIC_FREE;
- q->next = queue->free;
- queue->free = q;
X }
+ spin_unlock_irqrestore(&queue->queue_lock, flags);
X
- restore_flags (flags);
-
- return q != NULL;
+ return found;
X }
X
X EXPORT_SYMBOL(queue_initialise);
X EXPORT_SYMBOL(queue_free);
+EXPORT_SYMBOL(__queue_add);
X EXPORT_SYMBOL(queue_remove);
X EXPORT_SYMBOL(queue_remove_exclude);
-EXPORT_SYMBOL(queue_add_cmd_ordered);
-EXPORT_SYMBOL(queue_add_cmd_tail);
X EXPORT_SYMBOL(queue_remove_tgtluntag);
+EXPORT_SYMBOL(queue_remove_cmd);
X EXPORT_SYMBOL(queue_probetgtlun);
-EXPORT_SYMBOL(queue_cmdonqueue);
-EXPORT_SYMBOL(queue_removecmd);
X
X #ifdef MODULE
X int init_module (void)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acorn/scsi/queue.h linux/drivers/acorn/scsi/queue.h
--- v2.4.0-test8/linux/drivers/acorn/scsi/queue.h Sun Apr 2 17:28:22 2000
+++ linux/drivers/acorn/scsi/queue.h Mon Sep 18 15:15:22 2000
@@ -1,16 +1,20 @@
X /*
- * queue.h: queue handling
+ * linux/drivers/acorn/scsi/queue.h: queue handling
X *
- * Copyright (C) 1997 Russell King
+ * Copyright (C) 1997 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X */

X #ifndef QUEUE_H
X #define QUEUE_H
X
X typedef struct {
- struct queue_entry *head; /* head of queue */
- struct queue_entry *tail; /* tail of queue */
- struct queue_entry *free; /* free list */
- void *alloc; /* start of allocated mem */
+ struct list_head head;
+ struct list_head free;
+ spinlock_t queue_lock;
+ void *alloc; /* start of allocated mem */
X } Queue_t;
X
X /*
@@ -36,32 +40,27 @@
X extern Scsi_Cmnd *queue_remove (Queue_t *queue);
X
X /*
- * Function: Scsi_Cmnd *queue_remove_exclude_ref (queue, exclude, ref)
+ * Function: Scsi_Cmnd *queue_remove_exclude_ref (queue, exclude)
X * Purpose : remove a SCSI command from a queue
X * Params : queue - queue to remove command from
X * exclude - array of busy LUNs
- * ref - a reference that can be used to put the command back
X * Returns : Scsi_Cmnd if successful (and a reference), or NULL if no command available
X */
-extern Scsi_Cmnd *queue_remove_exclude (Queue_t *queue, unsigned char *exclude);
-
-/*
- * Function: int queue_add_cmd_ordered (Queue_t *queue, Scsi_Cmnd *SCpnt)
- * Purpose : Add a new command onto a queue, queueing REQUEST_SENSE first
- * Params : queue - destination queue
- * SCpnt - command to add
- * Returns : 0 on error, !0 on success
- */
-extern int queue_add_cmd_ordered (Queue_t *queue, Scsi_Cmnd *SCpnt);
+extern Scsi_Cmnd *queue_remove_exclude (Queue_t *queue, void *exclude);
X
+#define queue_add_cmd_ordered(queue,SCpnt) \
+ __queue_add(queue,SCpnt,(SCpnt)->cmnd[0] == REQUEST_SENSE)
+#define queue_add_cmd_tail(queue,SCpnt) \
+ __queue_add(queue,SCpnt,0)
X /*
- * Function: int queue_add_cmd_tail (Queue_t *queue, Scsi_Cmnd *SCpnt)
- * Purpose : Add a new command onto a queue, queueing at end of list
+ * Function: int __queue_add(Queue_t *queue, Scsi_Cmnd *SCpnt, int head)
+ * Purpose : Add a new command onto a queue
X * Params : queue - destination queue
X * SCpnt - command to add
+ * head - add command to head of queue
X * Returns : 0 on error, !0 on success
X */
-extern int queue_add_cmd_tail (Queue_t *queue, Scsi_Cmnd *SCpnt);
+extern int __queue_add(Queue_t *queue, Scsi_Cmnd *SCpnt, int head);
X
X /*
X * Function: Scsi_Cmnd *queue_remove_tgtluntag (queue, target, lun, tag)
@@ -86,21 +85,12 @@
X extern int queue_probetgtlun (Queue_t *queue, int target, int lun);
X
X /*
- * Function: int queue_cmdonqueue (queue, SCpnt)
- * Purpose : check to see if we have a command on the queue
- * Params : queue - queue to look in
- * SCpnt - command to find
- * Returns : 0 if not found, != 0 if found
- */
-int queue_cmdonqueue (Queue_t *queue, Scsi_Cmnd *SCpnt);
-
-/*
- * Function: int queue_removecmd (Queue_t *queue, Scsi_Cmnd *SCpnt)
+ * Function: int queue_remove_cmd (Queue_t *queue, Scsi_Cmnd *SCpnt)
X * Purpose : remove a specific command from the queues
X * Params : queue - queue to look in
X * SCpnt - command to find
X * Returns : 0 if not found
X */
-int queue_removecmd (Queue_t *queue, Scsi_Cmnd *SCpnt);
+int queue_remove_cmd(Queue_t *queue, Scsi_Cmnd *SCpnt);
X
X #endif /* QUEUE_H */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/Makefile linux/drivers/acpi/Makefile
--- v2.4.0-test8/linux/drivers/acpi/Makefile Wed Jul 12 13:21:57 2000
+++ linux/drivers/acpi/Makefile Fri Sep 15 18:21:43 2000
@@ -2,7 +2,7 @@
X # Makefile for the Linux ACPI interpreter
X #
X
-SUB_DIRS :=
+SUB_DIRS :=
X MOD_SUB_DIRS := $(SUB_DIRS)
X MOD_IN_SUB_DIRS :=
X ALL_SUB_DIRS := $(SUB_DIRS)
@@ -11,13 +11,22 @@
X O_OBJS :=
X M_OBJS :=
X
-ACPI_OBJS := driver.o ec.o cpu.o os.o sys.o tables.o
-ACPI_OBJS += $(patsubst %.c,%.o,$(wildcard */*.c))
+export ACPI_CFLAGS
+ACPI_CFLAGS := -D_LINUX
X
-EXTRA_CFLAGS += -I./include -D_LINUX
+EXTRA_CFLAGS += -I./include
+
+EXTRA_CFLAGS += $(ACPI_CFLAGS)
X
X # if the interpreter is used, it overrides arch/i386/kernel/acpi.c
X ifeq ($(CONFIG_ACPI_INTERPRETER),y)
+
+ SUB_DIRS += common dispatcher events hardware\
+ interpreter namespace parser resources tables
+
+ ACPI_OBJS := $(patsubst %,%.o,$(SUB_DIRS))
+ ACPI_OBJS += $(patsubst %.c,%.o,$(wildcard *.c))
+
X O_OBJS += $(ACPI_OBJS)
X endif
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/common/Makefile linux/drivers/acpi/common/Makefile
--- v2.4.0-test8/linux/drivers/acpi/common/Makefile Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/common/Makefile Fri Sep 15 18:21:43 2000
@@ -0,0 +1,28 @@
+#
+# Makefile for all Linux ACPI interpreter subdirectories
+#
+
+SUB_DIRS :=
+MOD_SUB_DIRS := $(SUB_DIRS)
+MOD_IN_SUB_DIRS :=
+ALL_SUB_DIRS := $(SUB_DIRS)
+
+O_TARGET := ../$(shell basename `pwd`).o
+O_OBJS :=
+M_OBJS :=
+
+ACPI_OBJS := $(patsubst %.c,%.o,$(wildcard *.c))
+
+EXTRA_CFLAGS += -I../include
+
+EXTRA_CFLAGS += $(ACPI_CFLAGS)
+
+# if the interpreter is used, it overrides arch/i386/kernel/acpi.c
+ifeq ($(CONFIG_ACPI_INTERPRETER),y)
+ O_OBJS := $(ACPI_OBJS)
+endif
+
+include $(TOPDIR)/Rules.make
+
+clean:
+ $(RM) *.o
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/common/cmalloc.c linux/drivers/acpi/common/cmalloc.c
--- v2.4.0-test8/linux/drivers/acpi/common/cmalloc.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/common/cmalloc.c Fri Sep 15 14:30:29 2000


@@ -1,6 +1,7 @@
X /******************************************************************************
X *

X * Module Name: cmalloc - local memory allocation routines
+ * $Revision: 73 $


X *
X *****************************************************************************/
X

@@ -24,13 +25,13 @@


X
X
X #include "acpi.h"

-#include "parser.h"
-#include "interp.h"
-#include "namesp.h"
-#include "globals.h"
+#include "acparser.h"
+#include "acinterp.h"
+#include "acnamesp.h"
+#include "acglobal.h"


X
X #define _COMPONENT MISCELLANEOUS

- MODULE_NAME ("cmalloc");
+ MODULE_NAME ("cmalloc")
X
X
X /*****************************************************************************
@@ -52,8 +53,8 @@
X _cm_allocate (
X u32 size,
X u32 component,
- ACPI_STRING module,
- s32 line)
+ NATIVE_CHAR *module,
+ u32 line)
X {
X void *address = NULL;
X
@@ -98,8 +99,8 @@
X _cm_callocate (
X u32 size,
X u32 component,
- ACPI_STRING module,
- s32 line)
+ NATIVE_CHAR *module,
+ u32 line)
X {
X void *address = NULL;
X
@@ -146,8 +147,8 @@
X _cm_free (
X void *address,
X u32 component,
- ACPI_STRING module,
- s32 line)
+ NATIVE_CHAR *module,
+ u32 line)
X {
X
X if (NULL == address) {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/common/cmclib.c linux/drivers/acpi/common/cmclib.c
--- v2.4.0-test8/linux/drivers/acpi/common/cmclib.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/common/cmclib.c Fri Sep 15 14:30:29 2000
@@ -0,0 +1,821 @@
+/******************************************************************************
+ *
+ * Module Name: cmclib - Local implementation of C library functions
+ * $Revision: 24 $
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 R. Byron Moore


+ *
+ * This program is free software; you can redistribute it and/or modify

+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "acpi.h"
+#include "acevents.h"
+#include "achware.h"
+#include "acnamesp.h"
+#include "acinterp.h"
+#include "amlcode.h"
+
+/*
+ * These implementations of standard C Library routines can optionally be
+ * used if a C library is not available. In general, they are less efficient
+ * than an inline or assembly implementation
+ */
+
+#define _COMPONENT MISCELLANEOUS
+ MODULE_NAME ("cmclib")
+
+
+#ifdef _MSC_VER /* disable some level-4 warnings for VC++ */
+#pragma warning(disable:4706) /* warning C4706: assignment within conditional expression */
+#endif
+
+#ifndef ACPI_USE_SYSTEM_CLIBRARY
+
+/*******************************************************************************
+ *
+ * FUNCTION: strlen


+ *
+ * PARAMETERS: String - Null terminated string

SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 018'
echo 'File patch-2.4.0-test9 is continued in part 019'
echo "019" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part020

#!/bin/sh -x
# this is part 020 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 020; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

X
X return;
@@ -385,7 +384,7 @@
X
X ACPI_STATUS
X acpi_cm_get_simple_object_size (


- ACPI_OBJECT_INTERNAL *internal_obj,
+ ACPI_OPERAND_OBJECT *internal_obj,

X u32 *obj_length)
X {
X u32 length;
@@ -405,7 +404,7 @@
X length = sizeof (ACPI_OBJECT);
X
X if (VALID_DESCRIPTOR_TYPE (internal_obj, ACPI_DESC_TYPE_NAMED)) {
- /* Object is an NTE (reference), just return the length */
+ /* Object is a named object (reference), just return the length */
X
X *obj_length = (u32) ROUND_UP_TO_NATIVE_WORD (length);
X return (status);
@@ -495,13 +494,13 @@
X
X ACPI_STATUS
X acpi_cm_get_package_object_size (


- ACPI_OBJECT_INTERNAL *internal_obj,
+ ACPI_OPERAND_OBJECT *internal_obj,

X u32 *obj_length)
X {
X
- ACPI_OBJECT_INTERNAL *this_internal_obj;
- ACPI_OBJECT_INTERNAL *parent_obj[MAX_PACKAGE_DEPTH] = { 0,0,0,0,0 };
- ACPI_OBJECT_INTERNAL *this_parent;
+ ACPI_OPERAND_OBJECT *this_internal_obj;
+ ACPI_OPERAND_OBJECT *parent_obj[MAX_PACKAGE_DEPTH] = { 0,0,0,0,0 };
+ ACPI_OPERAND_OBJECT *this_parent;
X u32 this_index;
X u32 index[MAX_PACKAGE_DEPTH] = { 0,0,0,0,0 };


X u32 length = 0;

@@ -537,7 +536,7 @@
X status =
X acpi_cm_get_simple_object_size (this_internal_obj, &object_space);
X

- if (status != AE_OK) {

+ if (ACPI_FAILURE (status)) {
X return (status);
X }
X
@@ -603,8 +602,6 @@
X }
X }
X }
-


- return (AE_OK);
X }
X
X

@@ -624,7 +621,7 @@
X
X ACPI_STATUS
X acpi_cm_get_object_size(


- ACPI_OBJECT_INTERNAL *internal_obj,
+ ACPI_OPERAND_OBJECT *internal_obj,

X u32 *obj_length)
X {
X ACPI_STATUS status;
@@ -642,7 +639,7 @@
X acpi_cm_get_simple_object_size (internal_obj, obj_length);
X }
X
- return status;
+ return (status);
X }
X
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/common/cmutils.c linux/drivers/acpi/common/cmutils.c
--- v2.4.0-test8/linux/drivers/acpi/common/cmutils.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/common/cmutils.c Fri Sep 15 14:30:29 2000
@@ -1,8 +1,9 @@
-/******************************************************************************
+/*******************************************************************************
X *
X * Module Name: cmutils - common utility procedures
+ * $Revision: 18 $
X *
- *****************************************************************************/
+ ******************************************************************************/
X
X /*
X * Copyright (C) 2000 R. Byron Moore
@@ -24,19 +25,19 @@


X
X
X #include "acpi.h"

-#include "events.h"
-#include "hardware.h"
-#include "namesp.h"
-#include "interp.h"
+#include "acevents.h"
+#include "achware.h"
+#include "acnamesp.h"
+#include "acinterp.h"
X #include "amlcode.h"
-#include "debugger.h"
+#include "acdebug.h"


X
X
X #define _COMPONENT MISCELLANEOUS

- MODULE_NAME ("cmutils");
+ MODULE_NAME ("cmutils")
X
X
-/*****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_cm_valid_acpi_name
X *
@@ -49,13 +50,13 @@
X * 2) numeric
X * 3) underscore
X *
- ****************************************************************************/
+ ******************************************************************************/
X
X u8
X acpi_cm_valid_acpi_name (
X u32 name)
X {
- char *name_ptr = (char *) &name;
+ NATIVE_CHAR *name_ptr = (NATIVE_CHAR *) &name;
X u32 i;
X
X
@@ -64,16 +65,16 @@
X (name_ptr[i] >= 'A' && name_ptr[i] <= 'Z') ||
X (name_ptr[i] >= '0' && name_ptr[i] <= '9')))


X {
- return FALSE;
+ return (FALSE);
X }
X }
X
X
- return TRUE;
+ return (TRUE);
X }
X
X

-/*****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_cm_valid_acpi_character
X *
@@ -83,11 +84,11 @@
X *
X * DESCRIPTION: Check for a printable character
X *
- ****************************************************************************/
+ ******************************************************************************/
X
X u8
X acpi_cm_valid_acpi_character (
- char character)
+ NATIVE_CHAR character)
X {
X
X return ((u8) ((character == '_') ||
@@ -96,7 +97,7 @@
X }
X
X
-/*****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_cm_mutex_initialize
X *
@@ -106,7 +107,7 @@
X *
X * DESCRIPTION: Create the system mutex objects.
X *
- ****************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS
X acpi_cm_mutex_initialize (


@@ -130,7 +131,7 @@
X }

X
X
-/*****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_cm_mutex_terminate
X *
@@ -140,7 +141,7 @@
X *
X * DESCRIPTION: Delete all of the system mutex objects.
X *
- ****************************************************************************/
+ ******************************************************************************/
X
X void
X acpi_cm_mutex_terminate (
@@ -160,7 +161,7 @@
X }
X
X
-/*****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_cm_create_mutex
X *
@@ -170,7 +171,7 @@
X *
X * DESCRIPTION: Create a mutex object.
X *
- ****************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS
X acpi_cm_create_mutex (
@@ -195,7 +196,7 @@
X }
X
X
-/*****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_cm_delete_mutex
X *
@@ -205,7 +206,7 @@
X *
X * DESCRIPTION: Delete a mutex object.
X *
- ****************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS
X acpi_cm_delete_mutex (


@@ -228,7 +229,7 @@
X }

X
X
-/*****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_cm_acquire_mutex
X *
@@ -238,7 +239,7 @@
X *
X * DESCRIPTION: Acquire a mutex object.
X *
- ****************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS
X acpi_cm_acquire_mutex (
@@ -252,9 +253,8 @@
X }
X
X
- status =
- acpi_os_wait_semaphore (acpi_gbl_acpi_mutex_info[mutex_id].mutex,
- 1, WAIT_FOREVER);
+ status = acpi_os_wait_semaphore (acpi_gbl_acpi_mutex_info[mutex_id].mutex,
+ 1, WAIT_FOREVER);
X
X if (ACPI_SUCCESS (status)) {
X acpi_gbl_acpi_mutex_info[mutex_id].locked = TRUE;
@@ -265,7 +265,7 @@
X }
X
X
-/*****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_cm_release_mutex
X *
@@ -275,7 +275,7 @@
X *
X * DESCRIPTION: Release a mutex object.
X *
- ****************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS
X acpi_cm_release_mutex (
@@ -291,14 +291,14 @@
X
X acpi_gbl_acpi_mutex_info[mutex_id].locked = FALSE; /* Mark before unlocking */
X
- status =
- acpi_os_signal_semaphore (acpi_gbl_acpi_mutex_info[mutex_id].mutex, 1);
+ status = acpi_os_signal_semaphore (acpi_gbl_acpi_mutex_info[mutex_id].mutex, 1);
+
X
X return (status);
X }
X
X
-/******************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_cm_create_update_state_and_push
X *
@@ -314,7 +314,7 @@
X
X ACPI_STATUS
X acpi_cm_create_update_state_and_push (


- ACPI_OBJECT_INTERNAL *object,
+ ACPI_OPERAND_OBJECT *object,

X u16 action,
X ACPI_GENERIC_STATE **state_list)
X {
@@ -324,21 +324,21 @@
X /* Ignore null objects; these are expected */
X
X if (!object) {
- return AE_OK;
+ return (AE_OK);
X }
X
X state = acpi_cm_create_update_state (object, action);
X if (!state) {
- return AE_NO_MEMORY;
+ return (AE_NO_MEMORY);
X }
X
X
X acpi_cm_push_generic_state (state_list, state);
- return AE_OK;
+ return (AE_OK);
X }
X
X
-/******************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_cm_push_generic_state
X *


@@ -365,7 +365,7 @@
X }

X
X
-/******************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_cm_pop_generic_state
X *
@@ -397,7 +397,7 @@
X }
X
X
-/******************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_cm_create_generic_state
X *
@@ -433,6 +433,7 @@
X acpi_gbl_generic_state_cache_depth--;


X
X acpi_cm_release_mutex (ACPI_MTX_CACHES);
+

X }
X
X else {
@@ -446,18 +447,23 @@
X /* Initialize */
X
X if (state) {
+ /* Always zero out the object before init */
+
+ MEMSET (state, 0, sizeof (ACPI_GENERIC_STATE));
+
X state->common.data_type = ACPI_DESC_TYPE_STATE;
X }
X
- return state;
+ return (state);
X }
X
X
-/******************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_cm_create_update_state
X *
- * PARAMETERS: Object - Initial Object to be installed in the state
+ * PARAMETERS: Object - Initial Object to be installed in the
+ * state
X * Action - Update action to be performed


X *
X * RETURN: Status

@@ -470,7 +476,7 @@
X
X ACPI_GENERIC_STATE *
X acpi_cm_create_update_state (


- ACPI_OBJECT_INTERNAL *object,
+ ACPI_OPERAND_OBJECT *object,
X u16 action)
X {

X ACPI_GENERIC_STATE *state;
@@ -480,7 +486,7 @@
X
X state = acpi_cm_create_generic_state ();
X if (!state) {
- return NULL;
+ return (NULL);
X }
X
X /* Init fields specific to the update struct */
@@ -492,7 +498,7 @@
X }
X
X
-/******************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_cm_create_control_state
X *
@@ -516,7 +522,7 @@
X
X state = acpi_cm_create_generic_state ();
X if (!state) {
- return NULL;
+ return (NULL);
X }
X
X
@@ -528,7 +534,7 @@
X }
X
X
-/******************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_cm_delete_generic_state
X *


@@ -575,7 +581,7 @@
X }
X

X
-/******************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_cm_delete_generic_state_cache
X *
@@ -603,13 +609,14 @@
X next = acpi_gbl_generic_state_cache->common.next;
X acpi_cm_free (acpi_gbl_generic_state_cache);
X acpi_gbl_generic_state_cache = next;
+ acpi_gbl_generic_state_cache_depth--;
X }
X
X return;
X }
X
X
-/*****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: _Report_error
X *
@@ -622,14 +629,14 @@
X *
X * DESCRIPTION: Print error message from KD table
X *
- ****************************************************************************/
+ ******************************************************************************/
X
X void
X _report_error (


- char *module_name,
- s32 line_number,
- s32 component_id,

- char *message)


+ NATIVE_CHAR *module_name,
+ u32 line_number,
+ u32 component_id,

+ NATIVE_CHAR *message)
X {
X
X debug_print (module_name, line_number, component_id, ACPI_ERROR,
@@ -638,7 +645,7 @@
X }
X
X
-/*****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: _Report_warning
X *
@@ -651,14 +658,14 @@
X *
X * DESCRIPTION: Print warning message from KD table
X *
- ****************************************************************************/
+ ******************************************************************************/
X
X void
X _report_warning (


- char *module_name,
- s32 line_number,
- s32 component_id,

- char *message)


+ NATIVE_CHAR *module_name,
+ u32 line_number,
+ u32 component_id,

+ NATIVE_CHAR *message)
X {
X
X debug_print (module_name, line_number, component_id, ACPI_WARN,
@@ -667,35 +674,7 @@
X }
X
X
-/*****************************************************************************
- *
- * FUNCTION: _Report_success
- *
- * PARAMETERS: Module_name - Caller's module name (for error output)
- * Line_number - Caller's line number (for error output)
- * Component_id - Caller's component ID (for error output)
- * Message - Error message to use on failure
- *
- * RETURN: None
- *
- * DESCRIPTION: Print warning message from KD table
- *
- ****************************************************************************/
-
-void
-_report_success (


- char *module_name,
- s32 line_number,
- s32 component_id,

- char *message)
-{
-
- debug_print (module_name, line_number, component_id, ACPI_OK,
- "*** Success: %s\n", message);
-}
-
-
-/*****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: _Report_info
X *
@@ -708,14 +687,14 @@
X *
X * DESCRIPTION: Print information message from KD table
X *
- ****************************************************************************/
+ ******************************************************************************/
X
X void
X _report_info (


- char *module_name,
- s32 line_number,
- s32 component_id,

- char *message)


+ NATIVE_CHAR *module_name,
+ u32 line_number,
+ u32 component_id,

+ NATIVE_CHAR *message)
X {
X
X debug_print (module_name, line_number, component_id, ACPI_INFO,
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/common/cmxface.c linux/drivers/acpi/common/cmxface.c
--- v2.4.0-test8/linux/drivers/acpi/common/cmxface.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/common/cmxface.c Fri Sep 15 14:30:29 2000


@@ -1,6 +1,7 @@
X /******************************************************************************
X *

X * Module Name: cmxface - External interfaces for "global" ACPI functions
+ * $Revision: 43 $


X *
X *****************************************************************************/
X

@@ -24,16 +25,16 @@


X
X
X #include "acpi.h"

-#include "events.h"
-#include "hardware.h"
-#include "namesp.h"
-#include "interp.h"
+#include "acevents.h"
+#include "achware.h"
+#include "acnamesp.h"
+#include "acinterp.h"
X #include "amlcode.h"
-#include "debugger.h"
+#include "acdebug.h"


X
X
X #define _COMPONENT MISCELLANEOUS

- MODULE_NAME ("cmxface");
+ MODULE_NAME ("cmxface")
X
X
X /*******************************************************************************
@@ -77,6 +78,8 @@
X
X /* If configured, initialize the AML debugger */
X
+ DEBUGGER_EXEC (acpi_db_initialize ());
+
X return (status);
X }
X
@@ -100,7 +103,9 @@
X /* Terminate the AML Debuger if present */
X
X acpi_gbl_db_terminate_threads = TRUE;
- acpi_cm_release_mutex (ACPI_MTX_DEBUG_CMD_READY);
+
+ /* TBD: [Investigate] This is no longer needed?*/
+/* Acpi_cm_release_mutex (ACPI_MTX_DEBUG_CMD_READY); */
X
X
X /* Shutdown and free all resources */
@@ -224,7 +229,7 @@
X ACPI_BUFFER *out_buffer)
X {
X u32 length;
- char *formatted_exception;
+ NATIVE_CHAR *formatted_exception;
X
X
X /*
@@ -237,14 +242,7 @@
X }
X
X
- /* Exception must be within range */
-
- if (exception > ACPI_MAX_STATUS) {
- return (AE_BAD_PARAMETER);
- }
-
-
- /* Convert the exception code */
+ /* Convert the exception code (Handles bad exception codes) */
X
X formatted_exception = acpi_cm_format_exception (exception);
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/cpu.c linux/drivers/acpi/cpu.c
--- v2.4.0-test8/linux/drivers/acpi/cpu.c Wed Jul 12 13:21:57 2000
+++ linux/drivers/acpi/cpu.c Fri Sep 15 14:30:29 2000
@@ -25,6 +25,9 @@
X #include "acpi.h"
X #include "driver.h"
X
+#define _COMPONENT OS_DEPENDENT
+ MODULE_NAME ("cpu")
+
X unsigned long acpi_c2_exit_latency = ACPI_INFINITE;
X unsigned long acpi_c3_exit_latency = ACPI_INFINITE;
X unsigned long acpi_c2_enter_latency = ACPI_INFINITE;
@@ -33,6 +36,7 @@
X static unsigned long acpi_pblk = ACPI_INVALID;
X static int acpi_c2_tested = 0;
X static int acpi_c3_tested = 0;
+static int acpi_max_c_state = 1;
X
X /*
X * Clear busmaster activity flag
@@ -101,10 +105,14 @@
X /*
X * start from the previous sleep level..
X */
- if (sleep_level == 1)
+ if (sleep_level == 1
+ || acpi_max_c_state < 2)
X goto sleep1;
- if (sleep_level == 2)
+
+ if (sleep_level == 2
+ || acpi_max_c_state < 3)
X goto sleep2;
+
X sleep3:
X sleep_level = 3;
X if (!acpi_c3_tested) {
@@ -193,7 +201,8 @@
X acpi_clear_bm_activity(facp);
X continue;
X }
- if (time > acpi_c3_enter_latency)
+ if (time > acpi_c3_enter_latency
+ && acpi_max_c_state >= 3)
X goto sleep3;
X }
X
@@ -210,7 +219,8 @@
X time = TIME_BEGIN(pm_tmr);
X safe_halt();
X time = TIME_END(pm_tmr, time);
- if (time > acpi_c2_enter_latency)
+ if (time > acpi_c2_enter_latency
+ && acpi_max_c_state >= 2)
X goto sleep2;
X }
X
@@ -260,12 +270,19 @@
X return AE_OK;
X
X if (lat[2].latency < MAX_CX_STATE_LATENCY) {
- printk(KERN_INFO "ACPI: C2 supported\n");
+ printk(KERN_INFO "ACPI: C2");
X acpi_c2_exit_latency = lat[2].latency;
- }
- if (lat[3].latency < MAX_CX_STATE_LATENCY) {
- printk(KERN_INFO "ACPI: C3 supported\n");
- acpi_c3_exit_latency = lat[3].latency;
+ acpi_max_c_state = 2;
+
+ if (lat[3].latency < MAX_CX_STATE_LATENCY) {
+ printk(", C3 supported\n");
+ acpi_c3_exit_latency = lat[3].latency;
+ acpi_max_c_state = 3;
+ }
+ else {
+ printk(" supported\n");
+ }
+
X }
X
X memset(throttle, 0, sizeof(throttle));
@@ -291,7 +308,7 @@
X {
X acpi_walk_namespace(ACPI_TYPE_PROCESSOR,
X ACPI_ROOT_OBJECT,
- ACPI_INT32_MAX,
+ ACPI_UINT32_MAX,
X acpi_find_cpu,
X NULL,
X NULL);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/dispatcher/Makefile linux/drivers/acpi/dispatcher/Makefile
--- v2.4.0-test8/linux/drivers/acpi/dispatcher/Makefile Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/dispatcher/Makefile Fri Sep 15 18:21:43 2000

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/dispatcher/dsfield.c linux/drivers/acpi/dispatcher/dsfield.c
--- v2.4.0-test8/linux/drivers/acpi/dispatcher/dsfield.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/dispatcher/dsfield.c Fri Sep 15 14:30:29 2000


@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *

X * Module Name: dsfield - Dispatcher field routines
+ * $Revision: 29 $


X *
X *****************************************************************************/
X
@@ -26,13 +26,13 @@
X

X #include "acpi.h"
X #include "amlcode.h"
-#include "dispatch.h"
-#include "interp.h"
-#include "namesp.h"
+#include "acdispat.h"


+#include "acinterp.h"
+#include "acnamesp.h"
X
X

X #define _COMPONENT DISPATCHER
- MODULE_NAME ("dsfield");
+ MODULE_NAME ("dsfield")
X
X
X /*
@@ -46,28 +46,28 @@
X #define FIELD_UPDATE_RULE_MASK 0x60
X
X
-/*****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_ds_create_field
X *
X * PARAMETERS: Op - Op containing the Field definition and args
- * Region - NTE for the containing Operation Region
+ * Region_node - Object for the containing Operation Region


X *
X * RETURN: Status

X *
X * DESCRIPTION: Create a new field in the specified operation region
X *
- ****************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS
X acpi_ds_create_field (
- ACPI_GENERIC_OP *op,
- ACPI_HANDLE region,
+ ACPI_PARSE_OBJECT *op,
+ ACPI_NAMESPACE_NODE *region_node,
X ACPI_WALK_STATE *walk_state)
X {
X ACPI_STATUS status = AE_AML_ERROR;
- ACPI_GENERIC_OP *arg;
- ACPI_NAMED_OBJECT *entry;
+ ACPI_PARSE_OBJECT *arg;
+ ACPI_NAMESPACE_NODE *node;
X u8 field_flags;
X u8 access_attribute = 0;
X u32 field_bit_position = 0;
@@ -76,6 +76,16 @@
X /* First arg is the name of the parent Op_region */
X
X arg = op->value.arg;
+ if (!region_node) {
+ status = acpi_ns_lookup (walk_state->scope_info, arg->value.name,
+ ACPI_TYPE_REGION, IMODE_EXECUTE,
+ NS_SEARCH_PARENT, walk_state,
+ &region_node);
+
+ if (ACPI_FAILURE (status)) {
+ return (status);
+ }
+ }
X
X /* Second arg is the field flags */
X
@@ -111,32 +121,29 @@
X case AML_NAMEDFIELD_OP:
X
X status = acpi_ns_lookup (walk_state->scope_info,
- (char *) &((ACPI_NAMED_OP *)arg)->name,
+ (NATIVE_CHAR *) &((ACPI_PARSE2_OBJECT *)arg)->name,
X INTERNAL_TYPE_DEF_FIELD,
X IMODE_LOAD_PASS1,
X NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE,
- NULL, &entry);
+ NULL, &node);
X
X if (ACPI_FAILURE (status)) {
X return (status);
X }
X
X /*
- * Initialize an object for the new NTE that is on
+ * Initialize an object for the new Node that is on
X * the object stack
X */
X
- status = acpi_aml_prep_def_field_value (entry, region,
- field_flags,
- access_attribute,
- field_bit_position,
- arg->value.size);
+ status = acpi_aml_prep_def_field_value (node, region_node, field_flags,
+ access_attribute, field_bit_position, arg->value.size);
X
X if (ACPI_FAILURE (status)) {
X return (status);
X }
X
- /* Keep track of bit position for the *next* field */
+ /* Keep track of bit position for *next* field */
X
X field_bit_position += arg->value.size;
X break;
@@ -149,29 +156,29 @@
X }
X
X
-/*****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_ds_create_bank_field
X *
X * PARAMETERS: Op - Op containing the Field definition and args
- * Region - NTE for the containing Operation Region
+ * Region_node - Object for the containing Operation Region


X *
X * RETURN: Status

X *
X * DESCRIPTION: Create a new bank field in the specified operation region
X *
- ****************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS
X acpi_ds_create_bank_field (
- ACPI_GENERIC_OP *op,
- ACPI_HANDLE region,
+ ACPI_PARSE_OBJECT *op,
+ ACPI_NAMESPACE_NODE *region_node,
X ACPI_WALK_STATE *walk_state)
X {
X ACPI_STATUS status = AE_AML_ERROR;
- ACPI_GENERIC_OP *arg;
- ACPI_NAMED_OBJECT *bank_reg;
- ACPI_NAMED_OBJECT *entry;
+ ACPI_PARSE_OBJECT *arg;
+ ACPI_NAMESPACE_NODE *register_node;
+ ACPI_NAMESPACE_NODE *node;
X u32 bank_value;
X u8 field_flags;
X u8 access_attribute = 0;
@@ -181,8 +188,18 @@
X /* First arg is the name of the parent Op_region */
X
X arg = op->value.arg;
+ if (!region_node) {
+ status = acpi_ns_lookup (walk_state->scope_info, arg->value.name,
+ ACPI_TYPE_REGION, IMODE_EXECUTE,
+ NS_SEARCH_PARENT, walk_state,
+ &region_node);
+
+ if (ACPI_FAILURE (status)) {
+ return (status);
+ }
+ }
X
- /* Socond arg is the Bank Register */
+ /* Second arg is the Bank Register */
X
X arg = arg->next;
X
@@ -190,7 +207,7 @@
X INTERNAL_TYPE_BANK_FIELD_DEFN,
X IMODE_LOAD_PASS1,
X NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE,
- NULL, &bank_reg);
+ NULL, &register_node);
X
X if (ACPI_FAILURE (status)) {
X return (status);
@@ -236,27 +253,24 @@
X case AML_NAMEDFIELD_OP:
X
X status = acpi_ns_lookup (walk_state->scope_info,
- (char *) &((ACPI_NAMED_OP *)arg)->name,
+ (NATIVE_CHAR *) &((ACPI_PARSE2_OBJECT *)arg)->name,
X INTERNAL_TYPE_DEF_FIELD,
X IMODE_LOAD_PASS1,
X NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE,
- NULL, &entry);
+ NULL, &node);
X
X if (ACPI_FAILURE (status)) {
X return (status);
X }
X
X /*
- * Initialize an object for the new NTE that is on
+ * Initialize an object for the new Node that is on
X * the object stack
X */
X
- status = acpi_aml_prep_bank_field_value (entry, region,
- bank_reg, bank_value,
- field_flags,
- access_attribute,
- field_bit_position,
- arg->value.size);
+ status = acpi_aml_prep_bank_field_value (node, region_node, register_node,
+ bank_value, field_flags, access_attribute,
+ field_bit_position, arg->value.size);
X
X if (ACPI_FAILURE (status)) {
X return (status);
@@ -276,30 +290,30 @@
X }
X
X
-/*****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_ds_create_index_field
X *
X * PARAMETERS: Op - Op containing the Field definition and args
- * Region - NTE for the containing Operation Region
+ * Region_node - Object for the containing Operation Region


X *
X * RETURN: Status

X *
X * DESCRIPTION: Create a new index field in the specified operation region
X *
- ****************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS
X acpi_ds_create_index_field (
- ACPI_GENERIC_OP *op,
- ACPI_HANDLE region,
+ ACPI_PARSE_OBJECT *op,
+ ACPI_HANDLE region_node,
X ACPI_WALK_STATE *walk_state)
X {
X ACPI_STATUS status;
- ACPI_GENERIC_OP *arg;
- ACPI_NAMED_OBJECT *entry;
- ACPI_NAMED_OBJECT *index_reg;
- ACPI_NAMED_OBJECT *data_reg;
+ ACPI_PARSE_OBJECT *arg;
+ ACPI_NAMESPACE_NODE *node;
+ ACPI_NAMESPACE_NODE *index_register_node;
+ ACPI_NAMESPACE_NODE *data_register_node;
X u8 field_flags;
X u8 access_attribute = 0;
X u32 field_bit_position = 0;
@@ -312,7 +326,7 @@
X status = acpi_ns_lookup (walk_state->scope_info, arg->value.string,
X ACPI_TYPE_ANY, IMODE_LOAD_PASS1,
X NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE,
- NULL, &index_reg);
+ NULL, &index_register_node);
X
X if (ACPI_FAILURE (status)) {
X return (status);
@@ -326,7 +340,7 @@
X INTERNAL_TYPE_INDEX_FIELD_DEFN,
X IMODE_LOAD_PASS1,
X NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE,
- NULL, &data_reg);
+ NULL, &data_register_node);
X
X if (ACPI_FAILURE (status)) {
X return (status);
@@ -368,26 +382,24 @@
X case AML_NAMEDFIELD_OP:
X
X status = acpi_ns_lookup (walk_state->scope_info,
- (char *) &((ACPI_NAMED_OP *)arg)->name,
+ (NATIVE_CHAR *) &((ACPI_PARSE2_OBJECT *)arg)->name,
X INTERNAL_TYPE_INDEX_FIELD,
X IMODE_LOAD_PASS1,
X NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE,
- NULL, &entry);
+ NULL, &node);
X
X if (ACPI_FAILURE (status)) {
X return (status);
X }
X
X /*
- * Initialize an object for the new NTE that is on
+ * Initialize an object for the new Node that is on
X * the object stack
X */
X
- status = acpi_aml_prep_index_field_value (entry, index_reg,
- data_reg, field_flags,
- access_attribute,
- field_bit_position,
- arg->value.size);
+ status = acpi_aml_prep_index_field_value (node, index_register_node, data_register_node,
+ field_flags, access_attribute,
+ field_bit_position, arg->value.size);
X
X if (ACPI_FAILURE (status)) {
X return (status);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/dispatcher/dsmethod.c linux/drivers/acpi/dispatcher/dsmethod.c
--- v2.4.0-test8/linux/drivers/acpi/dispatcher/dsmethod.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/dispatcher/dsmethod.c Fri Sep 15 14:30:29 2000


@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *

X * Module Name: dsmethod - Parser/Interpreter interface - control method parsing
+ * $Revision: 52 $


X *
X *****************************************************************************/
X

@@ -25,24 +25,24 @@


X
X
X #include "acpi.h"

-#include "parser.h"
+#include "acparser.h"
X #include "amlcode.h"
-#include "dispatch.h"


-#include "interp.h"
-#include "namesp.h"
-#include "tables.h"

-#include "debugger.h"
+#include "acdispat.h"


+#include "acinterp.h"
+#include "acnamesp.h"
+#include "actables.h"

+#include "acdebug.h"
X
X
X #define _COMPONENT DISPATCHER
- MODULE_NAME ("dsmethod");
+ MODULE_NAME ("dsmethod")
X
X
X /*******************************************************************************
X *
X * FUNCTION: Acpi_ds_parse_method
X *
- * PARAMETERS: Obj_handle - NTE of the method
+ * PARAMETERS: Obj_handle - Node of the method
X * Level - Current nesting level
X * Context - Points to a method counter
X * Return_value - Not used
@@ -61,9 +61,9 @@
X ACPI_HANDLE obj_handle)
X {
X ACPI_STATUS status;
- ACPI_OBJECT_INTERNAL *obj_desc;
- ACPI_GENERIC_OP *op;
- ACPI_NAMED_OBJECT *entry;
+ ACPI_OPERAND_OBJECT *obj_desc;
+ ACPI_PARSE_OBJECT *op;
+ ACPI_NAMESPACE_NODE *node;
X ACPI_OWNER_ID owner_id;
X
X
@@ -74,10 +74,10 @@
X }
X
X
- /* Extract the method object from the method NTE */
+ /* Extract the method object from the method Node */
X
- entry = (ACPI_NAMED_OBJECT*) obj_handle;
- obj_desc = entry->object;
+ node = (ACPI_NAMESPACE_NODE *) obj_handle;
+ obj_desc = node->object;
X if (!obj_desc) {
X return (AE_NULL_OBJECT);
X }
@@ -87,8 +87,7 @@
X if ((obj_desc->method.concurrency != INFINITE_CONCURRENCY) &&
X (!obj_desc->method.semaphore))
X {
- status = acpi_os_create_semaphore (1,
- obj_desc->method.concurrency,
+ status = acpi_os_create_semaphore (1,obj_desc->method.concurrency,
X &obj_desc->method.semaphore);
X if (ACPI_FAILURE (status)) {
X return (status);
@@ -105,17 +104,17 @@
X return (AE_NO_MEMORY);
X }
X
- /* Init new op with the method name and pointer back to the NTE */
+ /* Init new op with the method name and pointer back to the Node */
X
- acpi_ps_set_name (op, entry->name);
- op->acpi_named_object = entry;
+ acpi_ps_set_name (op, node->name);
+ op->node = node;
X
X
X /*
- * Parse the method, creating a parse tree.
+ * Parse the method, first pass
X *
- * The parse also includes a first pass load of the
- * namespace where newly declared named objects are
+ * The first pass load is
+ * where newly declared named objects are
X * added into the namespace. Actual evaluation of
X * the named objects (what would be called a "second
X * pass") happens during the actual execution of the
@@ -124,7 +123,10 @@
X */
X
X status = acpi_ps_parse_aml (op, obj_desc->method.pcode,
- obj_desc->method.pcode_length, 0);
+ obj_desc->method.pcode_length,
+ ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE,
+ node, NULL, NULL,
+ acpi_ds_load1_begin_op, acpi_ds_load1_end_op);
X
X if (ACPI_FAILURE (status)) {
X return (status);
@@ -133,11 +135,13 @@
X /* Get a new Owner_id for objects created by this method */
X
X owner_id = acpi_cm_allocate_owner_id (OWNER_TYPE_METHOD);
+ obj_desc->method.owning_id = owner_id;
X
X /* Install the parsed tree in the method object */
+ /* TBD: [Restructure] Obsolete field? */
+
+ acpi_ps_delete_parse_tree (op);
X
- obj_desc->method.parser_op = op;
- obj_desc->method.owning_id = owner_id;
X
X return (status);
X }
@@ -147,7 +151,7 @@
X *
X * FUNCTION: Acpi_ds_begin_method_execution
X *
- * PARAMETERS: Method_entry - NTE of the method
+ * PARAMETERS: Method_node - Node of the method
X * Obj_desc - The method object


X *
X * RETURN: Status

@@ -162,38 +166,31 @@
X
X ACPI_STATUS
X acpi_ds_begin_method_execution (
- ACPI_NAMED_OBJECT *method_entry,
- ACPI_OBJECT_INTERNAL *obj_desc)
+ ACPI_NAMESPACE_NODE *method_node,
+ ACPI_OPERAND_OBJECT *obj_desc)
X {
X ACPI_STATUS status = AE_OK;
X
X
- if (!method_entry) {
+ if (!method_node) {
X return (AE_NULL_ENTRY);
X }
X
- obj_desc = acpi_ns_get_attached_object (method_entry);
+ obj_desc = acpi_ns_get_attached_object (method_node);
X if (!obj_desc) {
X return (AE_NULL_OBJECT);
X }
X
+
X /*
- * Lock the parser while we check for and possibly parse the
- * control method
+ * If there is a concurrency limit on this method, we need to
+ * obtain a unit from the method semaphore. This releases the
+ * interpreter if we block
X */
X
- acpi_cm_acquire_mutex (ACPI_MTX_PARSER);
-
-
- /* If method is not parsed at this time, we must parse it first */
-
- if (!obj_desc->method.parser_op) {
-
- status = acpi_ds_parse_method (method_entry);
- if (ACPI_FAILURE (status)) {
- acpi_cm_release_mutex (ACPI_MTX_PARSER);
- return (status);
- }
+ if (obj_desc->method.semaphore) {
+ status = acpi_aml_system_wait_semaphore (obj_desc->method.semaphore,
+ WAIT_FOREVER);
X }
X
X
@@ -204,29 +201,10 @@
X * the last thread completes execution of the method
X */
X
- ((ACPI_DEFERRED_OP *) obj_desc->method.parser_op)->thread_count++;
-
- /*
- * Parsing is complete, we can unlock the parser. Parse tree
- * cannot be deleted at least until this thread completes.
- */
-
- acpi_cm_release_mutex (ACPI_MTX_PARSER);
-
- /*
- * If there is a concurrency limit on this method, we need to
- * obtain a unit from the method semaphore. This releases the
- * interpreter if we block
- */
-
- if (obj_desc->method.semaphore) {
- status = acpi_aml_system_wait_semaphore (obj_desc->method.semaphore,
- WAIT_FOREVER);
- }
+ obj_desc->method.thread_count++;
X
X
X return (status);
-
X }
X
X
@@ -247,61 +225,76 @@
X acpi_ds_call_control_method (
X ACPI_WALK_LIST *walk_list,
X ACPI_WALK_STATE *this_walk_state,
- ACPI_GENERIC_OP *op)
+ ACPI_PARSE_OBJECT *op)
X {
X ACPI_STATUS status;
- ACPI_DEFERRED_OP *method;
- ACPI_NAMED_OBJECT *method_entry;
- ACPI_OBJECT_INTERNAL *obj_desc;
+ ACPI_NAMESPACE_NODE *method_node;
+ ACPI_OPERAND_OBJECT *obj_desc;
X ACPI_WALK_STATE *next_walk_state;
+ ACPI_PARSE_STATE *parser_state;
X u32 i;
X
X
X /*
- * Prev_op points to the METHOD_CALL Op.
- * Get the NTE entry (in the METHOD_CALL->NAME Op) and the
- * corresponding METHOD Op
+ * Get the namespace entry for the control method we are about to call
X */
X
- method_entry = (this_walk_state->prev_op->value.arg)->acpi_named_object;
- if (!method_entry) {
+ method_node = this_walk_state->method_call_node;
+ if (!method_node) {
X return (AE_NULL_ENTRY);
X }
X
- obj_desc = acpi_ns_get_attached_object (method_entry);
+ obj_desc = acpi_ns_get_attached_object (method_node);
X if (!obj_desc) {
X return (AE_NULL_OBJECT);
X }
X
- /* Parse method if necessary, wait on concurrency semaphore */
X
- status = acpi_ds_begin_method_execution (method_entry, obj_desc);
+ /* Init for new method, wait on concurrency semaphore */
+
+ status = acpi_ds_begin_method_execution (method_node, obj_desc);
X if (ACPI_FAILURE (status)) {
X return (status);
X }
X
- /* Save the (current) Op for when this walk is restarted */
X
- this_walk_state->method_call_op = this_walk_state->prev_op;
- this_walk_state->prev_op = op;
- method = obj_desc->method.parser_op;
+ /* Create and initialize a new parser state */
+
+ parser_state = acpi_ps_create_state (obj_desc->method.pcode,
+ obj_desc->method.pcode_length);
+ if (!parser_state) {
+ return (AE_NO_MEMORY);
+ }
+
+ acpi_ps_init_scope (parser_state, NULL);
+ parser_state->start_node = method_node;
+
X
X /* Create a new state for the preempting walk */
X
X next_walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id,
- (ACPI_GENERIC_OP *) method,
- obj_desc, walk_list);
+ NULL, obj_desc, walk_list);
X if (!next_walk_state) {
+ /* TBD: delete parser state */
+
X return (AE_NO_MEMORY);
X }
X
+ next_walk_state->walk_type = WALK_METHOD;
+ next_walk_state->method_node = method_node;
+ next_walk_state->parser_state = parser_state;
+ next_walk_state->parse_flags = this_walk_state->parse_flags;
+ next_walk_state->descending_callback = this_walk_state->descending_callback;
+ next_walk_state->ascending_callback = this_walk_state->ascending_callback;
+
X /* The Next_op of the Next_walk will be the beginning of the method */
+ /* TBD: [Restructure] -- obsolete? */
X
- next_walk_state->next_op = (ACPI_GENERIC_OP *) method;
+ next_walk_state->next_op = NULL;
X
X /* Open a new scope */
X
- status = acpi_ds_scope_stack_push (method_entry->child_table,
+ status = acpi_ds_scope_stack_push (method_node,
X ACPI_TYPE_METHOD, next_walk_state);
X if (ACPI_FAILURE (status)) {
X goto cleanup;
@@ -316,11 +309,28 @@
X */
X
X status = acpi_ds_method_data_init_args (&this_walk_state->operands[0],
- this_walk_state->num_operands);
+ this_walk_state->num_operands,
+ next_walk_state);
X if (ACPI_FAILURE (status)) {
X goto cleanup;
X }
X
+
+ /* Create and init a Root Node */
+
+ op = acpi_ps_alloc_op (AML_SCOPE_OP);
+ if (!op) {
+ return (AE_NO_MEMORY);
+ }
+
+ status = acpi_ps_parse_aml (op, obj_desc->method.pcode,
+ obj_desc->method.pcode_length,
+ ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE,
+ method_node, NULL, NULL,
+ acpi_ds_load1_begin_op, acpi_ds_load1_end_op);
+ acpi_ps_delete_parse_tree (op);
+
+
X /*
X * Delete the operands on the previous walkstate operand stack
X * (they were copied to new objects)
@@ -328,6 +338,7 @@
X
X for (i = 0; i < obj_desc->method.param_count; i++) {
X acpi_cm_remove_reference (this_walk_state->operands [i]);
+ this_walk_state->operands [i] = NULL;
X }
X
X /* Clear the operand stack */
@@ -364,30 +375,33 @@
X ACPI_STATUS
X acpi_ds_restart_control_method (
X ACPI_WALK_STATE *walk_state,
- ACPI_OBJECT_INTERNAL *return_desc)
+ ACPI_OPERAND_OBJECT *return_desc)


X {
X ACPI_STATUS status;
X

X
X if (return_desc) {
- /*
- * Get the return value (if any) from the previous method.
- * NULL if no return value
- */
+ if (walk_state->return_used) {
+ /*
+ * Get the return value (if any) from the previous method.
+ * NULL if no return value
+ */
+
+ status = acpi_ds_result_stack_push (return_desc, walk_state);
+ if (ACPI_FAILURE (status)) {
+ acpi_cm_remove_reference (return_desc);
+ return (status);
+ }
+ }
X
- status = acpi_ds_result_stack_push (return_desc, walk_state);
- if (ACPI_FAILURE (status)) {
+ else {
+ /*
+ * Delete the return value if it will not be used by the
+ * calling method
+ */
X acpi_cm_remove_reference (return_desc);
- return (status);
X }
X
- /*
- * Delete the return value if it will not be used by the
- * calling method
- */
-
- acpi_ds_delete_result_if_not_used (walk_state->method_call_op,
- return_desc, walk_state);
X }
X
X
@@ -414,9 +428,8 @@
X ACPI_WALK_STATE *walk_state)
X {
X ACPI_STATUS status;
- ACPI_OBJECT_INTERNAL *obj_desc;
- ACPI_DEFERRED_OP *op;
- ACPI_NAMED_OBJECT *method_entry;
+ ACPI_OPERAND_OBJECT *obj_desc;
+ ACPI_NAMESPACE_NODE *method_node;
X
X
X /* The method object should be stored in the walk state */
@@ -438,66 +451,41 @@
X
X acpi_cm_acquire_mutex (ACPI_MTX_PARSER);
X
- /*
- * The root of the method parse tree should be stored
- * in the method object
- */
-
- op = obj_desc->method.parser_op;
- if (!op) {
- goto unlock_and_exit;
- }
X
X /* Signal completion of the execution of this method if necessary */
X
X if (walk_state->method_desc->method.semaphore) {
X status = acpi_os_signal_semaphore (
- walk_state->method_desc->method.semaphore, 1);
+ walk_state->method_desc->method.semaphore, 1);
X }
X
X /* Decrement the thread count on the method parse tree */
X
- op->thread_count--;
- if (!op->thread_count) {
+ walk_state->method_desc->method.thread_count--;
+ if (!walk_state->method_desc->method.thread_count) {
X /*
X * There are no more threads executing this method. Perform
X * additional cleanup.
X *
- * The method NTE is stored in the method Op
+ * The method Node is stored in the walk state
X */
- method_entry = op->acpi_named_object;
-
+ method_node = walk_state->method_node;
X /*
X * Delete any namespace entries created immediately underneath
X * the method
X */
X acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
- if (method_entry->child_table) {
- acpi_ns_delete_namespace_subtree (method_entry);
+ if (method_node->child) {
+ acpi_ns_delete_namespace_subtree (method_node);
X }
X
X /*
X * Delete any namespace entries created anywhere else within
X * the namespace
X */
-
- acpi_ns_delete_namespace_by_owner (
- walk_state->method_desc->method.owning_id);
-
+ acpi_ns_delete_namespace_by_owner (walk_state->method_desc->method.owning_id);
X acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
-
- /*
- * Delete the method's parse tree if asked to
- */
- if (acpi_gbl_when_to_parse_methods & METHOD_DELETE_AT_COMPLETION) {
- acpi_ps_delete_parse_tree (
- walk_state->method_desc->method.parser_op);
-
- walk_state->method_desc->method.parser_op = NULL;
- }
X }
-
-unlock_and_exit:
X
X acpi_cm_release_mutex (ACPI_MTX_PARSER);
X return (AE_OK);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/dispatcher/dsmthdat.c linux/drivers/acpi/dispatcher/dsmthdat.c
--- v2.4.0-test8/linux/drivers/acpi/dispatcher/dsmthdat.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/dispatcher/dsmthdat.c Fri Sep 15 14:30:29 2000
@@ -1,9 +1,9 @@
-
-/******************************************************************************
+/*******************************************************************************
X *
X * Module Name: dsmthdat - control method arguments and local variables
+ * $Revision: 34 $
X *
- *****************************************************************************/
+ ******************************************************************************/
X
X /*
X * Copyright (C) 2000 R. Byron Moore
@@ -25,18 +25,18 @@


X
X
X #include "acpi.h"

-#include "parser.h"
-#include "dispatch.h"
-#include "interp.h"
+#include "acparser.h"
+#include "acdispat.h"
+#include "acinterp.h"
X #include "amlcode.h"
-#include "namesp.h"
+#include "acnamesp.h"
X
X
X #define _COMPONENT DISPATCHER
- MODULE_NAME ("dsmthdat");
+ MODULE_NAME ("dsmthdat")
X
X
-/*****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_ds_method_data_init
X *
@@ -49,7 +49,7 @@
X * This allows Ref_of and De_ref_of to work properly for these
X * special data types.
X *
- ****************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS
X acpi_ds_method_data_init (
@@ -62,8 +62,8 @@
X * Walk_state fields are initialized to zero by the
X * Acpi_cm_callocate().
X *
- * An NTE is assigned to each argument and local so
- * that Ref_of() can return a pointer to the NTE.
+ * An Node is assigned to each argument and local so
+ * that Ref_of() can return a pointer to the Node.
X */
X
X /* Init the method arguments */
@@ -72,10 +72,9 @@
X MOVE_UNALIGNED32_TO_32 (&walk_state->arguments[i].name,
X NAMEOF_ARG_NTE);
X
- walk_state->arguments[i].name |= (i << 24);
- walk_state->arguments[i].data_type = ACPI_DESC_TYPE_NAMED;
- walk_state->arguments[i].type =
- INTERNAL_TYPE_METHOD_ARGUMENT;
+ walk_state->arguments[i].name |= (i << 24);
+ walk_state->arguments[i].data_type = ACPI_DESC_TYPE_NAMED;
+ walk_state->arguments[i].type = INTERNAL_TYPE_METHOD_ARGUMENT;
X }
X
X /* Init the method locals */
@@ -84,18 +83,16 @@
X MOVE_UNALIGNED32_TO_32 (&walk_state->local_variables[i].name,
X NAMEOF_LOCAL_NTE);
X
- walk_state->local_variables[i].name |= (i << 24);
+ walk_state->local_variables[i].name |= (i << 24);
X walk_state->local_variables[i].data_type = ACPI_DESC_TYPE_NAMED;
- walk_state->local_variables[i].type =
- INTERNAL_TYPE_METHOD_LOCAL_VAR;
+ walk_state->local_variables[i].type = INTERNAL_TYPE_METHOD_LOCAL_VAR;
X }
X
-
X return (AE_OK);
X }
X
X
-/*****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_ds_method_data_delete_all
X *
@@ -106,14 +103,14 @@
X * DESCRIPTION: Delete method locals and arguments. Arguments are only
X * deleted if this method was called from another method.
X *
- ****************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS
X acpi_ds_method_data_delete_all (
X ACPI_WALK_STATE *walk_state)
X {
X u32 index;


- ACPI_OBJECT_INTERNAL *object;
+ ACPI_OPERAND_OBJECT *object;
X
X

X /* Delete the locals */
@@ -122,8 +119,11 @@
X object = walk_state->local_variables[index].object;
X if (object) {
X /* Remove first */
+
X walk_state->local_variables[index].object = NULL;
+
X /* Was given a ref when stored */
+
X acpi_cm_remove_reference (object);
X }
X }
@@ -135,8 +135,11 @@
X object = walk_state->arguments[index].object;
X if (object) {
X /* Remove first */
+
X walk_state->arguments[index].object = NULL;
+
X /* Was given a ref when stored */
+
X acpi_cm_remove_reference (object);
X }
X }
@@ -145,7 +148,7 @@
X }
X
X
-/*****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_ds_method_data_init_args
X *
@@ -155,12 +158,13 @@
X *
X * DESCRIPTION: Initialize arguments for a method
X *
- ****************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS
X acpi_ds_method_data_init_args (
- ACPI_OBJECT_INTERNAL **params,
- u32 max_param_count)
+ ACPI_OPERAND_OBJECT **params,
+ u32 max_param_count,
+ ACPI_WALK_STATE *walk_state)
X {
X ACPI_STATUS status;
X u32 mindex;
@@ -183,9 +187,8 @@
X * Set the current method argument to the
X * Params[Pindex++] argument object descriptor
X */
- status = acpi_ds_method_data_set_value (MTH_TYPE_ARG,
- mindex,
- params[pindex]);
+ status = acpi_ds_method_data_set_value (MTH_TYPE_ARG, mindex,
+ params[pindex], walk_state);
X if (ACPI_FAILURE (status)) {
X break;
X }
@@ -202,7 +205,7 @@
X }
X
X
-/*****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_ds_method_data_get_entry
X *
@@ -215,18 +218,16 @@
X *
X * DESCRIPTION: Get the address of the stack entry given by Type:Index
X *
- ****************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS
X acpi_ds_method_data_get_entry (
X u32 type,
X u32 index,
- ACPI_OBJECT_INTERNAL ***entry)
+ ACPI_WALK_STATE *walk_state,
+ ACPI_OPERAND_OBJECT ***entry)
X {
- ACPI_WALK_STATE *walk_state;
-
X
- walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list);
X
X /*
X * Get the requested object.
@@ -243,7 +244,7 @@
X }
X
X *entry =
- (ACPI_OBJECT_INTERNAL **) &walk_state->local_variables[index].object;
+ (ACPI_OPERAND_OBJECT **) &walk_state->local_variables[index].object;
X break;
X
X
@@ -254,7 +255,7 @@
X }
X
X *entry =
- (ACPI_OBJECT_INTERNAL **) &walk_state->arguments[index].object;
+ (ACPI_OPERAND_OBJECT **) &walk_state->arguments[index].object;
X break;
X
X
@@ -267,7 +268,7 @@
X }
X
X
-/*****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_ds_method_data_set_entry
X *
@@ -279,21 +280,22 @@
X *
X * DESCRIPTION: Insert an object onto the method stack at entry Type:Index.
X *
- ****************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS
X acpi_ds_method_data_set_entry (
X u32 type,
X u32 index,
- ACPI_OBJECT_INTERNAL *object)
+ ACPI_OPERAND_OBJECT *object,
+ ACPI_WALK_STATE *walk_state)
X {
X ACPI_STATUS status;
- ACPI_OBJECT_INTERNAL **entry;
+ ACPI_OPERAND_OBJECT **entry;
X
X
X /* Get a pointer to the stack entry to set */
X
- status = acpi_ds_method_data_get_entry (type, index, &entry);
+ status = acpi_ds_method_data_get_entry (type, index, walk_state, &entry);
X if (ACPI_FAILURE (status)) {
X return (status);
X }
@@ -310,7 +312,7 @@
X }
X
X
-/*****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_ds_method_data_get_type
X *
@@ -321,21 +323,22 @@
X * RETURN: Data type of selected Arg or Local
X * Used only in Exec_monadic2()/Type_op.
X *
- ****************************************************************************/
+ ******************************************************************************/
X
X OBJECT_TYPE_INTERNAL
X acpi_ds_method_data_get_type (
X u32 type,
- u32 index)
+ u32 index,
+ ACPI_WALK_STATE *walk_state)
X {
X ACPI_STATUS status;
- ACPI_OBJECT_INTERNAL **entry;
- ACPI_OBJECT_INTERNAL *object;
+ ACPI_OPERAND_OBJECT **entry;


+ ACPI_OPERAND_OBJECT *object;
X
X

X /* Get a pointer to the requested stack entry */
X
- status = acpi_ds_method_data_get_entry (type, index, &entry);
+ status = acpi_ds_method_data_get_entry (type, index, walk_state, &entry);
X if (ACPI_FAILURE (status)) {
X return ((ACPI_TYPE_NOT_FOUND));


X }
@@ -355,7 +358,7 @@
X }

X
X
-/*****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_ds_method_data_get_nte
X *
@@ -363,20 +366,17 @@
X * Index - Which local_var or argument whose type
X * to get
X *
- * RETURN: Get the NTE associated with a local or arg.
+ * RETURN: Get the Node associated with a local or arg.
X *
- ****************************************************************************/
+ ******************************************************************************/
X
-ACPI_NAMED_OBJECT*
+ACPI_NAMESPACE_NODE *
X acpi_ds_method_data_get_nte (
X u32 type,
- u32 index)
+ u32 index,
+ ACPI_WALK_STATE *walk_state)
X {
- ACPI_NAMED_OBJECT *entry = NULL;
- ACPI_WALK_STATE *walk_state;
-
-
- walk_state = acpi_ds_get_current_walk_state (acpi_gbl_current_walk_list);
+ ACPI_NAMESPACE_NODE *node = NULL;
X
X
X switch (type)
@@ -385,20 +385,20 @@
X case MTH_TYPE_LOCAL:
X
X if (index > MTH_MAX_LOCAL) {
- return (entry);
+ return (node);
X }
X
- entry = &walk_state->local_variables[index];
+ node = &walk_state->local_variables[index];
X break;
X
X
X case MTH_TYPE_ARG:
X
X if (index > MTH_MAX_ARG) {
- return (entry);
+ return (node);
X }
X
- entry = &walk_state->arguments[index];
+ node = &walk_state->arguments[index];
X break;
X
X
@@ -407,11 +407,11 @@
X }
X
X
- return (entry);
+ return (node);
X }
X
X
-/*****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_ds_method_data_get_value
X *
@@ -426,17 +426,18 @@
X * at the current top of the method stack.
X * Used only in Acpi_aml_resolve_to_value().
X *
- ****************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS
X acpi_ds_method_data_get_value (
X u32 type,
X u32 index,
- ACPI_OBJECT_INTERNAL **dest_desc)
+ ACPI_WALK_STATE *walk_state,
+ ACPI_OPERAND_OBJECT **dest_desc)
X {
X ACPI_STATUS status;
- ACPI_OBJECT_INTERNAL **entry;
- ACPI_OBJECT_INTERNAL *object;
+ ACPI_OPERAND_OBJECT **entry;


+ ACPI_OPERAND_OBJECT *object;
X
X

X /* Validate the object descriptor */
@@ -448,7 +449,7 @@
X
X /* Get a pointer to the requested method stack entry */
X
- status = acpi_ds_method_data_get_entry (type, index, &entry);
+ status = acpi_ds_method_data_get_entry (type, index, walk_state, &entry);
X if (ACPI_FAILURE (status)) {
X return (status);
X }
@@ -494,7 +495,7 @@
X }
X
X
-/*****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_ds_method_data_delete_value
X *
@@ -506,21 +507,22 @@
X * DESCRIPTION: Delete the entry at Type:Index on the method stack. Inserts
X * a null into the stack slot after the object is deleted.
X *
- ****************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS
X acpi_ds_method_data_delete_value (
X u32 type,
- u32 index)
+ u32 index,
+ ACPI_WALK_STATE *walk_state)
X {
X ACPI_STATUS status;
- ACPI_OBJECT_INTERNAL **entry;


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 020'
echo 'File patch-2.4.0-test9 is continued in part 021'
echo "021" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part021

#!/bin/sh -x
# this is part 021 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 021; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

- ACPI_OBJECT_INTERNAL *object;
+ ACPI_OPERAND_OBJECT **entry;
+ ACPI_OPERAND_OBJECT *object;
X
X

X /* Get a pointer to the requested entry */


X
- status = acpi_ds_method_data_get_entry (type, index, &entry);
+ status = acpi_ds_method_data_get_entry (type, index, walk_state, &entry);
X if (ACPI_FAILURE (status)) {
X return (status);
X }

@@ -532,7 +534,7 @@
X /*
X * Undefine the Arg or Local by setting its descriptor
X * pointer to NULL. Locals/Args can contain both
- * ACPI_OBJECT_INTERNALS and ACPI_NAMED_OBJECTs
+ * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs
X */
X *entry = NULL;
X
@@ -554,7 +556,7 @@


X }
X
X
-/*****************************************************************************
+/*******************************************************************************
X *

X * FUNCTION: Acpi_ds_method_data_set_value
X *
@@ -573,16 +575,17 @@
X * as the new value for the Arg or Local and the reference count
X * is incremented.


X *
- ****************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS

X acpi_ds_method_data_set_value (


X u32 type,
X u32 index,

- ACPI_OBJECT_INTERNAL *src_desc)
+ ACPI_OPERAND_OBJECT *src_desc,


+ ACPI_WALK_STATE *walk_state)
X {
X ACPI_STATUS status;
- ACPI_OBJECT_INTERNAL **entry;
+ ACPI_OPERAND_OBJECT **entry;
X
X

X /* Parameter validation */
@@ -594,7 +597,7 @@


X
X /* Get a pointer to the requested method stack entry */
X
- status = acpi_ds_method_data_get_entry (type, index, &entry);
+ status = acpi_ds_method_data_get_entry (type, index, walk_state, &entry);
X if (ACPI_FAILURE (status)) {

X goto cleanup;
X }
@@ -614,7 +617,7 @@
X if (*entry) {
X /*
X * Check for an indirect store if an argument
- * contains an object reference (stored as an NTE).
+ * contains an object reference (stored as an Node).
X * We don't allow this automatic dereferencing for
X * locals, since a store to a local should overwrite
X * anything there, including an object reference.
@@ -632,16 +635,16 @@
X if ((type == MTH_TYPE_ARG) &&
X (VALID_DESCRIPTOR_TYPE (*entry, ACPI_DESC_TYPE_NAMED)))
X {
- /* Detach an existing object from the NTE */
+ /* Detach an existing object from the Node */
X
- acpi_ns_detach_object (*entry);
+ acpi_ns_detach_object ((ACPI_NAMESPACE_NODE *) *entry);
X
X /*
- * Store this object into the NTE
+ * Store this object into the Node
X * (do the indirect store)
X */
X
- status = acpi_ns_attach_object (*entry, src_desc,
+ status = acpi_ns_attach_object ((ACPI_NAMESPACE_NODE *) *entry, src_desc,
X src_desc->common.type);
X return (status);
X }
@@ -652,7 +655,7 @@
X * before storing the new one
X */
X
- acpi_ds_method_data_delete_value (type, index);
+ acpi_ds_method_data_delete_value (type, index, walk_state);
X }
X
X
@@ -663,7 +666,7 @@
X * (increments the object reference count by one)
X */
X
- status = acpi_ds_method_data_set_entry (type, index, src_desc);
+ status = acpi_ds_method_data_set_entry (type, index, src_desc, walk_state);
X if (ACPI_FAILURE (status)) {
X goto cleanup;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/dispatcher/dsobject.c linux/drivers/acpi/dispatcher/dsobject.c
--- v2.4.0-test8/linux/drivers/acpi/dispatcher/dsobject.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/dispatcher/dsobject.c Fri Sep 15 14:30:29 2000


@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *

X * Module Name: dsobject - Dispatcher object management routines


+ * $Revision: 43 $
X *
X *****************************************************************************/
X

@@ -25,21 +25,21 @@


X
X
X #include "acpi.h"
-#include "parser.h"
+#include "acparser.h"
X #include "amlcode.h"
-#include "dispatch.h"
-#include "interp.h"
-#include "namesp.h"

+#include "acdispat.h"
+#include "acinterp.h"
+#include "acnamesp.h"
X
X #define _COMPONENT DISPATCHER

- MODULE_NAME ("dsobject");
+ MODULE_NAME ("dsobject")


X
X
X /*******************************************************************************
X *

X * FUNCTION: Acpi_ds_init_one_object
X *
- * PARAMETERS: Obj_handle - NTE of the object


+ * PARAMETERS: Obj_handle - Node

X * Level - Current nesting level

X * Context - Points to a init info struct


X * Return_value - Not used

@@ -64,7 +64,6 @@
X {
X OBJECT_TYPE_INTERNAL type;


X ACPI_STATUS status;
- ACPI_OBJECT_INTERNAL *obj_desc;

X INIT_WALK_INFO *info = (INIT_WALK_INFO *) context;
X
X
@@ -73,10 +72,10 @@
X * was just loaded
X */
X
- if (((ACPI_NAMED_OBJECT*) obj_handle)->owner_id !=
+ if (((ACPI_NAMESPACE_NODE *) obj_handle)->owner_id !=
X info->table_desc->table_id)
X {


- return AE_OK;
+ return (AE_OK);
X }
X
X

@@ -119,12 +118,7 @@
X */
X
X if (acpi_gbl_when_to_parse_methods != METHOD_PARSE_AT_INIT) {
-
X acpi_ns_delete_namespace_subtree (obj_handle);
-
- obj_desc = ((ACPI_NAMED_OBJECT*)obj_handle)->object;
- acpi_ps_delete_parse_tree (obj_desc->method.parser_op);
- obj_desc->method.parser_op = NULL;
X }
X
X break;
@@ -149,15 +143,15 @@
X *
X * RETURN: Status
X *
- * DESCRIPTION: Walk the entire namespace and perform any necessary initialization
- * on the objects found therein
+ * DESCRIPTION: Walk the entire namespace and perform any necessary
+ * initialization on the objects found therein
X *
X ******************************************************************************/
X
X ACPI_STATUS
X acpi_ds_initialize_objects (
X ACPI_TABLE_DESC *table_desc,
- ACPI_NAMED_OBJECT *start_entry)
+ ACPI_NAMESPACE_NODE *start_node)
X {
X ACPI_STATUS status;
X INIT_WALK_INFO info;


@@ -170,8 +164,8 @@
X

X /* Walk entire namespace from the supplied root */
X
- status = acpi_walk_namespace (ACPI_TYPE_ANY, start_entry,
- ACPI_INT32_MAX, acpi_ds_init_one_object,
+ status = acpi_walk_namespace (ACPI_TYPE_ANY, start_node,
+ ACPI_UINT32_MAX, acpi_ds_init_one_object,
X &info, NULL);
X
X return (AE_OK);
@@ -197,28 +191,28 @@
X ACPI_STATUS
X acpi_ds_init_object_from_op (
X ACPI_WALK_STATE *walk_state,
- ACPI_GENERIC_OP *op,
+ ACPI_PARSE_OBJECT *op,
X u16 opcode,
- ACPI_OBJECT_INTERNAL *obj_desc)
+ ACPI_OPERAND_OBJECT **obj_desc)


X {
X ACPI_STATUS status;
- ACPI_GENERIC_OP *arg;

- ACPI_BYTELIST_OP *byte_list;
- ACPI_OBJECT_INTERNAL *arg_desc;
- ACPI_OP_INFO *op_info;
+ ACPI_PARSE_OBJECT *arg;
+ ACPI_PARSE2_OBJECT *byte_list;
+ ACPI_OPERAND_OBJECT *arg_desc;
+ ACPI_OPCODE_INFO *op_info;
X
X
X op_info = acpi_ps_get_opcode_info (opcode);
- if (!op_info) {
+ if (ACPI_GET_OP_TYPE (op_info) != ACPI_OP_TYPE_OPCODE) {
X /* Unknown opcode */
X
- return AE_TYPE;
+ return (AE_TYPE);
X }
X
X
X /* Get and prepare the first argument */
X
- switch (obj_desc->common.type)
+ switch ((*obj_desc)->common.type)
X {
X case ACPI_TYPE_BUFFER:
X
@@ -230,31 +224,31 @@
X
X /* Resolve the object (could be an arg or local) */
X
- status = acpi_aml_resolve_to_value (&arg_desc);
+ status = acpi_aml_resolve_to_value (&arg_desc, walk_state);
X if (ACPI_FAILURE (status)) {
X acpi_cm_remove_reference (arg_desc);


- return status;
+ return (status);
X }
X

X /* We are expecting a number */
X
X if (arg_desc->common.type != ACPI_TYPE_NUMBER) {
X acpi_cm_remove_reference (arg_desc);
- return AE_TYPE;
+ return (AE_TYPE);
X }
X
X /* Get the value, delete the internal object */
X
- obj_desc->buffer.length = arg_desc->number.value;
+ (*obj_desc)->buffer.length = arg_desc->number.value;
X acpi_cm_remove_reference (arg_desc);
X
X /* Allocate the buffer */
X
- obj_desc->buffer.pointer =
- acpi_cm_callocate (obj_desc->buffer.length);
+ (*obj_desc)->buffer.pointer =
+ acpi_cm_callocate ((*obj_desc)->buffer.length);
X
- if (!obj_desc->buffer.pointer) {
- return AE_NO_MEMORY;
+ if (!(*obj_desc)->buffer.pointer) {


+ return (AE_NO_MEMORY);
X }
X

X /*
@@ -265,27 +259,42 @@
X
X /* skip first arg */


X arg = op->value.arg;

- byte_list = (ACPI_BYTELIST_OP *) arg->next;
+ byte_list = (ACPI_PARSE2_OBJECT *) arg->next;
X if (byte_list) {
X if (byte_list->opcode != AML_BYTELIST_OP) {
- return AE_TYPE;
+ return (AE_TYPE);
X }
X
- MEMCPY (obj_desc->buffer.pointer, byte_list->data,
- obj_desc->buffer.length);
+ MEMCPY ((*obj_desc)->buffer.pointer, byte_list->data,
+ (*obj_desc)->buffer.length);
X }
X
X break;
X
X
+ case ACPI_TYPE_PACKAGE:
+
+ /*
+ * When called, an internal package object has already
+ * been built and is pointed to by *Obj_desc.
+ * Acpi_ds_build_internal_object build another internal
+ * package object, so remove reference to the original
+ * so that it is deleted. Error checking is done
+ * within the remove reference function.
+ */
+ acpi_cm_remove_reference(*obj_desc);
+
+ status = acpi_ds_build_internal_object (walk_state, op, obj_desc);
+ break;
+
X case ACPI_TYPE_NUMBER:
- obj_desc->number.value = op->value.integer;
+ (*obj_desc)->number.value = op->value.integer;
X break;
X
X
X case ACPI_TYPE_STRING:
- obj_desc->string.pointer = op->value.string;
- obj_desc->string.length = STRLEN (op->value.string);
+ (*obj_desc)->string.pointer = op->value.string;
+ (*obj_desc)->string.length = STRLEN (op->value.string);
X break;
X
X
@@ -295,33 +304,33 @@
X
X case INTERNAL_TYPE_REFERENCE:
X
- switch (op_info->flags & OP_INFO_TYPE)
+ switch (ACPI_GET_OP_CLASS (op_info))
X {
X case OPTYPE_LOCAL_VARIABLE:
X
X /* Split the opcode into a base opcode + offset */
X
- obj_desc->reference.op_code = AML_LOCAL_OP;
- obj_desc->reference.offset = opcode - AML_LOCAL_OP;
+ (*obj_desc)->reference.op_code = AML_LOCAL_OP;
+ (*obj_desc)->reference.offset = opcode - AML_LOCAL_OP;
X break;
X
X case OPTYPE_METHOD_ARGUMENT:
X
X /* Split the opcode into a base opcode + offset */
X
- obj_desc->reference.op_code = AML_ARG_OP;
- obj_desc->reference.offset = opcode - AML_ARG_OP;
+ (*obj_desc)->reference.op_code = AML_ARG_OP;
+ (*obj_desc)->reference.offset = opcode - AML_ARG_OP;
X break;
X
X default: /* Constants, Literals, etc.. */
X
X if (op->opcode == AML_NAMEPATH_OP) {
- /* Nte was saved in Op */
+ /* Node was saved in Op */
X
- obj_desc->reference.nte = op->acpi_named_object;
+ (*obj_desc)->reference.node = op->node;
X }
X
- obj_desc->reference.op_code = opcode;
+ (*obj_desc)->reference.op_code = opcode;
X break;
X }
X
@@ -333,7 +342,7 @@
X break;
X }
X

- return AE_OK;
+ return (AE_OK);
X }
X
X

@@ -354,10 +363,10 @@
X ACPI_STATUS
X acpi_ds_build_internal_simple_obj (
X ACPI_WALK_STATE *walk_state,
- ACPI_GENERIC_OP *op,
- ACPI_OBJECT_INTERNAL **obj_desc_ptr)
+ ACPI_PARSE_OBJECT *op,
+ ACPI_OPERAND_OBJECT **obj_desc_ptr)


X {
- ACPI_OBJECT_INTERNAL *obj_desc;
+ ACPI_OPERAND_OBJECT *obj_desc;

X OBJECT_TYPE_INTERNAL type;
X ACPI_STATUS status;
X
@@ -369,13 +378,13 @@
X * Otherwise, go ahead and look it up now
X */
X
- if (!op->acpi_named_object) {
+ if (!op->node) {


X status = acpi_ns_lookup (walk_state->scope_info,

X op->value.string, ACPI_TYPE_ANY,
X IMODE_EXECUTE,
X NS_SEARCH_PARENT | NS_DONT_OPEN_SCOPE,
X NULL,
- (ACPI_NAMED_OBJECT**)&(op->acpi_named_object));
+ (ACPI_NAMESPACE_NODE **)&(op->node));


X
X if (ACPI_FAILURE (status)) {
X return (status);

@@ -403,7 +412,7 @@
X }
X
X status = acpi_ds_init_object_from_op (walk_state, op,
- op->opcode, obj_desc);
+ op->opcode, &obj_desc);


X
X if (ACPI_FAILURE (status)) {

X acpi_cm_remove_reference (obj_desc);
@@ -433,11 +442,11 @@
X ACPI_STATUS
X acpi_ds_build_internal_package_obj (
X ACPI_WALK_STATE *walk_state,
- ACPI_GENERIC_OP *op,
- ACPI_OBJECT_INTERNAL **obj_desc_ptr)
+ ACPI_PARSE_OBJECT *op,
+ ACPI_OPERAND_OBJECT **obj_desc_ptr)
X {
- ACPI_GENERIC_OP *arg;
- ACPI_OBJECT_INTERNAL *obj_desc;
+ ACPI_PARSE_OBJECT *arg;
+ ACPI_OPERAND_OBJECT *obj_desc;


X ACPI_STATUS status = AE_OK;
X
X

@@ -466,7 +475,7 @@
X
X REPORT_ERROR ("Ds_build_internal_package_obj: Package vector allocation failure");
X
- acpi_cm_free (obj_desc);
+ acpi_cm_delete_object_desc (obj_desc);


X return (AE_NO_MEMORY);
X }
X

@@ -514,8 +523,8 @@
X ACPI_STATUS
X acpi_ds_build_internal_object (
X ACPI_WALK_STATE *walk_state,
- ACPI_GENERIC_OP *op,
- ACPI_OBJECT_INTERNAL **obj_desc_ptr)
+ ACPI_PARSE_OBJECT *op,
+ ACPI_OPERAND_OBJECT **obj_desc_ptr)


X {
X ACPI_STATUS status;
X

@@ -536,7 +545,7 @@
X
X /*****************************************************************************
X *
- * FUNCTION: Acpi_ds_create_named_object
+ * FUNCTION: Acpi_ds_create_node
X *
X * PARAMETERS: Op - Parser object to be translated
X * Obj_desc_ptr - Where the ACPI internal object is returned
@@ -548,13 +557,13 @@
X ****************************************************************************/
X
X ACPI_STATUS
-acpi_ds_create_named_object (
+acpi_ds_create_node (
X ACPI_WALK_STATE *walk_state,
- ACPI_NAMED_OBJECT *entry,
- ACPI_GENERIC_OP *op)
+ ACPI_NAMESPACE_NODE *node,


+ ACPI_PARSE_OBJECT *op)
X {
X ACPI_STATUS status;

- ACPI_OBJECT_INTERNAL *obj_desc;
+ ACPI_OPERAND_OBJECT *obj_desc;
X

X
X if (!op->value.arg) {
@@ -575,12 +584,12 @@
X
X /* Re-type the object according to it's argument */
X
- entry->type = obj_desc->common.type;
+ node->type = obj_desc->common.type;
X
X /* Init obj */
X
- status = acpi_ns_attach_object ((ACPI_HANDLE) entry, obj_desc,
- (u8) entry->type);
+ status = acpi_ns_attach_object ((ACPI_HANDLE) node, obj_desc,
+ (u8) node->type);


X if (ACPI_FAILURE (status)) {
X goto cleanup;
X }

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/dispatcher/dsopcode.c linux/drivers/acpi/dispatcher/dsopcode.c
--- v2.4.0-test8/linux/drivers/acpi/dispatcher/dsopcode.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/dispatcher/dsopcode.c Fri Sep 15 14:30:29 2000
@@ -1,8 +1,8 @@


-
X /******************************************************************************
X *

- * Module Name: dsopcode - Dispatcher Op Region support
- * and handling of "control" opcodes
+ * Module Name: dsopcode - Dispatcher Op Region support and handling of
+ * "control" opcodes
+ * $Revision: 17 $


X *
X *****************************************************************************/
X

@@ -26,16 +26,16 @@
X
X

X #include "acpi.h"
-#include "parser.h"
+#include "acparser.h"
X #include "amlcode.h"
-#include "dispatch.h"
-#include "interp.h"
-#include "namesp.h"

-#include "events.h"
-#include "tables.h"


+#include "acdispat.h"
+#include "acinterp.h"
+#include "acnamesp.h"

+#include "acevents.h"
+#include "actables.h"


X
X #define _COMPONENT DISPATCHER

- MODULE_NAME ("dsopcode");
+ MODULE_NAME ("dsopcode")
X
X
X /*****************************************************************************
@@ -53,23 +53,23 @@
X
X ACPI_STATUS
X acpi_ds_get_region_arguments (
- ACPI_OBJECT_INTERNAL *rgn_desc)
+ ACPI_OPERAND_OBJECT *rgn_desc)
X {
- ACPI_OBJECT_INTERNAL *method_desc;
- ACPI_NAMED_OBJECT *entry;
- ACPI_GENERIC_OP *op;
- ACPI_GENERIC_OP *region_op;
+ ACPI_OPERAND_OBJECT *method_desc;
+ ACPI_NAMESPACE_NODE *node;
+ ACPI_PARSE_OBJECT *op;
+ ACPI_PARSE_OBJECT *region_op;
X ACPI_STATUS status;
X ACPI_TABLE_DESC *table_desc;
X
X
- if (rgn_desc->region.region_flags & REGION_AGRUMENT_DATA_VALID) {
+ if (rgn_desc->region.flags & AOPOBJ_DATA_VALID) {


X return (AE_OK);
X }
X
X

X method_desc = rgn_desc->region.method;
- entry = rgn_desc->region.nte;
+ node = rgn_desc->region.node;
X
X
X /*
@@ -77,18 +77,18 @@
X * Op_region tree
X */
X
- op = acpi_ps_alloc_op (AML_REGION_OP);


+ op = acpi_ps_alloc_op (AML_SCOPE_OP);

X if (!op) {


- return AE_NO_MEMORY;
+ return (AE_NO_MEMORY);
X }
X

- /* Save the NTE for use in Acpi_ps_parse_aml */
+ /* Save the Node for use in Acpi_ps_parse_aml */
X
- op->acpi_named_object = acpi_ns_get_parent_entry (entry);
+ op->node = acpi_ns_get_parent_object (node);
X
X /* Get a handle to the parent ACPI table */
X
- status = acpi_tb_handle_to_object (entry->owner_id, &table_desc);
+ status = acpi_tb_handle_to_object (node->owner_id, &table_desc);


X if (ACPI_FAILURE (status)) {
X return (status);
X }

@@ -96,20 +96,44 @@
X /* Parse the entire Op_region declaration, creating a parse tree */
X
X status = acpi_ps_parse_aml (op, method_desc->method.pcode,
- method_desc->method.pcode_length, 0);
- if (ACPI_SUCCESS (status)) {
- /* Get and init the actual Region_op created above */
-
- region_op = op->value.arg;
- region_op->acpi_named_object = entry;
-
- /* Acpi_evaluate the address and length arguments for the Op_region */
-
- acpi_ps_walk_parsed_aml (region_op, region_op, NULL, NULL, NULL,
- NULL, table_desc->table_id,
- acpi_ds_exec_begin_op, acpi_ds_exec_end_op);
+ method_desc->method.pcode_length, 0,
+ NULL, NULL, NULL, acpi_ds_load1_begin_op, acpi_ds_load1_end_op);


+
+ if (ACPI_FAILURE (status)) {

+ acpi_ps_delete_parse_tree (op);


+ return (status);
X }
X

+
+ /* Get and init the actual Region_op created above */
+
+/* Region_op = Op->Value.Arg;
+ Op->Node = Node;*/
+
+
+ region_op = op->value.arg;
+ region_op->node = node;
+ acpi_ps_delete_parse_tree (op);
+
+ /* Acpi_evaluate the address and length arguments for the Op_region */


+
+ op = acpi_ps_alloc_op (AML_SCOPE_OP);
+ if (!op) {
+ return (AE_NO_MEMORY);
+ }
+

+ op->node = acpi_ns_get_parent_object (node);
+
+ status = acpi_ps_parse_aml (op, method_desc->method.pcode,
+ method_desc->method.pcode_length,
+ ACPI_PARSE_EXECUTE | ACPI_PARSE_DELETE_TREE,
+ NULL /*Method_desc*/, NULL, NULL,
+ acpi_ds_exec_begin_op, acpi_ds_exec_end_op);
+/*
+ Acpi_ps_walk_parsed_aml (Region_op, Region_op, NULL, NULL, NULL,
+ NULL, Table_desc->Table_id,
+ Acpi_ds_exec_begin_op, Acpi_ds_exec_end_op);
+*/
X /* All done with the parse tree, delete it */
X
X acpi_ps_delete_parse_tree (op);
@@ -134,7 +158,7 @@
X acpi_ds_initialize_region (
X ACPI_HANDLE obj_handle)


X {
- ACPI_OBJECT_INTERNAL *obj_desc;
+ ACPI_OPERAND_OBJECT *obj_desc;

X ACPI_STATUS status;
X
X

@@ -144,7 +168,7 @@
X
X status = acpi_ev_initialize_region (obj_desc, FALSE);


X
- return status;
+ return (status);
X }
X
X

@@ -164,20 +188,20 @@
X ACPI_STATUS
X acpi_ds_eval_region_operands (
X ACPI_WALK_STATE *walk_state,


- ACPI_GENERIC_OP *op)
+ ACPI_PARSE_OBJECT *op)
X {
X ACPI_STATUS status;

- ACPI_OBJECT_INTERNAL *obj_desc;
- ACPI_OBJECT_INTERNAL *region_desc;
- ACPI_NAMED_OBJECT *entry;
- ACPI_GENERIC_OP *next_op;
+ ACPI_OPERAND_OBJECT *obj_desc;
+ ACPI_OPERAND_OBJECT *region_desc;
+ ACPI_NAMESPACE_NODE *node;
+ ACPI_PARSE_OBJECT *next_op;
X
X
X /*
X * This is where we evaluate the address and length fields of the Op_region declaration
X */
X
- entry = op->acpi_named_object;
+ node = op->node;
X
X /* Next_op points to the op that holds the Space_iD */
X next_op = op->value.arg;
@@ -192,7 +216,7 @@


X return (status);
X }
X

- region_desc = acpi_ns_get_attached_object (entry);
+ region_desc = acpi_ns_get_attached_object (node);
X if (!region_desc) {
X return (AE_NOT_EXIST);
X }
@@ -216,7 +240,7 @@
X
X /* Now the address and length are valid for this opregion */
X
- region_desc->region.region_flags |= REGION_AGRUMENT_DATA_VALID;
+ region_desc->region.flags |= AOPOBJ_DATA_VALID;


X
X return (status);
X }

@@ -239,7 +263,7 @@
X ACPI_STATUS
X acpi_ds_exec_begin_control_op (
X ACPI_WALK_STATE *walk_state,


- ACPI_GENERIC_OP *op)
+ ACPI_PARSE_OBJECT *op)
X {

X ACPI_STATUS status = AE_OK;
X ACPI_GENERIC_STATE *control_state;
@@ -263,6 +287,14 @@
X }
X
X acpi_cm_push_generic_state (&walk_state->control_state, control_state);
+
+ /*
+ * Save a pointer to the predicate for multiple executions
+ * of a loop
+ */
+ walk_state->control_state->control.aml_predicate_start =
+ walk_state->parser_state->aml - 1;
+ /*Acpi_ps_pkg_length_encoding_size (GET8 (Walk_state->Parser_state->Aml));*/
X break;
X
X
@@ -287,7 +319,7 @@
X break;


X }
X
- return status;
+ return (status);
X }
X
X

@@ -309,7 +341,7 @@
X ACPI_STATUS
X acpi_ds_exec_end_control_op (
X ACPI_WALK_STATE *walk_state,


- ACPI_GENERIC_OP *op)
+ ACPI_PARSE_OBJECT *op)
X {

X ACPI_STATUS status = AE_OK;
X ACPI_GENERIC_STATE *control_state;
@@ -350,16 +382,18 @@
X if (walk_state->control_state->common.value) {
X /* Predicate was true, go back and evaluate it again! */
X
- status = AE_CTRL_TRUE;
+ status = AE_CTRL_PENDING;
X }
X
- else {
+/* else {*/
X /* Pop this control state and free it */
X
X control_state =
X acpi_cm_pop_generic_state (&walk_state->control_state);
+
+ walk_state->aml_last_while = control_state->control.aml_predicate_start;
X acpi_cm_delete_generic_state (control_state);
- }
+/* }*/
X
X break;
X
@@ -367,44 +401,62 @@
X case AML_RETURN_OP:
X
X
- /* One optional operand -- the return value */
-
+ /*
+ * One optional operand -- the return value
+ * It can be either an immediate operand or a result that
+ * has been bubbled up the tree
+ */
X if (op->value.arg) {
+ /* Return statement has an immediate operand */
+
X status = acpi_ds_create_operands (walk_state, op->value.arg);
X if (ACPI_FAILURE (status)) {


- return status;
+ return (status);
X }
X

X /*
- * TBD: [Restructure] Just check for NULL arg
- * to signify no return value???
- */
-
- /*
X * If value being returned is a Reference (such as
X * an arg or local), resolve it now because it may
X * cease to exist at the end of the method.
X */
X
- status = acpi_aml_resolve_to_value (&walk_state->operands [0]);
+ status = acpi_aml_resolve_to_value (&walk_state->operands [0], walk_state);
X if (ACPI_FAILURE (status)) {


- return status;
+ return (status);
X }
X

X /*
X * Get the return value and save as the last result
- * value
- * This is the only place where Walk_state->Return_desc
+ * value. This is the only place where Walk_state->Return_desc
X * is set to anything other than zero!
X */
X
X walk_state->return_desc = walk_state->operands[0];
X }
X
+ else if (walk_state->num_results > 0) {
+ /*
+ * The return value has come from a previous calculation.
+ *
+ * If value being returned is a Reference (such as
+ * an arg or local), resolve it now because it may
+ * cease to exist at the end of the method.
+ */
+
+ status = acpi_aml_resolve_to_value (&walk_state->results [0], walk_state);
+ if (ACPI_FAILURE (status)) {
+ return (status);
+ }
+
+ walk_state->return_desc = walk_state->results [0];
+ }
+
X else {
X /* No return operand */
X
- acpi_cm_remove_reference (walk_state->operands [0]);
+ if (walk_state->num_operands) {
+ acpi_cm_remove_reference (walk_state->operands [0]);
+ }
X
X walk_state->operands [0] = NULL;
X walk_state->num_operands = 0;
@@ -417,7 +469,7 @@
X break;
X
X
- case AML_NOOP_CODE:
+ case AML_NOOP_OP:
X
X /* Just do nothing! */
X break;
@@ -459,6 +511,6 @@
X }
X
X

- return status;
+ return (status);
X }
X

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/dispatcher/dsutils.c linux/drivers/acpi/dispatcher/dsutils.c
--- v2.4.0-test8/linux/drivers/acpi/dispatcher/dsutils.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/dispatcher/dsutils.c Fri Sep 15 14:30:29 2000


@@ -1,9 +1,9 @@
-
-/******************************************************************************
+/*******************************************************************************
X *

X * Module Name: dsutils - Dispatcher utilities
+ * $Revision: 44 $


X *
- *****************************************************************************/
+ ******************************************************************************/
X
X /*
X * Copyright (C) 2000 R. Byron Moore

@@ -25,20 +25,20 @@


X
X
X #include "acpi.h"
-#include "parser.h"
+#include "acparser.h"
X #include "amlcode.h"
-#include "dispatch.h"
-#include "interp.h"
-#include "namesp.h"

-#include "debugger.h"
+#include "acdispat.h"
+#include "acinterp.h"
+#include "acnamesp.h"

+#include "acdebug.h"
X
X #define _COMPONENT PARSER
- MODULE_NAME ("dsutils");
+ MODULE_NAME ("dsutils")


X
X
-/*****************************************************************************
+/*******************************************************************************
X *

- * FUNCTION: Acpi_ds_delete_result_if_not_used
+ * FUNCTION: Acpi_ds_is_result_used


X *
X * PARAMETERS: Op

X * Result_obj
@@ -46,52 +46,32 @@
X *
X * RETURN: Status
X *
- * DESCRIPTION: Used after interpretation of an opcode. If there is an internal
- * result descriptor, check if the parent opcode will actually use
- * this result. If not, delete the result now so that it will
- * not become orphaned.
+ * DESCRIPTION: Check if a result object will be used by the parent


X *
- ****************************************************************************/
+ ******************************************************************************/
X

-void
-acpi_ds_delete_result_if_not_used (
- ACPI_GENERIC_OP *op,
- ACPI_OBJECT_INTERNAL *result_obj,
- ACPI_WALK_STATE *walk_state)
+u8
+acpi_ds_is_result_used (
+ ACPI_PARSE_OBJECT *op)
X {
- ACPI_OP_INFO *parent_info;
- ACPI_OBJECT_INTERNAL *obj_desc;
- ACPI_STATUS status;
+ ACPI_OPCODE_INFO *parent_info;
+
X
+ /* Must have both an Op and a Result Object */
X
X if (!op) {
- return;


+ return (TRUE);
X }
X

- if (!result_obj) {
- return;
- }
X
+ /*
+ * If there is no parent, the result can't possibly be used!
+ * (An executing method typically has no parent, since each
+ * method is parsed separately) However, a method that is
+ * invoked from another method has a parent.
+ */
X if (!op->parent) {
- /*
- * If there is no parent, the result can't possibly be used!
- * (An executing method typically has no parent, since each
- * method is parsed separately
- */
-
- /*
- * Must pop the result stack (Obj_desc should be equal
- * to Result_obj)
- */
-
- status = acpi_ds_result_stack_pop (&obj_desc, walk_state);
- if (ACPI_FAILURE (status)) {
- return;
- }
-
- acpi_cm_remove_reference (result_obj);
-
- return;


+ return (FALSE);
X }
X
X

@@ -100,15 +80,15 @@
X */
X
X parent_info = acpi_ps_get_opcode_info (op->parent->opcode);
- if (!parent_info) {
- return;
+ if (ACPI_GET_OP_TYPE (parent_info) != ACPI_OP_TYPE_OPCODE) {


+ return (FALSE);
X }
X
X

X /* Never delete the return value associated with a return opcode */
X
X if (op->parent->opcode == AML_RETURN_OP) {
- return;


+ return (TRUE);
X }
X
X

@@ -119,26 +99,15 @@
X * as an operand later.
X */
X
- switch (parent_info->flags & OP_INFO_TYPE)
+ switch (ACPI_GET_OP_CLASS (parent_info))
X {
X /*
- * In these cases, the parent will never use the return object,
- * so delete it here and now.
+ * In these cases, the parent will never use the return object
X */
X case OPTYPE_CONTROL: /* IF, ELSE, WHILE only */
X case OPTYPE_NAMED_OBJECT: /* Scope, method, etc. */
X
- /*
- * Must pop the result stack (Obj_desc should be equal
- * to Result_obj)
- */
-
- status = acpi_ds_result_stack_pop (&obj_desc, walk_state);
- if (ACPI_FAILURE (status)) {
- return;
- }
-
- acpi_cm_remove_reference (result_obj);
+ return (FALSE);
X break;
X
X /*
@@ -149,11 +118,63 @@
X break;
X }
X
+ return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_ds_delete_result_if_not_used
+ *
+ * PARAMETERS: Op
+ * Result_obj
+ * Walk_state
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Used after interpretation of an opcode. If there is an internal
+ * result descriptor, check if the parent opcode will actually use
+ * this result. If not, delete the result now so that it will
+ * not become orphaned.


+ *
+ ******************************************************************************/
+
+void

+acpi_ds_delete_result_if_not_used (
+ ACPI_PARSE_OBJECT *op,
+ ACPI_OPERAND_OBJECT *result_obj,
+ ACPI_WALK_STATE *walk_state)
+{
+ ACPI_OPERAND_OBJECT *obj_desc;
+ ACPI_STATUS status;
+
+
+ if (!op) {
+ return;
+ }
+
+ if (!result_obj) {
+ return;
+ }
+
+
+ if (!acpi_ds_is_result_used (op)) {
+ /*
+ * Must pop the result stack (Obj_desc should be equal
+ * to Result_obj)
+ */
+
+ status = acpi_ds_result_stack_pop (&obj_desc, walk_state);
+ if (ACPI_SUCCESS (status)) {
+ acpi_cm_remove_reference (result_obj);
+ }
+ }
+


X return;
X }
X
X
-/*****************************************************************************
+/*******************************************************************************
X *

X * FUNCTION: Acpi_ds_create_operand
X *
@@ -167,19 +188,19 @@
X * looking up a name or entering a new name into the internal
X * namespace.


X *
- ****************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS

X acpi_ds_create_operand (
X ACPI_WALK_STATE *walk_state,
- ACPI_GENERIC_OP *arg)
+ ACPI_PARSE_OBJECT *arg)


X {
X ACPI_STATUS status = AE_OK;

- char *name_string;
+ NATIVE_CHAR *name_string;
X u32 name_length;
X OBJECT_TYPE_INTERNAL data_type;
- ACPI_OBJECT_INTERNAL *obj_desc;
- ACPI_GENERIC_OP *parent_op;
+ ACPI_OPERAND_OBJECT *obj_desc;
+ ACPI_PARSE_OBJECT *parent_op;
X u16 opcode;
X u32 flags;
X OPERATING_MODE interpreter_mode;
@@ -214,7 +235,7 @@
X */
X
X parent_op = arg->parent;
- if ((acpi_ps_is_named_object_op (parent_op->opcode)) &&
+ if ((acpi_ps_is_node_op (parent_op->opcode)) &&
X (parent_op->opcode != AML_METHODCALL_OP) &&
X (parent_op->opcode != AML_NAMEPATH_OP))
X {
@@ -233,7 +254,7 @@
X ACPI_TYPE_ANY, interpreter_mode,
X NS_SEARCH_PARENT | NS_DONT_OPEN_SCOPE,
X walk_state,
- (ACPI_NAMED_OBJECT**) &obj_desc);
+ (ACPI_NAMESPACE_NODE **) &obj_desc);
X
X /* Free the namestring created above */
X
@@ -252,7 +273,7 @@
X * indicate this to the interpreter, set the
X * object to the root
X */
- obj_desc = (ACPI_OBJECT_INTERNAL *) acpi_gbl_root_object;
+ obj_desc = (ACPI_OPERAND_OBJECT *) acpi_gbl_root_node;
X status = AE_OK;
X }
X
@@ -277,6 +298,7 @@


X if (ACPI_FAILURE (status)) {
X return (status);
X }

+ DEBUGGER_EXEC (acpi_db_display_argument_object (obj_desc, walk_state));
X }
X
X
@@ -311,6 +333,8 @@
X }
X
X if (flags & OP_HAS_RETURN_VALUE) {
+ DEBUGGER_EXEC (acpi_db_display_argument_object (walk_state->operands [walk_state->num_operands - 1], walk_state));
+
X /*
X * Use value that was already previously returned
X * by the evaluation of this argument
@@ -338,9 +362,9 @@
X /* Initialize the new object */
X
X status = acpi_ds_init_object_from_op (walk_state, arg,
- opcode, obj_desc);
+ opcode, &obj_desc);
X if (ACPI_FAILURE (status)) {
- acpi_cm_free (obj_desc);
+ acpi_cm_delete_object_desc (obj_desc);


X return (status);
X }
X }

@@ -352,13 +376,14 @@


X return (status);
X }
X

+ DEBUGGER_EXEC (acpi_db_display_argument_object (obj_desc, walk_state));
X }
X

X return (AE_OK);
X }
X
X
-/*****************************************************************************
+/*******************************************************************************
X *

X * FUNCTION: Acpi_ds_create_operands
X *
@@ -370,15 +395,15 @@
X * namespace objects and place those argument object on the object
X * stack in preparation for evaluation by the interpreter.


X *
- ****************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS

X acpi_ds_create_operands (
X ACPI_WALK_STATE *walk_state,
- ACPI_GENERIC_OP *first_arg)
+ ACPI_PARSE_OBJECT *first_arg)


X {
X ACPI_STATUS status = AE_OK;

- ACPI_GENERIC_OP *arg;
+ ACPI_PARSE_OBJECT *arg;
X u32 args_pushed = 0;
X
X
@@ -416,7 +441,7 @@


X }
X
X
-/*****************************************************************************
+/*******************************************************************************
X *

X * FUNCTION: Acpi_ds_resolve_operands
X *
@@ -428,7 +453,7 @@
X * arguments to a control method invocation (a call from one
X * method to another.)


X *
- ****************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS

X acpi_ds_resolve_operands (
@@ -449,7 +474,7 @@
X */
X
X for (i = 0; i < walk_state->num_operands; i++) {
- status = acpi_aml_resolve_to_value (&walk_state->operands[i]);
+ status = acpi_aml_resolve_to_value (&walk_state->operands[i], walk_state);


X if (ACPI_FAILURE (status)) {
X break;
X }

@@ -459,7 +484,7 @@


X }
X
X
-/*****************************************************************************
+/*******************************************************************************
X *

X * FUNCTION: Acpi_ds_map_opcode_to_data_type
X *
@@ -472,7 +497,7 @@
X * if any. If the opcode returns a value as part of the
X * intepreter execution, a flag is returned in Out_flags.


X *
- ****************************************************************************/
+ ******************************************************************************/
X
X OBJECT_TYPE_INTERNAL

X acpi_ds_map_opcode_to_data_type (
@@ -480,18 +505,18 @@
X u32 *out_flags)
X {
X OBJECT_TYPE_INTERNAL data_type = INTERNAL_TYPE_INVALID;
- ACPI_OP_INFO *op_info;
+ ACPI_OPCODE_INFO *op_info;
X u32 flags = 0;
X
X
X op_info = acpi_ps_get_opcode_info (opcode);
- if (!op_info) {
+ if (ACPI_GET_OP_TYPE (op_info) != ACPI_OP_TYPE_OPCODE) {
X /* Unknown opcode */
X
- return data_type;
+ return (data_type);
X }
X
- switch (op_info->flags & OP_INFO_TYPE)
+ switch (ACPI_GET_OP_CLASS (op_info))
X {
X
X case OPTYPE_LITERAL:
@@ -552,6 +577,7 @@
X case OPTYPE_DYADIC2_s:
X case OPTYPE_INDEX:
X case OPTYPE_MATCH:
+ case OPTYPE_RETURN:
X
X flags = OP_HAS_RETURN_VALUE;
X data_type = ACPI_TYPE_ANY;
@@ -592,11 +618,11 @@
X *out_flags = flags;
X }
X
- return data_type;
+ return (data_type);


X }
X
X
-/*****************************************************************************
+/*******************************************************************************
X *

X * FUNCTION: Acpi_ds_map_named_opcode_to_data_type
X *
@@ -607,7 +633,7 @@
X * DESCRIPTION: Convert a raw Named AML opcode to the associated data type.
X * Named opcodes are a subsystem of the AML opcodes.


X *
- ****************************************************************************/
+ ******************************************************************************/
X
X OBJECT_TYPE_INTERNAL

X acpi_ds_map_named_opcode_to_data_type (
@@ -688,7 +714,7 @@
X
X }
X
- return data_type;
+ return (data_type);
X }
X
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/dispatcher/dswexec.c linux/drivers/acpi/dispatcher/dswexec.c
--- v2.4.0-test8/linux/drivers/acpi/dispatcher/dswexec.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/dispatcher/dswexec.c Fri Sep 15 14:30:29 2000
@@ -1,7 +1,8 @@
X /******************************************************************************
X *
X * Module Name: dswexec - Dispatcher method execution callbacks;
- * Dispatch to interpreter.
+ * dispatch to interpreter.
+ * $Revision: 42 $


X *
X *****************************************************************************/
X

@@ -25,16 +26,16 @@


X
X
X #include "acpi.h"
-#include "parser.h"
+#include "acparser.h"
X #include "amlcode.h"
-#include "dispatch.h"
-#include "interp.h"
-#include "namesp.h"

-#include "debugger.h"
+#include "acdispat.h"
+#include "acinterp.h"
+#include "acnamesp.h"

+#include "acdebug.h"
X
X
X #define _COMPONENT DISPATCHER

- MODULE_NAME ("dswexec");
+ MODULE_NAME ("dswexec")
X
X
X /*****************************************************************************
@@ -55,14 +56,29 @@
X
X ACPI_STATUS
X acpi_ds_exec_begin_op (
+ u16 opcode,
+ ACPI_PARSE_OBJECT *op,
X ACPI_WALK_STATE *walk_state,
- ACPI_GENERIC_OP *op)
+ ACPI_PARSE_OBJECT **out_op)
X {
- ACPI_OP_INFO *op_info;
+ ACPI_OPCODE_INFO *op_info;


X ACPI_STATUS status = AE_OK;
X
X

+ if (!op) {
+ status = acpi_ds_load2_begin_op (opcode, NULL, walk_state, out_op);


+ if (ACPI_FAILURE (status)) {
+ return (status);
+ }
+

+ op = *out_op;
+ }
+
X if (op == walk_state->origin) {
+ if (out_op) {
+ *out_op = op;
+ }
+


X return (AE_OK);
X }
X

@@ -97,7 +113,7 @@
X * Handle the opcode based upon the opcode type
X */
X
- switch (op_info->flags & OP_INFO_TYPE)
+ switch (ACPI_GET_OP_CLASS (op_info))
X {
X case OPTYPE_CONTROL:
X

@@ -107,7 +123,7 @@
X

X case OPTYPE_NAMED_OBJECT:
X
- if (walk_state->origin->opcode == AML_METHOD_OP) {
+ if (walk_state->walk_type == WALK_METHOD) {
X /*
X * Found a named object declaration during method
X * execution; we must enter this object into the
@@ -116,7 +132,7 @@
X * of this method.
X */
X
- status = acpi_ds_load2_begin_op (walk_state, op);
+ status = acpi_ds_load2_begin_op (op->opcode, op, walk_state, NULL);
X }
X break;
X
@@ -150,17 +166,17 @@
X ACPI_STATUS
X acpi_ds_exec_end_op (
X ACPI_WALK_STATE *walk_state,


- ACPI_GENERIC_OP *op)
+ ACPI_PARSE_OBJECT *op)
X {

X ACPI_STATUS status = AE_OK;
X u16 opcode;
X u8 optype;
- ACPI_OBJECT_INTERNAL *obj_desc;
- ACPI_GENERIC_OP *next_op;
- ACPI_NAMED_OBJECT *entry;
- ACPI_GENERIC_OP *first_arg;
- ACPI_OBJECT_INTERNAL *result_obj = NULL;
- ACPI_OP_INFO *op_info;
+ ACPI_OPERAND_OBJECT *obj_desc;
+ ACPI_PARSE_OBJECT *next_op;
+ ACPI_NAMESPACE_NODE *node;
+ ACPI_PARSE_OBJECT *first_arg;
+ ACPI_OPERAND_OBJECT *result_obj = NULL;
+ ACPI_OPCODE_INFO *op_info;
X u32 operand_index;
X
X
@@ -168,11 +184,11 @@
X
X
X op_info = acpi_ps_get_opcode_info (op->opcode);
- if (!op_info) {
+ if (ACPI_GET_OP_TYPE (op_info) != ACPI_OP_TYPE_OPCODE) {
X return (AE_NOT_IMPLEMENTED);
X }
X
- optype = (u8) (op_info->flags & OP_INFO_TYPE);
+ optype = (u8) ACPI_GET_OP_CLASS (op_info);
X first_arg = op->value.arg;
X
X /* Init the walk state */
@@ -183,6 +199,9 @@
X
X /* Call debugger for single step support (DEBUG build only) */
X
+ DEBUGGER_EXEC (status = acpi_db_single_step (walk_state, op, optype));
+ DEBUGGER_EXEC (if (ACPI_FAILURE (status)) {return (status);});
+
X
X /* Decode the opcode */
X
@@ -220,6 +239,7 @@
X case OPTYPE_CREATE_FIELD:
X case OPTYPE_FATAL:
X
+
X status = acpi_ds_create_operands (walk_state, first_arg);


X if (ACPI_FAILURE (status)) {
X goto cleanup;

@@ -376,12 +396,12 @@
X case OPTYPE_METHOD_CALL:
X
X /*
- * (AML_METHODCALL) Op->Value->Arg->Acpi_named_object contains
- * the method NTE pointer
+ * (AML_METHODCALL) Op->Value->Arg->Node contains
+ * the method Node pointer
X */
X /* Next_op points to the op that holds the method name */
X next_op = first_arg;
- entry = next_op->acpi_named_object;
+ node = next_op->node;
X
X /* Next_op points to first argument op */
X next_op = next_op->next;


@@ -410,7 +430,7 @@
X

X /* Open new scope on the scope stack */
X /*
- Status = Acpi_ns_scope_stack_push_entry (Entry);
+ Status = Acpi_ns_scope_stack_push_entry (Node);
X if (ACPI_FAILURE (Status)) {
X break;
X }
@@ -419,7 +439,7 @@
X /* Tell the walk loop to preempt this running method and
X execute the new method */
X
- status = AE_CTRL_PENDING;
+ status = AE_CTRL_TRANSFER;
X
X /* Return now; we don't want to disturb anything,
X especially the operand count! */
@@ -431,14 +451,20 @@
X case OPTYPE_NAMED_OBJECT:
X
X
- if ((walk_state->origin->opcode == AML_METHOD_OP) &&
- (walk_state->origin != op))
+ status = acpi_ds_load2_end_op (walk_state, op);
+ if (ACPI_FAILURE (status)) {
+ break;
+ }
+/*
+ if ((Walk_state->Origin->Opcode == AML_METHOD_OP) &&
+ (Walk_state->Origin != Op))
X {
- status = acpi_ds_load2_end_op (walk_state, op);
- if (ACPI_FAILURE (status)) {
+ Status = Acpi_ds_load2_end_op (Walk_state, Op);
+ if (ACPI_FAILURE (Status)) {
X break;
X }
X }
+*/
X
X switch (op->opcode)
X {
@@ -504,7 +530,7 @@


X goto cleanup;
X }
X

- status = acpi_aml_resolve_to_value (&walk_state->operands [0]);
+ status = acpi_aml_resolve_to_value (&walk_state->operands [0], walk_state);
X if (ACPI_FAILURE (status)) {
X goto cleanup;
X }
@@ -537,6 +563,8 @@
X
X /* Break to debugger to display result */
X
+ DEBUGGER_EXEC (acpi_db_display_result_object (obj_desc, walk_state));
+
X /* Delete the predicate result object (we know that
X we don't need it anymore) and cleanup the stack */
X
@@ -551,6 +579,8 @@
X
X if (result_obj) {
X /* Break to debugger to display result */
+
+ DEBUGGER_EXEC (acpi_db_display_result_object (result_obj, walk_state));
X
X /*
X * Delete the result op if and only if:
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/dispatcher/dswload.c linux/drivers/acpi/dispatcher/dswload.c
--- v2.4.0-test8/linux/drivers/acpi/dispatcher/dswload.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/dispatcher/dswload.c Fri Sep 15 14:30:29 2000


@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *

X * Module Name: dswload - Dispatcher namespace load callbacks
+ * $Revision: 19 $


X *
X *****************************************************************************/
X

@@ -25,16 +25,16 @@


X
X
X #include "acpi.h"

-#include "parser.h"
+#include "acparser.h"
X #include "amlcode.h"
-#include "dispatch.h"
-#include "interp.h"
-#include "namesp.h"

-#include "events.h"


+#include "acdispat.h"
+#include "acinterp.h"
+#include "acnamesp.h"

+#include "acevents.h"


X
X
X #define _COMPONENT DISPATCHER

- MODULE_NAME ("dswload");
+ MODULE_NAME ("dswload")
X
X
X /*****************************************************************************
@@ -53,61 +53,75 @@
X
X ACPI_STATUS
X acpi_ds_load1_begin_op (
+ u16 opcode,
+ ACPI_PARSE_OBJECT *op,
X ACPI_WALK_STATE *walk_state,
- ACPI_GENERIC_OP *op)
+ ACPI_PARSE_OBJECT **out_op)
X {
- ACPI_NAMED_OBJECT *new_entry;
+ ACPI_NAMESPACE_NODE *node;
X ACPI_STATUS status;
X OBJECT_TYPE_INTERNAL data_type;
+ NATIVE_CHAR *path;
X
X
X /* We are only interested in opcodes that have an associated name */
X
- if (!acpi_ps_is_named_op (op->opcode)) {
- return AE_OK;
+ if (!acpi_ps_is_named_op (opcode)) {
+ *out_op = op;


+ return (AE_OK);
X }
X
X

X /* Check if this object has already been installed in the namespace */
X
- if (op->acpi_named_object) {
- return AE_OK;
+ if (op && op->node) {
+ *out_op = op;


+ return (AE_OK);
X }
X

+ path = acpi_ps_get_next_namestring (walk_state->parser_state);
+
X /* Map the raw opcode into an internal object type */
X
- data_type = acpi_ds_map_named_opcode_to_data_type (op->opcode);
+ data_type = acpi_ds_map_named_opcode_to_data_type (opcode);
X
- /* Attempt to type a NAME opcode by examining the argument */
X
- /* TBD: [Investigate] is this the right place to do this? */
+ /*
+ * Enter the named type into the internal namespace. We enter the name
+ * as we go downward in the parse tree. Any necessary subobjects that involve
+ * arguments to the opcode must be created as we go back up the parse tree later.
+ */
+ status = acpi_ns_lookup (walk_state->scope_info, path,
+ data_type, IMODE_LOAD_PASS1,
+ NS_NO_UPSEARCH, walk_state, &(node));
X
- if (op->opcode == AML_NAME_OP) {
- if (op->value.arg) {


+ if (ACPI_FAILURE (status)) {
+ return (status);
+ }

X
- data_type = acpi_ds_map_opcode_to_data_type ((op->value.arg)->opcode,
- NULL);
+ if (!op) {
+ /* Create a new op */
+
+ op = acpi_ps_alloc_op (opcode);


+ if (!op) {
+ return (AE_NO_MEMORY);

X }
X }
X
+ /* Initialize */
+
+ ((ACPI_PARSE2_OBJECT *)op)->name = node->name;
X
X /*
- * Enter the named type into the internal namespace. We enter the name
- * as we go downward in the parse tree. Any necessary subobjects that involve
- * arguments to the opcode must be created as we go back up the parse tree later.
+ * Put the Node in the "op" object that the parser uses, so we
+ * can get it again quickly when this scope is closed
X */
- status = acpi_ns_lookup (walk_state->scope_info,
- (char *) &((ACPI_NAMED_OP *)op)->name,
- data_type, IMODE_LOAD_PASS1,
- NS_NO_UPSEARCH, walk_state, &(new_entry));


+ op->node = node;
X

- if (ACPI_SUCCESS (status)) {
- /*
- * Put the NTE in the "op" object that the parser uses, so we
- * can get it again quickly when this scope is closed
- */
- op->acpi_named_object = new_entry;
- }
+
+ acpi_ps_append_arg (acpi_ps_get_parent_scope (walk_state->parser_state), op);
+
+ *out_op = op;


X
X return (status);
X }

@@ -131,7 +145,7 @@
X ACPI_STATUS
X acpi_ds_load1_end_op (
X ACPI_WALK_STATE *walk_state,


- ACPI_GENERIC_OP *op)
+ ACPI_PARSE_OBJECT *op)
X {

X OBJECT_TYPE_INTERNAL data_type;
X
@@ -139,20 +153,26 @@
X /* We are only interested in opcodes that have an associated name */
X
X if (!acpi_ps_is_named_op (op->opcode)) {


- return AE_OK;
+ return (AE_OK);
X }
X

- /* TBD: [Investigate] can this be removed? */
X
- if (op->opcode == AML_SCOPE_OP) {
- if (((ACPI_NAMED_OP *)op)->name == -1) {
- return AE_OK;
+ /* Get the type to determine if we should pop the scope */
+
+ data_type = acpi_ds_map_named_opcode_to_data_type (op->opcode);
+
+ if (op->opcode == AML_NAME_OP) {
+ /* For Name opcode, check the argument */
+
+ if (op->value.arg) {
+ data_type = acpi_ds_map_opcode_to_data_type (
+ (op->value.arg)->opcode, NULL);
+ ((ACPI_NAMESPACE_NODE *)op->node)->type =
+ (u8) data_type;
X }
X }
X
X
- data_type = acpi_ds_map_named_opcode_to_data_type (op->opcode);
-
X /* Pop the scope stack */
X
X if (acpi_ns_opens_scope (data_type)) {
@@ -160,7 +180,7 @@
X acpi_ds_scope_stack_pop (walk_state);
X }
X

- return AE_OK;
+ return (AE_OK);
X
X }
X

@@ -181,60 +201,74 @@
X
X ACPI_STATUS
X acpi_ds_load2_begin_op (
+ u16 opcode,
+ ACPI_PARSE_OBJECT *op,
X ACPI_WALK_STATE *walk_state,
- ACPI_GENERIC_OP *op)
+ ACPI_PARSE_OBJECT **out_op)
X {
- ACPI_NAMED_OBJECT *new_entry;
+ ACPI_NAMESPACE_NODE *node;
X ACPI_STATUS status;
X OBJECT_TYPE_INTERNAL data_type;
- char *buffer_ptr;
+ NATIVE_CHAR *buffer_ptr;
X void *original = NULL;
X
X
X /* We only care about Namespace opcodes here */
X
- if (!acpi_ps_is_namespace_op (op->opcode) &&
- op->opcode != AML_NAMEPATH_OP)
+ if (!acpi_ps_is_namespace_op (opcode) &&
+ opcode != AML_NAMEPATH_OP)
X {


- return AE_OK;
+ return (AE_OK);
X }
X
X

- /*
- * Get the name we are going to enter or lookup in the namespace
- */
- if (op->opcode == AML_NAMEPATH_OP) {
- /* For Namepath op , get the path string */
+ /* Temp! same code as in psparse */
+
+ if (!acpi_ps_is_named_op (opcode)) {
+ return (AE_OK);
+ }
+
+ if (op) {
+ /*
+ * Get the name we are going to enter or lookup in the namespace
+ */
+ if (opcode == AML_NAMEPATH_OP) {
+ /* For Namepath op, get the path string */
+
+ buffer_ptr = op->value.string;
+ if (!buffer_ptr) {
+ /* No name, just exit */
+
+ return (AE_OK);
+ }
+ }
X
- buffer_ptr = op->value.string;
- if (!buffer_ptr) {
- /* No name, just exit */
+ else {
+ /* Get name from the op */
X
- return AE_OK;
+ buffer_ptr = (NATIVE_CHAR *) &((ACPI_PARSE2_OBJECT *)op)->name;
X }
X }
X
X else {
- /* Get name from the op */
-
- buffer_ptr = (char *) &((ACPI_NAMED_OP *)op)->name;
+ buffer_ptr = acpi_ps_get_next_namestring (walk_state->parser_state);
X }
X
X
X /* Map the raw opcode into an internal object type */
X
- data_type = acpi_ds_map_named_opcode_to_data_type (op->opcode);
+ data_type = acpi_ds_map_named_opcode_to_data_type (opcode);
X
X
- if (op->opcode == AML_DEF_FIELD_OP ||
- op->opcode == AML_BANK_FIELD_OP ||
- op->opcode == AML_INDEX_FIELD_OP)
+ if (opcode == AML_DEF_FIELD_OP ||
+ opcode == AML_BANK_FIELD_OP ||
+ opcode == AML_INDEX_FIELD_OP)
X {
- new_entry = NULL;
+ node = NULL;
X status = AE_OK;
X }
X
- else if (op->opcode == AML_NAMEPATH_OP) {
+ else if (opcode == AML_NAMEPATH_OP) {
X /*
X * The Name_path is an object reference to an existing object. Don't enter the
X * name into the namespace, but look it up for use later
@@ -242,16 +276,16 @@
X status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr,
X data_type, IMODE_EXECUTE,
X NS_SEARCH_PARENT, walk_state,
- &(new_entry));
+ &(node));
X }
X
X else {
- if (op->acpi_named_object) {
- original = op->acpi_named_object;
- new_entry = op->acpi_named_object;
+ if (op && op->node) {
+ original = op->node;
+ node = op->node;
X
X if (acpi_ns_opens_scope (data_type)) {
- status = acpi_ds_scope_stack_push (new_entry->child_table,
+ status = acpi_ds_scope_stack_push (node,
X data_type,
X walk_state);
X if (ACPI_FAILURE (status)) {
@@ -259,7 +293,7 @@
X }
X
X }


- return AE_OK;
+ return (AE_OK);
X }
X

X /*
@@ -270,15 +304,30 @@
X status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr,
X data_type, IMODE_EXECUTE,
X NS_NO_UPSEARCH, walk_state,
- &(new_entry));
+ &(node));
X }


X
X if (ACPI_SUCCESS (status)) {

+ if (!op) {
+ /* Create a new op */
+
+ op = acpi_ps_alloc_op (opcode);


+ if (!op) {
+ return (AE_NO_MEMORY);
+ }
+

+ /* Initialize */
+
+ ((ACPI_PARSE2_OBJECT *)op)->name = node->name;
+ *out_op = op;
+ }
+
+
X /*
- * Put the NTE in the "op" object that the parser uses, so we
+ * Put the Node in the "op" object that the parser uses, so we
X * can get it again quickly when this scope is closed
X */
- op->acpi_named_object = new_entry;


+ op->node = node;
X
X }
X

@@ -305,22 +354,22 @@
X ACPI_STATUS
X acpi_ds_load2_end_op (
X ACPI_WALK_STATE *walk_state,


- ACPI_GENERIC_OP *op)
+ ACPI_PARSE_OBJECT *op)
X {

X ACPI_STATUS status = AE_OK;
X OBJECT_TYPE_INTERNAL data_type;
- ACPI_NAMED_OBJECT *entry;
- ACPI_GENERIC_OP *arg;
- ACPI_NAMED_OBJECT *new_entry;
+ ACPI_NAMESPACE_NODE *node;
+ ACPI_PARSE_OBJECT *arg;
+ ACPI_NAMESPACE_NODE *new_node;
X
X
X if (!acpi_ps_is_namespace_object_op (op->opcode)) {


- return AE_OK;
+ return (AE_OK);
X }
X

X if (op->opcode == AML_SCOPE_OP) {
- if (((ACPI_NAMED_OP *)op)->name == -1) {
- return AE_OK;
+ if (((ACPI_PARSE2_OBJECT *)op)->name == -1) {


+ return (AE_OK);
X }
X }
X

@@ -328,17 +377,17 @@
X data_type = acpi_ds_map_named_opcode_to_data_type (op->opcode);
X
X /*
- * Get the NTE/name from the earlier lookup
+ * Get the Node/name from the earlier lookup
X * (It was saved in the *op structure)
X */
- entry = op->acpi_named_object;
+ node = op->node;
X
X /*
- * Put the NTE on the object stack (Contains the ACPI Name of
+ * Put the Node on the object stack (Contains the ACPI Name of
X * this object)
X */
X
- walk_state->operands[0] = (void *) entry;
+ walk_state->operands[0] = (void *) node;
X walk_state->num_operands = 1;
X
X /* Pop the scope stack */
@@ -409,29 +458,38 @@
X INTERNAL_TYPE_DEF_ANY,


X IMODE_LOAD_PASS1,
X NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE,

- walk_state, &(new_entry));
+ walk_state, &(new_node));


X
X if (ACPI_SUCCESS (status)) {

- /* We could put the returned object (NTE) on the object stack for later, but
+ /* We could put the returned object (Node) on the object stack for later, but
X * for now, we will put it in the "op" object that the parser uses, so we
X * can get it again at the end of this scope
X */
- op->acpi_named_object = new_entry;
- }
+ op->node = new_node;
X
+ /*
+ * If this is NOT a control method, we need to evaluate this opcode now.
+ */
+
+ /* THIS WON"T WORK. Must execute all operands like Add(). => Must do an execute pass
+ if (!Walk_state->Method_desc) {
+ Status = Acpi_ds_exec_end_op (Walk_state, Op);
+ }
+ */
+ }
X break;
X
X
X case AML_METHODCALL_OP:
X
X /*
- * Lookup the method name and save the NTE
+ * Lookup the method name and save the Node
X */
X

X status = acpi_ns_lookup (walk_state->scope_info, arg->value.string,

X ACPI_TYPE_ANY, IMODE_LOAD_PASS2,
X NS_SEARCH_PARENT | NS_DONT_OPEN_SCOPE,
- walk_state, &(new_entry));
+ walk_state, &(new_node));


X
X if (ACPI_SUCCESS (status)) {
X

@@ -440,11 +498,11 @@
X /* TBD: [Restructure] Make sure that what we found is indeed a method! */
X /* We didn't search for a method on purpose, to see if the name would resolve! */
X
- /* We could put the returned object (NTE) on the object stack for later, but
+ /* We could put the returned object (Node) on the object stack for later, but
X * for now, we will put it in the "op" object that the parser uses, so we
X * can get it again at the end of this scope
X */
- op->acpi_named_object = new_entry;
+ op->node = new_node;
X }
X
X
@@ -455,7 +513,7 @@
X
X /* Nothing to do other than enter object into namespace */
X
- status = acpi_aml_exec_create_processor (op, (ACPI_HANDLE) entry);
+ status = acpi_aml_exec_create_processor (op, (ACPI_HANDLE) node);


X if (ACPI_FAILURE (status)) {
X goto cleanup;
X }

@@ -467,7 +525,7 @@
X
X /* Nothing to do other than enter object into namespace */
X
- status = acpi_aml_exec_create_power_resource (op, (ACPI_HANDLE) entry);
+ status = acpi_aml_exec_create_power_resource (op, (ACPI_HANDLE) node);


X if (ACPI_FAILURE (status)) {
X goto cleanup;
X }

@@ -487,7 +545,7 @@


X arg = op->value.arg;

X
X status = acpi_ds_create_field (op,
- (ACPI_HANDLE) arg->acpi_named_object,
+ arg->node,
X walk_state);
X break;
X
@@ -497,7 +555,7 @@


X arg = op->value.arg;

X
X status = acpi_ds_create_index_field (op,
- (ACPI_HANDLE) arg->acpi_named_object,
+ (ACPI_HANDLE) arg->node,
X walk_state);
X break;
X
@@ -506,7 +564,7 @@


X
X arg = op->value.arg;

X status = acpi_ds_create_bank_field (op,
- (ACPI_HANDLE) arg->acpi_named_object,
+ arg->node,
X walk_state);
X break;
X
@@ -516,10 +574,10 @@
X */
X case AML_METHOD_OP:
X
- if (!entry->object) {
- status = acpi_aml_exec_create_method (((ACPI_DEFERRED_OP *) op)->body,
- ((ACPI_DEFERRED_OP *) op)->body_length,
- arg->value.integer, (ACPI_HANDLE) entry);
+ if (!node->object) {
+ status = acpi_aml_exec_create_method (((ACPI_PARSE2_OBJECT *) op)->data,
+ ((ACPI_PARSE2_OBJECT *) op)->length,
+ arg->value.integer, (ACPI_HANDLE) node);
X }
X
X break;
@@ -549,14 +607,18 @@
X
X case AML_REGION_OP:
X
+ if (node->object) {
+ break;


+ }
+
X
X /*

X * The Op_region is not fully parsed at this time. Only valid argument is the Space_id.
X * (We must save the address of the AML of the address and length operands)
X */
X
- status = acpi_aml_exec_create_region (((ACPI_DEFERRED_OP *) op)->body,
- ((ACPI_DEFERRED_OP *) op)->body_length,
+ status = acpi_aml_exec_create_region (((ACPI_PARSE2_OBJECT *) op)->data,
+ ((ACPI_PARSE2_OBJECT *) op)->length,
X arg->value.integer, walk_state);
X
X break;
@@ -577,7 +639,7 @@
X
X case AML_NAME_OP:
X
- status = acpi_ds_create_named_object (walk_state, entry, op);
+ status = acpi_ds_create_node (walk_state, node, op);
X
X break;
X
@@ -593,7 +655,9 @@
X
X
X cleanup:
- /* Remove the NTE pushed at the very beginning */
+
+ /* Remove the Node pushed at the very beginning */
+
X acpi_ds_obj_stack_pop (1, walk_state);


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 021'
echo 'File patch-2.4.0-test9 is continued in part 022'
echo "022" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part022

#!/bin/sh -x
# this is part 022 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 022; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

X return (status);
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/dispatcher/dswscope.c linux/drivers/acpi/dispatcher/dswscope.c
--- v2.4.0-test8/linux/drivers/acpi/dispatcher/dswscope.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/dispatcher/dswscope.c Fri Sep 15 14:30:29 2000


@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *

X * Module Name: dswscope - Scope stack manipulation
+ * $Revision: 38 $


X *
X *****************************************************************************/
X

@@ -25,12 +25,12 @@


X
X
X #include "acpi.h"

-#include "interp.h"
-#include "dispatch.h"
+#include "acinterp.h"
+#include "acdispat.h"
X
X
X #define _COMPONENT NAMESPACE
- MODULE_NAME ("dswscope");
+ MODULE_NAME ("dswscope")
X
X
X #define STACK_POP(head) head
@@ -69,24 +69,24 @@
X *
X * FUNCTION: Acpi_ds_scope_stack_push
X *
- * PARAMETERS: *New_scope, - Name to be made current
- * Type, - Type of frame being pushed
+ * PARAMETERS: *Node, - Name to be made current
+ * Type, - Type of frame being pushed
X *
X * DESCRIPTION: Push the current scope on the scope stack, and make the
- * passed nte current.
+ * passed Node current.
X *
X ***************************************************************************/
X
X ACPI_STATUS
X acpi_ds_scope_stack_push (
- ACPI_NAME_TABLE *new_scope,
+ ACPI_NAMESPACE_NODE *node,
X OBJECT_TYPE_INTERNAL type,
X ACPI_WALK_STATE *walk_state)
X {
X ACPI_GENERIC_STATE *scope_info;
X
X
- if (!new_scope) {
+ if (!node) {
X /* invalid scope */
X
X REPORT_ERROR ("Ds_scope_stack_push: null scope passed");
@@ -109,7 +109,7 @@
X
X /* Init new scope object */
X
- scope_info->scope.name_table = new_scope;
+ scope_info->scope.node = node;
X scope_info->common.value = (u16) type;
X
X /* Push new scope object onto stack */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/dispatcher/dswstate.c linux/drivers/acpi/dispatcher/dswstate.c
--- v2.4.0-test8/linux/drivers/acpi/dispatcher/dswstate.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/dispatcher/dswstate.c Fri Sep 15 14:30:29 2000
@@ -1,6 +1,7 @@
X /******************************************************************************
X *
X * Module Name: dswstate - Dispatcher parse tree walk management routines
+ * $Revision: 31 $


X *
X *****************************************************************************/
X

@@ -25,13 +26,13 @@


X
X #include "acpi.h"
X #include "amlcode.h"

-#include "parser.h"
-#include "dispatch.h"
-#include "namesp.h"
-#include "interp.h"
+#include "acparser.h"
+#include "acdispat.h"
+#include "acnamesp.h"
+#include "acinterp.h"


X
X #define _COMPONENT DISPATCHER

- MODULE_NAME ("dswstate");
+ MODULE_NAME ("dswstate")
X
X
X /*******************************************************************************
@@ -55,7 +56,7 @@
X walk_state->num_results = 0;
X walk_state->current_result = 0;


X
- return AE_OK;
+ return (AE_OK);
X }
X
X

@@ -80,13 +81,13 @@
X
X
X if (walk_state->num_results >= OBJ_NUM_OPERANDS) {
- return AE_STACK_OVERFLOW;
+ return (AE_STACK_OVERFLOW);
X }
X
X walk_state->results [walk_state->num_results] = object;
X walk_state->num_results++;


X
- return AE_OK;
+ return (AE_OK);
X }
X
X

@@ -106,7 +107,7 @@
X
X ACPI_STATUS
X acpi_ds_result_stack_pop (
- ACPI_OBJECT_INTERNAL **object,
+ ACPI_OPERAND_OBJECT **object,


X ACPI_WALK_STATE *walk_state)
X {
X

@@ -114,7 +115,7 @@
X /* Check for stack underflow */
X
X if (walk_state->num_results == 0) {
- return AE_AML_NO_OPERAND;
+ return (AE_AML_NO_OPERAND);
X }
X
X
@@ -125,13 +126,13 @@
X /* Check for a valid result object */
X
X if (!walk_state->results [walk_state->num_results]) {
- return AE_AML_NO_OPERAND;
+ return (AE_AML_NO_OPERAND);
X }
X
X *object = walk_state->results [walk_state->num_results];
X walk_state->results [walk_state->num_results] = NULL;


X
- return AE_OK;
+ return (AE_OK);
X }
X
X

@@ -191,7 +192,7 @@
X /* Check for stack overflow */
X
X if (walk_state->num_operands >= OBJ_NUM_OPERANDS) {
- return AE_STACK_OVERFLOW;
+ return (AE_STACK_OVERFLOW);
X }
X
X /* Put the object onto the stack */
@@ -199,7 +200,7 @@
X walk_state->operands [walk_state->num_operands] = object;
X walk_state->num_operands++;


X
- return AE_OK;
+ return (AE_OK);
X }
X
X

@@ -219,7 +220,7 @@
X
X ACPI_STATUS
X acpi_ds_obj_stack_pop_object (
- ACPI_OBJECT_INTERNAL **object,
+ ACPI_OPERAND_OBJECT **object,


X ACPI_WALK_STATE *walk_state)
X {
X

@@ -227,7 +228,7 @@
X /* Check for stack underflow */
X
X if (walk_state->num_operands == 0) {
- return AE_AML_NO_OPERAND;
+ return (AE_AML_NO_OPERAND);
X }
X
X
@@ -238,7 +239,7 @@
X /* Check for a valid operand */
X
X if (!walk_state->operands [walk_state->num_operands]) {
- return AE_AML_NO_OPERAND;
+ return (AE_AML_NO_OPERAND);
X }
X
X /* Get operand and set stack entry to null */
@@ -246,7 +247,7 @@
X *object = walk_state->operands [walk_state->num_operands];
X walk_state->operands [walk_state->num_operands] = NULL;


X
- return AE_OK;
+ return (AE_OK);
X }
X
X

@@ -276,7 +277,7 @@
X /* Check for stack underflow */
X
X if (walk_state->num_operands == 0) {
- return AE_STACK_UNDERFLOW;
+ return (AE_STACK_UNDERFLOW);
X }
X
X /* Just set the stack entry to null */
@@ -285,7 +286,7 @@
X walk_state->operands [walk_state->num_operands] = NULL;


X }
X
- return AE_OK;
+ return (AE_OK);
X }
X
X

@@ -309,14 +310,14 @@
X ACPI_WALK_STATE *walk_state)
X {
X u32 i;


- ACPI_OBJECT_INTERNAL *obj_desc;
+ ACPI_OPERAND_OBJECT *obj_desc;
X
X

X for (i = 0; i < pop_count; i++) {
X /* Check for stack underflow */
X
X if (walk_state->num_operands == 0) {
- return AE_STACK_UNDERFLOW;
+ return (AE_STACK_UNDERFLOW);
X }
X
X /* Pop the stack and delete an object if present in this stack entry */
@@ -329,7 +330,7 @@


X }
X }
X
- return AE_OK;
+ return (AE_OK);
X }
X
X

@@ -393,10 +394,10 @@
X {
X
X if (!walk_list) {


- return NULL;
+ return (NULL);
X }
X

- return walk_list->walk_state;
+ return (walk_list->walk_state);
X }
X
X
@@ -483,8 +484,8 @@
X ACPI_WALK_STATE *
X acpi_ds_create_walk_state (
X ACPI_OWNER_ID owner_id,
- ACPI_GENERIC_OP *origin,
- ACPI_OBJECT_INTERNAL *mth_desc,
+ ACPI_PARSE_OBJECT *origin,
+ ACPI_OPERAND_OBJECT *mth_desc,
X ACPI_WALK_LIST *walk_list)
X {
X ACPI_WALK_STATE *walk_state;
@@ -511,6 +512,7 @@
X /* The cache is empty, create a new object */
X
X /* Avoid deadlock with Acpi_cm_callocate */
+
X acpi_cm_release_mutex (ACPI_MTX_CACHES);
X
X walk_state = acpi_cm_callocate (sizeof (ACPI_WALK_STATE));
@@ -640,6 +642,7 @@
X next = acpi_gbl_walk_state_cache->next;
X acpi_cm_free (acpi_gbl_walk_state_cache);
X acpi_gbl_walk_state_cache = next;
+ acpi_gbl_walk_state_cache_depth--;
X }
X
X return;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/driver.c linux/drivers/acpi/driver.c
--- v2.4.0-test8/linux/drivers/acpi/driver.c Wed Jul 12 13:21:57 2000
+++ linux/drivers/acpi/driver.c Fri Sep 15 14:30:30 2000
@@ -32,6 +32,9 @@


X #include "acpi.h"
X #include "driver.h"
X
+#define _COMPONENT OS_DEPENDENT

+ MODULE_NAME ("driver")
+
X struct acpi_run_entry
X {
X void (*callback)(void*);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/ec.c linux/drivers/acpi/ec.c
--- v2.4.0-test8/linux/drivers/acpi/ec.c Thu Jul 13 09:39:49 2000
+++ linux/drivers/acpi/ec.c Fri Sep 15 14:30:30 2000
@@ -1,21 +1,21 @@
X /*
- * ec.c - Embedded controller support
+ * ec.c - Embedded controller support
X *
- * Copyright (C) 2000 Andrew Henroid
+ * Copyright (C) 2000 Andrew Henroid
X *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.

X *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.


+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.

X *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA


+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

X */
X
X #include <linux/kernel.h>

@@ -28,28 +28,28 @@


X #include "acpi.h"
X #include "driver.h"
X

-enum
-{
- ACPI_EC_HID = 0x090cd041,
-};
+#define _COMPONENT OS_DEPENDENT
+ MODULE_NAME ("ec")
+
+#define ACPI_EC_HID "PNP0A09"
X
X enum
X {
- ACPI_EC_SMI = 0x40,
- ACPI_EC_SCI = 0x20,
- ACPI_EC_BURST = 0x10,
- ACPI_EC_CMD = 0x08,
- ACPI_EC_IBF = 0x02,
- ACPI_EC_OBF = 0x01
+ ACPI_EC_SMI = 0x40,
+ ACPI_EC_SCI = 0x20,
+ ACPI_EC_BURST = 0x10,
+ ACPI_EC_CMD = 0x08,
+ ACPI_EC_IBF = 0x02,
+ ACPI_EC_OBF = 0x01
X };
X
X enum
X {
- ACPI_EC_READ = 0x80,
- ACPI_EC_WRITE = 0x81,
- ACPI_EC_BURST_ENABLE = 0x82,
- ACPI_EC_BURST_DISABLE = 0x83,
- ACPI_EC_QUERY = 0x84,
+ ACPI_EC_READ = 0x80,
+ ACPI_EC_WRITE = 0x81,
+ ACPI_EC_BURST_ENABLE = 0x82,
+ ACPI_EC_BURST_DISABLE = 0x83,
+ ACPI_EC_QUERY = 0x84,
X };
X
X
@@ -74,9 +74,9 @@
X static void
X acpi_ec_wait_control(void)
X {
- udelay(1);
- while(inb(acpi_ec_status) & ACPI_EC_IBF)
- udelay(10);
+ udelay(1);
+ while(inb(acpi_ec_status) & ACPI_EC_IBF)
+ udelay(10);
X }
X
X /*
@@ -88,12 +88,12 @@
X if (!acpi_ec_data || !acpi_ec_status)
X return -1;
X
- outb(ACPI_EC_READ, acpi_ec_status);
- acpi_ec_wait_control();
- outb(addr, acpi_ec_data);
- acpi_ec_wait_control();
- interruptible_sleep_on(&acpi_ec_wait);
- *value = inb(acpi_ec_data);
+ outb(ACPI_EC_READ, acpi_ec_status);
+ acpi_ec_wait_control();
+ outb(addr, acpi_ec_data);
+ acpi_ec_wait_control();
+ interruptible_sleep_on(&acpi_ec_wait);
+ *value = inb(acpi_ec_data);


X
X return 0;
X }

@@ -107,33 +107,32 @@
X if (!acpi_ec_data || !acpi_ec_status)
X return -1;
X
- outb(ACPI_EC_WRITE, acpi_ec_status);
- acpi_ec_wait_control();
- outb(addr, acpi_ec_data);
- acpi_ec_wait_control();
- outb(value, acpi_ec_data);
- acpi_ec_wait_control();
- interruptible_sleep_on(&acpi_ec_wait);
+ outb(ACPI_EC_WRITE, acpi_ec_status);
+ acpi_ec_wait_control();
+ outb(addr, acpi_ec_data);
+ acpi_ec_wait_control();
+ outb(value, acpi_ec_data);
+ acpi_ec_wait_control();
+ interruptible_sleep_on(&acpi_ec_wait);
X
X return 0;
X }
X
X /*
- * Get processor information
+ * Get Embedded Controller information
X */
X static ACPI_STATUS
X acpi_find_ec(ACPI_HANDLE handle, u32 level, void *ctx, void **value)
X {
- ACPI_BUFFER buf;
+ ACPI_DEVICE_INFO dev_info;
X ACPI_OBJECT obj;
+ ACPI_BUFFER buf;
X RESOURCE *res;
X int gpe;
X
- buf.length = sizeof(obj);
- buf.pointer = &obj;
- if (!ACPI_SUCCESS(acpi_evaluate_object(handle, "_HID", NULL, &buf))
- || obj.type != ACPI_TYPE_NUMBER
- || obj.number.value != ACPI_EC_HID)
+ if (!ACPI_SUCCESS(acpi_get_object_info(handle, &dev_info))
+ || !(dev_info.valid & ACPI_VALID_HID)
+ || 0 != STRCMP(dev_info.hardware_id, ACPI_EC_HID))
X return AE_OK;
X
X buf.length = 0;
@@ -160,20 +159,23 @@
X buf.length = sizeof(obj);
X buf.pointer = &obj;
X if (!ACPI_SUCCESS(acpi_evaluate_object(handle, "_GPE", NULL, &buf))
- || obj.type != ACPI_TYPE_NUMBER)
+ || obj.type != ACPI_TYPE_NUMBER)
X return AE_OK;
X gpe = (int) obj.number.value;
X
X printk(KERN_INFO "ACPI: found EC @ (0x%02x,0x%02x,%d)\n",
- acpi_ec_data, acpi_ec_status, gpe);
+ acpi_ec_data, acpi_ec_status, gpe);
X
X if (!ACPI_SUCCESS(acpi_install_gpe_handler(
X gpe,
X (ACPI_EVENT_LEVEL_TRIGGERED
X | ACPI_EVENT_EDGE_TRIGGERED),
X acpi_ec_gpe,
- NULL)))
+ NULL))) {
+
+ DEBUG_PRINT(ACPI_ERROR, ("Could not install GPE handler for EC.\n"));
X return AE_OK;
+ }
X
X return AE_OK;
X }
@@ -182,10 +184,10 @@
X acpi_ec_init(void)
X {
X acpi_walk_namespace(ACPI_TYPE_DEVICE,
- ACPI_ROOT_OBJECT,
- ACPI_INT32_MAX,
- acpi_find_ec,
- NULL,
- NULL);
+ ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX,
+ acpi_find_ec,
+ NULL,
+ NULL);
X return 0;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/events/Makefile linux/drivers/acpi/events/Makefile
--- v2.4.0-test8/linux/drivers/acpi/events/Makefile Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/events/Makefile Fri Sep 15 18:21:43 2000

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/events/evevent.c linux/drivers/acpi/events/evevent.c
--- v2.4.0-test8/linux/drivers/acpi/events/evevent.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/events/evevent.c Fri Sep 15 14:30:30 2000
@@ -2,6 +2,7 @@
X *
X * Module Name: evevent - Fixed and General Purpose Acpi_event
X * handling and dispatch
+ * $Revision: 13 $


X *
X *****************************************************************************/
X

@@ -24,13 +25,13 @@
X */
X

X #include "acpi.h"
-#include "hardware.h"

-#include "events.h"
-#include "namesp.h"
-#include "common.h"
+#include "achware.h"
+#include "acevents.h"
+#include "acnamesp.h"
+#include "accommon.h"
X
X #define _COMPONENT EVENT_HANDLING
- MODULE_NAME ("evevent");
+ MODULE_NAME ("evevent")
X
X
X /******************************************************************************
@@ -68,7 +69,7 @@
X acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_LOCK, ACPI_EVENT_RTC +
X TMR_EN, 0);


X
- return AE_OK;
+ return (AE_OK);
X }
X
X

@@ -140,7 +141,7 @@
X int_status |= acpi_ev_fixed_event_dispatch (ACPI_EVENT_SLEEP_BUTTON);
X }
X
- return int_status;
+ return (int_status);
X }
X
X
@@ -163,7 +164,7 @@
X {
X /* Clear the status bit */
X
- acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK, (s32)TMR_STS +
+ acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK, TMR_STS +
X event, 1);
X
X /*
@@ -175,13 +176,13 @@
X TMR_EN + event, 0);
X
X REPORT_ERROR("No installed handler for fixed event.");
- return INTERRUPT_NOT_HANDLED;
+ return (INTERRUPT_NOT_HANDLED);
X }
X
X /* Invoke the handler */
X
- return (acpi_gbl_fixed_event_handlers[event].handler)(
- acpi_gbl_fixed_event_handlers[event].context);
+ return ((acpi_gbl_fixed_event_handlers[event].handler)(
+ acpi_gbl_fixed_event_handlers[event].context));
X }
X
X
@@ -216,6 +217,11 @@
X gpe1_register_count = (u16) DIV_2 (acpi_gbl_FACP->gpe1_blk_len);
X acpi_gbl_gpe_register_count = gpe0register_count + gpe1_register_count;
X
+ if (!acpi_gbl_gpe_register_count) {
+ REPORT_WARNING ("No GPEs defined in the FACP");


+ return (AE_OK);
+ }
+

X /*
X * Allocate the Gpe information block
X */
@@ -341,17 +347,17 @@
X void **return_value)
X {
X u32 gpe_number;
- char name[ACPI_NAME_SIZE + 1];
+ NATIVE_CHAR name[ACPI_NAME_SIZE + 1];
X u8 type;
X
X
X /* Extract the name from the object and convert to a string */
X
- MOVE_UNALIGNED32_TO_32 (name, &((ACPI_NAMED_OBJECT*) obj_handle)->name);
+ MOVE_UNALIGNED32_TO_32 (name, &((ACPI_NAMESPACE_NODE *) obj_handle)->name);
X name[ACPI_NAME_SIZE] = 0;
X
X /*
- * Edge/Level determination is based on the 2nd char of the method name
+ * Edge/Level determination is based on the 2nd s8 of the method name
X */
X if (name[1] == 'L') {
X type = ACPI_EVENT_LEVEL_TRIGGERED;
@@ -362,7 +368,7 @@
X else {
X /* Unknown method type, just ignore it! */
X
- return AE_OK;


+ return (AE_OK);
X }
X

X /* Convert the last two characters of the name to the Gpe Number */
@@ -371,7 +377,7 @@
X if (gpe_number == ACPI_UINT32_MAX) {
X /* Conversion failed; invalid method, just ignore it */
X
- return AE_OK;


+ return (AE_OK);
X }
X

X /* Ensure that we have a valid GPE number */
@@ -379,7 +385,7 @@
X if (acpi_gbl_gpe_valid[gpe_number] == ACPI_GPE_INVALID) {
X /* Not valid, all we can do here is ignore it */
X
- return AE_OK;


+ return (AE_OK);
X }
X
X /*

@@ -397,7 +403,7 @@
X
X acpi_hw_enable_gpe (gpe_number);


X
- return AE_OK;
+ return (AE_OK);
X }
X
X

@@ -431,7 +437,7 @@
X /* Traverse the namespace under \_GPE to find all methods there */
X
X status = acpi_walk_namespace (ACPI_TYPE_METHOD, acpi_gbl_gpe_obj_handle,
- ACPI_INT32_MAX, acpi_ev_save_method_info,
+ ACPI_UINT32_MAX, acpi_ev_save_method_info,
X NULL, NULL);
X
X return (status);
@@ -523,7 +529,7 @@
X }
X }
X
- return int_status;
+ return (int_status);
X }
X
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/events/evmisc.c linux/drivers/acpi/events/evmisc.c
--- v2.4.0-test8/linux/drivers/acpi/events/evmisc.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/events/evmisc.c Fri Sep 15 14:30:30 2000
@@ -2,6 +2,7 @@
X *
X * Module Name: evmisc - ACPI device notification handler dispatch
X * and ACPI Global Lock support
+ * $Revision: 13 $


X *
X *****************************************************************************/
X

@@ -24,13 +25,13 @@
X */
X

X #include "acpi.h"
-#include "events.h"

-#include "namesp.h"
-#include "interp.h"
-#include "hardware.h"
+#include "acevents.h"
+#include "acnamesp.h"
+#include "acinterp.h"
+#include "achware.h"
X
X #define _COMPONENT EVENT_HANDLING
- MODULE_NAME ("evmisc");
+ MODULE_NAME ("evmisc")
X
X
X /**************************************************************************
@@ -51,8 +52,8 @@
X ACPI_HANDLE device,
X u32 notify_value)
X {
- ACPI_OBJECT_INTERNAL *obj_desc;
- ACPI_OBJECT_INTERNAL *handler_obj;
+ ACPI_OPERAND_OBJECT *obj_desc;
+ ACPI_OPERAND_OBJECT *handler_obj;
X NOTIFY_HANDLER handler;
X
X
@@ -108,7 +109,7 @@
X
X
X /*
- * Get the notify object which must be attached to the device NTE
+ * Get the notify object which must be attached to the device Node
X */
X
X obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) device);
@@ -211,7 +212,7 @@
X context);
X }
X
- return INTERRUPT_HANDLED;
+ return (INTERRUPT_HANDLED);
X }
X
X
@@ -349,7 +350,7 @@
X */
X if (pending) {
X acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_LOCK,
- (s32)PM1_CONTROL | GBL_RLS, 1);
+ PM1_CONTROL | GBL_RLS, 1);
X }
X }
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/events/evregion.c linux/drivers/acpi/events/evregion.c
--- v2.4.0-test8/linux/drivers/acpi/events/evregion.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/events/evregion.c Fri Sep 15 14:30:30 2000
@@ -1,6 +1,7 @@
X /******************************************************************************
X *
X * Module Name: evregion - ACPI Address_space / Op_region handler dispatch
+ * $Revision: 76 $


X *
X *****************************************************************************/
X

@@ -24,13 +25,13 @@


X
X
X #include "acpi.h"

-#include "events.h"


-#include "namesp.h"
-#include "interp.h"
+#include "acevents.h"

+#include "acnamesp.h"
+#include "acinterp.h"
X #include "amlcode.h"

X
X #define _COMPONENT EVENT_HANDLING
- MODULE_NAME ("evregion");
+ MODULE_NAME ("evregion")
X
X
X #define PCI_ROOT_HID_STRING "PNP0A03"
@@ -56,23 +57,23 @@
X void *context,
X void **return_value)
X {
- ACPI_NAMED_OBJECT *entry;
- ACPI_OBJECT_INTERNAL *obj_desc;
+ ACPI_NAMESPACE_NODE *node;


+ ACPI_OPERAND_OBJECT *obj_desc;
X ACPI_STATUS status;
X
X

- entry = (ACPI_NAMED_OBJECT*) obj_handle;

- obj_desc = ((ACPI_NAMED_OBJECT*)obj_handle)->object;

+ node = (ACPI_NAMESPACE_NODE *) obj_handle;

+ obj_desc = ((ACPI_NAMESPACE_NODE *) obj_handle)->object;
X
X
X /*
X * We are looking for all valid _HID objects.
X */
X
- if (STRNCMP ((char *)&entry->name, METHOD_NAME__HID, ACPI_NAME_SIZE) ||
+ if (STRNCMP ((NATIVE_CHAR *) &node->name, METHOD_NAME__HID, ACPI_NAME_SIZE) ||
X (!obj_desc))


X {
- return AE_OK;
+ return (AE_OK);
X }
X
X

@@ -87,7 +88,7 @@
X case ACPI_TYPE_NUMBER:
X
X if (obj_desc->number.value != PCI_ROOT_HID_VALUE) {


- return AE_OK;
+ return (AE_OK);
X }
X

X break;
@@ -97,14 +98,14 @@
X if (STRNCMP (obj_desc->string.pointer, PCI_ROOT_HID_STRING,
X sizeof (PCI_ROOT_HID_STRING)))


X {
- return AE_OK;
+ return (AE_OK);
X }
X

X break;
X
X default:


X
- return AE_OK;
+ return (AE_OK);
X }
X
X

@@ -114,11 +115,11 @@
X * handler for this PCI device.
X */
X
- status = acpi_install_address_space_handler (acpi_ns_get_parent_entry (entry),
+ status = acpi_install_address_space_handler (acpi_ns_get_parent_object (node),
X ADDRESS_SPACE_PCI_CONFIG,
X ACPI_DEFAULT_HANDLER, NULL, NULL);


X
- return AE_OK;
+ return (AE_OK);
X }
X
X

@@ -142,7 +143,90 @@
X acpi_ns_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
X FALSE, acpi_ev_find_one_pci_root_bus, NULL, NULL);


X
- return AE_OK;
+ return (AE_OK);

+}
+
+/******************************************************************************
+ *
+ * FUNCTION: Acpi_ev_init_one_device
+ *
+ * PARAMETERS: The usual "I'm a namespace callback" stuff
+ *
+ * RETURN: ACPI_STATUS
+ *
+ * DESCRIPTION: This is called once per device soon after ACPI is enabled
+ * to initialize each device. It determines if the device is
+ * present, and if so, calls _INI.


+ *
+ *****************************************************************************/
+

+ACPI_STATUS
+acpi_ev_init_one_device (
+ ACPI_HANDLE obj_handle,
+ u32 nesting_level,
+ void *context,
+ void **return_value)
+{
+ ACPI_STATUS status;
+ ACPI_OPERAND_OBJECT *ret_obj;
+
+
+ /*
+ * Run _STA to determine if we can run _INI on the device.
+ */
+ status = acpi_ns_evaluate_relative(obj_handle, "_STA", NULL, &ret_obj);
+ if (AE_NOT_FOUND == status) {
+ /* No _STA means device is present */
+ }
+ else if (ACPI_FAILURE (status)) {
+ return (status);
+ }
+ else if (ret_obj) {
+ if (ACPI_TYPE_NUMBER != ret_obj->common.type) {
+ status = AE_AML_OPERAND_TYPE;
+ goto cleanup;
+ }
+
+ /*
+ * if _STA "present" bit not set, we're done.
+ */
+ if (!(ret_obj->number.value & 1)) {
+ goto cleanup;
+ }
+ }
+
+ /*
+ * The device is present. Run _INI.
+ */
+
+ status = acpi_ns_evaluate_relative(obj_handle, "_INI", NULL, NULL);
+
+cleanup:
+
+ acpi_cm_remove_reference (ret_obj);


+ return (status);
+}
+

+/******************************************************************************
+ *
+ * FUNCTION: Acpi_ev_init_devices
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: ACPI_STATUS
+ *
+ * DESCRIPTION: This initializes all ACPI devices.


+ *
+ *****************************************************************************/
+

+ACPI_STATUS
+acpi_ev_init_devices (
+ void)
+{
+ acpi_ns_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
+ FALSE, acpi_ev_init_one_device, NULL, NULL);
+


+ return (AE_OK);
X }
X
X

@@ -172,28 +256,20 @@
X * associated with the address space. For these we use the root.
X */
X
- status = acpi_install_address_space_handler (acpi_gbl_root_object,
+ status = acpi_install_address_space_handler (acpi_gbl_root_node,
X ADDRESS_SPACE_SYSTEM_MEMORY,
X ACPI_DEFAULT_HANDLER, NULL, NULL);


X if (ACPI_FAILURE (status)) {
X return (status);
X }

X
- status = acpi_install_address_space_handler (acpi_gbl_root_object,
+ status = acpi_install_address_space_handler (acpi_gbl_root_node,
X ADDRESS_SPACE_SYSTEM_IO,
X ACPI_DEFAULT_HANDLER, NULL, NULL);


X if (ACPI_FAILURE (status)) {
X return (status);
X }

X
- /*
- * Install PCI config space handler for all PCI root bridges. A PCI root
- * bridge is found by searching for devices containing a HID with the value
- * EISAID("PNP0A03")
- */
-
- acpi_ev_find_pci_root_buses ();
-


X
X return (AE_OK);
X }

@@ -216,12 +292,12 @@
X
X ACPI_STATUS
X acpi_ev_execute_reg_method (
- ACPI_OBJECT_INTERNAL *region_obj,
+ ACPI_OPERAND_OBJECT *region_obj,
X u32 function)
X {
- ACPI_OBJECT_INTERNAL *params[3];
- ACPI_OBJECT_INTERNAL space_iD_obj;
- ACPI_OBJECT_INTERNAL function_obj;
+ ACPI_OPERAND_OBJECT *params[3];
+ ACPI_OPERAND_OBJECT space_iD_obj;
+ ACPI_OPERAND_OBJECT function_obj;


X ACPI_STATUS status;
X
X

@@ -286,7 +362,7 @@
X
X ACPI_STATUS
X acpi_ev_address_space_dispatch (
- ACPI_OBJECT_INTERNAL *region_obj,
+ ACPI_OPERAND_OBJECT *region_obj,
X u32 function,
X u32 address,
X u32 bit_width,
@@ -295,8 +371,8 @@
X ACPI_STATUS status;
X ADDRESS_SPACE_HANDLER handler;
X ADDRESS_SPACE_SETUP region_setup;
- ACPI_OBJECT_INTERNAL *handler_desc;
- void *region_context;
+ ACPI_OPERAND_OBJECT *handler_desc;
+ void *region_context = NULL;
X
X
X /*
@@ -312,7 +388,7 @@
X * It may be the case that the region has never been initialized
X * Some types of regions require special init code
X */
- if (!(region_obj->region.region_flags & REGION_INITIALIZED)) {
+ if (!(region_obj->region.flags & AOPOBJ_INITIALIZED)) {
X /*
X * This region has not been initialized yet, do it
X */
@@ -346,9 +422,10 @@
X }
X
X /*
- * Save the returned context for use in all accesses to the region
+ * Save the returned context for use in all accesses to
+ * this particular region.
X */
- handler_desc->addr_handler.context = region_context;
+ region_obj->region.region_context = region_context;
X }
X
X /*
@@ -369,7 +446,8 @@
X * Invoke the handler.
X */
X status = handler (function, address, bit_width, value,
- handler_desc->addr_handler.context);
+ handler_desc->addr_handler.context,
+ region_obj->region.region_context);
X
X
X if (!(handler_desc->addr_handler.flags & ADDR_HANDLER_DEFAULT_INSTALLED)) {
@@ -398,13 +476,13 @@
X
X void
X acpi_ev_disassociate_region_from_handler(
- ACPI_OBJECT_INTERNAL *region_obj)
+ ACPI_OPERAND_OBJECT *region_obj)
X {
- ACPI_OBJECT_INTERNAL *handler_obj;
- ACPI_OBJECT_INTERNAL *obj_desc;
- ACPI_OBJECT_INTERNAL **last_obj_ptr;
+ ACPI_OPERAND_OBJECT *handler_obj;
+ ACPI_OPERAND_OBJECT *obj_desc;
+ ACPI_OPERAND_OBJECT **last_obj_ptr;
X ADDRESS_SPACE_SETUP region_setup;
- void *region_context;
+ void *region_context = region_obj->region.region_context;


X ACPI_STATUS status;
X
X

@@ -436,7 +514,8 @@
X /*
X * This is it, remove it from the handler's list
X */
- *last_obj_ptr = obj_desc->region.link;
+ *last_obj_ptr = obj_desc->region.next;
+ obj_desc->region.next = NULL; /* Must clear field */
X
X /*
X * Now stop region accesses by executing the _REG method
@@ -452,12 +531,6 @@
X &region_context);
X
X /*
- * Save the returned context (It is the original context
- * passed into Install)
- */
- handler_obj->addr_handler.context = region_context;
-
- /*
X * Init routine may fail, Just ignore errors
X */
X
@@ -482,8 +555,8 @@
X /*
X * Move through the linked list of handlers
X */
- last_obj_ptr = &obj_desc->region.link;
- obj_desc = obj_desc->region.link;
+ last_obj_ptr = &obj_desc->region.next;
+ obj_desc = obj_desc->region.next;
X }
X
X /*
@@ -508,9 +581,10 @@


X ******************************************************************************/
X
X ACPI_STATUS

-acpi_ev_associate_region_and_handler(
- ACPI_OBJECT_INTERNAL *handler_obj,
- ACPI_OBJECT_INTERNAL *region_obj)
+acpi_ev_associate_region_and_handler (
+ ACPI_OPERAND_OBJECT *handler_obj,
+ ACPI_OPERAND_OBJECT *region_obj,
+ u8 acpi_ns_is_locked)


X {
X ACPI_STATUS status;
X

@@ -522,7 +596,7 @@
X * Link this region to the front of the handler's list
X */
X
- region_obj->region.link = handler_obj->addr_handler.region_list;
+ region_obj->region.next = handler_obj->addr_handler.region_list;
X handler_obj->addr_handler.region_list = region_obj;
X
X /*
@@ -539,9 +613,15 @@
X /*
X * Last thing, tell all users that this region is usable
X */
- acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+ if (acpi_ns_is_locked) {
+ acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
+ }
+
X status = acpi_ev_execute_reg_method (region_obj, 1);
- acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
+
+ if (acpi_ns_is_locked) {
+ acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
+ }


X
X return (status);
X }

@@ -551,7 +631,7 @@
X *
X * FUNCTION: Acpi_ev_addr_handler_helper
X *
- * PARAMETERS: Handle - Entry to be dumped
+ * PARAMETERS: Handle - Node to be dumped
X * Level - Nesting level of the handle
X * Context - Passed into Acpi_ns_walk_namespace
X *
@@ -573,14 +653,14 @@
X void *context,
X void **return_value)
X {
- ACPI_OBJECT_INTERNAL *handler_obj;
- ACPI_OBJECT_INTERNAL *tmp_obj;
- ACPI_OBJECT_INTERNAL *obj_desc;
- ACPI_NAMED_OBJECT *obj_entry;
+ ACPI_OPERAND_OBJECT *handler_obj;
+ ACPI_OPERAND_OBJECT *tmp_obj;
+ ACPI_OPERAND_OBJECT *obj_desc;


+ ACPI_NAMESPACE_NODE *node;
X ACPI_STATUS status;
X

X
- handler_obj = (ACPI_OBJECT_INTERNAL *) context;
+ handler_obj = (ACPI_OPERAND_OBJECT *) context;


X
X /* Parameter validation */

X
@@ -590,8 +670,8 @@
X
X /* Convert and validate the device handle */
X
- obj_entry = acpi_ns_convert_handle_to_entry (obj_handle);
- if (!obj_entry) {
+ node = acpi_ns_convert_handle_to_entry (obj_handle);
+ if (!node) {
X return (AE_BAD_PARAMETER);
X }
X
@@ -600,16 +680,16 @@
X * that can have address handlers
X */
X
- if ((obj_entry->type != ACPI_TYPE_DEVICE) &&
- (obj_entry->type != ACPI_TYPE_REGION) &&
- (obj_entry != acpi_gbl_root_object))
+ if ((node->type != ACPI_TYPE_DEVICE) &&
+ (node->type != ACPI_TYPE_REGION) &&
+ (node != acpi_gbl_root_node))


X {
X return (AE_OK);
X }
X

X /* Check for an existing internal object */
X
- obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) obj_entry);
+ obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) node);
X if (!obj_desc) {
X /*
X * The object DNE, we don't care about it
@@ -647,7 +727,7 @@
X /*
X * Move through the linked list of handlers
X */
- tmp_obj = tmp_obj->addr_handler.link;
+ tmp_obj = tmp_obj->addr_handler.next;
X }
X
X /*
@@ -682,7 +762,7 @@
X /*
X * Then connect the region to the new handler
X */
- status = acpi_ev_associate_region_and_handler (handler_obj, obj_desc);
+ status = acpi_ev_associate_region_and_handler (handler_obj, obj_desc, FALSE);


X
X return (status);
X }

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/events/evrgnini.c linux/drivers/acpi/events/evrgnini.c
--- v2.4.0-test8/linux/drivers/acpi/events/evrgnini.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/events/evrgnini.c Fri Sep 15 14:30:30 2000
@@ -1,6 +1,7 @@
X /******************************************************************************
X *
X * Module Name: evrgnini- ACPI Address_space / Op_region init
+ * $Revision: 22 $


X *
X *****************************************************************************/
X

@@ -24,13 +25,13 @@


X
X
X #include "acpi.h"

-#include "events.h"


-#include "namesp.h"
-#include "interp.h"
+#include "acevents.h"

+#include "acnamesp.h"
+#include "acinterp.h"
X #include "amlcode.h"

X
X #define _COMPONENT EVENT_HANDLING
- MODULE_NAME ("evrgnini");
+ MODULE_NAME ("evrgnini")
X
X
X /*****************************************************************************
@@ -40,8 +41,8 @@
X * PARAMETERS: Region_obj - region we are interested in
X * Function - start or stop
X * Handler_context - Address space handler context
- * Returned context - context to be used with each call to the
- * handler for this region
+ * Region_context - Region specific context
+ *


X * RETURN: Status
X *

X * DESCRIPTION: Do any prep work for region handling, a nop for now
@@ -53,21 +54,17 @@
X ACPI_HANDLE handle,
X u32 function,
X void *handler_context,
- void **return_context)
+ void **region_context)
X {
- MEM_HANDLER_CONTEXT *mem_context;
- ACPI_OBJECT_INTERNAL *region_obj = (ACPI_OBJECT_INTERNAL *) handle;
+ ACPI_OPERAND_OBJECT *region_obj = (ACPI_OPERAND_OBJECT *) handle;
X
X
X if (function == ACPI_REGION_DEACTIVATE) {
- region_obj->region.region_flags &= ~(REGION_INITIALIZED);
-
- *return_context = NULL;
- if (handler_context) {
- mem_context = handler_context;
- *return_context = mem_context->handler_context;
+ region_obj->region.flags &= ~(AOPOBJ_INITIALIZED);
X
- acpi_cm_free (mem_context);
+ if (*region_context) {
+ acpi_cm_free (*region_context);
+ *region_context = NULL;


X }
X return (AE_OK);
X }

@@ -75,17 +72,15 @@
X
X /* Activate. Create a new context */
X
- mem_context = acpi_cm_callocate (sizeof (MEM_HANDLER_CONTEXT));
- if (!mem_context) {
+ *region_context = acpi_cm_callocate (sizeof (MEM_HANDLER_CONTEXT));
+ if (!(*region_context)) {


X return (AE_NO_MEMORY);
X }
X

X /* Init. (Mapping fields are all set to zeros above) */
X
- mem_context->handler_context = handler_context;
- region_obj->region.region_flags |= REGION_INITIALIZED;
+ region_obj->region.flags |= AOPOBJ_INITIALIZED;
X
- *return_context = mem_context;


X return (AE_OK);
X }
X

@@ -97,8 +92,8 @@
X * PARAMETERS: Region_obj - region we are interested in
X * Function - start or stop
X * Handler_context - Address space handler context
- * Returned context - context to be used with each call to the
- * handler for this region
+ * Region_context - Region specific context
+ *


X * RETURN: Status
X *

X * DESCRIPTION: Do any prep work for region handling
@@ -110,21 +105,18 @@
X ACPI_HANDLE handle,
X u32 function,
X void *handler_context,
- void **return_context)
+ void **region_context)
X {
- ACPI_OBJECT_INTERNAL *region_obj = (ACPI_OBJECT_INTERNAL *) handle;
-
+ ACPI_OPERAND_OBJECT *region_obj = (ACPI_OPERAND_OBJECT *) handle;
X
X if (function == ACPI_REGION_DEACTIVATE) {
- region_obj->region.region_flags &= ~(REGION_INITIALIZED);
- *return_context = handler_context;
- return (AE_OK);
+ *region_context = NULL;
+ region_obj->region.flags &= ~(AOPOBJ_INITIALIZED);
+ }
+ else {
+ *region_context = handler_context;
+ region_obj->region.flags |= AOPOBJ_INITIALIZED;
X }
-
- /* Activate the region */
-
- region_obj->region.region_flags |= REGION_INITIALIZED;
- *return_context = handler_context;


X
X return (AE_OK);
X }

@@ -137,8 +129,8 @@
X * PARAMETERS: Region_obj - region we are interested in
X * Function - start or stop
X * Handler_context - Address space handler context
- * Returned context - context to be used with each call to the
- * handler for this region
+ * Region_context - Region specific context
+ *


X * RETURN: Status
X *

X * DESCRIPTION: Do any prep work for region handling
@@ -152,14 +144,14 @@
X ACPI_HANDLE handle,
X u32 function,
X void *handler_context,
- void **return_context)
+ void **region_context)


X {
X ACPI_STATUS status = AE_OK;

X u32 temp;
- PCI_HANDLER_CONTEXT *pci_context;
- ACPI_OBJECT_INTERNAL *handler_obj;
- ACPI_NAMED_OBJECT *search_scope;
- ACPI_OBJECT_INTERNAL *region_obj = (ACPI_OBJECT_INTERNAL *) handle;
+ PCI_HANDLER_CONTEXT *pci_context = *region_context;
+ ACPI_OPERAND_OBJECT *handler_obj;
+ ACPI_NAMESPACE_NODE *node;
+ ACPI_OPERAND_OBJECT *region_obj = (ACPI_OPERAND_OBJECT *) handle;
X
X
X handler_obj = region_obj->region.addr_handler;
@@ -173,14 +165,11 @@
X }
X
X if (function == ACPI_REGION_DEACTIVATE) {
- region_obj->region.region_flags &= ~(REGION_INITIALIZED);
-
- *return_context = NULL;
- if (handler_context) {
- pci_context = handler_context;
- *return_context = pci_context->handler_context;
+ region_obj->region.flags &= ~(AOPOBJ_INITIALIZED);
X
+ if (pci_context) {
X acpi_cm_free (pci_context);
+ *region_context = NULL;
X }
X
X return (status);
@@ -189,7 +178,7 @@
X
X /* Create a new context */
X
- pci_context = acpi_cm_allocate (sizeof(PCI_HANDLER_CONTEXT));
+ pci_context = acpi_cm_callocate (sizeof(PCI_HANDLER_CONTEXT));
X if (!pci_context) {
X return (AE_NO_MEMORY);
X }
@@ -203,16 +192,16 @@
X * First get device and function numbers from the _ADR object
X * in the parent's scope.
X */
- ACPI_ASSERT(region_obj->region.nte);
+ ACPI_ASSERT(region_obj->region.node);
X
- search_scope = acpi_ns_get_parent_entry (region_obj->region.nte);
+ node = acpi_ns_get_parent_object (region_obj->region.node);
X
X
X acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
X
X /* Acpi_evaluate the _ADR object */
X
- status = acpi_cm_evaluate_numeric_object (METHOD_NAME__ADR, search_scope, &temp);
+ status = acpi_cm_evaluate_numeric_object (METHOD_NAME__ADR, node, &temp);
X /*
X * The default is zero, since the allocation above zeroed the data, just
X * do nothing on failures.
@@ -232,9 +221,9 @@
X * This is the device the handler has been registered to handle.
X */
X
- search_scope = handler_obj->addr_handler.nte;
+ node = handler_obj->addr_handler.node;
X
- status = acpi_cm_evaluate_numeric_object (METHOD_NAME__SEG, search_scope, &temp);
+ status = acpi_cm_evaluate_numeric_object (METHOD_NAME__SEG, node, &temp);
X if (ACPI_SUCCESS (status)) {
X /*
X * Got it..
@@ -242,7 +231,7 @@
X pci_context->seg = temp;
X }
X
- status = acpi_cm_evaluate_numeric_object (METHOD_NAME__BBN, search_scope, &temp);
+ status = acpi_cm_evaluate_numeric_object (METHOD_NAME__BBN, node, &temp);
X if (ACPI_SUCCESS (status)) {
X /*
X * Got it..
@@ -250,11 +239,12 @@
X pci_context->bus = temp;
X }
X
+ *region_context = pci_context;
+
X acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
X
- *return_context = pci_context;
+ region_obj->region.flags |= AOPOBJ_INITIALIZED;
X
- region_obj->region.region_flags |= REGION_INITIALIZED;


X return (AE_OK);
X }
X

@@ -266,8 +256,8 @@
X * PARAMETERS: Region_obj - region we are interested in
X * Function - start or stop
X * Handler_context - Address space handler context
- * Returned context - context to be used with each call to the
- * handler for this region
+ * Region_context - Region specific context
+ *


X * RETURN: Status
X *

X * DESCRIPTION: Do any prep work for region handling
@@ -279,18 +269,18 @@
X ACPI_HANDLE handle,
X u32 function,
X void *handler_context,
- void **return_context)
+ void **region_context)
X {
- ACPI_OBJECT_INTERNAL *region_obj = (ACPI_OBJECT_INTERNAL *) handle;
+ ACPI_OPERAND_OBJECT *region_obj = (ACPI_OPERAND_OBJECT *) handle;
X
X
X if (function == ACPI_REGION_DEACTIVATE) {
- region_obj->region.region_flags &= ~(REGION_INITIALIZED);
- *return_context = NULL;
+ *region_context = NULL;
+ region_obj->region.flags &= ~(AOPOBJ_INITIALIZED);
X }
X else {
- region_obj->region.region_flags |= REGION_INITIALIZED;
- *return_context = handler_context;
+ *region_context = handler_context;
+ region_obj->region.flags |= AOPOBJ_INITIALIZED;


X }
X
X return (AE_OK);

@@ -320,15 +310,15 @@
X

X ACPI_STATUS
X acpi_ev_initialize_region (
- ACPI_OBJECT_INTERNAL *region_obj,
+ ACPI_OPERAND_OBJECT *region_obj,
X u8 acpi_ns_locked)
X {
- ACPI_OBJECT_INTERNAL *handler_obj;
- ACPI_OBJECT_INTERNAL *obj_desc;
+ ACPI_OPERAND_OBJECT *handler_obj;
+ ACPI_OPERAND_OBJECT *obj_desc;
X u32 space_id;
- ACPI_NAMED_OBJECT *entry; /* Namespace Object */


+ ACPI_NAMESPACE_NODE *node;
X ACPI_STATUS status;

- ACPI_NAMED_OBJECT *reg_entry;
+ ACPI_NAMESPACE_NODE *method_node;
X ACPI_NAME *reg_name_ptr = (ACPI_NAME *) METHOD_NAME__REG;
X
X
@@ -336,44 +326,44 @@
X return (AE_BAD_PARAMETER);
X }
X
- ACPI_ASSERT(region_obj->region.nte);
+ ACPI_ASSERT(region_obj->region.node);
X
- entry = acpi_ns_get_parent_entry (region_obj->region.nte);
+ node = acpi_ns_get_parent_object (region_obj->region.node);
X space_id = region_obj->region.space_id;
X
X region_obj->region.addr_handler = NULL;
X region_obj->region.REGmethod = NULL;
- region_obj->region.region_flags = INITIAL_REGION_FLAGS;
+ region_obj->region.flags &= ~(AOPOBJ_INITIALIZED);
X
X /*
X * Find any "_REG" associated with this region definition
X */
- status = acpi_ns_search_one_scope (*reg_name_ptr, entry->child_table,
- ACPI_TYPE_METHOD, &reg_entry, NULL);
- if (status == AE_OK) {
+ status = acpi_ns_search_node (*reg_name_ptr, node,
+ ACPI_TYPE_METHOD, &method_node);
+ if (ACPI_SUCCESS (status)) {
X /*
X * The _REG method is optional and there can be only one per region
X * definition. This will be executed when the handler is attached
X * or removed
X */
- region_obj->region.REGmethod = reg_entry;
+ region_obj->region.REGmethod = method_node;
X }
X
X /*
- * The following loop depends upon the root nte having no parent
- * ie: Acpi_gbl_Root_object->Parent_entry being set to NULL
+ * The following loop depends upon the root Node having no parent
+ * ie: Acpi_gbl_Root_node->Parent_entry being set to NULL
X */
- while (entry) {
+ while (node) {
X /*
X * Check to see if a handler exists
X */
X handler_obj = NULL;
- obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) entry);
+ obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) node);
X if (obj_desc) {
X /*
X * can only be a handler if the object exists
X */
- switch (entry->type)
+ switch (node->type)
X {
X case ACPI_TYPE_DEVICE:
X
@@ -400,11 +390,11 @@
X /*
X * Found it! Now update the region and the handler
X */
- acpi_ev_associate_region_and_handler(handler_obj, region_obj);
+ acpi_ev_associate_region_and_handler (handler_obj, region_obj, acpi_ns_locked);


X return (AE_OK);
X }
X

- handler_obj = handler_obj->addr_handler.link;
+ handler_obj = handler_obj->addr_handler.next;
X
X } /* while handlerobj */
X }
@@ -413,9 +403,9 @@
X * This one does not have the handler we need
X * Pop up one level
X */
- entry = acpi_ns_get_parent_entry (entry);
+ node = acpi_ns_get_parent_object (node);
X
- } /* while Entry != ROOT */
+ } /* while Node != ROOT */
X
X /*
X * If we get here, there is no handler for this region
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/events/evsci.c linux/drivers/acpi/events/evsci.c
--- v2.4.0-test8/linux/drivers/acpi/events/evsci.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/events/evsci.c Fri Sep 15 14:30:30 2000
@@ -1,9 +1,10 @@
-/******************************************************************************
+/*******************************************************************************
X *
X * Module Name: evsci - System Control Interrupt configuration and
X * legacy to ACPI mode state transition functions
+ * $Revision: 59 $


X *
- *****************************************************************************/
+ ******************************************************************************/
X
X /*
X * Copyright (C) 2000 R. Byron Moore

@@ -24,27 +25,26 @@
X */
X

X #include "acpi.h"
-#include "namesp.h"

-#include "hardware.h"
-#include "events.h"
+#include "acnamesp.h"
+#include "achware.h"
+#include "acevents.h"
X
X
X #define _COMPONENT EVENT_HANDLING
- MODULE_NAME ("evsci");
+ MODULE_NAME ("evsci")
X
X
X /*
- * Elements correspond to counts for
- * TMR, NOT_USED, GBL, PWR_BTN, SLP_BTN, RTC,
- * and GENERAL respectively. These counts
- * are modified by the ACPI interrupt handler...
- * Note that GENERAL should probably be split out
- * into one element for each bit in the GPE
- * registers
+ * Elements correspond to counts for TMR, NOT_USED, GBL, PWR_BTN, SLP_BTN, RTC,
+ * and GENERAL respectively. These counts are modified by the ACPI interrupt
+ * handler.
+ *
+ * TBD: [Investigate] Note that GENERAL should probably be split out into
+ * one element for each bit in the GPE registers
X */
X
X
-/******************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_ev_sci_handler
X *
@@ -61,16 +61,16 @@
X u32
X acpi_ev_sci_handler (void *context)
X {
- u32 interrupt_handled = INTERRUPT_NOT_HANDLED;
+ u32 interrupt_handled = INTERRUPT_NOT_HANDLED;
+
X
X /*
- * ACPI Enabled?
- * -------------
X * Make sure that ACPI is enabled by checking SCI_EN. Note that we are
X * required to treat the SCI interrupt as sharable, level, active low.
X */
- if (!acpi_hw_register_access (ACPI_READ, ACPI_MTX_DO_NOT_LOCK, (s32)SCI_EN)) {
- REPORT_ERROR ("Received and SCI but ACPI is not enabled.");
+ if (!acpi_hw_register_access (ACPI_READ, ACPI_MTX_DO_NOT_LOCK, SCI_EN)) {
+ /* ACPI is not enabled; this interrupt cannot be for us */
+
X return (INTERRUPT_NOT_HANDLED);
X }
X
@@ -107,12 +107,12 @@
X u32
X acpi_ev_install_sci_handler (void)
X {
- u32 except = AE_OK;
+ u32 except = AE_OK;
+
X
- except = acpi_os_install_interrupt_handler (
- (u32) acpi_gbl_FACP->sci_int,
- acpi_ev_sci_handler,
- NULL);
+ except = acpi_os_install_interrupt_handler ((u32) acpi_gbl_FACP->sci_int,
+ acpi_ev_sci_handler,
+ NULL);
X
X return (except);
X }
@@ -163,24 +163,21 @@
X
X #endif
X
- acpi_os_remove_interrupt_handler (
- (u32) acpi_gbl_FACP->sci_int,
- acpi_ev_sci_handler);
+ acpi_os_remove_interrupt_handler ((u32) acpi_gbl_FACP->sci_int,
+ acpi_ev_sci_handler);


X
X return (AE_OK);
X }
X
X

-/******************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_ev_sci_count
X *
- * PARAMETERS: char * Event_name name (fully qualified name from namespace
- * or one of the fixed event names defined above)
- * of the event to check if it's generated an SCI.
+ * PARAMETERS: Event Event that generated an SCI.
X *
- * RETURN: Number of SCI's for requested event since last time i_sci_occured()
- * was called for this event.
+ * RETURN: Number of SCI's for requested event since last time
+ * Sci_occured() was called for this event.
X *
X * DESCRIPTION: Checks to see if SCI has been generated from requested source
X * since the last time this function was called.
@@ -188,7 +185,7 @@
X ******************************************************************************/
X
X
-/******************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_ev_restore_acpi_state
X *
@@ -203,7 +200,7 @@
X void
X acpi_ev_restore_acpi_state (void)
X {


- s32 index;
+ u32 index;
X
X

X /* Restore the state of the chipset enable bits. */
@@ -283,6 +280,7 @@
X void
X acpi_ev_terminate (void)
X {
+
X
X /*
X * Free global tables, etc.
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/events/evxface.c linux/drivers/acpi/events/evxface.c
--- v2.4.0-test8/linux/drivers/acpi/events/evxface.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/events/evxface.c Fri Sep 15 14:30:30 2000
@@ -1,6 +1,7 @@
X /******************************************************************************
X *
X * Module Name: evxface - External interfaces for ACPI events
+ * $Revision: 88 $


X *
X *****************************************************************************/
X

@@ -24,14 +25,14 @@


X
X
X #include "acpi.h"

-#include "hardware.h"
-#include "namesp.h"
-#include "events.h"
+#include "achware.h"
+#include "acnamesp.h"
+#include "acevents.h"
X #include "amlcode.h"
-#include "interp.h"
+#include "acinterp.h"
X
X #define _COMPONENT EVENT_HANDLING
- MODULE_NAME ("evxface");
+ MODULE_NAME ("evxface")
X
X
X /******************************************************************************
@@ -172,9 +173,9 @@
X NOTIFY_HANDLER handler,
X void *context)
X {
- ACPI_OBJECT_INTERNAL *obj_desc;
- ACPI_OBJECT_INTERNAL *notify_obj;
- ACPI_NAMED_OBJECT *obj_entry;
+ ACPI_OPERAND_OBJECT *obj_desc;
+ ACPI_OPERAND_OBJECT *notify_obj;
+ ACPI_NAMESPACE_NODE *device_node;


X ACPI_STATUS status = AE_OK;
X
X

@@ -190,8 +191,8 @@
X

X acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
X
- obj_entry = acpi_ns_convert_handle_to_entry (device);
- if (!obj_entry) {
+ device_node = acpi_ns_convert_handle_to_entry (device);
+ if (!device_node) {
X status = AE_BAD_PARAMETER;
X goto unlock_and_exit;
X }
@@ -217,13 +218,13 @@
X }
X
X if (handler_type == ACPI_SYSTEM_NOTIFY) {
- acpi_gbl_sys_notify.nte = obj_entry;
+ acpi_gbl_sys_notify.node = device_node;
X acpi_gbl_sys_notify.handler = handler;
X acpi_gbl_sys_notify.context = context;
X }
X
X else {
- acpi_gbl_drv_notify.nte = obj_entry;
+ acpi_gbl_drv_notify.node = device_node;
X acpi_gbl_drv_notify.handler = handler;
X acpi_gbl_drv_notify.context = context;
X }
@@ -239,10 +240,10 @@
X * These are the ONLY objects that can receive ACPI notifications
X */
X
- if ((obj_entry->type != ACPI_TYPE_DEVICE) &&
- (obj_entry->type != ACPI_TYPE_PROCESSOR) &&
- (obj_entry->type != ACPI_TYPE_POWER) &&
- (obj_entry->type != ACPI_TYPE_THERMAL))
+ if ((device_node->type != ACPI_TYPE_DEVICE) &&
+ (device_node->type != ACPI_TYPE_PROCESSOR) &&
+ (device_node->type != ACPI_TYPE_POWER) &&
+ (device_node->type != ACPI_TYPE_THERMAL))
X {
X status = AE_BAD_PARAMETER;
X goto unlock_and_exit;
@@ -250,7 +251,7 @@
X
X /* Check for an existing internal object */
X
- obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) obj_entry);
+ obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) device_node);
X if (obj_desc) {
X /*
X * The object exists.
@@ -270,15 +271,15 @@
X else {
X /* Create a new object */
X
- obj_desc = acpi_cm_create_internal_object (obj_entry->type);
+ obj_desc = acpi_cm_create_internal_object (device_node->type);
X if (!obj_desc) {
X status = AE_NO_MEMORY;
X goto unlock_and_exit;
X }
X
- /* Attach new object to the NTE */
+ /* Attach new object to the Node */
X
- status = acpi_ns_attach_object (device, obj_desc, (u8) obj_entry->type);
+ status = acpi_ns_attach_object (device, obj_desc, (u8) device_node->type);


X
X if (ACPI_FAILURE (status)) {

X goto unlock_and_exit;
@@ -296,7 +297,7 @@
X goto unlock_and_exit;
X }
X
- notify_obj->notify_handler.nte = obj_entry;
+ notify_obj->notify_handler.node = device_node;
X notify_obj->notify_handler.handler = handler;
X notify_obj->notify_handler.context = context;
X
@@ -337,9 +338,9 @@
X u32 handler_type,
X NOTIFY_HANDLER handler)
X {
- ACPI_OBJECT_INTERNAL *notify_obj;
- ACPI_OBJECT_INTERNAL *obj_desc;
- ACPI_NAMED_OBJECT *obj_entry;
+ ACPI_OPERAND_OBJECT *notify_obj;
+ ACPI_OPERAND_OBJECT *obj_desc;
+ ACPI_NAMESPACE_NODE *device_node;


X ACPI_STATUS status = AE_OK;
X
X

@@ -355,8 +356,8 @@
X
X /* Convert and validate the device handle */
X
- obj_entry = acpi_ns_convert_handle_to_entry (device);
- if (!obj_entry) {
+ device_node = acpi_ns_convert_handle_to_entry (device);
+ if (!device_node) {
X status = AE_BAD_PARAMETER;
X goto unlock_and_exit;
X }
@@ -365,10 +366,10 @@
X * These are the ONLY objects that can receive ACPI notifications
X */
X
- if ((obj_entry->type != ACPI_TYPE_DEVICE) &&
- (obj_entry->type != ACPI_TYPE_PROCESSOR) &&
- (obj_entry->type != ACPI_TYPE_POWER) &&
- (obj_entry->type != ACPI_TYPE_THERMAL))
+ if ((device_node->type != ACPI_TYPE_DEVICE) &&
+ (device_node->type != ACPI_TYPE_PROCESSOR) &&
+ (device_node->type != ACPI_TYPE_POWER) &&
+ (device_node->type != ACPI_TYPE_THERMAL))
X {
X status = AE_BAD_PARAMETER;
X goto unlock_and_exit;


@@ -376,7 +377,7 @@
X

X /* Check for an existing internal object */
X
- obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) obj_entry);
+ obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) device_node);
X if (!obj_desc) {
X status = AE_NOT_EXIST;
X goto unlock_and_exit;
@@ -573,7 +574,7 @@
X acpi_aml_exit_interpreter ();
X
X *out_handle = 0;


- return status;
+ return (status);
X }
X
X

@@ -598,7 +599,7 @@
X /* TBD: [Restructure] Validate handle */
X
X acpi_ev_release_global_lock ();


- return AE_OK;
+ return (AE_OK);
X }
X
X

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/events/evxfevnt.c linux/drivers/acpi/events/evxfevnt.c
--- v2.4.0-test8/linux/drivers/acpi/events/evxfevnt.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/events/evxfevnt.c Fri Sep 15 14:30:30 2000
@@ -1,6 +1,7 @@
X /******************************************************************************
X *
X * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable


+ * $Revision: 19 $
X *
X *****************************************************************************/
X

@@ -24,16 +25,24 @@
X
X

X #include "acpi.h"
-#include "hardware.h"

-#include "namesp.h"
-#include "events.h"
+#include "achware.h"
+#include "acnamesp.h"
+#include "acevents.h"
X #include "amlcode.h"
-#include "interp.h"
+#include "acinterp.h"
X
X #define _COMPONENT EVENT_HANDLING
- MODULE_NAME ("evxfevnt");
+ MODULE_NAME ("evxfevnt")
X
X
+ACPI_STATUS
+acpi_ev_find_pci_root_buses (
+ void);
+
+ACPI_STATUS
+acpi_ev_init_devices (
+ void);
+
X /**************************************************************************
X *
X * FUNCTION: Acpi_enable
@@ -60,12 +69,27 @@
X return (AE_NO_ACPI_TABLES);
X }
X
+ /* Init the hardware */
+
+ /*
+ * With the advent of a 3-pass parser, we need to be
+ * prepared to execute on initialized HW before the
+ * namespace has completed its load.
+ */
+
+ status = acpi_cm_hardware_initialize ();


+ if (ACPI_FAILURE (status)) {
+ return (status);
+ }
+
+

X /* Make sure the BIOS supports ACPI mode */
X
X if (SYS_MODE_LEGACY == acpi_hw_get_mode_capabilities()) {
X return (AE_ERROR);
X }
X
+
X acpi_gbl_original_mode = acpi_hw_get_mode();
X
X /*
@@ -74,24 +98,28 @@
X * before handers are installed.
X */
X
- if (ACPI_FAILURE (acpi_ev_fixed_event_initialize ())) {
- return (AE_ERROR);
+ status = acpi_ev_fixed_event_initialize ();


+ if (ACPI_FAILURE (status)) {
+ return (status);

X }
X
- if (ACPI_FAILURE (acpi_ev_gpe_initialize())) {
- return (AE_ERROR);
+ status = acpi_ev_gpe_initialize ();


+ if (ACPI_FAILURE (status)) {
+ return (status);

X }
X
X /* Install the SCI handler */
X
- if (ACPI_FAILURE (acpi_ev_install_sci_handler ())) {
- return (AE_ERROR);
+ status = acpi_ev_install_sci_handler ();


+ if (ACPI_FAILURE (status)) {
+ return (status);

X }
X
X /* Transition to ACPI mode */
X
- if (AE_OK != acpi_hw_set_mode (SYS_MODE_ACPI)) {


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 022'
echo 'File patch-2.4.0-test9 is continued in part 023'
echo "023" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part023

#!/bin/sh -x
# this is part 023 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 023; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

- return (AE_ERROR);
+ status = acpi_hw_set_mode (SYS_MODE_ACPI);


+ if (ACPI_FAILURE (status)) {
+ return (status);
X }
X

X /* Install handlers for control method GPE handlers (_Lxx, _Exx) */
@@ -100,6 +128,26 @@
X
X status = acpi_ev_init_global_lock_handler ();
X
+ /*
+ * Perform additional initialization that may cause control methods
+ * to be executed
+ *
+ * It may be wise to move this code to a new interface
+ */
+
+
+ /*
+ * Install PCI config space handler for all PCI root bridges. A PCI root
+ * bridge is found by searching for devices containing a HID with the value
+ * EISAID("PNP0A03")
+ */
+
+ acpi_ev_find_pci_root_buses ();
+
+ /* Call _INI on all devices */
+
+ acpi_ev_init_devices ();
+


X return (status);
X }
X

@@ -120,12 +168,14 @@
X ACPI_STATUS
X acpi_disable (void)
X {
+ ACPI_STATUS status;
X
X
X /* Restore original mode */
X
- if (AE_OK != acpi_hw_set_mode (acpi_gbl_original_mode)) {
- return (AE_ERROR);
+ status = acpi_hw_set_mode (acpi_gbl_original_mode);


+ if (ACPI_FAILURE (status)) {
+ return (status);
X }
X

X /* Unload the SCI interrupt handler */
@@ -133,7 +183,7 @@
X acpi_ev_remove_sci_handler ();
X acpi_ev_restore_acpi_state ();
X
- return (AE_OK);


+ return (status);
X }
X
X

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/events/evxfregn.c linux/drivers/acpi/events/evxfregn.c
--- v2.4.0-test8/linux/drivers/acpi/events/evxfregn.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/events/evxfregn.c Fri Sep 15 14:30:30 2000


@@ -2,6 +2,7 @@
X *

X * Module Name: evxfregn - External Interfaces, ACPI Operation Regions and
X * Address Spaces.
+ * $Revision: 20 $


X *
X *****************************************************************************/
X

@@ -25,14 +26,14 @@


X
X
X #include "acpi.h"
-#include "hardware.h"
-#include "namesp.h"
-#include "events.h"
+#include "achware.h"
+#include "acnamesp.h"
+#include "acevents.h"
X #include "amlcode.h"
-#include "interp.h"
+#include "acinterp.h"
X
X #define _COMPONENT EVENT_HANDLING

- MODULE_NAME ("evxfregn");
+ MODULE_NAME ("evxfregn")
X
X
X /******************************************************************************
@@ -59,9 +60,9 @@
X ADDRESS_SPACE_SETUP setup,


X void *context)
X {
- ACPI_OBJECT_INTERNAL *obj_desc;

- ACPI_OBJECT_INTERNAL *handler_obj;


- ACPI_NAMED_OBJECT *obj_entry;
+ ACPI_OPERAND_OBJECT *obj_desc;

+ ACPI_OPERAND_OBJECT *handler_obj;
+ ACPI_NAMESPACE_NODE *node;
X ACPI_STATUS status = AE_OK;
X OBJECT_TYPE_INTERNAL type;
X u16 flags = 0;
@@ -80,8 +81,8 @@


X
X /* Convert and validate the device handle */
X
- obj_entry = acpi_ns_convert_handle_to_entry (device);
- if (!obj_entry) {

+ node = acpi_ns_convert_handle_to_entry (device);
+ if (!node) {


X status = AE_BAD_PARAMETER;
X goto unlock_and_exit;
X }

@@ -92,10 +93,10 @@
X * get placed.


X */
X
- if ((obj_entry->type != ACPI_TYPE_DEVICE) &&
- (obj_entry->type != ACPI_TYPE_PROCESSOR) &&

- (obj_entry->type != ACPI_TYPE_THERMAL) &&


- (obj_entry != acpi_gbl_root_object))
+ if ((node->type != ACPI_TYPE_DEVICE) &&

+ (node->type != ACPI_TYPE_PROCESSOR) &&
+ (node->type != ACPI_TYPE_THERMAL) &&


+ (node != acpi_gbl_root_node))
X {

X status = AE_BAD_PARAMETER;
X goto unlock_and_exit;

@@ -139,7 +140,7 @@
X * Check for an existing internal object
X */


X
- obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) obj_entry);
+ obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) node);

X if (obj_desc) {
X /*
X * The object exists.

@@ -162,19 +163,19 @@


X /*
X * Move through the linked list of handlers
X */

- handler_obj = handler_obj->addr_handler.link;
+ handler_obj = handler_obj->addr_handler.next;
X }
X }

X
X else {
X /* Obj_desc does not exist, create one */
X
- if (obj_entry->type == ACPI_TYPE_ANY) {
+ if (node->type == ACPI_TYPE_ANY) {
X type = ACPI_TYPE_DEVICE;
X }
X
X else {
- type = obj_entry->type;
+ type = node->type;
X }
X
X obj_desc = acpi_cm_create_internal_object (type);
@@ -187,19 +188,13 @@
X
X obj_desc->common.type = (u8) type;
X
- /* Attach the new object to the NTE */
+ /* Attach the new object to the Node */
X
X status = acpi_ns_attach_object (device, obj_desc, (u8) type);
X if (ACPI_FAILURE (status)) {
X acpi_cm_remove_reference (obj_desc);
X goto unlock_and_exit;
X }
-
- /* TBD: [Investigate] Will this always be of type DEVICE? */
-
- if (type == ACPI_TYPE_DEVICE) {
- obj_desc->device.handle = device;
- }
X }
X
X /*
@@ -215,11 +210,11 @@


X goto unlock_and_exit;
X }
X

- handler_obj->addr_handler.space_id = (u16) space_id;
+ handler_obj->addr_handler.space_id = (u8) space_id;
X handler_obj->addr_handler.hflags = flags;
- handler_obj->addr_handler.link = obj_desc->device.addr_handler;
+ handler_obj->addr_handler.next = obj_desc->device.addr_handler;
X handler_obj->addr_handler.region_list = NULL;
- handler_obj->addr_handler.nte = obj_entry;
+ handler_obj->addr_handler.node = node;
X handler_obj->addr_handler.handler = handler;
X handler_obj->addr_handler.context = context;
X handler_obj->addr_handler.setup = setup;
@@ -237,7 +232,7 @@
X * of the branch
X */
X status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, device,
- ACPI_INT32_MAX, NS_WALK_NO_UNLOCK,
+ ACPI_UINT32_MAX, NS_WALK_UNLOCK,
X acpi_ev_addr_handler_helper,
X handler_obj, NULL);
X
@@ -276,11 +271,11 @@
X ACPI_ADDRESS_SPACE_TYPE space_id,
X ADDRESS_SPACE_HANDLER handler)


X {
- ACPI_OBJECT_INTERNAL *obj_desc;
- ACPI_OBJECT_INTERNAL *handler_obj;

- ACPI_OBJECT_INTERNAL *region_obj;
- ACPI_OBJECT_INTERNAL **last_obj_ptr;


- ACPI_NAMED_OBJECT *obj_entry;
+ ACPI_OPERAND_OBJECT *obj_desc;

+ ACPI_OPERAND_OBJECT *handler_obj;
+ ACPI_OPERAND_OBJECT *region_obj;
+ ACPI_OPERAND_OBJECT **last_obj_ptr;
+ ACPI_NAMESPACE_NODE *node;


X ACPI_STATUS status = AE_OK;
X
X

@@ -297,8 +292,8 @@


X
X /* Convert and validate the device handle */
X
- obj_entry = acpi_ns_convert_handle_to_entry (device);
- if (!obj_entry) {

+ node = acpi_ns_convert_handle_to_entry (device);
+ if (!node) {


X status = AE_BAD_PARAMETER;
X goto unlock_and_exit;
X }

@@ -306,7 +301,7 @@
X
X /* Make sure the internal object exists */


X
- obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) obj_entry);
+ obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) node);
X if (!obj_desc) {
X /*

X * The object DNE.
@@ -356,7 +351,7 @@
X /*
X * Remove this Handler object from the list
X */
- *last_obj_ptr = handler_obj->addr_handler.link;
+ *last_obj_ptr = handler_obj->addr_handler.next;
X
X /*
X * Now we can delete the handler object
@@ -370,8 +365,8 @@


X /*
X * Move through the linked list of handlers
X */

- last_obj_ptr = &handler_obj->addr_handler.link;


- handler_obj = handler_obj->addr_handler.link;

+ last_obj_ptr = &handler_obj->addr_handler.next;


+ handler_obj = handler_obj->addr_handler.next;
X }
X

X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/hardware/Makefile linux/drivers/acpi/hardware/Makefile
--- v2.4.0-test8/linux/drivers/acpi/hardware/Makefile Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/hardware/Makefile Fri Sep 15 18:21:43 2000

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/hardware/hwacpi.c linux/drivers/acpi/hardware/hwacpi.c
--- v2.4.0-test8/linux/drivers/acpi/hardware/hwacpi.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/hardware/hwacpi.c Fri Sep 15 14:30:30 2000


@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *

X * Module Name: hwacpi - ACPI hardware functions - mode and timer


+ * $Revision: 22 $
X *
X *****************************************************************************/
X

@@ -25,11 +25,11 @@


X
X
X #include "acpi.h"
-#include "hardware.h"

+#include "achware.h"
X
X
X #define _COMPONENT HARDWARE
- MODULE_NAME ("hwacpi");
+ MODULE_NAME ("hwacpi")
X
X
X /******************************************************************************
@@ -95,7 +95,7 @@
X {
X
X
- if (acpi_hw_register_access (ACPI_READ, ACPI_MTX_LOCK, (s32)SCI_EN)) {
+ if (acpi_hw_register_access (ACPI_READ, ACPI_MTX_LOCK, SCI_EN)) {
X return (SYS_MODE_ACPI);
X }
X else {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/hardware/hwcpu32.c linux/drivers/acpi/hardware/hwcpu32.c
--- v2.4.0-test8/linux/drivers/acpi/hardware/hwcpu32.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/hardware/hwcpu32.c Fri Sep 15 14:30:30 2000


@@ -1,6 +1,7 @@
X /******************************************************************************
X *

X * Name: hwcpu32.c - CPU support for IA32 (Throttling, Cx_states)
+ * $Revision: 33 $


X *
X *****************************************************************************/
X

@@ -23,11 +24,11 @@


X */
X
X #include "acpi.h"
-#include "namesp.h"
-#include "hardware.h"

+#include "acnamesp.h"
+#include "achware.h"
X
X #define _COMPONENT HARDWARE
- MODULE_NAME ("Hwcpu32");
+ MODULE_NAME ("Hwcpu32")
X
X
X #define BIT_4 0x10 /* TBD: [investigate] is this correct? */
@@ -82,7 +83,7 @@
X *pm_timer_ticks = timer;


X }
X
- return AE_OK;
+ return (AE_OK);
X }
X
X

@@ -108,7 +109,7 @@
X
X

X if (!pblk_address || !pm_timer_ticks) {
- return AE_BAD_PARAMETER;
+ return (AE_BAD_PARAMETER);
X }
X
X /*
@@ -146,7 +147,7 @@
X */
X enable ();


X
- return AE_OK;
+ return (AE_OK);
X }
X
X

@@ -175,7 +176,7 @@
X
X
X if (!pblk_address || !pm_timer_ticks) {
- return AE_BAD_PARAMETER;
+ return (AE_BAD_PARAMETER);
X }
X
X /*
@@ -186,14 +187,14 @@
X * eventually cause a demotion to C2
X */
X if (1 == (bus_master_status =
- acpi_hw_register_access (ACPI_READ, ACPI_MTX_LOCK, (s32)BM_STS)))
+ acpi_hw_register_access (ACPI_READ, ACPI_MTX_LOCK, BM_STS)))
X {
X /*
X * Clear the BM_STS bit by setting it.
X */
- acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_LOCK, (s32)BM_STS, 1);
+ acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_STS, 1);
X *pm_timer_ticks = 0;


- return AE_OK;
+ return (AE_OK);
X }
X
X /*

@@ -253,7 +254,7 @@
X */
X enable();


X
- return AE_OK;
+ return (AE_OK);
X }
X
X

@@ -277,7 +278,7 @@
X {
X
X if (!acpi_hw_cx_handlers[acpi_hw_active_cx_state]) {
- return AE_SUPPORT;
+ return (AE_SUPPORT);
X }
X
X return (acpi_hw_cx_handlers[acpi_hw_active_cx_state] (pblk_address, pm_timer_ticks));
@@ -305,11 +306,11 @@
X * ----------------
X */
X if ((cx_state < 1) || (cx_state > 3)) {
- return AE_BAD_PARAMETER;
+ return (AE_BAD_PARAMETER);
X }
X
X if (!acpi_hw_cx_handlers[cx_state]) {
- return AE_SUPPORT;
+ return (AE_SUPPORT);
X }
X
X /*
@@ -318,7 +319,7 @@
X * We only care when moving from one state to another...
X */
X if (acpi_hw_active_cx_state == cx_state) {


- return AE_OK;
+ return (AE_OK);
X }
X
X /*

@@ -331,7 +332,7 @@
X switch (cx_state)
X {
X case 3:
- acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_LOCK, (s32)BM_RLD, 1);
+ acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_RLD, 1);
X break;
X }
X
@@ -345,7 +346,7 @@
X switch (acpi_hw_active_cx_state)
X {
X case 3:
- acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_LOCK, (s32)BM_RLD, 0);
+ acpi_hw_register_access (ACPI_WRITE, ACPI_MTX_LOCK, BM_RLD, 0);
X break;
X }
X
@@ -355,7 +356,7 @@
X */
X acpi_hw_active_cx_state = cx_state;


X
- return AE_OK;
+ return (AE_OK);
X }
X
X

@@ -526,7 +527,7 @@
X result = result * x;
X }
X
- return result;
+ return (result);
X }
X
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/hardware/hwgpe.c linux/drivers/acpi/hardware/hwgpe.c
--- v2.4.0-test8/linux/drivers/acpi/hardware/hwgpe.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/hardware/hwgpe.c Fri Sep 15 14:30:30 2000


@@ -1,6 +1,7 @@
X /******************************************************************************
X *

X * Module Name: hwgpe - Low level GPE enable/disable/clear functions


+ * $Revision: 22 $
X *
X *****************************************************************************/
X

@@ -23,12 +24,12 @@


X */
X
X #include "acpi.h"
-#include "hardware.h"

-#include "namesp.h"
-#include "events.h"
+#include "achware.h"
+#include "acnamesp.h"
+#include "acevents.h"
X

X #define _COMPONENT HARDWARE
- MODULE_NAME ("hwgpe");
+ MODULE_NAME ("hwgpe")
X
X
X u8 decode_to8bit [8] = {1,2,4,8,16,32,64,128};
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/hardware/hwregs.c linux/drivers/acpi/hardware/hwregs.c
--- v2.4.0-test8/linux/drivers/acpi/hardware/hwregs.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/hardware/hwregs.c Fri Sep 15 14:30:30 2000
@@ -1,10 +1,11 @@


X
-/******************************************************************************
+/*******************************************************************************
X *

X * Module Name: hwregs - Read/write access functions for the various ACPI
X * control and status registers.
+ * $Revision: 67 $


X *
- *****************************************************************************/
+ ******************************************************************************/
X
X /*
X * Copyright (C) 2000 R. Byron Moore

@@ -26,20 +27,20 @@


X
X
X #include "acpi.h"
-#include "hardware.h"
-#include "namesp.h"

+#include "achware.h"
+#include "acnamesp.h"
X
X #define _COMPONENT HARDWARE
- MODULE_NAME ("hwregs");
+ MODULE_NAME ("hwregs")
X
X
X /* This matches the #defines in actypes.h. */
X
-ACPI_STRING sleep_state_table[] = {"\\_S0_","\\_S1_","\\_S2_","\\_S3_",
+NATIVE_CHAR *sleep_state_table[] = {"\\_S0_","\\_S1_","\\_S2_","\\_S3_",
X "\\_S4_","\\_S4_b","\\_S5_"};


X
X
-/******************************************************************************
+/*******************************************************************************
X *

X * FUNCTION: Acpi_hw_get_bit_shift
X *
@@ -52,11 +53,11 @@


X *
X ******************************************************************************/
X

-s32
+u32
X acpi_hw_get_bit_shift (
X u32 mask)
X {
- s32 shift;
+ u32 shift;
X
X
X for (shift = 0; ((mask >> shift) & 1) == 0; shift++) { ; }
@@ -65,7 +66,7 @@


X }
X
X
-/******************************************************************************
+/*******************************************************************************
X *

X * FUNCTION: Acpi_hw_clear_acpi_status
X *


@@ -116,7 +117,7 @@
X }

X
X
-/****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_hw_obtain_sleep_type_register_data
X *
@@ -129,8 +130,7 @@
X * DESCRIPTION: Acpi_hw_obtain_sleep_type_register_data() obtains the SLP_TYP and
X * SLP_TYPb values for the sleep state requested.
X *
-
- ***************************************************************************/


+ ******************************************************************************/
X
X ACPI_STATUS

X acpi_hw_obtain_sleep_type_register_data (
@@ -139,7 +139,7 @@
X u8 *slp_typ_b)


X {
X ACPI_STATUS status = AE_OK;

- ACPI_OBJECT_INTERNAL *obj_desc;
+ ACPI_OPERAND_OBJECT *obj_desc;
X
X

X /*
@@ -157,45 +157,64 @@
X */
X
X status = acpi_ns_evaluate_by_name (sleep_state_table[sleep_state], NULL, &obj_desc);
- if (AE_OK == status) {
- if (obj_desc) {
- /*
- * We got something, now ensure it is correct. The object must
- * be a package and must have at least 2 numeric values as the
- * two elements
- */


+ if (ACPI_FAILURE (status)) {
+ return (status);
+ }

X
- if ((obj_desc->common.type != ACPI_TYPE_PACKAGE) ||
- ((obj_desc->package.elements[0])->common.type !=
- ACPI_TYPE_NUMBER) ||
- ((obj_desc->package.elements[1])->common.type !=
- ACPI_TYPE_NUMBER))
- {
- /* Invalid _Sx_ package type or value */
+ if (!obj_desc) {
+ REPORT_ERROR ("Missing Sleep State object");
+ return (AE_NOT_EXIST);
+ }
X
- REPORT_ERROR ("Object type returned from interpreter differs from expected value");
- status = AE_ERROR;
- }
- else {
- /*
- * Valid _Sx_ package size, type, and value
- */
- *slp_typ_a =
- (u8) (obj_desc->package.elements[0])->number.value;
+ /*
+ * We got something, now ensure it is correct. The object must
+ * be a package and must have at least 2 numeric values as the
+ * two elements
+ */
X
- *slp_typ_b =
- (u8) (obj_desc->package.elements[1])->number.value;
- }
+ if (obj_desc->common.type != ACPI_TYPE_PACKAGE) {
+ /* Must be a package */
X
- acpi_cm_remove_reference (obj_desc);
- }
+ REPORT_ERROR ("Sleep State object is not of type Package");


+ status = AE_ERROR;
+ }

+
+ else if (obj_desc->package.count < 2) {
+ /* Must have at least two elements */
+
+ REPORT_ERROR ("Sleep State package does not have at least two elements");


+ status = AE_ERROR;
+ }

+
+ else if (((obj_desc->package.elements[0])->common.type !=
+ ACPI_TYPE_NUMBER) ||
+ ((obj_desc->package.elements[1])->common.type !=
+ ACPI_TYPE_NUMBER))
+ {
+ /* Must have two */
+
+ REPORT_ERROR ("Sleep State package elements are not both of type Number");
+ status = AE_ERROR;
X }
X
+ else {
+ /*
+ * Valid _Sx_ package size, type, and value
+ */
+ *slp_typ_a = (u8) (obj_desc->package.elements[0])->number.value;
+
+ *slp_typ_b = (u8) (obj_desc->package.elements[1])->number.value;
+ }
+
+
+
+ acpi_cm_remove_reference (obj_desc);
+


X return (status);
X }
X

X
-/******************************************************************************
+/*******************************************************************************
X *

X * FUNCTION: Acpi_hw_register_access
X *
@@ -229,7 +248,7 @@
X va_list marker;
X
X va_start (marker, register_id);
- value = va_arg (marker, s32);
+ value = va_arg (marker, u32);
X va_end (marker);


X }
X
@@ -407,7 +426,7 @@

X register_value = (u32) acpi_os_in16 (acpi_gbl_FACP->pm1a_cnt_blk);
X }
X
- if (acpi_gbl_FACP->pm1b_cnt_blk && register_id != (s32) SLP_TYPE_A) {
+ if (acpi_gbl_FACP->pm1b_cnt_blk && register_id != (u32) SLP_TYPE_A) {
X register_value |= (u32) acpi_os_in16 (acpi_gbl_FACP->pm1b_cnt_blk);
X }
X
@@ -469,7 +488,7 @@
X }
X }
X
- if (acpi_gbl_FACP->pm1b_cnt_blk && register_id != (s32) SLP_TYPE_A) {
+ if (acpi_gbl_FACP->pm1b_cnt_blk && register_id != (u32) SLP_TYPE_A) {
X acpi_os_out16 (acpi_gbl_FACP->pm1b_cnt_blk, (u16) register_value);
X }
X }
@@ -551,13 +570,17 @@
X mask = (((u32) register_id) & BIT_IN_REGISTER_MASK);
X mask = 1 << (mask-1);
X
- /* The base address of the GPE 0 Register Block */
- /* Plus 1/2 the length of the GPE 0 Register Block */
- /* The enable register is the register following the Status Register */
- /* and each register is defined as 1/2 of the total Register Block */
-
- /* This sets the bit within Enable_bit that needs to be written to */
- /* the register indicated in Mask to a 1, all others are 0 */
+ /*
+ * The base address of the GPE 0 Register Block
+ * Plus 1/2 the length of the GPE 0 Register Block
+ * The enable register is the register following the Status Register
+ * and each register is defined as 1/2 of the total Register Block
+ */
+
+ /*
+ * This sets the bit within Enable_bit that needs to be written to
+ * the register indicated in Mask to a 1, all others are 0
+ */
X
X if (mask > LOW_BYTE) {
X /* Shift the value 1 byte to the right and add 1 to the register */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/hardware/hwxface.c linux/drivers/acpi/hardware/hwxface.c
--- v2.4.0-test8/linux/drivers/acpi/hardware/hwxface.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/hardware/hwxface.c Fri Sep 15 14:30:30 2000
@@ -2,6 +2,7 @@
X /******************************************************************************
X *
X * Name: hwxface.c - Hardware access external interfaces


+ * $Revision: 31 $
X *
X *****************************************************************************/
X

@@ -24,11 +25,11 @@


X */
X
X #include "acpi.h"
-#include "namesp.h"
-#include "hardware.h"

+#include "acnamesp.h"
+#include "achware.h"
X
X #define _COMPONENT HARDWARE
- MODULE_NAME ("hwxface");
+ MODULE_NAME ("hwxface")
X
X
X /******************************************************************************
@@ -68,10 +69,9 @@
X NATIVE_UINT num_throttle_states;
X NATIVE_UINT buffer_space_needed;
X NATIVE_UINT i;
- u8 duty_offset;
- u8 duty_width;
- ACPI_NAMED_OBJECT *cpu_entry;
- ACPI_OBJECT_INTERNAL *cpu_obj;
+ u8 duty_width = 0;
+ ACPI_NAMESPACE_NODE *cpu_node;
+ ACPI_OPERAND_OBJECT *cpu_obj;
X ACPI_CPU_THROTTLING_STATE *state_ptr;
X
X
@@ -86,8 +86,8 @@
X * Convert and validate the device handle
X */
X
- cpu_entry = acpi_ns_convert_handle_to_entry (processor_handle);
- if (!cpu_entry) {
+ cpu_node = acpi_ns_convert_handle_to_entry (processor_handle);
+ if (!cpu_node) {


X return (AE_BAD_PARAMETER);
X }
X

@@ -95,23 +95,27 @@
X * Check for an existing internal object
X */
X
- cpu_obj = acpi_ns_get_attached_object ((ACPI_HANDLE) cpu_entry);
+ cpu_obj = acpi_ns_get_attached_object ((ACPI_HANDLE) cpu_node);
X if (!cpu_obj) {
X return (AE_NOT_FOUND);
X }
X
- duty_offset = acpi_gbl_FACP->duty_offset;
+#ifndef _IA64
+ /*
+ * No Duty fields in IA64 tables
+ */
X duty_width = acpi_gbl_FACP->duty_width;
+#endif
X
X /*
X * P0 must always have a P_BLK all others may be null
- * in either case, we can't thottle a processor that has no P_BLK
+ * in either case, we can't throttle a processor that has no P_BLK
X *
X * Also if no Duty width, one state and it is 100%
X *
X */
- if (!cpu_obj->processor.pblk_length || !duty_width ||
- (0xFFFF < cpu_obj->processor.pblk_address))
+ if (!cpu_obj->processor.length || !duty_width ||
+ (0xFFFF < cpu_obj->processor.address))
X {
X /*
X * Acpi_even though we can't throttle, we still have one state (100%)
@@ -169,30 +173,35 @@
X ACPI_HANDLE processor_handle,
X u32 *throttle_state)
X {
- ACPI_NAMED_OBJECT *cpu_entry;
- ACPI_OBJECT_INTERNAL *cpu_obj;
+ ACPI_NAMESPACE_NODE *cpu_node;
+ ACPI_OPERAND_OBJECT *cpu_obj;
X u32 num_throttle_states;
X u32 duty_cycle;
- u8 duty_offset;
- u8 duty_width;
+ u8 duty_offset = 0;
+ u8 duty_width = 0;
X
X

X /* Convert and validate the device handle */
X

- cpu_entry = acpi_ns_convert_handle_to_entry (processor_handle);
- if (!cpu_entry || !throttle_state) {
+ cpu_node = acpi_ns_convert_handle_to_entry (processor_handle);
+ if (!cpu_node || !throttle_state) {


X return (AE_BAD_PARAMETER);
X }
X

X /* Check for an existing internal object */
X

- cpu_obj = acpi_ns_get_attached_object ((ACPI_HANDLE) cpu_entry);
+ cpu_obj = acpi_ns_get_attached_object ((ACPI_HANDLE) cpu_node);
X if (!cpu_obj) {
X return (AE_NOT_FOUND);
X }
X
+#ifndef _IA64
+ /*
+ * No Duty fields in IA64 tables
+ */
X duty_offset = acpi_gbl_FACP->duty_offset;
X duty_width = acpi_gbl_FACP->duty_width;
+#endif
X
X /*
X * Must have a valid P_BLK P0 must have a P_BLK all others may be null
@@ -201,8 +210,8 @@
X *
X * also, if Duty_width is zero there are no additional states
X */
- if (!cpu_obj->processor.pblk_length || !duty_width ||
- (0xFFFF < cpu_obj->processor.pblk_address))
+ if (!cpu_obj->processor.length || !duty_width ||
+ (0xFFFF < cpu_obj->processor.address))
X {
X *throttle_state = 0;
X return(AE_OK);
@@ -214,7 +223,7 @@
X * Get the current duty cycle value.
X */
X duty_cycle = acpi_hw_get_duty_cycle (duty_offset,
- cpu_obj->processor.pblk_address,
+ cpu_obj->processor.address,
X num_throttle_states);
X
X /*
@@ -251,8 +260,8 @@
X ACPI_HANDLE processor_handle,
X u32 throttle_state)
X {
- ACPI_NAMED_OBJECT *cpu_entry;
- ACPI_OBJECT_INTERNAL *cpu_obj;
+ ACPI_NAMESPACE_NODE *cpu_node;
+ ACPI_OPERAND_OBJECT *cpu_obj;
X u32 num_throttle_states = 0;
X u8 duty_offset = 0;
X u8 duty_width = 0;


@@ -261,20 +270,25 @@
X

X /* Convert and validate the device handle */
X

- cpu_entry = acpi_ns_convert_handle_to_entry (processor_handle);
- if (!cpu_entry) {
+ cpu_node = acpi_ns_convert_handle_to_entry (processor_handle);
+ if (!cpu_node) {


X return (AE_BAD_PARAMETER);
X }
X

X /* Check for an existing internal object */
X

- cpu_obj = acpi_ns_get_attached_object ((ACPI_HANDLE) cpu_entry);
+ cpu_obj = acpi_ns_get_attached_object ((ACPI_HANDLE) cpu_node);
X if (!cpu_obj) {
X return (AE_NOT_FOUND);
X }
X
+#ifndef _IA64
+ /*
+ * No Duty fields in IA64 tables
+ */
X duty_offset = acpi_gbl_FACP->duty_offset;
X duty_width = acpi_gbl_FACP->duty_width;
+#endif
X
X /*
X * Must have a valid P_BLK P0 must have a P_BLK all others may be null
@@ -283,8 +297,8 @@
X *
X * also, if Duty_width is zero there are no additional states
X */
- if (!cpu_obj->processor.pblk_length || !duty_width ||
- (0xFFFF < cpu_obj->processor.pblk_address))
+ if (!cpu_obj->processor.length || !duty_width ||
+ (0xFFFF < cpu_obj->processor.address))
X {
X /*
X * If caller wants to set the state to the only state we handle
@@ -312,19 +326,19 @@
X /*
X * Turn off throttling (don't muck with the h/w while throttling).
X */
- acpi_hw_disable_throttling (cpu_obj->processor.pblk_address);
+ acpi_hw_disable_throttling (cpu_obj->processor.address);
X
X /*
X * Program the throttling state.
X */
X acpi_hw_program_duty_cycle (duty_offset, duty_cycle,
- cpu_obj->processor.pblk_address, num_throttle_states);
+ cpu_obj->processor.address, num_throttle_states);
X
X /*
X * Only enable throttling for non-zero states (0 - 100%)
X */
X if (throttle_state) {
- acpi_hw_enable_throttling (cpu_obj->processor.pblk_address);
+ acpi_hw_enable_throttling (cpu_obj->processor.address);
X }
X
X return(AE_OK);
@@ -438,9 +452,9 @@
X ACPI_HANDLE processor_handle,
X u32 *pm_timer_ticks)
X {
- ACPI_NAMED_OBJECT *cpu_entry = NULL;
- ACPI_OBJECT_INTERNAL *cpu_obj = NULL;
- ACPI_IO_ADDRESS pblk_address = 0;
+ ACPI_NAMESPACE_NODE *cpu_node = NULL;
+ ACPI_OPERAND_OBJECT *cpu_obj = NULL;
+ ACPI_IO_ADDRESS address = 0;
X
X
X /*
@@ -449,31 +463,31 @@


X
X /* Convert and validate the device handle */
X

- cpu_entry = acpi_ns_convert_handle_to_entry (processor_handle);
- if (!cpu_entry) {
- return AE_BAD_PARAMETER;
+ cpu_node = acpi_ns_convert_handle_to_entry (processor_handle);
+ if (!cpu_node) {
+ return (AE_BAD_PARAMETER);


X }
X
X /* Check for an existing internal object */
X

- cpu_obj = acpi_ns_get_attached_object ((ACPI_HANDLE) cpu_entry);
+ cpu_obj = acpi_ns_get_attached_object ((ACPI_HANDLE) cpu_node);
X if (!cpu_obj) {
- return AE_NOT_FOUND;
+ return (AE_NOT_FOUND);
X }
X
X /* Get the processor register block (P_BLK) address */
X
- pblk_address = cpu_obj->processor.pblk_address;
- if (!cpu_obj->processor.pblk_length) {
+ address = cpu_obj->processor.address;
+ if (!cpu_obj->processor.length) {
X /* Ensure a NULL addresss (note that P_BLK isn't required for C1) */
X
- pblk_address = 0;
+ address = 0;
X }
X
X /*
X * Enter the currently active Cx sleep state.
X */
- return acpi_hw_enter_cx (pblk_address, pm_timer_ticks);
+ return (acpi_hw_enter_cx (address, pm_timer_ticks));
X }
X
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/accommon.h linux/drivers/acpi/include/accommon.h
--- v2.4.0-test8/linux/drivers/acpi/include/accommon.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/include/accommon.h Fri Sep 15 14:30:30 2000
@@ -0,0 +1,661 @@
+/******************************************************************************
+ *
+ * Name: accommon.h -- prototypes for the common (subsystem-wide) procedures
+ * $Revision: 74 $


+ *
+ *****************************************************************************/
+

+/*
+ * Copyright (C) 2000 R. Byron Moore
+ *

+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.

+ *


+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.

+ *


+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

+ */
+
+#ifndef _ACCOMMON_H
+#define _ACCOMMON_H
+
+
+#define REF_INCREMENT (u16) 0
+#define REF_DECREMENT (u16) 1
+#define REF_FORCE_DELETE (u16) 2
+
+/* Acpi_cm_dump_buffer */
+
+#define DB_BYTE_DISPLAY 1
+#define DB_WORD_DISPLAY 2
+#define DB_DWORD_DISPLAY 4
+#define DB_QWORD_DISPLAY 8
+
+
+/* Global initialization interfaces */
+
+void
+acpi_cm_init_globals (
+ ACPI_INIT_DATA *init_data);
+
+void
+acpi_cm_terminate (
+ void);
+
+
+/*
+ * Acpi_cm_init - miscellaneous initialization and shutdown
+ */
+
+ACPI_STATUS
+acpi_cm_hardware_initialize (
+ void);
+
+ACPI_STATUS
+acpi_cm_subsystem_shutdown (
+ void);
+
+/*
+ * Acpi_cm_global - Global data structures and procedures
+ */
+
+NATIVE_CHAR *
+acpi_cm_get_mutex_name (
+ u32 mutex_id);
+
+NATIVE_CHAR *
+acpi_cm_get_type_name (
+ u32 type);
+
+u8
+acpi_cm_valid_object_type (
+ u32 type);
+
+ACPI_OWNER_ID
+acpi_cm_allocate_owner_id (
+ u32 id_type);
+
+
+/*
+ * Acpi_cm_clib - Local implementations of C library functions
+ */


+
+NATIVE_UINT
+acpi_cm_strlen (
+ const NATIVE_CHAR *string);
+

+NATIVE_CHAR *
+acpi_cm_strcpy (
+ NATIVE_CHAR *dst_string,
+ const NATIVE_CHAR *src_string);
+

+NATIVE_CHAR *
+acpi_cm_strncpy (
+ NATIVE_CHAR *dst_string,
+ const NATIVE_CHAR *src_string,
+ NATIVE_UINT count);
+

+u32
+acpi_cm_strncmp (
+ const NATIVE_CHAR *string1,
+ const NATIVE_CHAR *string2,
+ NATIVE_UINT count);
+

+u32
+acpi_cm_strcmp (
+ const NATIVE_CHAR *string1,
+ const NATIVE_CHAR *string2);
+

+NATIVE_CHAR *
+acpi_cm_strcat (
+ NATIVE_CHAR *dst_string,
+ const NATIVE_CHAR *src_string);
+

+NATIVE_CHAR *
+acpi_cm_strncat (
+ NATIVE_CHAR *dst_string,
+ const NATIVE_CHAR *src_string,
+ NATIVE_UINT count);
+

+u32
+acpi_cm_strtoul (
+ const NATIVE_CHAR *string,
+ NATIVE_CHAR **terminator,
+ u32 base);
+

+NATIVE_CHAR *
+acpi_cm_strstr (
+ NATIVE_CHAR *string1,
+ NATIVE_CHAR *string2);
+

+NATIVE_CHAR *
+acpi_cm_strupr (
+ NATIVE_CHAR *src_string);
+

+void *
+acpi_cm_memcpy (
+ void *dest,
+ const void *src,
+ NATIVE_UINT count);
+

+void *
+acpi_cm_memset (
+ void *dest,
+ u32 value,
+ NATIVE_UINT count);
+

+u32
+acpi_cm_to_upper (
+ u32 c);
+

+u32
+acpi_cm_to_lower (
+ u32 c);
+
+

+/*
+ * Acpi_cm_copy - Object construction and conversion interfaces
+ */
+
+ACPI_STATUS
+acpi_cm_build_simple_object(
+ ACPI_OPERAND_OBJECT *obj,
+ ACPI_OBJECT *user_obj,
+ u8 *data_space,
+ u32 *buffer_space_used);
+
+ACPI_STATUS
+acpi_cm_build_package_object (
+ ACPI_OPERAND_OBJECT *obj,
+ u8 *buffer,
+ u32 *space_used);
+
+ACPI_STATUS
+acpi_cm_build_external_object (
+ ACPI_OPERAND_OBJECT *obj,
+ ACPI_BUFFER *ret_buffer);
+
+ACPI_STATUS
+acpi_cm_build_internal_simple_object(
+ ACPI_OBJECT *user_obj,
+ ACPI_OPERAND_OBJECT *obj);
+
+ACPI_STATUS
+acpi_cm_build_internal_object (
+ ACPI_OBJECT *obj,
+ ACPI_OPERAND_OBJECT *internal_obj);
+
+ACPI_STATUS
+acpi_cm_copy_internal_simple_object (
+ ACPI_OPERAND_OBJECT *source_obj,
+ ACPI_OPERAND_OBJECT *dest_obj);
+
+ACPI_STATUS
+acpi_cm_build_copy_internal_package_object (
+ ACPI_OPERAND_OBJECT *source_obj,
+ ACPI_OPERAND_OBJECT *dest_obj);
+
+
+/*
+ * Acpi_cm_create - Object creation
+ */
+
+ACPI_STATUS
+acpi_cm_update_object_reference (
+ ACPI_OPERAND_OBJECT *object,
+ u16 action);
+
+ACPI_OPERAND_OBJECT *
+_cm_create_internal_object (


+ NATIVE_CHAR *module_name,
+ u32 line_number,
+ u32 component_id,

+ OBJECT_TYPE_INTERNAL type);
+
+
+/*
+ * Acpi_cm_debug - Debug interfaces
+ */
+
+u32
+get_debug_level (
+ void);
+
+void
+set_debug_level (
+ u32 level);
+
+void
+function_trace (


+ NATIVE_CHAR *module_name,
+ u32 line_number,
+ u32 component_id,

+ NATIVE_CHAR *function_name);
+
+void
+function_trace_ptr (


+ NATIVE_CHAR *module_name,
+ u32 line_number,
+ u32 component_id,

+ NATIVE_CHAR *function_name,
+ void *pointer);
+
+void
+function_trace_u32 (


+ NATIVE_CHAR *module_name,
+ u32 line_number,
+ u32 component_id,

+ NATIVE_CHAR *function_name,
+ u32 integer);
+
+void
+function_trace_str (


+ NATIVE_CHAR *module_name,
+ u32 line_number,
+ u32 component_id,

+ NATIVE_CHAR *function_name,
+ NATIVE_CHAR *string);
+
+void
+function_exit (


+ NATIVE_CHAR *module_name,
+ u32 line_number,
+ u32 component_id,

+ NATIVE_CHAR *function_name);
+
+void
+function_status_exit (


+ NATIVE_CHAR *module_name,
+ u32 line_number,
+ u32 component_id,

+ NATIVE_CHAR *function_name,
+ ACPI_STATUS status);
+
+void
+function_value_exit (


+ NATIVE_CHAR *module_name,
+ u32 line_number,
+ u32 component_id,

+ NATIVE_CHAR *function_name,
+ NATIVE_UINT value);
+
+void
+function_ptr_exit (


+ NATIVE_CHAR *module_name,
+ u32 line_number,
+ u32 component_id,

+ NATIVE_CHAR *function_name,
+ u8 *ptr);
+
+void
+debug_print_prefix (
+ NATIVE_CHAR *module_name,
+ u32 line_number);
+
+void
+debug_print (


+ NATIVE_CHAR *module_name,
+ u32 line_number,
+ u32 component_id,

+ u32 print_level,
+ NATIVE_CHAR *format, ...);
+
+void
+debug_print_raw (
+ NATIVE_CHAR *format, ...);
+
+void
+_report_info (


+ NATIVE_CHAR *module_name,
+ u32 line_number,
+ u32 component_id,

+ NATIVE_CHAR *message);
+
+void
+_report_error (


+ NATIVE_CHAR *module_name,
+ u32 line_number,
+ u32 component_id,

+ NATIVE_CHAR *message);
+
+void
+_report_warning (


+ NATIVE_CHAR *module_name,
+ u32 line_number,
+ u32 component_id,

+ NATIVE_CHAR *message);
+
+void
+acpi_cm_dump_buffer (
+ u8 *buffer,
+ u32 count,
+ u32 display,
+ u32 component_id);
+
+
+/*
+ * Acpi_cm_delete - Object deletion
+ */
+
+void
+acpi_cm_delete_internal_obj (
+ ACPI_OPERAND_OBJECT *object);
+
+void
+acpi_cm_delete_internal_package_object (
+ ACPI_OPERAND_OBJECT *object);
+
+void
+acpi_cm_delete_internal_simple_object (
+ ACPI_OPERAND_OBJECT *object);
+
+ACPI_STATUS
+acpi_cm_delete_internal_object_list (
+ ACPI_OPERAND_OBJECT **obj_list);
+
+
+/*
+ * Acpi_cm_eval - object evaluation
+ */
+
+/* Method name strings */
+
+#define METHOD_NAME__HID "_HID"
+#define METHOD_NAME__UID "_UID"
+#define METHOD_NAME__ADR "_ADR"
+#define METHOD_NAME__STA "_STA"
+#define METHOD_NAME__REG "_REG"
+#define METHOD_NAME__SEG "_SEG"
+#define METHOD_NAME__BBN "_BBN"
+
+
+ACPI_STATUS
+acpi_cm_evaluate_numeric_object (
+ NATIVE_CHAR *method_name,
+ ACPI_NAMESPACE_NODE *device_node,
+ u32 *address);
+
+ACPI_STATUS
+acpi_cm_execute_HID (
+ ACPI_NAMESPACE_NODE *device_node,
+ DEVICE_ID *hid);
+
+ACPI_STATUS
+acpi_cm_execute_STA (
+ ACPI_NAMESPACE_NODE *device_node,
+ u32 *status_flags);
+
+ACPI_STATUS
+acpi_cm_execute_UID (
+ ACPI_NAMESPACE_NODE *device_node,
+ DEVICE_ID *uid);
+
+
+/*
+ * Acpi_cm_error - exception interfaces
+ */
+
+NATIVE_CHAR *
+acpi_cm_format_exception (
+ ACPI_STATUS status);
+
+
+/*
+ * Acpi_cm_mutex - mutual exclusion interfaces
+ */
+
+ACPI_STATUS
+acpi_cm_mutex_initialize (
+ void);
+
+void
+acpi_cm_mutex_terminate (
+ void);
+
+ACPI_STATUS
+acpi_cm_create_mutex (
+ ACPI_MUTEX_HANDLE mutex_id);
+
+ACPI_STATUS
+acpi_cm_delete_mutex (
+ ACPI_MUTEX_HANDLE mutex_id);
+
+ACPI_STATUS
+acpi_cm_acquire_mutex (
+ ACPI_MUTEX_HANDLE mutex_id);
+
+ACPI_STATUS
+acpi_cm_release_mutex (
+ ACPI_MUTEX_HANDLE mutex_id);
+
+
+/*
+ * Acpi_cm_object - internal object create/delete/cache routines
+ */
+
+void *
+_cm_allocate_object_desc (


+ NATIVE_CHAR *module_name,
+ u32 line_number,

+ u32 component_id);
+
+#define acpi_cm_create_internal_object(t) _cm_create_internal_object(_THIS_MODULE,__LINE__,_COMPONENT,t)
+#define acpi_cm_allocate_object_desc() _cm_allocate_object_desc(_THIS_MODULE,__LINE__,_COMPONENT)
+
+void
+acpi_cm_delete_object_desc (
+ ACPI_OPERAND_OBJECT *object);
+
+u8
+acpi_cm_valid_internal_object (
+ void *object);
+
+
+/*
+ * Acpi_cm_ref_cnt - Object reference count management
+ */
+
+void
+acpi_cm_add_reference (
+ ACPI_OPERAND_OBJECT *object);
+
+void
+acpi_cm_remove_reference (
+ ACPI_OPERAND_OBJECT *object);
+
+/*
+ * Acpi_cm_size - Object size routines
+ */
+
+ACPI_STATUS
+acpi_cm_get_simple_object_size (
+ ACPI_OPERAND_OBJECT *obj,
+ u32 *obj_length);
+
+ACPI_STATUS
+acpi_cm_get_package_object_size (
+ ACPI_OPERAND_OBJECT *obj,
+ u32 *obj_length);
+
+ACPI_STATUS
+acpi_cm_get_object_size(
+ ACPI_OPERAND_OBJECT *obj,
+ u32 *obj_length);
+
+
+/*
+ * Acpi_cm_state - Generic state creation/cache routines
+ */
+
+void
+acpi_cm_push_generic_state (
+ ACPI_GENERIC_STATE **list_head,
+ ACPI_GENERIC_STATE *state);
+
+ACPI_GENERIC_STATE *
+acpi_cm_pop_generic_state (
+ ACPI_GENERIC_STATE **list_head);
+
+
+ACPI_GENERIC_STATE *
+acpi_cm_create_generic_state (
+ void);
+
+ACPI_GENERIC_STATE *
+acpi_cm_create_update_state (
+ ACPI_OPERAND_OBJECT *object,
+ u16 action);
+
+ACPI_STATUS
+acpi_cm_create_update_state_and_push (
+ ACPI_OPERAND_OBJECT *object,
+ u16 action,
+ ACPI_GENERIC_STATE **state_list);
+
+ACPI_GENERIC_STATE *
+acpi_cm_create_control_state (
+ void);
+
+void
+acpi_cm_delete_generic_state (
+ ACPI_GENERIC_STATE *state);
+
+void
+acpi_cm_delete_generic_state_cache (
+ void);
+
+void
+acpi_cm_delete_object_cache (
+ void);
+
+/*
+ * Acpi_cmutils
+ */
+
+u8
+acpi_cm_valid_acpi_name (
+ u32 name);
+
+u8
+acpi_cm_valid_acpi_character (
+ NATIVE_CHAR character);
+
+
+/*
+ * Memory allocation functions and related macros.
+ * Macros that expand to include filename and line number
+ */
+
+void *
+_cm_allocate (
+ u32 size,
+ u32 component,
+ NATIVE_CHAR *module,
+ u32 line);
+
+void *
+_cm_callocate (
+ u32 size,
+ u32 component,
+ NATIVE_CHAR *module,
+ u32 line);
+
+void
+_cm_free (
+ void *address,
+ u32 component,
+ NATIVE_CHAR *module,
+ u32 line);
+
+void
+acpi_cm_init_static_object (
+ ACPI_OPERAND_OBJECT *obj_desc);
+
+#define acpi_cm_allocate(a) _cm_allocate(a,_COMPONENT,_THIS_MODULE,__LINE__)
+#define acpi_cm_callocate(a) _cm_callocate(a, _COMPONENT,_THIS_MODULE,__LINE__)
+#define acpi_cm_free(a) _cm_free(a,_COMPONENT,_THIS_MODULE,__LINE__)
+
+#ifndef ACPI_DEBUG
+
+#define acpi_cm_add_element_to_alloc_list(a,b,c,d,e,f)
+#define acpi_cm_delete_element_from_alloc_list(a,b,c,d)
+#define acpi_cm_dump_current_allocations(a,b)
+#define acpi_cm_dump_allocation_info()
+
+#define DECREMENT_OBJECT_METRICS(a)
+#define INCREMENT_OBJECT_METRICS(a)
+#define INITIALIZE_ALLOCATION_METRICS()
+#define DECREMENT_NAME_TABLE_METRICS(a)
+#define INCREMENT_NAME_TABLE_METRICS(a)
+
+#else
+
+#define INITIALIZE_ALLOCATION_METRICS() \
+ acpi_gbl_current_object_count = 0; \
+ acpi_gbl_current_object_size = 0; \
+ acpi_gbl_running_object_count = 0; \
+ acpi_gbl_running_object_size = 0; \
+ acpi_gbl_max_concurrent_object_count = 0; \
+ acpi_gbl_max_concurrent_object_size = 0; \
+ acpi_gbl_current_alloc_size = 0; \
+ acpi_gbl_current_alloc_count = 0; \
+ acpi_gbl_running_alloc_size = 0; \
+ acpi_gbl_running_alloc_count = 0; \
+ acpi_gbl_max_concurrent_alloc_size = 0; \
+ acpi_gbl_max_concurrent_alloc_count = 0; \
+ acpi_gbl_current_node_count = 0; \
+ acpi_gbl_current_node_size = 0; \
+ acpi_gbl_max_concurrent_node_count = 0
+
+
+#define DECREMENT_OBJECT_METRICS(a) \
+ acpi_gbl_current_object_count--; \
+ acpi_gbl_current_object_size -= a
+
+#define INCREMENT_OBJECT_METRICS(a) \
+ acpi_gbl_current_object_count++; \
+ acpi_gbl_running_object_count++; \
+ if (acpi_gbl_max_concurrent_object_count < acpi_gbl_current_object_count) \
+ { \
+ acpi_gbl_max_concurrent_object_count = acpi_gbl_current_object_count; \
+ } \
+ acpi_gbl_running_object_size += a; \
+ acpi_gbl_current_object_size += a; \
+ if (acpi_gbl_max_concurrent_object_size < acpi_gbl_current_object_size) \
+ { \
+ acpi_gbl_max_concurrent_object_size = acpi_gbl_current_object_size; \
+ }
+
+#define DECREMENT_NAME_TABLE_METRICS(a) \
+ acpi_gbl_current_node_count--; \
+ acpi_gbl_current_node_size -= (a)
+
+#define INCREMENT_NAME_TABLE_METRICS(a) \
+ acpi_gbl_current_node_count++; \
+ acpi_gbl_current_node_size+= (a); \
+ if (acpi_gbl_max_concurrent_node_count < acpi_gbl_current_node_count) \
+ { \
+ acpi_gbl_max_concurrent_node_count = acpi_gbl_current_node_count; \
+ } \
+
+
+void
+acpi_cm_dump_allocation_info (
+ void);
+
+void
+acpi_cm_dump_current_allocations (
+ u32 component,
+ NATIVE_CHAR *module);
+
+#endif
+
+
+#endif /* _ACCOMMON_H */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/acconfig.h linux/drivers/acpi/include/acconfig.h
--- v2.4.0-test8/linux/drivers/acpi/include/acconfig.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/include/acconfig.h Fri Sep 15 14:30:30 2000
@@ -0,0 +1,186 @@
+/******************************************************************************
+ *
+ * Name: acconfig.h - Global configuration constants


+ * $Revision: 42 $

+ *
+ *****************************************************************************/
+

+/*
+ * Copyright (C) 2000 R. Byron Moore
+ *

+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.

+ *


+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.

+ *


+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

+ */
+
+#ifndef _ACCONFIG_H
+#define _ACCONFIG_H


+
+
+/******************************************************************************
+ *

+ * Compile-time options


+ *
+ *****************************************************************************/
+

+/*
+ * ACPI_DEBUG - This switch enables all the debug facilities of the ACPI
+ * subsystem. This includes the DEBUG_PRINT output statements
+ * When disabled, all DEBUG_PRINT statements are compiled out.
+ *
+ * ACPI_APPLICATION - Use this switch if the subsystem is going to be run
+ * at the application level.
+ *
+ */


+
+
+/******************************************************************************
+ *

+ * Subsystem Constants


+ *
+ *****************************************************************************/
+
+

+/* Version string */
+
+#define ACPI_CA_VERSION __DATE__
+
+/* Name of host operating system (returned by the _OS_ namespace object) */
+
+#ifdef _LINUX
+#define ACPI_OS_NAME "Linux"
+#else
+#define ACPI_OS_NAME "Intel ACPI/CA Core Subsystem"
+#endif
+
+
+/*
+ * How and when control methods will be parsed
+ * The default action is to parse all methods at table load time to verify them, but delete the parse trees
+ * to conserve memory. Methods are parsed just in time before execution and the parse tree is deleted
+ * when execution completes.
+ */
+#define METHOD_PARSE_AT_INIT 0x0 /* Parse at table init, never delete the method parse tree */
+#define METHOD_PARSE_JUST_IN_TIME 0x1 /* Parse only when a method is invoked */
+#define METHOD_DELETE_AT_COMPLETION 0x2 /* Delete parse tree on method completion */
+
+/* Default parsing configuration */
+
+#define METHOD_PARSE_CONFIGURATION (METHOD_PARSE_JUST_IN_TIME | METHOD_DELETE_AT_COMPLETION)
+
+
+/* Maximum objects in the various object caches */
+
+#define MAX_STATE_CACHE_DEPTH 64 /* State objects for stacks */
+#define MAX_PARSE_CACHE_DEPTH 96 /* Parse tree objects */
+#define MAX_EXTPARSE_CACHE_DEPTH 64 /* Parse tree objects */
+#define MAX_OBJECT_CACHE_DEPTH 64 /* Interpreter operand objects */
+#define MAX_WALK_CACHE_DEPTH 2 /* Objects for parse tree walks (method execution) */
+
+/*
+ * Name_space Table size
+ *
+ * All tables are the same size to simplify the implementation.
+ * Tables may be extended by allocating additional tables that
+ * are in turn linked together to form a chain of tables.
+ */
+
+#define NS_TABLE_SIZE 4
+
+/* String size constants */
+
+#define MAX_STRING_LENGTH 512
+#define PATHNAME_MAX 256 /* A full namespace pathname */
+
+
+/* Maximum count for a semaphore object */
+
+#define MAX_SEMAPHORE_COUNT 256
+
+
+/* Max reference count (for debug only) */
+
+#define MAX_REFERENCE_COUNT 0x200
+
+
+/* Size of cached memory mapping for system memory operation region */
+
+#define SYSMEM_REGION_WINDOW_SIZE 4096
+
+
+/*
+ * Debugger threading model
+ * Use single threaded if the entire subsystem is contained in an application
+ * Use multiple threaded when the the subsystem is running in the kernel.
+ *
+ * By default the model is single threaded if ACPI_APPLICATION is set,
+ * multi-threaded if ACPI_APPLICATION is not set.
+ */
+
+#define DEBUGGER_SINGLE_THREADED 0
+#define DEBUGGER_MULTI_THREADED 1
+
+#ifdef ACPI_APPLICATION
+#define DEBUGGER_THREADING DEBUGGER_SINGLE_THREADED
+
+#else
+#define DEBUGGER_THREADING DEBUGGER_MULTI_THREADED
+#endif


+
+
+/******************************************************************************
+ *

+ * ACPI Specification constants (Do not change unless the specification changes)


+ *
+ *****************************************************************************/
+

+/*
+ * Method info (in WALK_STATE), containing local variables and argumetns
+ */
+
+#define MTH_NUM_LOCALS 8
+#define MTH_MAX_LOCAL 7
+
+#define MTH_NUM_ARGS 7
+#define MTH_MAX_ARG 6
+
+/*
+ * Operand Stack (in WALK_STATE), Must be large enough to contain MTH_MAX_ARG
+ */
+
+#define OBJ_NUM_OPERANDS 8
+#define OBJ_MAX_OPERAND 7
+
+/* Names within the namespace are 4 bytes long */
+
+#define ACPI_NAME_SIZE 4
+#define PATH_SEGMENT_LENGTH 5 /* 4 chars for name + 1 s8 for separator */
+#define PATH_SEPARATOR '.'
+
+
+/* Constants used in searching for the RSDP in low memory */
+
+#define LO_RSDP_WINDOW_BASE (void *) 0
+#define HI_RSDP_WINDOW_BASE (void *) 0xE0000
+#define LO_RSDP_WINDOW_SIZE 0x400
+#define HI_RSDP_WINDOW_SIZE 0x20000
+#define RSDP_SCAN_STEP 16
+
+
+/* Maximum nesting of package objects */
+
+#define MAX_PACKAGE_DEPTH 16
+
+
+#endif /* _ACCONFIG_H */
+
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/acdebug.h linux/drivers/acpi/include/acdebug.h
--- v2.4.0-test8/linux/drivers/acpi/include/acdebug.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/include/acdebug.h Fri Sep 15 14:30:30 2000
@@ -0,0 +1,396 @@
+/******************************************************************************
+ *
+ * Name: acdebug.h - ACPI/AML debugger
+ * $Revision: 35 $


+ *
+ *****************************************************************************/
+

+/*
+ * Copyright (C) 2000 R. Byron Moore
+ *

+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.

+ *


+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.

+ *


+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

+ */
+
+#ifndef __ACDEBUG_H__
+#define __ACDEBUG_H__
+
+
+#define DB_MAX_ARGS 8 /* Must be max method args + 1 */
+
+#define DB_COMMAND_PROMPT '-'
+#define DB_EXECUTE_PROMPT '%'
+
+
+extern int optind;
+extern NATIVE_CHAR *optarg;
+extern u8 *aml_ptr;
+extern u32 acpi_aml_length;
+
+extern u8 opt_tables;
+extern u8 opt_disasm;
+extern u8 opt_stats;
+extern u8 opt_parse_jit;
+extern u8 opt_verbose;
+
+
+extern NATIVE_CHAR *args[DB_MAX_ARGS];
+extern NATIVE_CHAR line_buf[80];
+extern NATIVE_CHAR scope_buf[40];
+extern NATIVE_CHAR debug_filename[40];
+extern u8 output_to_file;
+extern NATIVE_CHAR *buffer;
+extern NATIVE_CHAR *filename;
+extern NATIVE_CHAR *INDENT_STRING;
+extern u8 acpi_gbl_db_output_flags;
+extern u32 acpi_gbl_db_debug_level;
+extern u32 acpi_gbl_db_console_debug_level;
+
+extern u32 num_names;
+extern u32 num_methods;
+extern u32 num_regions;
+extern u32 num_packages;
+extern u32 num_aliases;
+extern u32 num_devices;
+extern u32 num_field_defs;
+extern u32 num_thermal_zones;
+extern u32 num_nodes;
+extern u32 num_grammar_elements;
+extern u32 num_method_elements ;
+extern u32 num_mutexes;
+extern u32 num_power_resources;
+extern u32 num_bank_fields ;
+extern u32 num_index_fields;
+extern u32 num_events;
+
+extern u32 size_of_parse_tree;
+extern u32 size_of_method_trees;
+extern u32 size_of_nTes;
+extern u32 size_of_acpi_objects;
+
+
+#define BUFFER_SIZE 4196
+
+#define DB_REDIRECTABLE_OUTPUT 0x01
+#define DB_CONSOLE_OUTPUT 0x02
+#define DB_DUPLICATE_OUTPUT 0x03
+
+
+typedef struct command_info
+{
+ NATIVE_CHAR *name; /* Command Name */
+ u8 min_args; /* Minimum arguments required */
+
+} COMMAND_INFO;
+
+
+typedef struct argument_info
+{
+ NATIVE_CHAR *name; /* Argument Name */
+
+} ARGUMENT_INFO;
+
+
+#define PARAM_LIST(pl) pl
+
+#define DBTEST_OUTPUT_LEVEL(lvl) if (opt_verbose)
+
+#define VERBOSE_PRINT(fp) DBTEST_OUTPUT_LEVEL(lvl) {\
+ acpi_os_printf PARAM_LIST(fp);}
+
+#define EX_NO_SINGLE_STEP 1
+#define EX_SINGLE_STEP 2
+
+
+/* Prototypes */
+
+
+/*
+ * dbapi - external debugger interfaces
+ */
+
+int
+acpi_db_initialize (
+ void);
+
+ACPI_STATUS
+acpi_db_single_step (
+ ACPI_WALK_STATE *walk_state,
+ ACPI_PARSE_OBJECT *op,
+ u8 op_type);
+
+
+/*
+ * dbcmds - debug commands and output routines
+ */
+
+
+void
+acpi_db_display_table_info (
+ NATIVE_CHAR *table_arg);
+
+void
+acpi_db_unload_acpi_table (
+ NATIVE_CHAR *table_arg,
+ NATIVE_CHAR *instance_arg);
+
+void
+acpi_db_set_method_breakpoint (
+ NATIVE_CHAR *location,
+ ACPI_WALK_STATE *walk_state,
+ ACPI_PARSE_OBJECT *op);
+
+void
+acpi_db_set_method_call_breakpoint (
+ ACPI_PARSE_OBJECT *op);
+
+void
+acpi_db_disassemble_aml (
+ NATIVE_CHAR *statements,
+ ACPI_PARSE_OBJECT *op);
+
+void
+acpi_db_dump_namespace (
+ NATIVE_CHAR *start_arg,
+ NATIVE_CHAR *depth_arg);
+
+void
+acpi_db_dump_namespace_by_owner (
+ NATIVE_CHAR *owner_arg,
+ NATIVE_CHAR *depth_arg);
+
+void
+acpi_db_send_notify (
+ NATIVE_CHAR *name,
+ u32 value);
+
+void
+acpi_db_set_method_data (
+ NATIVE_CHAR *type_arg,
+ NATIVE_CHAR *index_arg,
+ NATIVE_CHAR *value_arg);
+
+ACPI_STATUS
+acpi_db_display_objects (
+ NATIVE_CHAR *obj_type_arg,
+ NATIVE_CHAR *display_count_arg);
+
+ACPI_STATUS
+acpi_db_find_name_in_namespace (
+ NATIVE_CHAR *name_arg);
+
+void
+acpi_db_set_scope (
+ NATIVE_CHAR *name);
+
+void
+acpi_db_find_references (
+ NATIVE_CHAR *object_arg);
+
+
+/*
+ * dbdisasm - AML disassembler
+ */
+
+void
+acpi_db_display_op (
+ ACPI_PARSE_OBJECT *origin,
+ u32 num_opcodes);
+
+void
+acpi_db_display_namestring (
+ NATIVE_CHAR *name);
+
+void
+acpi_db_display_path (
+ ACPI_PARSE_OBJECT *op);
+
+void
+acpi_db_display_opcode (
+ ACPI_PARSE_OBJECT *op);
+
+
+/*
+ * dbdisply - debug display commands
+ */
+
+
+void
+acpi_db_display_method_info (
+ ACPI_PARSE_OBJECT *op);
+
+void
+acpi_db_decode_and_display_object (
+ NATIVE_CHAR *target,
+ NATIVE_CHAR *output_type);
+
+void
+acpi_db_display_result_object (
+ ACPI_OPERAND_OBJECT *obj_desc,
+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS
+acpi_db_display_all_methods (
+ NATIVE_CHAR *display_count_arg);
+
+void
+acpi_db_display_internal_object (
+ ACPI_OPERAND_OBJECT *obj_desc,
+ ACPI_WALK_STATE *walk_state);
+
+void
+acpi_db_display_arguments (
+ void);
+
+void
+acpi_db_display_locals (
+ void);
+
+void
+acpi_db_display_results (
+ void);
+
+void
+acpi_db_display_calling_tree (
+ void);
+
+void
+acpi_db_display_argument_object (
+ ACPI_OPERAND_OBJECT *obj_desc,


+ ACPI_WALK_STATE *walk_state);
+
+

+/*
+ * dbexec - debugger control method execution


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 023'
echo 'File patch-2.4.0-test9 is continued in part 024'
echo "024" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part024

#!/bin/sh -x
# this is part 024 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 024; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ */
+
+void
+acpi_db_execute (
+ NATIVE_CHAR *name,
+ NATIVE_CHAR **args,
+ u32 flags);
+
+void
+acpi_db_create_execution_threads (
+ NATIVE_CHAR *num_threads_arg,
+ NATIVE_CHAR *num_loops_arg,
+ NATIVE_CHAR *method_name_arg);
+
+
+/*
+ * dbfileio - Debugger file I/O commands
+ */
+
+OBJECT_TYPE_INTERNAL
+acpi_db_match_argument (
+ NATIVE_CHAR *user_argument,
+ ARGUMENT_INFO *arguments);
+
+
+void
+acpi_db_close_debug_file (
+ void);
+
+void
+acpi_db_open_debug_file (
+ NATIVE_CHAR *name);
+
+ACPI_STATUS
+acpi_db_load_acpi_table (
+ NATIVE_CHAR *filename);
+
+
+/*
+ * dbhistry - debugger HISTORY command
+ */
+
+void
+acpi_db_add_to_history (
+ NATIVE_CHAR *command_line);
+
+void
+acpi_db_display_history (void);
+
+NATIVE_CHAR *
+acpi_db_get_from_history (
+ NATIVE_CHAR *command_num_arg);
+
+
+/*
+ * dbinput - user front-end to the AML debugger
+ */
+
+ACPI_STATUS
+acpi_db_command_dispatch (
+ NATIVE_CHAR *input_buffer,


+ ACPI_WALK_STATE *walk_state,
+ ACPI_PARSE_OBJECT *op);
+
+void

+acpi_db_execute_thread (
+ void *context);
+
+ACPI_STATUS
+acpi_db_user_commands (
+ NATIVE_CHAR prompt,


+ ACPI_PARSE_OBJECT *op);
+
+
+/*

+ * dbstats - Generation and display of ACPI table statistics
+ */
+
+void
+acpi_db_generate_statistics (
+ ACPI_PARSE_OBJECT *root,
+ u8 is_method);
+
+
+ACPI_STATUS
+acpi_db_display_statistics (
+ NATIVE_CHAR *type_arg);
+
+
+/*
+ * dbutils - AML debugger utilities
+ */
+
+void
+acpi_db_set_output_destination (
+ u32 where);
+
+void
+acpi_db_dump_buffer (
+ u32 address);
+
+void
+acpi_db_dump_object (
+ ACPI_OBJECT *obj_desc,


+ u32 level);
+
+void

+acpi_db_prep_namestring (


+ NATIVE_CHAR *name);
+
+

+ACPI_STATUS
+acpi_db_second_pass_parse (
+ ACPI_PARSE_OBJECT *root);
+
+ACPI_NAMESPACE_NODE *
+acpi_db_local_ns_lookup (


+ NATIVE_CHAR *name);
+
+

+#endif /* __ACDEBUG_H__ */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/acdispat.h linux/drivers/acpi/include/acdispat.h
--- v2.4.0-test8/linux/drivers/acpi/include/acdispat.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/include/acdispat.h Fri Sep 15 14:30:30 2000
@@ -0,0 +1,401 @@
+/******************************************************************************
+ *
+ * Name: acdispat.h - dispatcher (parser to interpreter interface)
+ * $Revision: 29 $


+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 R. Byron Moore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+

+#ifndef _ACDISPAT_H_
+#define _ACDISPAT_H_
+
+
+#define NAMEOF_LOCAL_NTE "__L0"
+#define NAMEOF_ARG_NTE "__A0"
+
+
+/* For Acpi_ds_method_data_set_value */
+
+#define MTH_TYPE_LOCAL 0
+#define MTH_TYPE_ARG 1
+
+
+/* Common interfaces */
+
+ACPI_STATUS
+acpi_ds_obj_stack_push (
+ void *object,


+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS

+acpi_ds_obj_stack_pop (
+ u32 pop_count,
+ ACPI_WALK_STATE *walk_state);
+
+void *
+acpi_ds_obj_stack_get_value (
+ u32 index,


+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS

+acpi_ds_obj_stack_pop_object (
+ ACPI_OPERAND_OBJECT **object,


+ ACPI_WALK_STATE *walk_state);
+
+

+/* dsregion - Op region support */
+
+ACPI_STATUS
+acpi_ds_get_region_arguments (
+ ACPI_OPERAND_OBJECT *rgn_desc);
+
+
+/* dsctrl - Parser/Interpreter interface, control stack routines */
+
+
+ACPI_STATUS
+acpi_ds_exec_begin_control_op (
+ ACPI_WALK_STATE *walk_state,
+ ACPI_PARSE_OBJECT *op);
+
+ACPI_STATUS
+acpi_ds_exec_end_control_op (
+ ACPI_WALK_STATE *walk_state,
+ ACPI_PARSE_OBJECT *op);
+
+
+/* dsexec - Parser/Interpreter interface, method execution callbacks */
+
+ACPI_STATUS
+acpi_ds_exec_begin_op (


+ u16 opcode,
+ ACPI_PARSE_OBJECT *op,

+ ACPI_WALK_STATE *walk_state,
+ ACPI_PARSE_OBJECT **out_op);
+
+ACPI_STATUS
+acpi_ds_exec_end_op (
+ ACPI_WALK_STATE *state,


+ ACPI_PARSE_OBJECT *op);
+
+

+/* dsfield - Parser/Interpreter interface for AML fields */
+
+
+ACPI_STATUS
+acpi_ds_create_field (
+ ACPI_PARSE_OBJECT *op,
+ ACPI_NAMESPACE_NODE *region_node,


+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS

+acpi_ds_create_bank_field (
+ ACPI_PARSE_OBJECT *op,
+ ACPI_NAMESPACE_NODE *region_node,


+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS

+acpi_ds_create_index_field (
+ ACPI_PARSE_OBJECT *op,
+ ACPI_HANDLE region_node,


+ ACPI_WALK_STATE *walk_state);
+
+

+/* dsload - Parser/Interpreter interface, namespace load callbacks */
+
+ACPI_STATUS
+acpi_ds_load1_begin_op (


+ u16 opcode,
+ ACPI_PARSE_OBJECT *op,

+ ACPI_WALK_STATE *walk_state,
+ ACPI_PARSE_OBJECT **out_op);
+
+ACPI_STATUS
+acpi_ds_load1_end_op (
+ ACPI_WALK_STATE *walk_state,
+ ACPI_PARSE_OBJECT *op);
+
+ACPI_STATUS
+acpi_ds_load2_begin_op (


+ u16 opcode,
+ ACPI_PARSE_OBJECT *op,

+ ACPI_WALK_STATE *walk_state,
+ ACPI_PARSE_OBJECT **out_op);
+
+ACPI_STATUS
+acpi_ds_load2_end_op (
+ ACPI_WALK_STATE *state,


+ ACPI_PARSE_OBJECT *op);
+
+

+/* dsmthdat - method data (locals/args) */
+
+
+ACPI_STATUS
+acpi_ds_method_data_get_entry (
+ u32 type,
+ u32 index,
+ ACPI_WALK_STATE *walk_state,
+ ACPI_OPERAND_OBJECT ***node);
+
+ACPI_STATUS
+acpi_ds_method_data_delete_all (
+ ACPI_WALK_STATE *walk_state);
+
+u8
+acpi_ds_is_method_value (
+ ACPI_OPERAND_OBJECT *obj_desc);
+
+OBJECT_TYPE_INTERNAL
+acpi_ds_method_data_get_type (
+ u32 type,
+ u32 index,


+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS

+acpi_ds_method_data_get_value (
+ u32 type,
+ u32 index,
+ ACPI_WALK_STATE *walk_state,
+ ACPI_OPERAND_OBJECT **dest_desc);
+
+ACPI_STATUS
+acpi_ds_method_data_set_value (
+ u32 type,
+ u32 index,
+ ACPI_OPERAND_OBJECT *src_desc,


+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS

+acpi_ds_method_data_delete_value (
+ u32 type,
+ u32 index,


+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS

+acpi_ds_method_data_init_args (


+ ACPI_OPERAND_OBJECT **params,
+ u32 max_param_count,

+ ACPI_WALK_STATE *walk_state);
+
+ACPI_NAMESPACE_NODE *
+acpi_ds_method_data_get_nte (
+ u32 type,
+ u32 index,


+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS

+acpi_ds_method_data_init (


+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS

+acpi_ds_method_data_set_entry (
+ u32 type,
+ u32 index,
+ ACPI_OPERAND_OBJECT *object,


+ ACPI_WALK_STATE *walk_state);
+
+

+/* dsmethod - Parser/Interpreter interface - control method parsing */
+
+ACPI_STATUS
+acpi_ds_parse_method (
+ ACPI_HANDLE obj_handle);
+
+ACPI_STATUS
+acpi_ds_call_control_method (
+ ACPI_WALK_LIST *walk_list,


+ ACPI_WALK_STATE *walk_state,
+ ACPI_PARSE_OBJECT *op);
+

+ACPI_STATUS
+acpi_ds_restart_control_method (
+ ACPI_WALK_STATE *walk_state,
+ ACPI_OPERAND_OBJECT *return_desc);
+
+ACPI_STATUS
+acpi_ds_terminate_control_method (


+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS

+acpi_ds_begin_method_execution (
+ ACPI_NAMESPACE_NODE *method_node,
+ ACPI_OPERAND_OBJECT *obj_desc);
+
+
+/* dsobj - Parser/Interpreter interface - object initialization and conversion */
+
+ACPI_STATUS
+acpi_ds_init_one_object (
+ ACPI_HANDLE obj_handle,
+ u32 level,


+ void *context,
+ void **return_value);
+

+ACPI_STATUS
+acpi_ds_initialize_objects (
+ ACPI_TABLE_DESC *table_desc,
+ ACPI_NAMESPACE_NODE *start_node);
+
+ACPI_STATUS
+acpi_ds_build_internal_package_obj (


+ ACPI_WALK_STATE *walk_state,
+ ACPI_PARSE_OBJECT *op,

+ ACPI_OPERAND_OBJECT **obj_desc);
+
+ACPI_STATUS
+acpi_ds_build_internal_object (


+ ACPI_WALK_STATE *walk_state,
+ ACPI_PARSE_OBJECT *op,

+ ACPI_OPERAND_OBJECT **obj_desc_ptr);
+
+ACPI_STATUS
+acpi_ds_init_object_from_op (


+ ACPI_WALK_STATE *walk_state,
+ ACPI_PARSE_OBJECT *op,

+ u16 opcode,
+ ACPI_OPERAND_OBJECT **obj_desc);
+
+ACPI_STATUS
+acpi_ds_create_node (
+ ACPI_WALK_STATE *walk_state,
+ ACPI_NAMESPACE_NODE *node,


+ ACPI_PARSE_OBJECT *op);
+
+

+/* dsregn - Parser/Interpreter interface - Op Region parsing */
+
+ACPI_STATUS
+acpi_ds_eval_region_operands (
+ ACPI_WALK_STATE *walk_state,
+ ACPI_PARSE_OBJECT *op);
+
+ACPI_STATUS
+acpi_ds_initialize_region (
+ ACPI_HANDLE obj_handle);
+
+
+/* dsutils - Parser/Interpreter interface utility routines */
+
+u8
+acpi_ds_is_result_used (


+ ACPI_PARSE_OBJECT *op);
+
+void

+acpi_ds_delete_result_if_not_used (
+ ACPI_PARSE_OBJECT *op,
+ ACPI_OPERAND_OBJECT *result_obj,

+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS

+acpi_ds_create_operand (
+ ACPI_WALK_STATE *walk_state,
+ ACPI_PARSE_OBJECT *arg);
+
+ACPI_STATUS
+acpi_ds_create_operands (
+ ACPI_WALK_STATE *walk_state,
+ ACPI_PARSE_OBJECT *first_arg);
+
+ACPI_STATUS
+acpi_ds_resolve_operands (
+ ACPI_WALK_STATE *walk_state);
+
+OBJECT_TYPE_INTERNAL
+acpi_ds_map_opcode_to_data_type (
+ u16 opcode,
+ u32 *out_flags);
+
+OBJECT_TYPE_INTERNAL
+acpi_ds_map_named_opcode_to_data_type (
+ u16 opcode);
+
+
+/*
+ * dswscope - Scope Stack manipulation
+ */
+
+ACPI_STATUS
+acpi_ds_scope_stack_push (
+ ACPI_NAMESPACE_NODE *node,
+ OBJECT_TYPE_INTERNAL type,


+ ACPI_WALK_STATE *walk_state);
+
+

+ACPI_STATUS
+acpi_ds_scope_stack_pop (


+ ACPI_WALK_STATE *walk_state);
+
+void

+acpi_ds_scope_stack_clear (


+ ACPI_WALK_STATE *walk_state);
+
+

+/* Acpi_dswstate - parser WALK_STATE management routines */
+
+ACPI_WALK_STATE *
+acpi_ds_create_walk_state (
+ ACPI_OWNER_ID owner_id,


+ ACPI_PARSE_OBJECT *origin,
+ ACPI_OPERAND_OBJECT *mth_desc,

+ ACPI_WALK_LIST *walk_list);
+
+ACPI_STATUS
+acpi_ds_obj_stack_delete_all (


+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS

+acpi_ds_obj_stack_pop_and_delete (
+ u32 pop_count,


+ ACPI_WALK_STATE *walk_state);
+
+void

+acpi_ds_delete_walk_state (
+ ACPI_WALK_STATE *walk_state);
+
+ACPI_WALK_STATE *
+acpi_ds_pop_walk_state (
+ ACPI_WALK_LIST *walk_list);
+
+ACPI_STATUS
+acpi_ds_result_stack_pop (
+ ACPI_OPERAND_OBJECT **object,


+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS

+acpi_ds_result_stack_push (
+ void *object,


+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS

+acpi_ds_result_stack_clear (
+ ACPI_WALK_STATE *walk_state);
+
+ACPI_WALK_STATE *
+acpi_ds_get_current_walk_state (
+ ACPI_WALK_LIST *walk_list);
+
+void
+acpi_ds_delete_walk_state_cache (
+ void);
+
+
+#endif /* _ACDISPAT_H_ */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/acenv.h linux/drivers/acpi/include/acenv.h
--- v2.4.0-test8/linux/drivers/acpi/include/acenv.h Thu Jul 6 01:22:24 2000
+++ linux/drivers/acpi/include/acenv.h Fri Sep 15 21:37:23 2000


@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *

X * Name: acenv.h - Generation environment specific items
+ * $Revision: 53 $


X *
X *****************************************************************************/
X

@@ -75,10 +75,7 @@
X #include <linux/kernel.h>
X #include <linux/ctype.h>
X #include <asm/system.h>
-
-/* Single threaded */
-
-#define ACPI_APPLICATION
+#include <asm/atomic.h>
X
X /* Use native Linux string library */
X
@@ -88,13 +85,27 @@
X
X #define strtoul simple_strtoul
X
+/* Linux clib doesn't to strupr, but we do. */
+char *
+strupr(char *str);
+
+#else
+
+#ifdef _AED_EFI
+
+#include <efi.h>
+#include <efistdarg.h>
+#include <efilib.h>
+
X #else
X
+
X /* All other environments */
X
X #define ACPI_USE_STANDARD_HEADERS
X
X #endif
+#endif
X
X
X /******************************************************************************
@@ -117,6 +128,7 @@
X #include <stdarg.h>
X #include <stdlib.h>
X #include <string.h>
+#include <ctype.h>
X
X #endif /* ACPI_USE_STANDARD_HEADERS */
X
@@ -124,20 +136,20 @@
X * We will be linking to the standard Clib functions
X */
X
-#define STRSTR(s1,s2) strstr((char *) (s1), (char *) (s2))
-#define STRUPR(s) strupr((char *) (s))
-#define STRLEN(s) strlen((char *) (s))
-#define STRCPY(d,s) strcpy((char *) (d), (char *) (s))
-#define STRNCPY(d,s,n) strncpy((char *) (d), (char *) (s), (n))
-#define STRNCMP(d,s,n) strncmp((char *) (d), (char *) (s), (n))
-#define STRCMP(d,s) strcmp((char *) (d), (char *) (s))
-#define STRCAT(d,s) strcat((char *) (d), (char *) (s))
-#define STRNCAT(d,s,n) strncat((char *) (d), (char *) (s), (n))
-#define STRTOUL(d,s,n) strtoul((char *) (d), (char **) (s), (n))
-#define MEMCPY(d,s,n) memcpy(d, s, (size_t) n)
-#define MEMSET(d,s,n) memset(d, s, (size_t) n)
-#define TOUPPER toupper
-#define TOLOWER tolower
+#define STRSTR(s1,s2) strstr((s1), (s2))
+#define STRUPR(s) strupr((s))
+#define STRLEN(s) strlen((s))
+#define STRCPY(d,s) strcpy((d), (s))
+#define STRNCPY(d,s,n) strncpy((d), (s), (n))
+#define STRNCMP(d,s,n) strncmp((d), (s), (n))
+#define STRCMP(d,s) strcmp((d), (s))
+#define STRCAT(d,s) strcat((d), (s))
+#define STRNCAT(d,s,n) strncat((d), (s), (n))
+#define STRTOUL(d,s,n) strtoul((d), (s), (n))
+#define MEMCPY(d,s,n) memcpy((d), (s), (n))
+#define MEMSET(d,s,n) memset((d), (s), (n))
+#define TOUPPER toupper
+#define TOLOWER tolower
X
X
X /******************************************************************************
@@ -165,37 +177,35 @@
X * Storage alignment properties
X */
X
-#define _AUPBND (sizeof(int) - 1)
-#define _ADNBND (sizeof(int) - 1)
+#define _AUPBND (sizeof(int) - 1)
+#define _ADNBND (sizeof(int) - 1)
X
X /*
X * Variable argument list macro definitions
X */
X
-#define _bnd(X, bnd) (((sizeof(X)) + (bnd)) & (~(bnd)))
-#define va_arg(ap, T) (*(T *)(((ap) += ((_bnd(T, _AUPBND))) \
- - (_bnd(T, _ADNBND)))))
-#define va_end(ap) (void)0
-#define va_start(ap, A) (void) ((ap) = (((char *)&(A)) \
- + (_bnd(A, _AUPBND))))
+#define _bnd(X, bnd) (((sizeof(X)) + (bnd)) & (~(bnd)))
+#define va_arg(ap, T) (*(T *)(((ap)+=((_bnd(T, _AUPBND)))-(_bnd(T,_ADNBND)))))
+#define va_end(ap) (void)0
+#define va_start(ap, A) (void)((ap)=(((char*)&(A))+(_bnd(A,_AUPBND))))
X
X #endif /* va_arg */
X
X
-#define STRSTR(s1,s2) acpi_cm_strstr ((char *) (s1), (char *) (s2))
-#define STRUPR(s) acpi_cm_strupr ((char *) (s))
-#define STRLEN(s) acpi_cm_strlen ((char *) (s))
-#define STRCPY(d,s) acpi_cm_strcpy ((char *) (d), (char *) (s))
-#define STRNCPY(d,s,n) acpi_cm_strncpy ((char *) (d), (char *) (s), (n))
-#define STRNCMP(d,s,n) acpi_cm_strncmp ((char *) (d), (char *) (s), (n))
-#define STRCMP(d,s) acpi_cm_strcmp ((char *) (d), (char *) (s))
-#define STRCAT(d,s) acpi_cm_strcat ((char *) (d), (char *) (s))
-#define STRNCAT(d,s,n) acpi_cm_strncat ((char *) (d), (char *) (s), (n))
-#define STRTOUL(d,s,n) acpi_cm_strtoul ((char *) (d), (char **) (s), (n))
-#define MEMCPY(d,s,n) acpi_cm_memcpy ((void *) (d), (const void *) (s), (n))
-#define MEMSET(d,v,n) acpi_cm_memset ((void *) (d), (v), (n))
-#define TOUPPER acpi_cm_to_upper
-#define TOLOWER acpi_cm_to_lower
+#define STRSTR(s1,s2) acpi_cm_strstr ((s1), (s2))
+#define STRUPR(s) acpi_cm_strupr ((s))
+#define STRLEN(s) acpi_cm_strlen ((s))
+#define STRCPY(d,s) acpi_cm_strcpy ((d), (s))
+#define STRNCPY(d,s,n) acpi_cm_strncpy ((d), (s), (n))
+#define STRNCMP(d,s,n) acpi_cm_strncmp ((d), (s), (n))
+#define STRCMP(d,s) acpi_cm_strcmp ((d), (s))
+#define STRCAT(d,s) acpi_cm_strcat ((d), (s))
+#define STRNCAT(d,s,n) acpi_cm_strncat ((d), (s), (n))
+#define STRTOUL(d,s,n) acpi_cm_strtoul ((d), (s),(n))
+#define MEMCPY(d,s,n) acpi_cm_memcpy ((d), (s), (n))
+#define MEMSET(d,v,n) acpi_cm_memset ((d), (v), (n))
+#define TOUPPER acpi_cm_to_upper
+#define TOLOWER acpi_cm_to_lower
X
X #endif /* ACPI_USE_SYSTEM_CLIBRARY */
X
@@ -217,27 +227,90 @@
X
X #ifdef __GNUC__
X
+
X #ifdef __ia64__
-#define _IA64
-#endif
+
+/* Single threaded */
+#define ACPI_APPLICATION
X
X #define ACPI_ASM_MACROS
X #define causeinterrupt(level)
X #define BREAKPOINT3
X #define disable() __cli()
X #define enable() __sti()
-#define halt() __asm__ __volatile__ ("sti; hlt":::"memory")
X #define wbinvd()
X
+/*! [Begin] no source code translation */
+#include <asm/pal.h>
+
+/* PAL_HALT[_LIGHT] */
+#define halt() ia64_pal_halt_light()
+
+/* PAL_HALT */
+#define safe_halt() ia64_pal_halt(1)
+
+#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \
+ do { \
+ __asm__ volatile ("1: ld4 r29=%1\n" \
+ ";;\n" \
+ "mov ar.ccv=r29\n" \
+ "mov r2=r29\n" \
+ "shr.u r30=r29,1\n" \
+ "and r29=-4,r29\n" \
+ ";;\n" \
+ "add r29=2,r29\n" \
+ "and r30=1,r30\n" \
+ ";;\n" \
+ "add r29=r29,r30\n" \
+ ";;\n" \
+ "cmpxchg4.acq r30=%1,r29,ar.ccv\n" \
+ ";;\n" \
+ "cmp.eq p6,p7=r2,r30\n" \
+ "(p7) br.dpnt.few 1b\n" \
+ "cmp.gt p8,p9=3,r29\n" \
+ ";;\n" \
+ "(p8) mov %0=-1\n" \
+ "(p9) mov %0=r0\n" \
+ :"=r"(Acq):"m" __atomic_fool_gcc((GLptr)):"r2","r29","r30","memory"); \
+ } while (0)
+
+#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \
+ do { \
+ __asm__ volatile ("1: ld4 r29=%1\n" \
+ ";;\n" \
+ "mov ar.ccv=r29\n" \
+ "mov r2=r29\n" \
+ "and r29=-4,r29\n" \
+ ";;\n" \
+ "cmpxchg4.acq r30=%1,r29,ar.ccv\n" \
+ ";;\n" \
+ "cmp.eq p6,p7=r2,r30\n" \
+ "(p7) br.dpnt.few 1b\n" \
+ "and %0=1,r2\n" \
+ ";;\n" \
+ :"=r"(Acq):"m" __atomic_fool_gcc((GLptr)):"r2","r29","r30","memory"); \
+ } while (0)
+/*! [End] no source code translation !*/
+
+#else /* DO IA32 */
+
+#define ACPI_ASM_MACROS
+#define causeinterrupt(level)
+#define BREAKPOINT3
+#define disable() __cli()
+#define enable() __sti()
+#define halt() __asm__ __volatile__ ("sti; hlt":::"memory")
+#define wbinvd()
X
X /*! [Begin] no source code translation
X *
X * A brief explanation as GNU inline assembly is a bit hairy
X * %0 is the output parameter in EAX ("=a")
- * %1 and %2 are the input parameters in ECX ("c") and an immediate value ("i") respectively
+ * %1 and %2 are the input parameters in ECX ("c")
+ * and an immediate value ("i") respectively
X * All actual register references are preceded with "%%" as in "%%edx"
X * Immediate values in the assembly are preceded by "$" as in "$0x1"
- * The final asm parameter is the non-output registers altered by the operation
+ * The final asm parameter are the operation altered non-output registers.
X */
X #define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \
X do { \
@@ -267,12 +340,12 @@
X } while(0)
X /*! [End] no source code translation !*/
X
+#endif /* IA 32 */
X #endif /* __GNUC__ */
X
X
-#ifndef ACPI_ASM_MACROS
-
X /* Unrecognized compiler, use defaults */
+#ifndef ACPI_ASM_MACROS
X
X #define ACPI_ASM_MACROS
X #define causeinterrupt(level)
@@ -280,7 +353,6 @@
X #define disable()
X #define enable()
X #define halt()
-
X #define ACPI_ACQUIRE_GLOBAL_LOCK(Glptr, acq)
X #define ACPI_RELEASE_GLOBAL_LOCK(Glptr, acq)
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/acevents.h linux/drivers/acpi/include/acevents.h
--- v2.4.0-test8/linux/drivers/acpi/include/acevents.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/include/acevents.h Fri Sep 15 14:30:30 2000
@@ -0,0 +1,210 @@
+/******************************************************************************
+ *
+ * Name: acevents.h - Event subcomponent prototypes and defines
+ * $Revision: 56 $


+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 R. Byron Moore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+

+#ifndef __ACEVENTS_H__
+#define __ACEVENTS_H__
+
+
+/*
+ * Acpi_evfixed - Fixed event handling
+ */
+
+ACPI_STATUS
+acpi_ev_fixed_event_initialize (
+ void);
+
+u32
+acpi_ev_fixed_event_detect (
+ void);
+
+u32
+acpi_ev_fixed_event_dispatch (
+ u32 acpi_event);
+
+
+/*
+ * Acpi_evglock - Global Lock support
+ */
+
+ACPI_STATUS
+acpi_ev_acquire_global_lock(
+ void);
+
+void
+acpi_ev_release_global_lock(
+ void);
+
+ACPI_STATUS
+acpi_ev_init_global_lock_handler (


+ void);
+
+
+/*

+ * Acpi_evgpe - GPE handling and dispatch
+ */
+
+ACPI_STATUS
+acpi_ev_gpe_initialize (
+ void);
+
+ACPI_STATUS
+acpi_ev_init_gpe_control_methods (
+ void);
+
+u32
+acpi_ev_gpe_dispatch (
+ u32 gpe_number);
+
+u32
+acpi_ev_gpe_detect (


+ void);
+
+
+/*

+ * Acpi_evnotify - Device Notify handling and dispatch
+ */
+
+void
+acpi_ev_notify_dispatch (
+ ACPI_HANDLE device,
+ u32 notify_value);
+
+
+/*
+ * Acpi_evregion - Address Space handling
+ */
+
+ACPI_STATUS
+acpi_ev_install_default_address_space_handlers (
+ void);
+
+ACPI_STATUS
+acpi_ev_address_space_dispatch (
+ ACPI_OPERAND_OBJECT *region_obj,
+ u32 function,
+ u32 address,
+ u32 bit_width,
+ u32 *value);
+
+
+ACPI_STATUS
+acpi_ev_addr_handler_helper (
+ ACPI_HANDLE obj_handle,
+ u32 level,


+ void *context,
+ void **return_value);
+

+void
+acpi_ev_disassociate_region_from_handler(
+ ACPI_OPERAND_OBJECT *region_obj);
+
+
+ACPI_STATUS


+acpi_ev_associate_region_and_handler (
+ ACPI_OPERAND_OBJECT *handler_obj,
+ ACPI_OPERAND_OBJECT *region_obj,

+ u8 acpi_ns_is_locked);
+
+
+/*
+ * Acpi_evregini - Region initialization and setup
+ */
+
+ACPI_STATUS
+acpi_ev_system_memory_region_setup (
+ ACPI_HANDLE handle,
+ u32 function,
+ void *handler_context,
+ void **region_context);
+
+ACPI_STATUS
+acpi_ev_io_space_region_setup (
+ ACPI_HANDLE handle,
+ u32 function,
+ void *handler_context,
+ void **region_context);
+
+ACPI_STATUS
+acpi_ev_pci_config_region_setup (
+ ACPI_HANDLE handle,
+ u32 function,
+ void *handler_context,
+ void **region_context);
+
+ACPI_STATUS
+acpi_ev_default_region_setup (
+ ACPI_HANDLE handle,
+ u32 function,
+ void *handler_context,
+ void **region_context);
+
+ACPI_STATUS
+acpi_ev_initialize_region (
+ ACPI_OPERAND_OBJECT *region_obj,
+ u8 acpi_ns_locked);
+
+
+/*
+ * Evsci - SCI (System Control Interrupt) handling/dispatch
+ */
+
+u32
+acpi_ev_install_sci_handler (
+ void);
+
+ACPI_STATUS
+acpi_ev_remove_sci_handler (
+ void);
+
+u32
+acpi_ev_initialize_sCI (
+ u32 program_sCI);
+
+void
+acpi_ev_restore_acpi_state (
+ void);
+
+void
+acpi_ev_terminate (
+ void);
+
+
+/* Debug support */
+
+#ifdef ACPI_DEBUG
+
+u32
+acpi_ev_sci_count (
+ u32 acpi_event);
+
+#define DEBUG_INCREMENT_EVENT_COUNT(a) acpi_gbl_event_count[a]++;
+
+#else
+
+#define DEBUG_INCREMENT_EVENT_COUNT(a)
+#endif
+
+
+#endif /* __ACEVENTS_H__ */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/acexcep.h linux/drivers/acpi/include/acexcep.h
--- v2.4.0-test8/linux/drivers/acpi/include/acexcep.h Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/include/acexcep.h Fri Sep 15 14:30:30 2000


@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *

X * Name: acexcep.h - Exception codes returned by the ACPI subsystem


+ * $Revision: 35 $

X *
X *****************************************************************************/
X

@@ -31,65 +31,105 @@
X * Exceptions returned by external ACPI interfaces
X */
X
+#define AE_CODE_ENVIRONMENTAL 0x0000
+#define AE_CODE_PROGRAMMER 0x1000
+#define AE_CODE_ACPI_TABLES 0x2000
+#define AE_CODE_AML 0x3000
+#define AE_CODE_CONTROL 0x4000
+#define AE_CODE_MASK 0xF000
+
+
X #define ACPI_SUCCESS(a) (!(a))
X #define ACPI_FAILURE(a) (a)
X
+
X #define AE_OK (ACPI_STATUS) 0x0000
-#define AE_CTRL_RETURN_VALUE (ACPI_STATUS) 0x0001
-#define AE_CTRL_PENDING (ACPI_STATUS) 0x0002
-#define AE_CTRL_TERMINATE (ACPI_STATUS) 0x0003
-#define AE_CTRL_TRUE (ACPI_STATUS) 0x0004
-#define AE_CTRL_FALSE (ACPI_STATUS) 0x0005
-#define AE_CTRL_DEPTH (ACPI_STATUS) 0x0006
-#define AE_CTRL_RESERVED (ACPI_STATUS) 0x0007
-#define AE_AML_ERROR (ACPI_STATUS) 0x0008
-#define AE_AML_PARSE (ACPI_STATUS) 0x0009
-#define AE_AML_BAD_OPCODE (ACPI_STATUS) 0x000A
-#define AE_AML_NO_OPERAND (ACPI_STATUS) 0x000B
-#define AE_AML_OPERAND_TYPE (ACPI_STATUS) 0x000C
-#define AE_AML_OPERAND_VALUE (ACPI_STATUS) 0x000D
-#define AE_AML_UNINITIALIZED_LOCAL (ACPI_STATUS) 0x000E
-#define AE_AML_UNINITIALIZED_ARG (ACPI_STATUS) 0x000F
-#define AE_AML_UNINITIALIZED_ELEMENT (ACPI_STATUS) 0x0010
-#define AE_AML_NUMERIC_OVERFLOW (ACPI_STATUS) 0x0011
-#define AE_AML_REGION_LIMIT (ACPI_STATUS) 0x0012
-#define AE_AML_BUFFER_LIMIT (ACPI_STATUS) 0x0013
-#define AE_AML_PACKAGE_LIMIT (ACPI_STATUS) 0x0014
-#define AE_AML_DIVIDE_BY_ZERO (ACPI_STATUS) 0x0015
-#define AE_AML_BAD_NAME (ACPI_STATUS) 0x0016
-#define AE_AML_NAME_NOT_FOUND (ACPI_STATUS) 0x0017
-#define AE_AML_INTERNAL (ACPI_STATUS) 0x0018
-#define AE_AML_RESERVED (ACPI_STATUS) 0x0019
-#define AE_ERROR (ACPI_STATUS) 0x001A
-#define AE_NO_ACPI_TABLES (ACPI_STATUS) 0x001B
-#define AE_NO_NAMESPACE (ACPI_STATUS) 0x001C
-#define AE_NO_MEMORY (ACPI_STATUS) 0x001D
-#define AE_BAD_SIGNATURE (ACPI_STATUS) 0x001E
-#define AE_BAD_HEADER (ACPI_STATUS) 0x001F
-#define AE_BAD_CHECKSUM (ACPI_STATUS) 0x0020
-#define AE_BAD_PARAMETER (ACPI_STATUS) 0x0021
-#define AE_BAD_CHARACTER (ACPI_STATUS) 0x0022
-#define AE_BAD_PATHNAME (ACPI_STATUS) 0x0023
-#define AE_BAD_DATA (ACPI_STATUS) 0x0024
-#define AE_BAD_ADDRESS (ACPI_STATUS) 0x0025
-#define AE_NOT_FOUND (ACPI_STATUS) 0x0026
-#define AE_NOT_EXIST (ACPI_STATUS) 0x0027
-#define AE_EXIST (ACPI_STATUS) 0x0028
-#define AE_TYPE (ACPI_STATUS) 0x0029
-#define AE_NULL_OBJECT (ACPI_STATUS) 0x002A
-#define AE_NULL_ENTRY (ACPI_STATUS) 0x002B
-#define AE_BUFFER_OVERFLOW (ACPI_STATUS) 0x002C
-#define AE_STACK_OVERFLOW (ACPI_STATUS) 0x002D
-#define AE_STACK_UNDERFLOW (ACPI_STATUS) 0x002E
-#define AE_NOT_IMPLEMENTED (ACPI_STATUS) 0x002F
-#define AE_VERSION_MISMATCH (ACPI_STATUS) 0x0030
-#define AE_SUPPORT (ACPI_STATUS) 0x0031
-#define AE_SHARE (ACPI_STATUS) 0x0032
-#define AE_LIMIT (ACPI_STATUS) 0x0033
-#define AE_TIME (ACPI_STATUS) 0x0034
-#define AE_UNKNOWN_STATUS (ACPI_STATUS) 0x0035
-#define ACPI_MAX_STATUS (ACPI_STATUS) 0x0035
-#define ACPI_NUM_STATUS (ACPI_STATUS) 0x0036
+
+/*
+ * Environmental exceptions
+ */
+#define AE_ERROR (ACPI_STATUS) (0x0001 | AE_CODE_ENVIRONMENTAL)
+#define AE_NO_ACPI_TABLES (ACPI_STATUS) (0x0002 | AE_CODE_ENVIRONMENTAL)
+#define AE_NO_NAMESPACE (ACPI_STATUS) (0x0003 | AE_CODE_ENVIRONMENTAL)
+#define AE_NO_MEMORY (ACPI_STATUS) (0x0004 | AE_CODE_ENVIRONMENTAL)
+#define AE_NOT_FOUND (ACPI_STATUS) (0x0005 | AE_CODE_ENVIRONMENTAL)
+#define AE_NOT_EXIST (ACPI_STATUS) (0x0006 | AE_CODE_ENVIRONMENTAL)
+#define AE_EXIST (ACPI_STATUS) (0x0007 | AE_CODE_ENVIRONMENTAL)
+#define AE_TYPE (ACPI_STATUS) (0x0008 | AE_CODE_ENVIRONMENTAL)
+#define AE_NULL_OBJECT (ACPI_STATUS) (0x0009 | AE_CODE_ENVIRONMENTAL)
+#define AE_NULL_ENTRY (ACPI_STATUS) (0x000A | AE_CODE_ENVIRONMENTAL)
+#define AE_BUFFER_OVERFLOW (ACPI_STATUS) (0x000B | AE_CODE_ENVIRONMENTAL)
+#define AE_STACK_OVERFLOW (ACPI_STATUS) (0x000C | AE_CODE_ENVIRONMENTAL)
+#define AE_STACK_UNDERFLOW (ACPI_STATUS) (0x000D | AE_CODE_ENVIRONMENTAL)
+#define AE_NOT_IMPLEMENTED (ACPI_STATUS) (0x000E | AE_CODE_ENVIRONMENTAL)
+#define AE_VERSION_MISMATCH (ACPI_STATUS) (0x000F | AE_CODE_ENVIRONMENTAL)
+#define AE_SUPPORT (ACPI_STATUS) (0x0010 | AE_CODE_ENVIRONMENTAL)
+#define AE_SHARE (ACPI_STATUS) (0x0011 | AE_CODE_ENVIRONMENTAL)
+#define AE_LIMIT (ACPI_STATUS) (0x0012 | AE_CODE_ENVIRONMENTAL)
+#define AE_TIME (ACPI_STATUS) (0x0013 | AE_CODE_ENVIRONMENTAL)
+#define AE_UNKNOWN_STATUS (ACPI_STATUS) (0x0014 | AE_CODE_ENVIRONMENTAL)
+
+#define AE_CODE_ENV_MAX 0x0014
+
+/*
+ * Programmer exceptions
+ */
+#define AE_BAD_PARAMETER (ACPI_STATUS) (0x0001 | AE_CODE_PROGRAMMER)
+#define AE_BAD_CHARACTER (ACPI_STATUS) (0x0002 | AE_CODE_PROGRAMMER)
+#define AE_BAD_PATHNAME (ACPI_STATUS) (0x0003 | AE_CODE_PROGRAMMER)
+#define AE_BAD_DATA (ACPI_STATUS) (0x0004 | AE_CODE_PROGRAMMER)
+#define AE_BAD_ADDRESS (ACPI_STATUS) (0x0005 | AE_CODE_PROGRAMMER)
+
+#define AE_CODE_PGM_MAX 0x0005
+
+
+/*
+ * Acpi table exceptions
+ */
+#define AE_BAD_SIGNATURE (ACPI_STATUS) (0x0001 | AE_CODE_ACPI_TABLES)
+#define AE_BAD_HEADER (ACPI_STATUS) (0x0002 | AE_CODE_ACPI_TABLES)
+#define AE_BAD_CHECKSUM (ACPI_STATUS) (0x0003 | AE_CODE_ACPI_TABLES)
+
+#define AE_CODE_TBL_MAX 0x0003
+
+
+/*
+ * AML exceptions. These are caused by problems with
+ * the actual AML byte stream
+ */
+#define AE_AML_ERROR (ACPI_STATUS) (0x0001 | AE_CODE_AML)
+#define AE_AML_PARSE (ACPI_STATUS) (0x0002 | AE_CODE_AML)
+#define AE_AML_BAD_OPCODE (ACPI_STATUS) (0x0003 | AE_CODE_AML)
+#define AE_AML_NO_OPERAND (ACPI_STATUS) (0x0004 | AE_CODE_AML)
+#define AE_AML_OPERAND_TYPE (ACPI_STATUS) (0x0005 | AE_CODE_AML)
+#define AE_AML_OPERAND_VALUE (ACPI_STATUS) (0x0006 | AE_CODE_AML)
+#define AE_AML_UNINITIALIZED_LOCAL (ACPI_STATUS) (0x0007 | AE_CODE_AML)
+#define AE_AML_UNINITIALIZED_ARG (ACPI_STATUS) (0x0008 | AE_CODE_AML)
+#define AE_AML_UNINITIALIZED_ELEMENT (ACPI_STATUS) (0x0009 | AE_CODE_AML)
+#define AE_AML_NUMERIC_OVERFLOW (ACPI_STATUS) (0x000A | AE_CODE_AML)
+#define AE_AML_REGION_LIMIT (ACPI_STATUS) (0x000B | AE_CODE_AML)
+#define AE_AML_BUFFER_LIMIT (ACPI_STATUS) (0x000C | AE_CODE_AML)
+#define AE_AML_PACKAGE_LIMIT (ACPI_STATUS) (0x000D | AE_CODE_AML)
+#define AE_AML_DIVIDE_BY_ZERO (ACPI_STATUS) (0x000E | AE_CODE_AML)
+#define AE_AML_BAD_NAME (ACPI_STATUS) (0x000F | AE_CODE_AML)
+#define AE_AML_NAME_NOT_FOUND (ACPI_STATUS) (0x0010 | AE_CODE_AML)
+#define AE_AML_INTERNAL (ACPI_STATUS) (0x0011 | AE_CODE_AML)
+
+#define AE_CODE_AML_MAX 0x0011
+
+/*
+ * Internal exceptions used for control
+ */
+#define AE_CTRL_RETURN_VALUE (ACPI_STATUS) (0x0001 | AE_CODE_CONTROL)
+#define AE_CTRL_PENDING (ACPI_STATUS) (0x0002 | AE_CODE_CONTROL)
+#define AE_CTRL_TERMINATE (ACPI_STATUS) (0x0003 | AE_CODE_CONTROL)
+#define AE_CTRL_TRUE (ACPI_STATUS) (0x0004 | AE_CODE_CONTROL)
+#define AE_CTRL_FALSE (ACPI_STATUS) (0x0005 | AE_CODE_CONTROL)
+#define AE_CTRL_DEPTH (ACPI_STATUS) (0x0006 | AE_CODE_CONTROL)
+#define AE_CTRL_END (ACPI_STATUS) (0x0007 | AE_CODE_CONTROL)
+#define AE_CTRL_TRANSFER (ACPI_STATUS) (0x0008 | AE_CODE_CONTROL)
+
+#define AE_CODE_CTRL_MAX 0x0008
X
X
X #ifdef DEFINE_ACPI_GLOBALS
@@ -98,46 +138,13 @@
X * String versions of the exception codes above
X * These strings must match the corresponding defines exactly
X */
-static char *acpi_gbl_exception_names[] =
+static NATIVE_CHAR *acpi_gbl_exception_names_env[] =
X {
X "AE_OK",
- "AE_CTRL_RETURN_VALUE",
- "AE_CTRL_PENDING",
- "AE_CTRL_TERMINATE",
- "AE_CTRL_TRUE",
- "AE_CTRL_FALSE",
- "AE_CTRL_DEPTH",
- "AE_CTRL_RESERVED",
- "AE_AML_ERROR",
- "AE_AML_PARSE",
- "AE_AML_BAD_OPCODE",
- "AE_AML_NO_OPERAND",
- "AE_AML_OPERAND_TYPE",
- "AE_AML_OPERAND_VALUE",
- "AE_AML_UNINITIALIZED_LOCAL",
- "AE_AML_UNINITIALIZED_ARG",
- "AE_AML_UNINITIALIZED_ELEMENT",
- "AE_AML_NUMERIC_OVERFLOW",
- "AE_AML_REGION_LIMIT",
- "AE_AML_BUFFER_LIMIT",
- "AE_AML_PACKAGE_LIMIT",
- "AE_AML_DIVIDE_BY_ZERO",
- "AE_AML_BAD_NAME",
- "AE_AML_NAME_NOT_FOUND",
- "AE_AML_INTERNAL",
- "AE_AML_RESERVED",
X "AE_ERROR",
X "AE_NO_ACPI_TABLES",
X "AE_NO_NAMESPACE",
X "AE_NO_MEMORY",
- "AE_BAD_SIGNATURE",
- "AE_BAD_HEADER",
- "AE_BAD_CHECKSUM",
- "AE_BAD_PARAMETER",
- "AE_BAD_CHARACTER",
- "AE_BAD_PATHNAME",
- "AE_BAD_DATA",
- "AE_BAD_ADDRESS",
X "AE_NOT_FOUND",
X "AE_NOT_EXIST",
X "AE_EXIST",
@@ -153,8 +160,58 @@
X "AE_SHARE",
X "AE_LIMIT",
X "AE_TIME",
- "AE_UNKNOWN_STATUS"
+ "AE_UNKNOWN_STATUS",
+};
+
+static NATIVE_CHAR *acpi_gbl_exception_names_pgm[] =
+{
+ "AE_BAD_PARAMETER",
+ "AE_BAD_CHARACTER",
+ "AE_BAD_PATHNAME",
+ "AE_BAD_DATA",
+ "AE_BAD_ADDRESS",
+};
+
+static NATIVE_CHAR *acpi_gbl_exception_names_tbl[] =
+{
+ "AE_BAD_SIGNATURE",
+ "AE_BAD_HEADER",
+ "AE_BAD_CHECKSUM",
+};
+
+static NATIVE_CHAR *acpi_gbl_exception_names_aml[] =
+{
+ "AE_AML_ERROR",
+ "AE_AML_PARSE",
+ "AE_AML_BAD_OPCODE",
+ "AE_AML_NO_OPERAND",
+ "AE_AML_OPERAND_TYPE",
+ "AE_AML_OPERAND_VALUE",
+ "AE_AML_UNINITIALIZED_LOCAL",
+ "AE_AML_UNINITIALIZED_ARG",
+ "AE_AML_UNINITIALIZED_ELEMENT",
+ "AE_AML_NUMERIC_OVERFLOW",
+ "AE_AML_REGION_LIMIT",
+ "AE_AML_BUFFER_LIMIT",
+ "AE_AML_PACKAGE_LIMIT",
+ "AE_AML_DIVIDE_BY_ZERO",
+ "AE_AML_BAD_NAME",
+ "AE_AML_NAME_NOT_FOUND",
+ "AE_AML_INTERNAL",
+};
+
+static NATIVE_CHAR *acpi_gbl_exception_names_ctrl[] =
+{
+ "AE_CTRL_RETURN_VALUE",
+ "AE_CTRL_PENDING",
+ "AE_CTRL_TERMINATE",
+ "AE_CTRL_TRUE",
+ "AE_CTRL_FALSE",
+ "AE_CTRL_DEPTH",
+ "AE_CTRL_END",
+ "AE_CTRL_TRANSFER",
X };
+
X
X #endif /* DEFINE_ACPI_GLOBALS */
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/acglobal.h linux/drivers/acpi/include/acglobal.h
--- v2.4.0-test8/linux/drivers/acpi/include/acglobal.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/include/acglobal.h Fri Sep 15 14:30:30 2000
@@ -0,0 +1,320 @@
+/******************************************************************************
+ *
+ * Name: acglobal.h - Declarations for global variables
+ * $Revision: 84 $


+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 R. Byron Moore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+

+#ifndef __ACGLOBAL_H__
+#define __ACGLOBAL_H__
+
+
+/*
+ * Ensure that the globals are actually defined only once.
+ *
+ * The use of these defines allows a single list of globals (here) in order
+ * to simplify maintenance of the code.
+ */
+#ifdef DEFINE_ACPI_GLOBALS
+#define ACPI_EXTERN
+#else
+#define ACPI_EXTERN extern
+#endif
+
+
+extern NATIVE_CHAR *msg_acpi_error_break;
+
+/*****************************************************************************
+ *
+ * Debug support
+ *
+ ****************************************************************************/
+
+/* Runtime configuration of debug print levels */
+
+extern u32 acpi_dbg_level;
+extern u32 acpi_dbg_layer;
+
+
+/* Procedure nesting level for debug output */
+
+extern u32 acpi_gbl_nesting_level;
+
+
+/*****************************************************************************
+ *
+ * ACPI Table globals
+ *
+ ****************************************************************************/
+
+/*
+ * Table pointers.
+ * Although these pointers are somewhat redundant with the global Acpi_table,
+ * they are convenient because they are typed pointers.
+ *
+ * These tables are single-table only; meaning that there can be at most one
+ * of each in the system. Each global points to the actual table.
+ *
+ */
+ACPI_EXTERN ROOT_SYSTEM_DESCRIPTOR_POINTER *acpi_gbl_RSDP;
+ACPI_EXTERN ROOT_SYSTEM_DESCRIPTION_TABLE *acpi_gbl_RSDT;
+ACPI_EXTERN FIRMWARE_ACPI_CONTROL_STRUCTURE *acpi_gbl_FACS;
+ACPI_EXTERN FIXED_ACPI_DESCRIPTION_TABLE *acpi_gbl_FACP;
+ACPI_EXTERN APIC_TABLE *acpi_gbl_APIC;
+ACPI_EXTERN ACPI_TABLE_HEADER *acpi_gbl_DSDT;
+ACPI_EXTERN ACPI_TABLE_HEADER *acpi_gbl_SBST;
+/*
+ * Since there may be multiple SSDTs and PSDTS, a single pointer is not
+ * sufficient; Therefore, there isn't one!
+ */
+
+
+/*
+ * ACPI Table info arrays
+ */
+extern ACPI_TABLE_DESC acpi_gbl_acpi_tables[NUM_ACPI_TABLES];
+extern ACPI_TABLE_SUPPORT acpi_gbl_acpi_table_data[NUM_ACPI_TABLES];
+
+/*
+ * Predefined mutex objects. This array contains the
+ * actual OS mutex handles, indexed by the local ACPI_MUTEX_HANDLEs.
+ * (The table maps local handles to the real OS handles)
+ */
+ACPI_EXTERN ACPI_MUTEX_INFO acpi_gbl_acpi_mutex_info [NUM_MTX];
+extern ACPI_INIT_DATA acpi_gbl_acpi_init_data;
+
+
+/*****************************************************************************
+ *
+ * Miscellaneous globals
+ *
+ ****************************************************************************/
+
+
+ACPI_EXTERN u8 *acpi_gbl_gpe0enable_register_save;
+ACPI_EXTERN u8 *acpi_gbl_gpe1_enable_register_save;
+ACPI_EXTERN ACPI_WALK_STATE *acpi_gbl_breakpoint_walk;
+ACPI_EXTERN ACPI_GENERIC_STATE *acpi_gbl_generic_state_cache;
+ACPI_EXTERN ACPI_PARSE_OBJECT *acpi_gbl_parse_cache;
+ACPI_EXTERN ACPI_PARSE2_OBJECT *acpi_gbl_ext_parse_cache;
+ACPI_EXTERN ACPI_OPERAND_OBJECT *acpi_gbl_object_cache;
+ACPI_EXTERN ACPI_WALK_STATE *acpi_gbl_walk_state_cache;
+ACPI_EXTERN ACPI_HANDLE acpi_gbl_global_lock_semaphore;
+
+
+ACPI_EXTERN u32 acpi_gbl_global_lock_thread_count;
+ACPI_EXTERN u32 acpi_gbl_restore_acpi_chipset;
+ACPI_EXTERN u32 acpi_gbl_original_mode;
+ACPI_EXTERN u32 acpi_gbl_edge_level_save;
+ACPI_EXTERN u32 acpi_gbl_irq_enable_save;
+ACPI_EXTERN u32 acpi_gbl_rsdp_original_location;
+
+ACPI_EXTERN u32 acpi_gbl_state_cache_requests;
+ACPI_EXTERN u32 acpi_gbl_state_cache_hits;
+ACPI_EXTERN u32 acpi_gbl_parse_cache_requests;
+ACPI_EXTERN u32 acpi_gbl_parse_cache_hits;
+ACPI_EXTERN u32 acpi_gbl_ext_parse_cache_requests;
+ACPI_EXTERN u32 acpi_gbl_ext_parse_cache_hits;
+ACPI_EXTERN u32 acpi_gbl_object_cache_requests;
+ACPI_EXTERN u32 acpi_gbl_object_cache_hits;
+ACPI_EXTERN u32 acpi_gbl_walk_state_cache_requests;
+ACPI_EXTERN u32 acpi_gbl_walk_state_cache_hits;
+ACPI_EXTERN u32 acpi_gbl_ns_lookup_count;
+ACPI_EXTERN u32 acpi_gbl_ps_find_count;
+
+
+ACPI_EXTERN u16 acpi_gbl_generic_state_cache_depth;
+ACPI_EXTERN u16 acpi_gbl_parse_cache_depth;
+ACPI_EXTERN u16 acpi_gbl_ext_parse_cache_depth;
+ACPI_EXTERN u16 acpi_gbl_object_cache_depth;
+ACPI_EXTERN u16 acpi_gbl_walk_state_cache_depth;
+ACPI_EXTERN u16 acpi_gbl_pm1_enable_register_save;
+ACPI_EXTERN u16 acpi_gbl_next_table_owner_id;
+ACPI_EXTERN u16 acpi_gbl_next_method_owner_id;
+
+ACPI_EXTERN u8 acpi_gbl_debugger_configuration;
+ACPI_EXTERN u8 acpi_gbl_global_lock_acquired;
+ACPI_EXTERN u8 acpi_gbl_global_lock_set; /* TBD: [Restructure] OBSOLETE?? */
+ACPI_EXTERN u8 acpi_gbl_step_to_next_call;
+ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present;
+
+
+ACPI_EXTERN ACPI_OBJECT_NOTIFY_HANDLER acpi_gbl_drv_notify;
+ACPI_EXTERN ACPI_OBJECT_NOTIFY_HANDLER acpi_gbl_sys_notify;
+
+
+extern u8 acpi_gbl_shutdown;
+extern u32 acpi_gbl_system_flags;
+extern u32 acpi_gbl_startup_flags;
+
+
+/*****************************************************************************
+ *
+ * Namespace globals
+ *
+ ****************************************************************************/
+
+#define NUM_NS_TYPES INTERNAL_TYPE_INVALID+1
+#define NUM_PREDEFINED_NAMES 9
+
+
+ACPI_EXTERN ACPI_NAMESPACE_NODE acpi_gbl_root_node_struct;
+ACPI_EXTERN ACPI_NAMESPACE_NODE *acpi_gbl_root_node;
+
+extern u8 acpi_gbl_ns_properties[NUM_NS_TYPES];
+extern PREDEFINED_NAMES acpi_gbl_pre_defined_names [NUM_PREDEFINED_NAMES];
+
+
+/* Used to detect memory leaks (DEBUG ONLY) */
+
+#ifdef ACPI_DEBUG
+ACPI_EXTERN ALLOCATION_INFO *acpi_gbl_head_alloc_ptr;
+ACPI_EXTERN ALLOCATION_INFO *acpi_gbl_tail_alloc_ptr;
+#endif
+
+
+/*****************************************************************************
+ *
+ * Interpreter globals
+ *
+ ****************************************************************************/
+
+
+ACPI_EXTERN u32 acpi_gbl_when_to_parse_methods;
+ACPI_EXTERN ACPI_WALK_LIST *acpi_gbl_current_walk_list;
+
+/* Base of AML block, and pointer to current location in it */
+
+ACPI_EXTERN u8 *acpi_gbl_Pcode_base;
+ACPI_EXTERN u8 *acpi_gbl_Pcode;
+
+/*
+ * Length of AML block, and remaining length of current package.
+ */
+ACPI_EXTERN u32 acpi_gbl_Pcode_block_len;
+ACPI_EXTERN u32 acpi_gbl_Pcode_len;
+
+ACPI_EXTERN u32 acpi_gbl_buf_seq; /* Counts allocated Buffer descriptors */
+ACPI_EXTERN u32 acpi_gbl_node_err; /* Indicate if inc_error should be called */
+
+/*
+ * Handle to the last method found - used during pass1 of load
+ */
+ACPI_EXTERN ACPI_HANDLE acpi_gbl_last_method;
+
+/*
+ * Table of Address Space handlers
+ */
+
+ACPI_EXTERN ACPI_ADDRESS_SPACE_INFO acpi_gbl_address_spaces[ACPI_NUM_ADDRESS_SPACES];
+
+
+/* Control method single step flag */
+
+ACPI_EXTERN u8 acpi_gbl_cm_single_step;
+
+
+/*****************************************************************************
+ *
+ * Parser globals
+ *
+ ****************************************************************************/
+
+ACPI_EXTERN ACPI_PARSE_OBJECT *acpi_gbl_parsed_namespace_root;
+
+extern ACPI_OPCODE_INFO acpi_gbl_aml_op_info[];
+extern u8 acpi_gbl_aml_op_info_index[256];
+
+
+/*****************************************************************************
+ *
+ * Hardware globals
+ *
+ ****************************************************************************/
+
+extern ACPI_C_STATE_HANDLER acpi_hw_cx_handlers[MAX_CX_STATES];
+extern u32 acpi_hw_active_cx_state;
+
+
+/*****************************************************************************
+ *
+ * Event globals
+ *
+ ****************************************************************************/
+
+ACPI_EXTERN ACPI_FIXED_EVENT_INFO acpi_gbl_fixed_event_handlers[NUM_FIXED_EVENTS];
+
+ACPI_EXTERN ACPI_HANDLE acpi_gbl_gpe_obj_handle;
+ACPI_EXTERN u32 acpi_gbl_gpe_register_count;
+ACPI_EXTERN ACPI_GPE_REGISTERS *acpi_gbl_gpe_registers;
+ACPI_EXTERN ACPI_GPE_LEVEL_INFO *acpi_gbl_gpe_info;
+
+/*
+ * Gpe validation and translation table
+ * Indexed by the GPE number, returns GPE_INVALID if the GPE is not supported.
+ * Otherwise, returns a valid index into the global GPE table.
+ *
+ * This table is needed because the GPE numbers supported by block 1 do not
+ * have to be contiguous with the GPE numbers supported by block 0.
+ */
+ACPI_EXTERN u8 acpi_gbl_gpe_valid [NUM_GPE];
+
+/* Acpi_event counter for debug only */
+
+#ifdef ACPI_DEBUG
+ACPI_EXTERN u32 acpi_gbl_event_count[NUM_FIXED_EVENTS];
+#endif
+
+
+/*****************************************************************************
+ *
+ * Debugger globals
+ *
+ ****************************************************************************/
+
+ACPI_EXTERN u8 acpi_gbl_method_executing;
+ACPI_EXTERN u8 acpi_gbl_db_terminate_threads;
+
+
+/* Memory allocation metrics - Debug Only! */
+
+#ifdef ACPI_DEBUG
+
+ACPI_EXTERN u32 acpi_gbl_current_alloc_size;
+ACPI_EXTERN u32 acpi_gbl_current_alloc_count;
+ACPI_EXTERN u32 acpi_gbl_running_alloc_size;
+ACPI_EXTERN u32 acpi_gbl_running_alloc_count;
+ACPI_EXTERN u32 acpi_gbl_max_concurrent_alloc_size;
+ACPI_EXTERN u32 acpi_gbl_max_concurrent_alloc_count;
+ACPI_EXTERN u32 acpi_gbl_current_object_count;
+ACPI_EXTERN u32 acpi_gbl_current_object_size;
+ACPI_EXTERN u32 acpi_gbl_max_concurrent_object_count;
+ACPI_EXTERN u32 acpi_gbl_max_concurrent_object_size;
+ACPI_EXTERN u32 acpi_gbl_running_object_count;
+ACPI_EXTERN u32 acpi_gbl_running_object_size;
+ACPI_EXTERN u32 acpi_gbl_current_node_count;
+ACPI_EXTERN u32 acpi_gbl_current_node_size;
+ACPI_EXTERN u32 acpi_gbl_max_concurrent_node_count;
+
+#endif
+
+
+#endif /* __ACGLOBAL_H__ */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/achware.h linux/drivers/acpi/include/achware.h
--- v2.4.0-test8/linux/drivers/acpi/include/achware.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/include/achware.h Fri Sep 15 14:30:30 2000
@@ -0,0 +1,169 @@
+/******************************************************************************
+ *
+ * Name: achware.h -- hardware specific interfaces
+ * $Revision: 41 $


+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 R. Byron Moore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+

+#ifndef __ACHWARE_H__
+#define __ACHWARE_H__


+
+
+/* Prototypes */
+
+

+ACPI_STATUS
+acpi_hw_initialize(
+ void);
+
+ACPI_STATUS
+acpi_hw_shutdown(
+ void);
+
+ACPI_STATUS
+acpi_hw_initialize_system_info(
+ void);
+
+ACPI_STATUS
+acpi_hw_set_mode (
+ u32 mode);
+
+u32
+acpi_hw_get_mode (
+ void);
+
+u32
+acpi_hw_get_mode_capabilities (
+ void);
+
+/* Register I/O Prototypes */
+
+u32
+acpi_hw_register_access (
+ NATIVE_UINT read_write,
+ u8 use_lock,
+ u32 register_id, ... /* DWORD Value */);
+
+void
+acpi_hw_clear_acpi_status (
+ void);
+
+
+/* GPE support */
+
+void
+acpi_hw_enable_gpe (
+ u32 gpe_index);
+
+void
+acpi_hw_disable_gpe (
+ u32 gpe_index);
+
+void
+acpi_hw_clear_gpe (
+ u32 gpe_index);
+
+void
+acpi_hw_get_gpe_status (
+ u32 gpe_number,
+ ACPI_EVENT_STATUS *event_status);
+
+/* Sleep Prototypes */
+
+ACPI_STATUS
+acpi_hw_obtain_sleep_type_register_data (
+ u8 sleep_state,
+ u8 *slp_typ_a,
+ u8 *slp_typ_b);
+
+
+/* Cx State Prototypes */
+
+ACPI_STATUS
+acpi_hw_enter_c1(
+ ACPI_IO_ADDRESS pblk_address,
+ u32 *pm_timer_ticks);
+
+ACPI_STATUS
+acpi_hw_enter_c2(
+ ACPI_IO_ADDRESS pblk_address,
+ u32 *pm_timer_ticks);
+
+ACPI_STATUS
+acpi_hw_enter_c3(
+ ACPI_IO_ADDRESS pblk_address,
+ u32 *pm_timer_ticks);
+
+ACPI_STATUS
+acpi_hw_enter_cx (
+ ACPI_IO_ADDRESS pblk_address,
+ u32 *pm_timer_ticks);
+
+ACPI_STATUS
+acpi_hw_set_cx (
+ u32 cx_state);
+
+ACPI_STATUS
+acpi_hw_get_cx_info (
+ u32 cx_states[]);
+
+
+/* Throttling Prototypes */
+
+void
+acpi_hw_enable_throttling (
+ ACPI_IO_ADDRESS pblk_address);
+
+void
+acpi_hw_disable_throttling (
+ ACPI_IO_ADDRESS pblk_address);
+
+u32
+acpi_hw_get_duty_cycle (
+ u8 duty_offset,
+ ACPI_IO_ADDRESS pblk_address,
+ u32 num_throttle_states);
+
+void
+acpi_hw_program_duty_cycle (
+ u8 duty_offset,
+ u32 duty_cycle,
+ ACPI_IO_ADDRESS pblk_address,
+ u32 num_throttle_states);
+
+NATIVE_UINT
+acpi_hw_local_pow (
+ NATIVE_UINT x,
+ NATIVE_UINT y);
+
+
+/* ACPI Timer prototypes */
+
+u32
+acpi_hw_pmt_ticks (
+ void);
+
+u32
+acpi_hw_pmt_resolution (
+ void);
+
+
+#endif /* __ACHWARE_H__ */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/acinterp.h linux/drivers/acpi/include/acinterp.h
--- v2.4.0-test8/linux/drivers/acpi/include/acinterp.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/include/acinterp.h Fri Sep 15 14:30:30 2000
@@ -0,0 +1,526 @@
+/******************************************************************************
+ *
+ * Name: acinterp.h - Interpreter subcomponent prototypes and defines
+ * $Revision: 79 $


+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 R. Byron Moore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+

+#ifndef __ACINTERP_H__
+#define __ACINTERP_H__
+
+
+#define WALK_OPERANDS &(walk_state->operands [walk_state->num_operands -1])
+
+
+/* Interpreter constants */
+
+#define AML_END_OF_BLOCK -1
+#define PUSH_PKG_LENGTH 1
+#define DO_NOT_PUSH_PKG_LENGTH 0
+
+
+#define STACK_TOP 0
+#define STACK_BOTTOM (u32) -1
+
+/* Constants for global "When_to_parse_methods" */
+
+#define METHOD_PARSE_AT_INIT 0x0
+#define METHOD_PARSE_JUST_IN_TIME 0x1
+#define METHOD_DELETE_AT_COMPLETION 0x2
+
+
+ACPI_STATUS
+acpi_aml_resolve_operands (
+ u16 opcode,
+ ACPI_OPERAND_OBJECT **stack_ptr,


+ ACPI_WALK_STATE *walk_state);
+
+
+/*

+ * amxface - External interpreter interfaces
+ */
+
+ACPI_STATUS
+acpi_aml_load_table (
+ ACPI_TABLE_TYPE table_id);
+
+ACPI_STATUS
+acpi_aml_execute_method (
+ ACPI_NAMESPACE_NODE *method_node,
+ ACPI_OPERAND_OBJECT **params,
+ ACPI_OPERAND_OBJECT **return_obj_desc);
+
+
+/*
+ * amfield - ACPI AML (p-code) execution - field manipulation
+ */
+
+
+ACPI_STATUS
+acpi_aml_read_field (
+ ACPI_OPERAND_OBJECT *obj_desc,
+ void *buffer,
+ u32 buffer_length,
+ u32 byte_length,
+ u32 datum_length,
+ u32 bit_granularity,
+ u32 byte_granularity);
+
+ACPI_STATUS
+acpi_aml_write_field (
+ ACPI_OPERAND_OBJECT *obj_desc,
+ void *buffer,
+ u32 buffer_length,
+ u32 byte_length,
+ u32 datum_length,
+ u32 bit_granularity,
+ u32 byte_granularity);
+
+ACPI_STATUS
+acpi_aml_setup_field (
+ ACPI_OPERAND_OBJECT *obj_desc,
+ ACPI_OPERAND_OBJECT *rgn_desc,
+ u32 field_bit_width);
+
+ACPI_STATUS
+acpi_aml_read_field_data (
+ ACPI_OPERAND_OBJECT *obj_desc,
+ u32 field_byte_offset,


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 024'
echo 'File patch-2.4.0-test9 is continued in part 025'
echo "025" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part025

#!/bin/sh -x
# this is part 025 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 025; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ u32 field_bit_width,
+ u32 *value);
+
+ACPI_STATUS
+acpi_aml_access_named_field (
+ u32 mode,
+ ACPI_HANDLE named_field,
+ void *buffer,
+ u32 length);
+
+/*
+ * ammisc - ACPI AML (p-code) execution - specific opcodes
+ */
+
+ACPI_STATUS
+acpi_aml_exec_create_field (
+ u16 opcode,
+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS
+acpi_aml_exec_reconfiguration (
+ u16 opcode,
+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS
+acpi_aml_exec_fatal (


+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS

+acpi_aml_exec_index (
+ ACPI_WALK_STATE *walk_state,
+ ACPI_OPERAND_OBJECT **return_desc);
+
+ACPI_STATUS
+acpi_aml_exec_match (
+ ACPI_WALK_STATE *walk_state,
+ ACPI_OPERAND_OBJECT **return_desc);
+
+ACPI_STATUS
+acpi_aml_exec_create_mutex (


+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS

+acpi_aml_exec_create_processor (
+ ACPI_PARSE_OBJECT *op,
+ ACPI_HANDLE processor_nTE);
+
+ACPI_STATUS
+acpi_aml_exec_create_power_resource (
+ ACPI_PARSE_OBJECT *op,
+ ACPI_HANDLE processor_nTE);
+
+ACPI_STATUS
+acpi_aml_exec_create_region (
+ u8 *aml_ptr,
+ u32 acpi_aml_length,
+ u32 region_space,


+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS

+acpi_aml_exec_create_event (


+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS

+acpi_aml_exec_create_alias (


+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS

+acpi_aml_exec_create_method (
+ u8 *aml_ptr,
+ u32 acpi_aml_length,
+ u32 method_flags,
+ ACPI_HANDLE method);
+
+
+/*
+ * amprep - ACPI AML (p-code) execution - prep utilities
+ */
+
+ACPI_STATUS
+acpi_aml_prep_def_field_value (
+ ACPI_NAMESPACE_NODE *node,
+ ACPI_HANDLE region,
+ u8 field_flags,
+ u8 field_attribute,
+ u32 field_position,
+ u32 field_length);
+
+ACPI_STATUS
+acpi_aml_prep_bank_field_value (
+ ACPI_NAMESPACE_NODE *node,
+ ACPI_HANDLE region,
+ ACPI_HANDLE bank_reg,
+ u32 bank_val,
+ u8 field_flags,
+ u8 field_attribute,
+ u32 field_position,
+ u32 field_length);
+
+ACPI_STATUS
+acpi_aml_prep_index_field_value (
+ ACPI_NAMESPACE_NODE *node,
+ ACPI_HANDLE index_reg,
+ ACPI_HANDLE data_reg,
+ u8 field_flags,
+ u8 field_attribute,
+ u32 field_position,
+ u32 field_length);
+
+
+/*
+ * amsystem - Interface to OS services
+ */
+
+u16
+acpi_aml_system_thread_id (
+ void);
+
+ACPI_STATUS
+acpi_aml_system_do_notify_op (
+ ACPI_OPERAND_OBJECT *value,
+ ACPI_OPERAND_OBJECT *obj_desc);
+
+void
+acpi_aml_system_do_suspend(
+ u32 time);
+
+void
+acpi_aml_system_do_stall (
+ u32 time);
+
+ACPI_STATUS
+acpi_aml_system_acquire_mutex(
+ ACPI_OPERAND_OBJECT *time,
+ ACPI_OPERAND_OBJECT *obj_desc);
+
+ACPI_STATUS
+acpi_aml_system_release_mutex(
+ ACPI_OPERAND_OBJECT *obj_desc);
+
+ACPI_STATUS
+acpi_aml_system_signal_event(
+ ACPI_OPERAND_OBJECT *obj_desc);
+
+ACPI_STATUS
+acpi_aml_system_wait_event(
+ ACPI_OPERAND_OBJECT *time,
+ ACPI_OPERAND_OBJECT *obj_desc);
+
+ACPI_STATUS
+acpi_aml_system_reset_event(
+ ACPI_OPERAND_OBJECT *obj_desc);
+
+ACPI_STATUS
+acpi_aml_system_wait_semaphore (
+ ACPI_HANDLE semaphore,
+ u32 timeout);
+
+
+/*
+ * ammonadic - ACPI AML (p-code) execution, monadic operators
+ */
+
+ACPI_STATUS
+acpi_aml_exec_monadic1 (
+ u16 opcode,
+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS
+acpi_aml_exec_monadic2 (
+ u16 opcode,
+ ACPI_WALK_STATE *walk_state,
+ ACPI_OPERAND_OBJECT **return_desc);
+
+ACPI_STATUS
+acpi_aml_exec_monadic2_r (
+ u16 opcode,
+ ACPI_WALK_STATE *walk_state,
+ ACPI_OPERAND_OBJECT **return_desc);
+
+
+/*
+ * amdyadic - ACPI AML (p-code) execution, dyadic operators
+ */
+
+ACPI_STATUS
+acpi_aml_exec_dyadic1 (
+ u16 opcode,
+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS
+acpi_aml_exec_dyadic2 (
+ u16 opcode,
+ ACPI_WALK_STATE *walk_state,
+ ACPI_OPERAND_OBJECT **return_desc);
+
+ACPI_STATUS
+acpi_aml_exec_dyadic2_r (
+ u16 opcode,
+ ACPI_WALK_STATE *walk_state,
+ ACPI_OPERAND_OBJECT **return_desc);
+
+ACPI_STATUS
+acpi_aml_exec_dyadic2_s (
+ u16 opcode,
+ ACPI_WALK_STATE *walk_state,
+ ACPI_OPERAND_OBJECT **return_desc);
+
+
+/*
+ * amresolv - Object resolution and get value functions
+ */
+
+ACPI_STATUS
+acpi_aml_resolve_to_value (


+ ACPI_OPERAND_OBJECT **stack_ptr,
+ ACPI_WALK_STATE *walk_state);
+

+ACPI_STATUS
+acpi_aml_resolve_node_to_value (
+ ACPI_NAMESPACE_NODE **stack_ptr);
+
+ACPI_STATUS
+acpi_aml_resolve_object_to_value (


+ ACPI_OPERAND_OBJECT **stack_ptr,
+ ACPI_WALK_STATE *walk_state);
+

+ACPI_STATUS
+acpi_aml_get_field_unit_value (
+ ACPI_OPERAND_OBJECT *field_desc,
+ ACPI_OPERAND_OBJECT *result_desc);
+
+
+/*
+ * amdump - Scanner debug output routines
+ */
+
+void
+acpi_aml_show_hex_value (
+ u32 byte_count,
+ u8 *aml_ptr,
+ u32 lead_space);
+
+
+ACPI_STATUS
+acpi_aml_dump_operand (
+ ACPI_OPERAND_OBJECT *entry_desc);
+
+void
+acpi_aml_dump_operands (
+ ACPI_OPERAND_OBJECT **operands,
+ OPERATING_MODE interpreter_mode,
+ NATIVE_CHAR *ident,
+ u32 num_levels,
+ NATIVE_CHAR *note,


+ NATIVE_CHAR *module_name,
+ u32 line_number);
+
+void

+acpi_aml_dump_object_descriptor (
+ ACPI_OPERAND_OBJECT *object,
+ u32 flags);
+
+
+void
+acpi_aml_dump_node (
+ ACPI_NAMESPACE_NODE *node,
+ u32 flags);
+
+
+/*
+ * amnames - interpreter/scanner name load/execute


+ */
+
+NATIVE_CHAR *

+acpi_aml_allocate_name_string (
+ u32 prefix_count,
+ u32 num_name_segs);
+
+u32
+acpi_aml_good_char (
+ u32 character);
+
+ACPI_STATUS
+acpi_aml_exec_name_segment (
+ u8 **in_aml_address,
+ NATIVE_CHAR *name_string);
+
+ACPI_STATUS
+acpi_aml_get_name_string (
+ OBJECT_TYPE_INTERNAL data_type,
+ u8 *in_aml_address,
+ NATIVE_CHAR **out_name_string,
+ u32 *out_name_length);
+
+ACPI_STATUS
+acpi_aml_do_name (
+ ACPI_OBJECT_TYPE data_type,
+ OPERATING_MODE load_exec_mode);
+
+
+/*
+ * amstore - Object store support
+ */
+
+ACPI_STATUS
+acpi_aml_exec_store (
+ ACPI_OPERAND_OBJECT *val_desc,
+ ACPI_OPERAND_OBJECT *dest_desc,


+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS

+acpi_aml_store_object_to_object (
+ ACPI_OPERAND_OBJECT *val_desc,
+ ACPI_OPERAND_OBJECT *dest_desc,


+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS

+acpi_aml_store_object_to_node (
+ ACPI_OPERAND_OBJECT *val_desc,
+ ACPI_NAMESPACE_NODE *node,


+ ACPI_WALK_STATE *walk_state);
+
+
+/*

+ * amutils - interpreter/scanner utilities
+ */
+
+void
+acpi_aml_enter_interpreter (
+ void);
+
+void
+acpi_aml_exit_interpreter (
+ void);
+
+u8
+acpi_aml_validate_object_type (
+ ACPI_OBJECT_TYPE type);
+
+u8
+acpi_aml_acquire_global_lock (
+ u32 rule);
+
+ACPI_STATUS
+acpi_aml_release_global_lock (
+ u8 locked);
+
+u32
+acpi_aml_buf_seq (
+ void);
+
+u32
+acpi_aml_digits_needed (
+ u32 value,
+ u32 base);
+
+ACPI_STATUS
+acpi_aml_eisa_id_to_string (
+ u32 numeric_id,
+ NATIVE_CHAR *out_string);
+
+ACPI_STATUS
+acpi_aml_build_copy_internal_package_object (
+ ACPI_OPERAND_OBJECT *source_obj,
+ ACPI_OPERAND_OBJECT *dest_obj,


+ ACPI_WALK_STATE *walk_state);
+
+
+/*

+ * amregion - default Op_region handlers
+ */
+
+ACPI_STATUS
+acpi_aml_system_memory_space_handler (


+ u32 function,
+ u32 address,
+ u32 bit_width,

+ u32 *value,
+ void *handler_context,
+ void *region_context);
+
+ACPI_STATUS
+acpi_aml_system_io_space_handler (


+ u32 function,
+ u32 address,
+ u32 bit_width,

+ u32 *value,
+ void *handler_context,
+ void *region_context);
+
+ACPI_STATUS
+acpi_aml_pci_config_space_handler (


+ u32 function,
+ u32 address,
+ u32 bit_width,

+ u32 *value,
+ void *handler_context,
+ void *region_context);
+
+ACPI_STATUS
+acpi_aml_embedded_controller_space_handler (


+ u32 function,
+ u32 address,
+ u32 bit_width,

+ u32 *value,
+ void *handler_context,
+ void *region_context);
+
+ACPI_STATUS
+acpi_aml_sm_bus_space_handler (


+ u32 function,
+ u32 address,
+ u32 bit_width,

+ u32 *value,
+ void *handler_context,
+ void *region_context);
+
+
+#endif /* __INTERP_H__ */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/aclocal.h linux/drivers/acpi/include/aclocal.h
--- v2.4.0-test8/linux/drivers/acpi/include/aclocal.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/include/aclocal.h Fri Sep 15 14:30:30 2000
@@ -0,0 +1,851 @@
+/******************************************************************************
+ *
+ * Name: aclocal.h - Internal data types used across the ACPI subsystem
+ * $Revision: 77 $


+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 R. Byron Moore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+

+#ifndef __ACLOCAL_H__
+#define __ACLOCAL_H__
+
+
+#define WAIT_FOREVER ((u32) -1)
+
+typedef void* ACPI_MUTEX;
+typedef u32 ACPI_MUTEX_HANDLE;
+
+
+/* Object descriptor types */
+
+#define ACPI_CACHED_OBJECT 0x11 /* ORed in when object is cached */
+#define ACPI_DESC_TYPE_STATE 0x22
+#define ACPI_DESC_TYPE_WALK 0x44
+#define ACPI_DESC_TYPE_PARSER 0x66
+#define ACPI_DESC_TYPE_INTERNAL 0x88
+#define ACPI_DESC_TYPE_NAMED 0xAA


+
+
+/*****************************************************************************
+ *

+ * Mutex typedefs and structs


+ *
+ ****************************************************************************/
+
+

+/*
+ * Predefined handles for the mutex objects used within the subsystem
+ * All mutex objects are automatically created by Acpi_cm_mutex_initialize.
+ * NOTE: any changes here must be reflected in the Acpi_gbl_Mutex_names table also!
+ */
+
+#define ACPI_MTX_HARDWARE 0
+#define ACPI_MTX_MEMORY 1
+#define ACPI_MTX_CACHES 2
+#define ACPI_MTX_TABLES 3
+#define ACPI_MTX_PARSER 4
+#define ACPI_MTX_DISPATCHER 5
+#define ACPI_MTX_INTERPRETER 6
+#define ACPI_MTX_EXECUTE 7
+#define ACPI_MTX_NAMESPACE 8
+#define ACPI_MTX_EVENTS 9
+#define ACPI_MTX_OP_REGIONS 10
+#define ACPI_MTX_DEBUG_CMD_READY 11
+#define ACPI_MTX_DEBUG_CMD_COMPLETE 12
+
+#define MAX_MTX 12
+#define NUM_MTX MAX_MTX+1
+
+
+#ifdef ACPI_DEBUG
+#ifdef DEFINE_ACPI_GLOBALS
+
+/* Names for the mutexes used in the subsystem */
+
+static NATIVE_CHAR *acpi_gbl_mutex_names[] =
+{
+ "ACPI_MTX_Hardware",
+ "ACPI_MTX_Memory",
+ "ACPI_MTX_Caches",
+ "ACPI_MTX_Tables",
+ "ACPI_MTX_Parser",
+ "ACPI_MTX_Dispatcher",
+ "ACPI_MTX_Interpreter",
+ "ACPI_MTX_Execute",
+ "ACPI_MTX_Namespace",
+ "ACPI_MTX_Events",
+ "ACPI_MTX_Op_regions",
+ "ACPI_MTX_Debug_cmd_ready",
+ "ACPI_MTX_Debug_cmd_complete"


+};
+
+#endif
+#endif
+

+
+/* Table for the global mutexes */
+
+typedef struct acpi_mutex_info
+{
+ ACPI_MUTEX mutex;
+ u32 use_count;
+ u8 locked;
+
+} ACPI_MUTEX_INFO;
+
+
+/* Lock flag parameter for various interfaces */
+
+#define ACPI_MTX_DO_NOT_LOCK 0
+#define ACPI_MTX_LOCK 1
+
+
+typedef u16 ACPI_OWNER_ID;
+#define OWNER_TYPE_TABLE 0x0
+#define OWNER_TYPE_METHOD 0x1
+#define FIRST_METHOD_ID 0x0000
+#define FIRST_TABLE_ID 0x8000
+
+/* TBD: [Restructure] get rid of the need for this! */
+
+#define TABLE_ID_DSDT (ACPI_OWNER_ID) 0xD1D1
+
+/*****************************************************************************
+ *
+ * Namespace typedefs and structs


+ *
+ ****************************************************************************/
+
+

+/* Operational modes of the AML interpreter/scanner */
+
+typedef enum
+{
+ IMODE_LOAD_PASS1 = 0x01,
+ IMODE_LOAD_PASS2 = 0x02,
+ IMODE_EXECUTE = 0x0E
+
+} OPERATING_MODE;
+
+
+/*
+ * The Node describes a named object that appears in the AML
+ * An Acpi_node is used to store Nodes.
+ *
+ * Data_type is used to differentiate between internal descriptors, and MUST
+ * be the first byte in this structure.
+ */
+
+typedef struct acpi_node
+{
+ u8 data_type;
+ u8 type; /* Type associated with this name */
+ u32 name; /* ACPI Name, always 4 chars per ACPI spec */
+ u16 owner_id;
+
+
+ void *object; /* Pointer to attached ACPI object (optional) */
+ struct acpi_node *child; /* first child */
+ struct acpi_node *peer; /* Next peer*/
+ u16 reference_count; /* Current count of references and children */
+ u8 flags;
+
+} ACPI_NAMESPACE_NODE;
+
+
+#define ENTRY_NOT_FOUND NULL
+
+
+/* Node flags */
+
+#define ANOBJ_AML_ATTACHMENT 0x1
+#define ANOBJ_END_OF_PEER_LIST 0x2
+
+
+/*
+ * ACPI Table Descriptor. One per ACPI table
+ */
+typedef struct acpi_table_desc
+{
+ struct acpi_table_desc *prev;
+ struct acpi_table_desc *next;
+ struct acpi_table_desc *installed_desc;
+ ACPI_TABLE_HEADER *pointer;
+ void *base_pointer;
+ u8 *aml_pointer;
+ u32 aml_length;
+ u32 length;
+ u32 count;
+ ACPI_OWNER_ID table_id;
+ u8 type;
+ u8 allocation;
+ u8 loaded_into_namespace;
+
+} ACPI_TABLE_DESC;
+
+
+typedef struct
+{
+ NATIVE_CHAR *search_for;
+ ACPI_HANDLE *list;
+ u32 *count;
+
+} FIND_CONTEXT;
+
+
+typedef struct
+{
+ ACPI_NAMESPACE_NODE *node;
+} NS_SEARCH_DATA;
+
+
+/*
+ * Predefined Namespace items
+ */
+#define ACPI_MAX_ADDRESS_SPACE 255
+#define ACPI_NUM_ADDRESS_SPACES 256
+
+
+typedef struct
+{
+ NATIVE_CHAR *name;
+ ACPI_OBJECT_TYPE type;
+ NATIVE_CHAR *val;
+
+} PREDEFINED_NAMES;


+
+
+/*****************************************************************************
+ *

+ * Event typedefs and structs


+ *
+ ****************************************************************************/
+
+

+/* Status bits. */
+
+#define ACPI_STATUS_PMTIMER 0x0001
+#define ACPI_STATUS_GLOBAL 0x0020
+#define ACPI_STATUS_POWER_BUTTON 0x0100
+#define ACPI_STATUS_SLEEP_BUTTON 0x0200
+#define ACPI_STATUS_RTC_ALARM 0x0400
+
+/* Enable bits. */
+
+#define ACPI_ENABLE_PMTIMER 0x0001
+#define ACPI_ENABLE_GLOBAL 0x0020
+#define ACPI_ENABLE_POWER_BUTTON 0x0100
+#define ACPI_ENABLE_SLEEP_BUTTON 0x0200
+#define ACPI_ENABLE_RTC_ALARM 0x0400
+
+
+/*
+ * Entry in the Address_space (AKA Operation Region) table
+ */
+
+typedef struct
+{
+ ADDRESS_SPACE_HANDLER handler;
+ void *context;
+
+} ACPI_ADDRESS_SPACE_INFO;
+
+
+/* Values and addresses of the GPE registers (both banks) */
+
+typedef struct
+{
+ u8 status; /* Current value of status reg */
+ u8 enable; /* Current value of enable reg */
+ u16 status_addr; /* Address of status reg */
+ u16 enable_addr; /* Address of enable reg */
+ u8 gpe_base; /* Base GPE number */
+
+} ACPI_GPE_REGISTERS;
+
+
+#define ACPI_GPE_LEVEL_TRIGGERED 1
+#define ACPI_GPE_EDGE_TRIGGERED 2
+
+
+/* Information about each particular GPE level */
+
+typedef struct
+{
+ u8 type; /* Level or Edge */
+
+ ACPI_HANDLE method_handle; /* Method handle for direct (fast) execution */
+ GPE_HANDLER handler; /* Address of handler, if any */
+ void *context; /* Context to be passed to handler */
+
+} ACPI_GPE_LEVEL_INFO;
+
+
+/* Information about each particular fixed event */
+
+typedef struct
+{
+ FIXED_EVENT_HANDLER handler; /* Address of handler. */
+ void *context; /* Context to be passed to handler */
+
+} ACPI_FIXED_EVENT_INFO;
+
+
+/* Information used during field processing */
+
+typedef struct
+{
+ u8 skip_field;
+ u8 field_flag;
+ u32 pkg_length;
+
+} ACPI_FIELD_INFO;


+
+
+/*****************************************************************************
+ *

+ * Generic "state" object for stacks


+ *
+ ****************************************************************************/
+
+

+#define CONTROL_NORMAL 0xC0
+#define CONTROL_CONDITIONAL_EXECUTING 0xC1
+#define CONTROL_PREDICATE_EXECUTING 0xC2
+#define CONTROL_PREDICATE_FALSE 0xC3
+#define CONTROL_PREDICATE_TRUE 0xC4
+
+
+/* Forward declaration */
+struct acpi_walk_state;
+struct acpi_parse_obj ;
+
+
+#define ACPI_STATE_COMMON /* Two 32-bit fields and a pointer */\
+ u8 data_type; /* To differentiate various internal objs */\
+ u8 flags; \
+ u16 value; \
+ u16 state; \
+ u16 acpi_eval; \
+ void *next; \
+
+typedef struct acpi_common_state
+{
+ ACPI_STATE_COMMON
+} ACPI_COMMON_STATE;
+
+
+/*
+ * Update state - used to traverse complex objects such as packages
+ */
+typedef struct acpi_update_state
+{
+ ACPI_STATE_COMMON
+ union acpi_operand_obj *object;
+
+} ACPI_UPDATE_STATE;
+
+/*
+ * Control state - one per if/else and while constructs.
+ * Allows nesting of these constructs
+ */
+typedef struct acpi_control_state
+{
+ ACPI_STATE_COMMON
+ struct acpi_parse_obj *predicate_op;
+ u8 *aml_predicate_start; /* Start of if/while predicate */
+
+} ACPI_CONTROL_STATE;
+
+
+/*
+ * Scope state - current scope during namespace lookups
+ */
+
+typedef struct acpi_scope_state
+{
+ ACPI_STATE_COMMON
+ ACPI_NAMESPACE_NODE *node;
+
+} ACPI_SCOPE_STATE;
+
+
+typedef struct acpi_pscope_state
+{
+ ACPI_STATE_COMMON
+ struct acpi_parse_obj *op; /* current op being parsed */
+ u8 *arg_end; /* current argument end */
+ u8 *pkg_end; /* current package end */
+ u32 arg_list; /* next argument to parse */
+ u32 arg_count; /* Number of fixed arguments */
+
+} ACPI_PSCOPE_STATE;
+
+
+typedef union acpi_gen_state
+{
+ ACPI_COMMON_STATE common;
+ ACPI_CONTROL_STATE control;
+ ACPI_UPDATE_STATE update;
+ ACPI_SCOPE_STATE scope;
+ ACPI_PSCOPE_STATE parse_scope;
+
+} ACPI_GENERIC_STATE;
+
+
+typedef
+ACPI_STATUS (*ACPI_PARSE_DOWNWARDS) (
+ u16 opcode,
+ struct acpi_parse_obj *op,
+ struct acpi_walk_state *walk_state,
+ struct acpi_parse_obj **out_op);
+
+typedef
+ACPI_STATUS (*ACPI_PARSE_UPWARDS) (
+ struct acpi_walk_state *walk_state,
+ struct acpi_parse_obj *op);


+
+
+/*****************************************************************************
+ *

+ * Parser typedefs and structs


+ *
+ ****************************************************************************/
+
+

+#define ACPI_OP_CLASS_MASK 0x1F
+#define ACPI_OP_ARGS_MASK 0x20
+#define ACPI_OP_TYPE_MASK 0xC0
+
+#define ACPI_OP_TYPE_OPCODE 0x00
+#define ACPI_OP_TYPE_ASCII 0x40
+#define ACPI_OP_TYPE_PREFIX 0x80
+#define ACPI_OP_TYPE_UNKNOWN 0xC0
+
+#define ACPI_GET_OP_CLASS(a) ((a)->flags & ACPI_OP_CLASS_MASK)
+#define ACPI_GET_OP_ARGS(a) ((a)->flags & ACPI_OP_ARGS_MASK)
+#define ACPI_GET_OP_TYPE(a) ((a)->flags & ACPI_OP_TYPE_MASK)
+
+
+/*
+ * AML opcode, name, and argument layout
+ */
+typedef struct acpi_opcode_info
+{
+ u8 flags; /* Opcode type, Has_args flag */
+ u32 parse_args; /* Grammar/Parse time arguments */
+ u32 runtime_args; /* Interpret time arguments */
+
+ DEBUG_ONLY_MEMBERS (
+ NATIVE_CHAR *name) /* op name (debug only) */
+
+} ACPI_OPCODE_INFO;
+
+
+typedef union acpi_parse_val
+{
+ u32 integer; /* integer constant */
+ u32 size; /* bytelist or field size */
+ NATIVE_CHAR *string; /* NULL terminated string */
+ u8 *buffer; /* buffer or string */
+ NATIVE_CHAR *name; /* NULL terminated string */
+ struct acpi_parse_obj *arg; /* arguments and contained ops */
+
+} ACPI_PARSE_VALUE;
+
+
+#define ACPI_PARSE_COMMON \
+ u8 data_type; /* To differentiate various internal objs */\
+ u8 flags; /* Type of Op */\
+ u16 opcode; /* AML opcode */\
+ u32 aml_offset; /* offset of declaration in AML */\
+ struct acpi_parse_obj *parent; /* parent op */\
+ struct acpi_parse_obj *next; /* next op */\
+ DEBUG_ONLY_MEMBERS (\
+ NATIVE_CHAR op_name[16]) /* op name (debug only) */\
+ /* NON-DEBUG members below: */\
+ ACPI_NAMESPACE_NODE *node;/* for use by interpreter */\
+ ACPI_PARSE_VALUE value; /* Value or args associated with the opcode */\
+
+
+/*
+ * generic operation (eg. If, While, Store)
+ */
+typedef struct acpi_parse_obj
+{
+ ACPI_PARSE_COMMON
+} ACPI_PARSE_OBJECT;
+
+
+/*
+ * Extended Op for named ops (Scope, Method, etc.), deferred ops (Methods and Op_regions),
+ * and bytelists.
+ */
+typedef struct acpi_parse2_obj
+{
+ ACPI_PARSE_COMMON
+ u8 *data; /* AML body or bytelist data */
+ u32 length; /* AML length */
+ u32 name; /* 4-byte name or zero if no name */
+
+} ACPI_PARSE2_OBJECT;
+
+
+/*
+ * Parse state - one state per parser invocation and each control
+ * method.
+ */
+
+typedef struct acpi_parse_state
+{
+ u8 *aml_start; /* first AML byte */
+ u8 *aml; /* next AML byte */
+ u8 *aml_end; /* (last + 1) AML byte */
+ u8 *pkg_start; /* current package begin */
+ u8 *pkg_end; /* current package end */
+ ACPI_PARSE_OBJECT *start_op; /* root of parse tree */
+ struct acpi_node *start_node;
+ ACPI_GENERIC_STATE *scope; /* current scope */
+ struct acpi_parse_state *next;
+
+} ACPI_PARSE_STATE;


+
+
+/*****************************************************************************
+ *

+ * Tree walking typedefs and structs


+ *
+ ****************************************************************************/
+
+

+/*
+ * Walk state - current state of a parse tree walk. Used for both a leisurely stroll through
+ * the tree (for whatever reason), and for control method execution.
+ */
+
+#define NEXT_OP_DOWNWARD 1
+#define NEXT_OP_UPWARD 2
+
+#define WALK_METHOD 1
+#define WALK_NON_METHOD 0
+
+typedef struct acpi_walk_state
+{
+ u8 data_type; /* To differentiate various internal objs */\
+ ACPI_OWNER_ID owner_id; /* Owner of objects created during the walk */
+ u8 last_predicate; /* Result of last predicate */
+ u8 next_op_info; /* Info about Next_op */
+ u8 num_operands; /* Stack pointer for Operands[] array */
+ u8 num_results; /* Stack pointer for Results[] array */
+ u8 current_result; /* */
+
+ struct acpi_walk_state *next; /* Next Walk_state in list */
+ ACPI_PARSE_OBJECT *origin; /* Start of walk */
+
+/* TBD: Obsolete with removal of WALK procedure ? */
+ ACPI_PARSE_OBJECT *prev_op; /* Last op that was processed */
+ ACPI_PARSE_OBJECT *next_op; /* next op to be processed */
+
+
+ ACPI_GENERIC_STATE *control_state; /* List of control states (nested IFs) */
+ ACPI_GENERIC_STATE *scope_info; /* Stack of nested scopes */
+ ACPI_PARSE_STATE *parser_state; /* Current state of parser */
+ u8 *aml_last_while;
+ ACPI_PARSE_DOWNWARDS descending_callback;
+ ACPI_PARSE_UPWARDS ascending_callback;
+
+ union acpi_operand_obj *return_desc; /* Return object, if any */
+ union acpi_operand_obj *method_desc; /* Method descriptor if running a method */
+ struct acpi_node *method_node; /* Method Node if running a method */
+ ACPI_PARSE_OBJECT *method_call_op; /* Method_call Op if running a method */
+ struct acpi_node *method_call_node; /* Called method Node*/
+ union acpi_operand_obj *operands[OBJ_NUM_OPERANDS]; /* Operands passed to the interpreter */
+ union acpi_operand_obj *results[OBJ_NUM_OPERANDS]; /* Accumulated results */
+ struct acpi_node arguments[MTH_NUM_ARGS]; /* Control method arguments */
+ struct acpi_node local_variables[MTH_NUM_LOCALS]; /* Control method locals */
+ u32 parse_flags;
+ u8 walk_type;
+ u8 return_used;
+ u32 prev_arg_types;
+
+ /* Debug support */
+
+ u32 method_breakpoint;
+
+
+} ACPI_WALK_STATE;
+
+
+/*
+ * Walk list - head of a tree of walk states. Multiple walk states are created when there
+ * are nested control methods executing.
+ */
+typedef struct acpi_walk_list
+{
+
+ ACPI_WALK_STATE *walk_state;
+
+} ACPI_WALK_LIST;
+
+
+/* Info used by Acpi_ps_init_objects */
+
+typedef struct init_walk_info
+{
+ u32 method_count;
+ u32 op_region_count;
+ ACPI_TABLE_DESC *table_desc;
+
+} INIT_WALK_INFO;
+
+
+/* TBD: [Restructure] Merge with struct above */
+
+typedef struct acpi_walk_info
+{
+ u32 debug_level;
+ u32 owner_id;
+
+} ACPI_WALK_INFO;


+
+
+/*****************************************************************************
+ *

+ * Hardware and PNP


+ *
+ ****************************************************************************/
+
+

+/* Sleep states */
+
+#define SLWA_DEBUG_LEVEL 4
+#define GTS_CALL 0
+#define GTS_WAKE 1
+
+/* Cx States */
+
+#define MAX_CX_STATE_LATENCY 0xFFFFFFFF
+#define MAX_CX_STATES 4
+
+/*
+ * The #define's and enum below establish an abstract way of identifying what
+ * register block and register is to be accessed. Do not change any of the
+ * values as they are used in switch statements and offset calculations.
+ */
+
+#define REGISTER_BLOCK_MASK 0xFF00
+#define BIT_IN_REGISTER_MASK 0x00FF
+#define PM1_EVT 0x0100
+#define PM1_CONTROL 0x0200
+#define PM2_CONTROL 0x0300
+#define PM_TIMER 0x0400
+#define PROCESSOR_BLOCK 0x0500
+#define GPE0_STS_BLOCK 0x0600
+#define GPE0_EN_BLOCK 0x0700
+#define GPE1_STS_BLOCK 0x0800
+#define GPE1_EN_BLOCK 0x0900
+
+enum
+{
+ /* PM1 status register ids */
+
+ TMR_STS = (PM1_EVT | 0x01),
+ BM_STS,
+ GBL_STS,
+ PWRBTN_STS,
+ SLPBTN_STS,
+ RTC_STS,
+ WAK_STS,
+
+ /* PM1 enable register ids */
+
+ TMR_EN,
+ /* need to skip 1 enable number since there's no bus master enable register */
+ GBL_EN = (PM1_EVT | 0x0A),
+ PWRBTN_EN,
+ SLPBTN_EN,
+ RTC_EN,
+
+ /* PM1 control register ids */
+
+ SCI_EN = (PM1_CONTROL | 0x01),
+ BM_RLD,
+ GBL_RLS,
+ SLP_TYPE_A,
+ SLP_TYPE_B,
+ SLP_EN,
+
+ /* PM2 control register ids */
+
+ ARB_DIS = (PM2_CONTROL | 0x01),
+
+ /* PM Timer register ids */
+
+ TMR_VAL = (PM_TIMER | 0x01),
+
+ GPE0_STS = (GPE0_STS_BLOCK | 0x01),
+ GPE0_EN = (GPE0_EN_BLOCK | 0x01),
+
+ GPE1_STS = (GPE1_STS_BLOCK | 0x01),
+ GPE1_EN = (GPE0_EN_BLOCK | 0x01),
+
+ /* Last register value is one less than LAST_REG */
+
+ LAST_REG
+};
+
+
+#define TMR_STS_MASK 0x0001
+#define BM_STS_MASK 0x0010
+#define GBL_STS_MASK 0x0020
+#define PWRBTN_STS_MASK 0x0100
+#define SLPBTN_STS_MASK 0x0200
+#define RTC_STS_MASK 0x0400
+#define WAK_STS_MASK 0x8000
+
+#define ALL_FIXED_STS_BITS (TMR_STS_MASK | BM_STS_MASK | GBL_STS_MASK | PWRBTN_STS_MASK | \
+ SLPBTN_STS_MASK | RTC_STS_MASK | WAK_STS_MASK)
+
+#define TMR_EN_MASK 0x0001
+#define GBL_EN_MASK 0x0020
+#define PWRBTN_EN_MASK 0x0100
+#define SLPBTN_EN_MASK 0x0200
+#define RTC_EN_MASK 0x0400
+
+#define SCI_EN_MASK 0x0001
+#define BM_RLD_MASK 0x0002
+#define GBL_RLS_MASK 0x0004
+#define SLP_TYPE_X_MASK 0x1C00
+#define SLP_EN_MASK 0x2000
+
+#define ARB_DIS_MASK 0x0001
+
+#define GPE0_STS_MASK
+#define GPE0_EN_MASK
+
+#define GPE1_STS_MASK
+#define GPE1_EN_MASK
+
+
+#define ACPI_READ 1
+#define ACPI_WRITE 2
+
+#define LOW_BYTE 0x00FF
+#define ONE_BYTE 0x08
+
+#ifndef SET
+ #define SET 1
+#endif
+#ifndef CLEAR
+ #define CLEAR 0
+#endif
+
+
+/* Plug and play */
+
+/* Pnp and ACPI data */
+
+#define VERSION_NO 0x01
+#define LOGICAL_DEVICE_ID 0x02
+#define COMPATIBLE_DEVICE_ID 0x03
+#define IRQ_FORMAT 0x04
+#define DMA_FORMAT 0x05
+#define START_DEPENDENT_TAG 0x06
+#define END_DEPENDENT_TAG 0x07
+#define IO_PORT_DESCRIPTOR 0x08
+#define FIXED_LOCATION_IO_DESCRIPTOR 0x09
+#define RESERVED_TYPE0 0x0A
+#define RESERVED_TYPE1 0x0B
+#define RESERVED_TYPE2 0x0C
+#define RESERVED_TYPE3 0x0D
+#define SMALL_VENDOR_DEFINED 0x0E
+#define END_TAG 0x0F
+
+/* Pnp and ACPI data */
+
+#define MEMORY_RANGE_24 0x81
+#define ISA_MEMORY_RANGE 0x81
+#define LARGE_VENDOR_DEFINED 0x84
+#define EISA_MEMORY_RANGE 0x85
+#define MEMORY_RANGE_32 0x85
+#define FIXED_EISA_MEMORY_RANGE 0x86
+#define FIXED_MEMORY_RANGE_32 0x86
+
+/* ACPI only data */
+
+#define DWORD_ADDRESS_SPACE 0x87
+#define WORD_ADDRESS_SPACE 0x88
+#define EXTENDED_IRQ 0x89
+
+/* MUST HAVES */
+
+
+typedef enum
+{
+ DWORD_DEVICE_ID,
+ STRING_PTR_DEVICE_ID,
+ STRING_DEVICE_ID
+
+} DEVICE_ID_TYPE;
+
+typedef struct
+{
+ DEVICE_ID_TYPE type;
+ union
+ {
+ u32 number;
+ NATIVE_CHAR *string_ptr;
+ NATIVE_CHAR buffer[9];
+ } data;
+
+} DEVICE_ID;


+
+
+/*****************************************************************************
+ *

+ * Debug


+ *
+ ****************************************************************************/
+
+

+/* Entry for a memory allocation (debug only) */
+
+#ifdef ACPI_DEBUG
+
+#define MEM_MALLOC 0
+#define MEM_CALLOC 1
+#define MAX_MODULE_NAME 16
+
+typedef struct allocation_info
+{
+ struct allocation_info *previous;
+ struct allocation_info *next;
+ void *address;
+ u32 size;
+ u32 component;
+ u32 line;
+ NATIVE_CHAR module[MAX_MODULE_NAME];
+ u8 alloc_type;
+
+} ALLOCATION_INFO;
+
+#endif
+
+#endif /* __ACLOCAL_H__ */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/acmacros.h linux/drivers/acpi/include/acmacros.h
--- v2.4.0-test8/linux/drivers/acpi/include/acmacros.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/include/acmacros.h Fri Sep 15 14:30:30 2000
@@ -0,0 +1,435 @@
+/******************************************************************************
+ *
+ * Name: acmacros.h - C macros for the entire subsystem.
+ * $Revision: 48 $


+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 R. Byron Moore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+

+#ifndef __ACMACROS_H__
+#define __ACMACROS_H__
+
+/*
+ * Data manipulation macros
+ */
+
+#ifndef LOWORD
+#define LOWORD(l) ((u16)(NATIVE_UINT)(l))
+#endif
+
+#ifndef HIWORD
+#define HIWORD(l) ((u16)((((NATIVE_UINT)(l)) >> 16) & 0xFFFF))
+#endif
+
+#ifndef LOBYTE
+#define LOBYTE(l) ((u8)(u16)(l))
+#endif
+
+#ifndef HIBYTE
+#define HIBYTE(l) ((u8)((((u16)(l)) >> 8) & 0xFF))
+#endif
+
+#define BIT0(x) ((((x) & 0x01) > 0) ? 1 : 0)
+#define BIT1(x) ((((x) & 0x02) > 0) ? 1 : 0)
+#define BIT2(x) ((((x) & 0x04) > 0) ? 1 : 0)
+
+#define BIT3(x) ((((x) & 0x08) > 0) ? 1 : 0)
+#define BIT4(x) ((((x) & 0x10) > 0) ? 1 : 0)
+#define BIT5(x) ((((x) & 0x20) > 0) ? 1 : 0)
+#define BIT6(x) ((((x) & 0x40) > 0) ? 1 : 0)
+#define BIT7(x) ((((x) & 0x80) > 0) ? 1 : 0)
+
+#define LOW_BASE(w) ((u16) ((w) & 0x0000FFFF))
+#define MID_BASE(b) ((u8) (((b) & 0x00FF0000) >> 16))
+#define HI_BASE(b) ((u8) (((b) & 0xFF000000) >> 24))
+#define LOW_LIMIT(w) ((u16) ((w) & 0x0000FFFF))
+#define HI_LIMIT(b) ((u8) (((b) & 0x00FF0000) >> 16))
+
+
+ /*
+ * Extract a byte of data using a pointer. Any more than a byte and we
+ * get into potential aligment issues -- see the STORE macros below
+ */
+#define GET8(addr) (*(u8*)(addr))
+
+
+/*
+ * Macros for moving data around to/from buffers that are possibly unaligned.
+ * If the hardware supports the transfer of unaligned data, just do the store.
+ * Otherwise, we have to move one byte at a time.
+ */
+
+#ifdef _HW_ALIGNMENT_SUPPORT
+
+/* The hardware supports unaligned transfers, just do the move */
+
+#define MOVE_UNALIGNED16_TO_16(d,s) *(u16*)(d) = *(u16*)(s)
+#define MOVE_UNALIGNED32_TO_32(d,s) *(u32*)(d) = *(u32*)(s)
+#define MOVE_UNALIGNED16_TO_32(d,s) *(u32*)(d) = *(u16*)(s)
+
+#else
+/*
+ * The hardware does not support unaligned transfers. We must move the
+ * data one byte at a time. These macros work whether the source or
+ * the destination (or both) is/are unaligned.
+ */
+
+#define MOVE_UNALIGNED16_TO_16(d,s) {((u8 *)(d))[0] = ((u8 *)(s))[0];\
+ ((u8 *)(d))[1] = ((u8 *)(s))[1];}
+
+#define MOVE_UNALIGNED32_TO_32(d,s) {((u8 *)(d))[0] = ((u8 *)(s))[0];\
+ ((u8 *)(d))[1] = ((u8 *)(s))[1];\
+ ((u8 *)(d))[2] = ((u8 *)(s))[2];\
+ ((u8 *)(d))[3] = ((u8 *)(s))[3];}
+
+#define MOVE_UNALIGNED16_TO_32(d,s) {(*(u32*)(d)) = 0; MOVE_UNALIGNED16_TO_16(d,s);}
+
+#endif
+
+
+/*
+ * Fast power-of-two math macros for non-optimized compilers
+ */
+
+#define _DIV(value,power_of2) ((u32) ((value) >> (power_of2)))
+#define _MUL(value,power_of2) ((u32) ((value) << (power_of2)))
+#define _MOD(value,divisor) ((u32) ((value) & ((divisor) -1)))
+
+#define DIV_2(a) _DIV(a,1)
+#define MUL_2(a) _MUL(a,1)
+#define MOD_2(a) _MOD(a,2)
+
+#define DIV_4(a) _DIV(a,2)
+#define MUL_4(a) _MUL(a,2)
+#define MOD_4(a) _MOD(a,4)
+
+#define DIV_8(a) _DIV(a,3)
+#define MUL_8(a) _MUL(a,3)
+#define MOD_8(a) _MOD(a,8)
+
+#define DIV_16(a) _DIV(a,4)
+#define MUL_16(a) _MUL(a,4)
+#define MOD_16(a) _MOD(a,16)
+
+
+/*
+ * Rounding macros (Power of two boundaries only)
+ */
+
+#define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1)))
+#define ROUND_UP(value,boundary) (((value) + ((boundary)-1)) & (~((boundary)-1)))
+
+#define ROUND_DOWN_TO_32_BITS(a) ROUND_DOWN(a,4)
+#define ROUND_DOWN_TO_NATIVE_WORD(a) ROUND_DOWN(a,ALIGNED_ADDRESS_BOUNDARY)
+
+#define ROUND_UP_TO_32_bITS(a) ROUND_UP(a,4)
+#define ROUND_UP_TO_NATIVE_WORD(a) ROUND_UP(a,ALIGNED_ADDRESS_BOUNDARY)
+
+
+#ifdef DEBUG_ASSERT
+#undef DEBUG_ASSERT
+#endif
+
+
+/*
+ * An ACPI_HANDLE (which is actually an ACPI_NAMESPACE_NODE *) can appear in some contexts,
+ * such as on ap_obj_stack, where a pointer to an ACPI_OPERAND_OBJECT can also
+ * appear. This macro is used to distinguish them.
+ *
+ * The Data_type field is the first field in both structures.
+ */
+
+#define VALID_DESCRIPTOR_TYPE(d,t) (((ACPI_NAMESPACE_NODE *)d)->data_type == t)
+
+
+/* Macro to test the object type */
+
+#define IS_THIS_OBJECT_TYPE(d,t) (((ACPI_OPERAND_OBJECT *)d)->common.type == (u8)t)
+
+/* Macro to check the table flags for SINGLE or MULTIPLE tables are allowed */
+
+#define IS_SINGLE_TABLE(x) (((x) & 0x01) == ACPI_TABLE_SINGLE ? 1 : 0)
+
+/*
+ * Macro to check if a pointer is within an ACPI table.
+ * Parameter (a) is the pointer to check. Parameter (b) must be defined
+ * as a pointer to an ACPI_TABLE_HEADER. (b+1) then points past the header,
+ * and ((u8 *)b+b->Length) points one byte past the end of the table.
+ */
+
+#ifndef _IA16
+#define IS_IN_ACPI_TABLE(a,b) (((u8 *)(a) >= (u8 *)(b + 1)) &&\
+ ((u8 *)(a) < ((u8 *)b + b->length)))
+
+#else
+#define IS_IN_ACPI_TABLE(a,b) (_segment)(a) == (_segment)(b) &&\
+ (((u8 *)(a) >= (u8 *)(b + 1)) &&\
+ ((u8 *)(a) < ((u8 *)b + b->length)))
+#endif
+
+/*
+ * Macros for the master AML opcode table
+ */
+
+#ifdef ACPI_DEBUG
+#define OP_INFO_ENTRY(flags,name,Pargs,Iargs) {flags,Pargs,Iargs,name}
+#else
+#define OP_INFO_ENTRY(flags,name,Pargs,Iargs) {flags,Pargs,Iargs}
+#endif
+
+#define ARG_TYPE_WIDTH 5
+#define ARG_1(x) ((u32)(x))
+#define ARG_2(x) ((u32)(x) << (1 * ARG_TYPE_WIDTH))
+#define ARG_3(x) ((u32)(x) << (2 * ARG_TYPE_WIDTH))
+#define ARG_4(x) ((u32)(x) << (3 * ARG_TYPE_WIDTH))
+#define ARG_5(x) ((u32)(x) << (4 * ARG_TYPE_WIDTH))
+#define ARG_6(x) ((u32)(x) << (5 * ARG_TYPE_WIDTH))
+
+#define ARGI_LIST1(a) (ARG_1(a))
+#define ARGI_LIST2(a,b) (ARG_1(b)|ARG_2(a))
+#define ARGI_LIST3(a,b,c) (ARG_1(c)|ARG_2(b)|ARG_3(a))
+#define ARGI_LIST4(a,b,c,d) (ARG_1(d)|ARG_2(c)|ARG_3(b)|ARG_4(a))
+#define ARGI_LIST5(a,b,c,d,e) (ARG_1(e)|ARG_2(d)|ARG_3(c)|ARG_4(b)|ARG_5(a))
+#define ARGI_LIST6(a,b,c,d,e,f) (ARG_1(f)|ARG_2(e)|ARG_3(d)|ARG_4(c)|ARG_5(b)|ARG_6(a))
+
+#define ARGP_LIST1(a) (ARG_1(a))
+#define ARGP_LIST2(a,b) (ARG_1(a)|ARG_2(b))
+#define ARGP_LIST3(a,b,c) (ARG_1(a)|ARG_2(b)|ARG_3(c))
+#define ARGP_LIST4(a,b,c,d) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d))
+#define ARGP_LIST5(a,b,c,d,e) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e))
+#define ARGP_LIST6(a,b,c,d,e,f) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e)|ARG_6(f))
+
+#define GET_CURRENT_ARG_TYPE(list) (list & 0x1F)
+#define INCREMENT_ARG_LIST(list) (list >>= ARG_TYPE_WIDTH)
+
+
+/*
+ * Reporting macros that are never compiled out
+ */
+
+/*
+ * Error reporting. These versions add callers module and line#. Since
+ * _THIS_MODULE gets compiled out when ACPI_DEBUG isn't defined, only
+ * use it in debug mode.
+ */
+
+#ifdef ACPI_DEBUG
+
+#define REPORT_INFO(a) _report_info(_THIS_MODULE,__LINE__,_COMPONENT,a)
+#define REPORT_ERROR(a) _report_error(_THIS_MODULE,__LINE__,_COMPONENT,a)
+#define REPORT_WARNING(a) _report_warning(_THIS_MODULE,__LINE__,_COMPONENT,a)
+
+#else
+
+#define REPORT_INFO(a) _report_info("",__LINE__,_COMPONENT,a)
+#define REPORT_ERROR(a) _report_error("",__LINE__,_COMPONENT,a)
+#define REPORT_WARNING(a) _report_warning("",__LINE__,_COMPONENT,a)
+
+#endif
+
+/* Error reporting. These versions pass thru the module and line# */
+
+#define _REPORT_INFO(a,b,c,d) _report_info(a,b,c,d)
+#define _REPORT_ERROR(a,b,c,d) _report_error(a,b,c,d)
+#define _REPORT_WARNING(a,b,c,d) _report_warning(a,b,c,d)
+
+/* Buffer dump macros */
+
+#define DUMP_BUFFER(a,b) acpi_cm_dump_buffer((u8 *)a,b,DB_BYTE_DISPLAY,_COMPONENT)
+
+/*
+ * Debug macros that are conditionally compiled
+ */
+
+#ifdef ACPI_DEBUG
+
+#define MODULE_NAME(name) static char *_THIS_MODULE = name;
+
+/*
+ * Function entry tracing.
+ * The first parameter should be the procedure name as a quoted string. This is declared
+ * as a local string ("_Proc_name) so that it can be also used by the function exit macros below.
+ */
+
+#define FUNCTION_TRACE(a) char * _proc_name = a;\
+ function_trace(_THIS_MODULE,__LINE__,_COMPONENT,a)
+#define FUNCTION_TRACE_PTR(a,b) char * _proc_name = a;\
+ function_trace_ptr(_THIS_MODULE,__LINE__,_COMPONENT,a,(void *)b)
+#define FUNCTION_TRACE_U32(a,b) char * _proc_name = a;\
+ function_trace_u32(_THIS_MODULE,__LINE__,_COMPONENT,a,(u32)b)
+#define FUNCTION_TRACE_STR(a,b) char * _proc_name = a;\
+ function_trace_str(_THIS_MODULE,__LINE__,_COMPONENT,a,(NATIVE_CHAR *)b)
+/*
+ * Function exit tracing.
+ * WARNING: These macros include a return statement. This is usually considered
+ * bad form, but having a separate exit macro is very ugly and difficult to maintain.
+ * One of the FUNCTION_TRACE macros above must be used in conjunction with these macros
+ * so that "_Proc_name" is defined.
+ */
+#define return_VOID {function_exit(_THIS_MODULE,__LINE__,_COMPONENT,_proc_name);return;}
+#define return_ACPI_STATUS(s) {function_status_exit(_THIS_MODULE,__LINE__,_COMPONENT,_proc_name,s);return(s);}
+#define return_VALUE(s) {function_value_exit(_THIS_MODULE,__LINE__,_COMPONENT,_proc_name,(NATIVE_UINT)s);return(s);}
+#define return_PTR(s) {function_ptr_exit(_THIS_MODULE,__LINE__,_COMPONENT,_proc_name,(u8 *)s);return(s);}
+
+
+/* Conditional execution */
+
+#define DEBUG_EXEC(a) a;
+#define NORMAL_EXEC(a)
+
+#define DEBUG_DEFINE(a) a;
+#define DEBUG_ONLY_MEMBERS(a) a;
+
+
+/* Stack and buffer dumping */
+
+#define DUMP_STACK_ENTRY(a) acpi_aml_dump_operand(a)
+#define DUMP_OPERANDS(a,b,c,d,e) acpi_aml_dump_operands(a,b,c,d,e,_THIS_MODULE,__LINE__)
+
+
+#define DUMP_ENTRY(a,b) acpi_ns_dump_entry (a,b)
+#define DUMP_TABLES(a,b) acpi_ns_dump_tables(a,b)
+#define DUMP_PATHNAME(a,b,c,d) acpi_ns_dump_pathname(a,b,c,d)
+#define DUMP_RESOURCE_LIST(a) acpi_rs_dump_resource_list(a)
+#define BREAK_MSG(a) acpi_os_breakpoint (a)
+
+/*
+ * Generate INT3 on ACPI_ERROR (Debug only!)
+ */
+
+#define ERROR_BREAK
+#ifdef ERROR_BREAK
+#define BREAK_ON_ERROR(lvl) if ((lvl)&ACPI_ERROR) acpi_os_breakpoint("Fatal error encountered\n")
+#else
+#define BREAK_ON_ERROR(lvl)
+#endif
+
+/*
+ * Master debug print macros
+ * Print iff:
+ * 1) Debug print for the current component is enabled
+ * 2) Debug error level or trace level for the print statement is enabled


+ *
+ */
+

+#define PARAM_LIST(pl) pl
+
+#define TEST_DEBUG_SWITCH(lvl) if (((lvl) & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer))
+
+#define DEBUG_PRINT(lvl,fp) TEST_DEBUG_SWITCH(lvl) {\
+ debug_print_prefix (_THIS_MODULE,__LINE__);\
+ debug_print_raw PARAM_LIST(fp);\
+ BREAK_ON_ERROR(lvl);}
+
+#define DEBUG_PRINT_RAW(lvl,fp) TEST_DEBUG_SWITCH(lvl) {\
+ debug_print_raw PARAM_LIST(fp);}
+
+
+/* Assert macros */
+
+#define ACPI_ASSERT(exp) if(!(exp)) \
+ acpi_os_dbg_assert(#exp, __FILE__, __LINE__, "Failed Assertion")
+
+#define DEBUG_ASSERT(msg, exp) if(!(exp)) \
+ acpi_os_dbg_assert(#exp, __FILE__, __LINE__, msg)
+
+
+#else
+/*
+ * This is the non-debug case -- make everything go away,
+ * leaving no executable debug code!
+ */
+
+#define MODULE_NAME(name)
+#define _THIS_MODULE ""
+
+#define DEBUG_EXEC(a)
+#define NORMAL_EXEC(a) a;
+
+#define DEBUG_DEFINE(a)
+#define DEBUG_ONLY_MEMBERS(a)
+#define FUNCTION_TRACE(a)
+#define FUNCTION_TRACE_PTR(a,b)
+#define FUNCTION_TRACE_U32(a,b)
+#define FUNCTION_TRACE_STR(a,b)
+#define FUNCTION_EXIT
+#define FUNCTION_STATUS_EXIT(s)
+#define FUNCTION_VALUE_EXIT(s)
+#define DUMP_STACK_ENTRY(a)
+#define DUMP_OPERANDS(a,b,c,d,e)
+#define DUMP_ENTRY(a,b)
+#define DUMP_TABLES(a,b)
+#define DUMP_PATHNAME(a,b,c,d)
+#define DUMP_RESOURCE_LIST(a)
+#define DEBUG_PRINT(l,f)
+#define DEBUG_PRINT_RAW(l,f)
+#define BREAK_MSG(a)
+
+#define return_VOID return
+#define return_ACPI_STATUS(s) return(s)
+#define return_VALUE(s) return(s)
+#define return_PTR(s) return(s)
+
+#define ACPI_ASSERT(exp)
+#define DEBUG_ASSERT(msg, exp)
+
+#endif
+
+/*
+ * Some code only gets executed when the debugger is built in.
+ * Note that this is entirely independent of whether the
+ * DEBUG_PRINT stuff (set by ACPI_DEBUG) is on, or not.
+ */
+#ifdef ENABLE_DEBUGGER
+#define DEBUGGER_EXEC(a) a;
+#else
+#define DEBUGGER_EXEC(a)
+#endif
+
+
+/*
+ * For 16-bit code, we want to shrink some things even though
+ * we are using ACPI_DEBUG to get the debug output
+ */
+#ifdef _IA16
+#undef DEBUG_ONLY_MEMBERS
+#define DEBUG_ONLY_MEMBERS(a)
+#undef OP_INFO_ENTRY
+#define OP_INFO_ENTRY(opcode,flags,name,Pargs,Iargs) {opcode,flags,Pargs,Iargs}
+#endif
+
+
+#ifdef ACPI_DEBUG
+
+/*
+ * 1) Set name to blanks
+ * 2) Copy the object name
+ */
+
+#define ADD_OBJECT_NAME(a,b) MEMSET (a->common.name, ' ', sizeof (a->common.name));\
+ STRNCPY (a->common.name, acpi_gbl_ns_type_names[b], sizeof (a->common.name))
+
+#else
+
+#define ADD_OBJECT_NAME(a,b)
+
+#endif
+
+#endif /* ACMACROS_H */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/acnamesp.h linux/drivers/acpi/include/acnamesp.h
--- v2.4.0-test8/linux/drivers/acpi/include/acnamesp.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/include/acnamesp.h Fri Sep 15 14:30:30 2000
@@ -0,0 +1,393 @@
+/******************************************************************************
+ *
+ * Name: acnamesp.h - Namespace subcomponent prototypes and defines
+ * $Revision: 94 $


+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 R. Byron Moore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+

+#ifndef __ACNAMESP_H__
+#define __ACNAMESP_H__
+
+
+/* To search the entire name space, pass this as Search_base */
+
+#define NS_ALL ((ACPI_HANDLE)0)
+
+/*
+ * Elements of Acpi_ns_properties are bit significant
+ * and should be one-to-one with values of ACPI_OBJECT_TYPE
+ */
+#define NSP_NORMAL 0
+#define NSP_NEWSCOPE 1 /* a definition of this type opens a name scope */
+#define NSP_LOCAL 2 /* suppress search of enclosing scopes */
+
+
+/* Definitions of the predefined namespace names */
+
+#define ACPI_UNKNOWN_NAME (u32) 0x3F3F3F3F /* Unknown name is "????" */
+#define ACPI_ROOT_NAME (u32) 0x2F202020 /* Root name is "/ " */
+#define ACPI_SYS_BUS_NAME (u32) 0x5F53425F /* Sys bus name is "_SB_" */
+
+#define NS_ROOT_PATH "/"
+#define NS_SYSTEM_BUS "_SB_"
+
+
+/* Flags for Acpi_ns_lookup, Acpi_ns_search_and_enter */
+
+#define NS_NO_UPSEARCH 0
+#define NS_SEARCH_PARENT 0x01
+#define NS_DONT_OPEN_SCOPE 0x02
+#define NS_NO_PEER_SEARCH 0x04
+
+#define NS_WALK_UNLOCK TRUE
+#define NS_WALK_NO_UNLOCK FALSE
+
+
+ACPI_STATUS
+acpi_ns_walk_namespace (
+ OBJECT_TYPE_INTERNAL type,
+ ACPI_HANDLE start_object,
+ u32 max_depth,
+ u8 unlock_before_callback,
+ WALK_CALLBACK user_function,


+ void *context,
+ void **return_value);
+
+

+ACPI_NAMESPACE_NODE *
+acpi_ns_get_next_object (
+ OBJECT_TYPE_INTERNAL type,
+ ACPI_NAMESPACE_NODE *parent,
+ ACPI_NAMESPACE_NODE *child);
+
+
+ACPI_STATUS
+acpi_ns_delete_namespace_by_owner (
+ u16 table_id);
+
+
+/* Namespace loading - nsload */
+
+ACPI_STATUS
+acpi_ns_parse_table (
+ ACPI_TABLE_DESC *table_desc,
+ ACPI_NAMESPACE_NODE *scope);
+
+ACPI_STATUS
+acpi_ns_load_table (
+ ACPI_TABLE_DESC *table_desc,
+ ACPI_NAMESPACE_NODE *node);
+
+ACPI_STATUS
+acpi_ns_load_table_by_type (
+ ACPI_TABLE_TYPE table_type);
+
+
+/*
+ * Top-level namespace access - nsaccess


+ */
+
+
+ACPI_STATUS

+acpi_ns_root_initialize (
+ void);
+
+ACPI_STATUS
+acpi_ns_lookup (
+ ACPI_GENERIC_STATE *scope_info,
+ NATIVE_CHAR *name,
+ OBJECT_TYPE_INTERNAL type,
+ OPERATING_MODE interpreter_mode,
+ u32 flags,
+ ACPI_WALK_STATE *walk_state,
+ ACPI_NAMESPACE_NODE **ret_node);
+
+
+/*
+ * Named object allocation/deallocation - nsalloc
+ */
+
+
+ACPI_NAMESPACE_NODE *
+acpi_ns_create_node (
+ u32 acpi_name);
+
+void
+acpi_ns_delete_node (
+ ACPI_NAMESPACE_NODE *node);
+
+ACPI_STATUS
+acpi_ns_delete_namespace_subtree (
+ ACPI_NAMESPACE_NODE *parent_handle);
+
+void
+acpi_ns_detach_object (
+ ACPI_NAMESPACE_NODE *node);
+
+void
+acpi_ns_delete_children (
+ ACPI_NAMESPACE_NODE *parent);
+
+
+/*
+ * Namespace modification - nsmodify
+ */
+
+ACPI_STATUS
+acpi_ns_unload_namespace (
+ ACPI_HANDLE handle);
+
+ACPI_STATUS
+acpi_ns_delete_subtree (
+ ACPI_HANDLE start_handle);
+
+
+/*
+ * Namespace dump/print utilities - nsdump
+ */
+
+void
+acpi_ns_dump_tables (
+ ACPI_HANDLE search_base,
+ u32 max_depth);
+
+void
+acpi_ns_dump_entry (
+ ACPI_HANDLE handle,
+ u32 debug_level);
+
+ACPI_STATUS
+acpi_ns_dump_pathname (
+ ACPI_HANDLE handle,
+ NATIVE_CHAR *msg,
+ u32 level,
+ u32 component);
+
+void
+acpi_ns_dump_root_devices (
+ void);
+
+void
+acpi_ns_dump_objects (
+ OBJECT_TYPE_INTERNAL type,
+ u32 max_depth,
+ u32 ownder_id,
+ ACPI_HANDLE start_handle);
+
+
+/*
+ * Namespace evaluation functions - nseval
+ */
+
+ACPI_STATUS
+acpi_ns_evaluate_by_handle (
+ ACPI_NAMESPACE_NODE *prefix_node,
+ ACPI_OPERAND_OBJECT **params,
+ ACPI_OPERAND_OBJECT **return_object);
+
+ACPI_STATUS
+acpi_ns_evaluate_by_name (
+ NATIVE_CHAR *pathname,
+ ACPI_OPERAND_OBJECT **params,
+ ACPI_OPERAND_OBJECT **return_object);
+
+ACPI_STATUS
+acpi_ns_evaluate_relative (
+ ACPI_NAMESPACE_NODE *prefix_node,
+ NATIVE_CHAR *pathname,
+ ACPI_OPERAND_OBJECT **params,
+ ACPI_OPERAND_OBJECT **return_object);
+
+ACPI_STATUS
+acpi_ns_execute_control_method (


+ ACPI_NAMESPACE_NODE *method_node,
+ ACPI_OPERAND_OBJECT **params,
+ ACPI_OPERAND_OBJECT **return_obj_desc);
+

+ACPI_STATUS
+acpi_ns_get_object_value (
+ ACPI_NAMESPACE_NODE *object_node,


+ ACPI_OPERAND_OBJECT **return_obj_desc);
+
+
+/*

+ * Parent/Child/Peer utility functions - nsfamily
+ */
+
+ACPI_NAME
+acpi_ns_find_parent_name (
+ ACPI_NAMESPACE_NODE *node_to_search);
+
+u8
+acpi_ns_exist_downstream_sibling (
+ ACPI_NAMESPACE_NODE *this_node);
+
+
+/*
+ * Scope manipulation - nsscope
+ */
+
+u32
+acpi_ns_opens_scope (
+ OBJECT_TYPE_INTERNAL type);
+
+NATIVE_CHAR *
+acpi_ns_get_table_pathname (
+ ACPI_NAMESPACE_NODE *node);
+
+NATIVE_CHAR *
+acpi_ns_name_of_current_scope (


+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS

+acpi_ns_handle_to_pathname (
+ ACPI_HANDLE obj_handle,
+ u32 *buf_size,
+ NATIVE_CHAR *user_buffer);
+
+u8
+acpi_ns_pattern_match (
+ ACPI_NAMESPACE_NODE *obj_node,
+ NATIVE_CHAR *search_for);
+
+ACPI_STATUS
+acpi_ns_name_compare (


+ ACPI_HANDLE obj_handle,
+ u32 level,
+ void *context,
+ void **return_value);
+
+ACPI_STATUS

+acpi_ns_get_node (
+ NATIVE_CHAR *pathname,
+ ACPI_NAMESPACE_NODE *in_prefix_node,
+ ACPI_NAMESPACE_NODE **out_node);
+
+/*
+ * Object management for NTEs - nsobject
+ */
+
+ACPI_STATUS
+acpi_ns_attach_object (
+ ACPI_NAMESPACE_NODE *node,
+ ACPI_OPERAND_OBJECT *object,


+ OBJECT_TYPE_INTERNAL type);
+
+

+void *
+acpi_ns_compare_value (


+ ACPI_HANDLE obj_handle,
+ u32 level,

+ void *obj_desc);
+
+
+/*
+ * Namespace searching and entry - nssearch
+ */
+
+ACPI_STATUS
+acpi_ns_search_and_enter (
+ u32 entry_name,


+ ACPI_WALK_STATE *walk_state,
+ ACPI_NAMESPACE_NODE *node,

+ OPERATING_MODE interpreter_mode,
+ OBJECT_TYPE_INTERNAL type,
+ u32 flags,
+ ACPI_NAMESPACE_NODE **ret_node);
+
+ACPI_STATUS
+acpi_ns_search_node (
+ u32 entry_name,


+ ACPI_NAMESPACE_NODE *node,
+ OBJECT_TYPE_INTERNAL type,

SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 025'
echo 'File patch-2.4.0-test9 is continued in part 026'
echo "026" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part026

#!/bin/sh -x
# this is part 026 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 026; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ ACPI_NAMESPACE_NODE **ret_node);


+
+ACPI_NAMESPACE_NODE *
+acpi_ns_create_node (
+ u32 acpi_name);
+
+void

+acpi_ns_install_node (
+ ACPI_WALK_STATE *walk_state,
+ ACPI_NAMESPACE_NODE *parent_node, /* Parent */
+ ACPI_NAMESPACE_NODE *node, /* New Child*/


+ OBJECT_TYPE_INTERNAL type);
+
+

+/*
+ * Utility functions - nsutils
+ */
+
+u8
+acpi_ns_valid_root_prefix (
+ NATIVE_CHAR prefix);
+
+u8
+acpi_ns_valid_path_separator (
+ NATIVE_CHAR sep);
+
+OBJECT_TYPE_INTERNAL
+acpi_ns_get_type (
+ ACPI_HANDLE obj_handle);
+
+void *
+acpi_ns_get_attached_object (
+ ACPI_HANDLE obj_handle);
+
+u32
+acpi_ns_local (
+ OBJECT_TYPE_INTERNAL type);
+
+ACPI_STATUS
+acpi_ns_internalize_name (
+ NATIVE_CHAR *dotted_name,
+ NATIVE_CHAR **converted_name);
+
+ACPI_STATUS
+acpi_ns_externalize_name (
+ u32 internal_name_length,
+ NATIVE_CHAR *internal_name,
+ u32 *converted_name_length,
+ NATIVE_CHAR **converted_name);
+
+ACPI_NAMESPACE_NODE *
+acpi_ns_convert_handle_to_entry (
+ ACPI_HANDLE handle);
+
+ACPI_HANDLE
+acpi_ns_convert_entry_to_handle(


+ ACPI_NAMESPACE_NODE *node);
+
+void

+acpi_ns_terminate (
+ void);
+
+ACPI_NAMESPACE_NODE *
+acpi_ns_get_parent_object (


+ ACPI_NAMESPACE_NODE *node);
+
+

+ACPI_NAMESPACE_NODE *
+acpi_ns_get_next_valid_object (


+ ACPI_NAMESPACE_NODE *node);
+
+

+#endif /* __ACNAMESP_H__ */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/acobject.h linux/drivers/acpi/include/acobject.h
--- v2.4.0-test8/linux/drivers/acpi/include/acobject.h Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/include/acobject.h Fri Sep 15 14:30:30 2000
@@ -1,7 +1,8 @@
X
X /******************************************************************************
X *
- * Name: acobject.h - Definition of ACPI_OBJECT_INTERNAL (Internal object only)
+ * Name: acobject.h - Definition of ACPI_OPERAND_OBJECT (Internal object only)
+ * $Revision: 71 $


X *
X *****************************************************************************/
X

@@ -26,17 +27,14 @@
X #ifndef _ACOBJECT_H
X #define _ACOBJECT_H
X
-#include "actypes.h"
-#include "macros.h"
-#include "internal.h"
X
X /*
- * The ACPI_OBJECT_INTERNAL is used to pass AML operands from the dispatcher
+ * The ACPI_OPERAND_OBJECT is used to pass AML operands from the dispatcher
X * to the interpreter, and to keep track of the various handlers such as
X * address space handlers and notify handlers. The object is a constant
X * size in order to allow them to be cached and reused.
X *
- * All variants of the ACPI_OBJECT_INTERNAL are defined with the same
+ * All variants of the ACPI_OPERAND_OBJECT are defined with the same
X * sequence of field types, with fields that are not used in a particular
X * variant being named "Reserved". This is not strictly necessary, but
X * may in some circumstances simplify understanding if these structures
@@ -60,32 +58,31 @@
X */
X
X
-#define ACPI_OBJECT_COMMON_HEADER /* Two 32-bit fields */\
- u8 data_type; /* To differentiate various internal objs */\
- u8 type; /* ACPI_OBJECT_TYPE */\
- u8 size; /* Size of entire descriptor */\
- u8 flags;\
- u16 reference_count; /* For object deletion management */\
- u16 acpi_cm_fill2;\
- union acpi_obj_internal *next; \
+#define ACPI_OBJECT_COMMON_HEADER /* Two 32-bit fields, one pointer, 8-bit flag */\


+ u8 data_type; /* To differentiate various internal objs */\

+ u8 type; /* ACPI_OBJECT_TYPE */\
+ u16 reference_count; /* For object deletion management */\
+ u8 flags; \
X
X /* Defines for flag byte above */
X
-#define AO_STATIC_ALLOCATION 0x1
+#define AOPOBJ_STATIC_ALLOCATION 0x1
+#define AOPOBJ_DATA_VALID 0x2
+#define AOPOBJ_INITIALIZED 0x4
X
X
X /*
X * Common bitfield for the field objects
X */
X #define ACPI_COMMON_FIELD_INFO /* Three 32-bit values */\
- u32 offset; /* Byte offset within containing object */\
- u16 length; /* # of bits in buffer */ \
- u8 granularity;\
- u8 bit_offset; /* Bit offset within min read/write data unit */\
- u8 access; /* Access_type */\
- u8 lock_rule;\
- u8 update_rule;\
- u8 access_attribute;
+ u8 granularity;\
+ u16 length; \
+ u32 offset; /* Byte offset within containing object */\
+ u8 bit_offset; /* Bit offset within min read/write data unit */\
+ u8 access; /* Access_type */\
+ u8 lock_rule;\
+ u8 update_rule;\
+ u8 access_attribute;
X
X
X /******************************************************************************
@@ -98,25 +95,23 @@
X typedef struct /* COMMON */
X {
X ACPI_OBJECT_COMMON_HEADER
- UCHAR first_non_common_byte;
X
X } ACPI_OBJECT_COMMON;
X
X
+typedef struct /* CACHE_LIST */
+{
+ ACPI_OBJECT_COMMON_HEADER
+ union acpi_operand_obj *next; /* Link for object cache and internal lists*/
+
+} ACPI_OBJECT_CACHE_LIST;
+
+
X typedef struct /* NUMBER - has value */
X {
X ACPI_OBJECT_COMMON_HEADER
X
- u32 value;
- u32 reserved2;
- u32 reserved3;
- u32 reserved4;
-
- void *reserved_p1;
- void *reserved_p2;
- void *reserved_p3;
- void *reserved_p4;
- void *reserved_p5;
+ u32 value;
X
X } ACPI_OBJECT_NUMBER;
X
@@ -125,16 +120,8 @@
X {
X ACPI_OBJECT_COMMON_HEADER
X
- u32 length; /* # of bytes in string, excluding trailing null */
- u32 reserved2;
- u32 reserved3;
- u32 reserved4;
-
- char *pointer; /* String value in AML stream or in allocated space */
- void *reserved_p2;
- void *reserved_p3;
- void *reserved_p4;
- void *reserved_p5;
+ u32 length;
+ NATIVE_CHAR *pointer; /* String value in AML stream or in allocated space */
X
X } ACPI_OBJECT_STRING;
X
@@ -143,16 +130,10 @@
X {
X ACPI_OBJECT_COMMON_HEADER
X
- u32 length; /* # of bytes in buffer */
- u32 sequence; /* Sequential count of buffers created */
- u32 reserved3;
- u32 reserved4;
-
- u8 *pointer; /* points to the buffer in allocated space */
- void *reserved_p2;
- void *reserved_p3;
- void *reserved_p4;
- void *reserved_p5;
+ u32 length;
+ u32 sequence; /* Sequential count of buffers created */
+
+ u8 *pointer; /* points to the buffer in allocated space */
X
X } ACPI_OBJECT_BUFFER;
X
@@ -161,16 +142,10 @@
X {
X ACPI_OBJECT_COMMON_HEADER
X
- u32 count; /* # of elements in package */
- u32 reserved2;
- u32 reserved3;
- u32 reserved4;
-
- union acpi_obj_internal **elements; /* Array of pointers to Acpi_objects */
- union acpi_obj_internal **next_element; /* used only while initializing */
- void *reserved_p3;
- void *reserved_p4;
- void *reserved_p5;
+ u32 count; /* # of elements in package */
+
+ union acpi_operand_obj **elements; /* Array of pointers to Acpi_objects */
+ union acpi_operand_obj **next_element; /* used only while initializing */
X
X } ACPI_OBJECT_PACKAGE;
X
@@ -180,13 +155,9 @@
X ACPI_OBJECT_COMMON_HEADER
X
X ACPI_COMMON_FIELD_INFO
- u32 sequence; /* Container's sequence number */
+ u32 sequence; /* Container's sequence number */
X
- union acpi_obj_internal *container; /* Containing object (Buffer) */
- void *reserved_p2;
- void *reserved_p3;
- void *reserved_p4;
- void *reserved_p5;
+ union acpi_operand_obj *container; /* Containing object (Buffer) */
X
X } ACPI_OBJECT_FIELD_UNIT;
X
@@ -195,16 +166,9 @@
X {
X ACPI_OBJECT_COMMON_HEADER
X
- u32 reserved1;
- u32 reserved2;
- u32 reserved3;
- u32 reserved4;
-
- ACPI_HANDLE handle;
- union acpi_obj_internal *sys_handler; /* Handler for system notifies */
- union acpi_obj_internal *drv_handler; /* Handler for driver notifies */
- union acpi_obj_internal *addr_handler; /* Handler for Address space */
- void *reserved_p5;
+ union acpi_operand_obj *sys_handler; /* Handler for system notifies */
+ union acpi_operand_obj *drv_handler; /* Handler for driver notifies */
+ union acpi_operand_obj *addr_handler; /* Handler for Address space */
X
X } ACPI_OBJECT_DEVICE;
X
@@ -213,18 +177,7 @@
X {
X ACPI_OBJECT_COMMON_HEADER
X
- u16 lock_count;
- u16 thread_id;
- u16 signal_count;
- u16 fill1;
- u32 reserved3;
- u32 reserved4;
-
- void *semaphore;
- void *reserved_p2;
- void *reserved_p3;
- void *reserved_p4;
- void *reserved_p5;
+ void *semaphore;
X
X } ACPI_OBJECT_EVENT;
X
@@ -234,21 +187,17 @@
X typedef struct /* METHOD */
X {
X ACPI_OBJECT_COMMON_HEADER
+ u8 method_flags;
+ u8 param_count;
+
+ u32 pcode_length;
X
- u8 method_flags;
- u8 param_count;
- u8 concurrency;
- u8 fill1;
- u32 pcode_length;
- u32 table_length;
- ACPI_OWNER_ID owning_id;
- u16 reserved4;
-
- u8 *pcode;
- u8 *acpi_table;
- void *parser_op;
- void *semaphore;
- void *reserved_p5;
+ void *semaphore;
+ u8 *pcode;
+
+ u8 concurrency;
+ u8 thread_count;
+ ACPI_OWNER_ID owning_id;
X
X } ACPI_OBJECT_METHOD;
X
@@ -256,45 +205,31 @@
X typedef struct /* MUTEX */
X {
X ACPI_OBJECT_COMMON_HEADER
+ u16 sync_level;
X
- u16 lock_count;
- u16 thread_id;
- u16 sync_level;
- u16 fill1;
- u32 reserved3;
- u32 reserved4;
-
- void *semaphore;
- void *reserved_p2;
- void *reserved_p3;
- void *reserved_p4;
- void *reserved_p5;
+ void *semaphore;
X
X } ACPI_OBJECT_MUTEX;
X
-/* Flags for Region */
-
-#define INITIAL_REGION_FLAGS 0x0000 /* value set when the region is created */
-#define REGION_AGRUMENT_DATA_VALID 0x0001 /* Addr/Len are set */
-#define REGION_INITIALIZED 0x0002 /* region init handler has been called */
- /* this includes _REG method, if any */
X
X typedef struct /* REGION */
X {
X ACPI_OBJECT_COMMON_HEADER
X
- u16 space_id;
- u16 region_flags; /* bits defined above */
- u32 address;
- u32 length;
- u32 reserved4; /* Region Specific data (PCI _ADR) */
-
- union acpi_obj_internal *method; /* Associated control method */
- union acpi_obj_internal *addr_handler; /* Handler for system notifies */
- union acpi_obj_internal *link; /* Link in list of regions */
- /* list is owned by Addr_handler */
- ACPI_NAMED_OBJECT *REGmethod; /* _REG method for this region (if any) */
- ACPI_NAMED_OBJECT *nte; /* containing object */
+ u8 space_id;
+ u32 length;
+ u32 address;
+ void *region_context; /* Region Specific data (Handler->Context
+ optional things like PCI _ADR) */
+
+ /* TBD: [Restructure] This field can go away when Pass3 is implemented */
+ union acpi_operand_obj *method; /* Associated control method */
+
+
+ union acpi_operand_obj *addr_handler; /* Handler for system notifies */
+ ACPI_NAMESPACE_NODE *REGmethod; /* _REG method for this region (if any) */
+ ACPI_NAMESPACE_NODE *node; /* containing object */
+ union acpi_operand_obj *next;
X
X } ACPI_OBJECT_REGION;
X
@@ -303,16 +238,11 @@
X {
X ACPI_OBJECT_COMMON_HEADER
X
- u32 system_level;
- u32 resource_order;
- u32 reserved3;
- u32 reserved4;
-
- ACPI_HANDLE handle;
- union acpi_obj_internal *sys_handler; /* Handler for system notifies */
- union acpi_obj_internal *drv_handler; /* Handler for driver notifies */
- void *reserved_p4;
- void *reserved_p5;
+ u32 system_level;
+ u32 resource_order;
+
+ union acpi_operand_obj *sys_handler; /* Handler for system notifies */
+ union acpi_operand_obj *drv_handler; /* Handler for driver notifies */
X
X } ACPI_OBJECT_POWER_RESOURCE;
X
@@ -321,17 +251,13 @@
X {
X ACPI_OBJECT_COMMON_HEADER
X
- u32 proc_id;
- ACPI_IO_ADDRESS pblk_address;
- u16 fill1;
- u32 pblk_length;
- u32 reserved4;
-
- ACPI_HANDLE handle;
- union acpi_obj_internal *sys_handler; /* Handler for system notifies */
- union acpi_obj_internal *drv_handler; /* Handler for driver notifies */
- union acpi_obj_internal *addr_handler; /* Handler for Address space */
- void *reserved_p5;
+ u32 proc_id;
+ u32 length;
+ ACPI_IO_ADDRESS address;
+
+ union acpi_operand_obj *sys_handler; /* Handler for system notifies */
+ union acpi_operand_obj *drv_handler; /* Handler for driver notifies */
+ union acpi_operand_obj *addr_handler; /* Handler for Address space */
X
X } ACPI_OBJECT_PROCESSOR;
X
@@ -340,16 +266,9 @@
X {
X ACPI_OBJECT_COMMON_HEADER
X
- u32 reserved1;
- u32 reserved2;
- u32 reserved3;
- u32 reserved4;
-
- ACPI_HANDLE handle;
- union acpi_obj_internal *sys_handler; /* Handler for system notifies */
- union acpi_obj_internal *drv_handler; /* Handler for driver notifies */
- union acpi_obj_internal *addr_handler; /* Handler for Address space */
- void *reserved_p5;
+ union acpi_operand_obj *sys_handler; /* Handler for system notifies */
+ union acpi_operand_obj *drv_handler; /* Handler for driver notifies */
+ union acpi_operand_obj *addr_handler; /* Handler for Address space */
X
X } ACPI_OBJECT_THERMAL_ZONE;
X
@@ -358,18 +277,14 @@
X * Internal types
X */
X
+
X typedef struct /* FIELD */
X {
X ACPI_OBJECT_COMMON_HEADER
X
X ACPI_COMMON_FIELD_INFO
- u32 reserved4;
X
- union acpi_obj_internal *container; /* Containing object */
- void *reserved_p2;
- void *reserved_p3;
- void *reserved_p4;
- void *reserved_p5;
+ union acpi_operand_obj *container; /* Containing object */
X
X } ACPI_OBJECT_FIELD;
X
@@ -379,13 +294,10 @@
X ACPI_OBJECT_COMMON_HEADER
X
X ACPI_COMMON_FIELD_INFO
- u32 value; /* Value to store into Bank_select */
+ u32 value; /* Value to store into Bank_select */
X
- ACPI_HANDLE bank_select; /* Bank select register */
- union acpi_obj_internal *container; /* Containing object */
- void *reserved_p3;
- void *reserved_p4;
- void *reserved_p5;
+ ACPI_HANDLE bank_select; /* Bank select register */
+ union acpi_operand_obj *container; /* Containing object */
X
X } ACPI_OBJECT_BANK_FIELD;
X
@@ -399,13 +311,10 @@
X ACPI_OBJECT_COMMON_HEADER
X
X ACPI_COMMON_FIELD_INFO
- u32 value; /* Value to store into Index register */
+ u32 value; /* Value to store into Index register */
X
- ACPI_HANDLE index; /* Index register */
- ACPI_HANDLE data; /* Data register */
- void *reserved_p3;
- void *reserved_p4;
- void *reserved_p5;
+ ACPI_HANDLE index; /* Index register */
+ ACPI_HANDLE data; /* Data register */
X
X } ACPI_OBJECT_INDEX_FIELD;
X
@@ -414,16 +323,9 @@
X {
X ACPI_OBJECT_COMMON_HEADER
X
- u32 reserved1;
- u32 reserved2;
- u32 reserved3;
- u32 reserved4;
-
- ACPI_NAMED_OBJECT *nte; /* Parent device */
- NOTIFY_HANDLER handler;
- void *context;
- void *reserved_p4;
- void *reserved_p5;
+ ACPI_NAMESPACE_NODE *node; /* Parent device */
+ NOTIFY_HANDLER handler;
+ void *context;
X
X } ACPI_OBJECT_NOTIFY_HANDLER;
X
@@ -432,19 +334,20 @@
X
X #define ADDR_HANDLER_DEFAULT_INSTALLED 0x1
X
+
X typedef struct /* ADDRESS HANDLER */
X {
X ACPI_OBJECT_COMMON_HEADER
X
- u16 space_id;
- u16 hflags;
- ADDRESS_SPACE_HANDLER handler;
-
- ACPI_NAMED_OBJECT *nte; /* Parent device */
- void *context;
- ADDRESS_SPACE_SETUP setup;
- union acpi_obj_internal *link; /* Link to next handler on device */
- union acpi_obj_internal *region_list; /* regions using this handler */
+ u8 space_id;
+ u16 hflags;
+ ADDRESS_SPACE_HANDLER handler;
+
+ ACPI_NAMESPACE_NODE *node; /* Parent device */
+ void *context;
+ ADDRESS_SPACE_SETUP setup;
+ union acpi_operand_obj *region_list; /* regions using this handler */
+ union acpi_operand_obj *next;
X
X } ACPI_OBJECT_ADDR_HANDLER;
X
@@ -458,31 +361,27 @@
X {
X ACPI_OBJECT_COMMON_HEADER
X
- u16 op_code;
- u8 fill1;
- u8 target_type; /* Used for Index_op */
- u32 offset; /* Used for Arg_op, Local_op, and Index_op */
- u32 reserved3;
- u32 reserved4;
-
- void *object; /* Name_op=>HANDLE to obj, Index_op=>ACPI_OBJECT_INTERNAL */
- ACPI_NAMED_OBJECT *nte;
- union acpi_obj_internal **where;
- void *reserved_p4;
- void *reserved_p5;
+ u8 target_type; /* Used for Index_op */
+ u16 op_code;
+ u32 offset; /* Used for Arg_op, Local_op, and Index_op */
+
+ void *object; /* Name_op=>HANDLE to obj, Index_op=>ACPI_OPERAND_OBJECT */
+ ACPI_NAMESPACE_NODE *node;
+ union acpi_operand_obj **where;
X
X } ACPI_OBJECT_REFERENCE;
X
X
X /******************************************************************************
X *
- * ACPI_OBJECT_INTERNAL Descriptor - a giant union of all of the above
+ * ACPI_OPERAND_OBJECT Descriptor - a giant union of all of the above


X *
X *****************************************************************************/
X

-typedef union acpi_obj_internal
+typedef union acpi_operand_obj
X {
X ACPI_OBJECT_COMMON common;
+ ACPI_OBJECT_CACHE_LIST cache;
X ACPI_OBJECT_NUMBER number;
X ACPI_OBJECT_STRING string;
X ACPI_OBJECT_BUFFER buffer;
@@ -503,6 +402,6 @@
X ACPI_OBJECT_NOTIFY_HANDLER notify_handler;
X ACPI_OBJECT_ADDR_HANDLER addr_handler;
X
-} ACPI_OBJECT_INTERNAL;
+} ACPI_OPERAND_OBJECT;
X
X #endif /* _ACOBJECT_H */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/acoutput.h linux/drivers/acpi/include/acoutput.h
--- v2.4.0-test8/linux/drivers/acpi/include/acoutput.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/include/acoutput.h Fri Sep 15 14:30:30 2000
@@ -0,0 +1,124 @@
+/******************************************************************************
+ *
+ * Name: acoutput.h -- debug output
+ * $Revision: 63 $


+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 R. Byron Moore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+

+#ifndef __ACOUTPUT_H__
+#define __ACOUTPUT_H__
+
+/*
+ * Debug levels and component IDs. These are used to control the
+ * granularity of the output of the DEBUG_PRINT macro -- on a per-
+ * component basis and a per-exception-type basis.
+ */
+
+/* Component IDs -- used in the global "Debug_layer" */
+
+#define GLOBAL 0x00000001
+#define COMMON 0x00000002
+#define PARSER 0x00000004
+#define DISPATCHER 0x00000008
+#define INTERPRETER 0x00000010
+#define NAMESPACE 0x00000020
+#define RESOURCE_MANAGER 0x00000040
+#define TABLE_MANAGER 0x00000080
+#define EVENT_HANDLING 0x00000100
+#define HARDWARE 0x00000200
+#define MISCELLANEOUS 0x00000400
+#define OS_DEPENDENT 0x00000800
+
+#define BUS_MANAGER 0x00001000
+
+#define PROCESSOR_CONTROL 0x00002000
+#define SYSTEM_CONTROL 0x00004000
+#define THERMAL_CONTROL 0x00008000
+#define POWER_CONTROL 0x00010000
+
+#define EMBEDDED_CONTROLLER 0x00020000
+#define BATTERY 0x00040000
+
+#define DEBUGGER 0x00100000
+#define ALL_COMPONENTS 0x001FFFFF
+
+
+/* Exception level -- used in the global "Debug_level" */
+
+#define ACPI_OK 0x00000001
+#define ACPI_INFO 0x00000002
+#define ACPI_WARN 0x00000004
+#define ACPI_ERROR 0x00000008
+#define ACPI_FATAL 0x00000010
+#define ACPI_DEBUG_OBJECT 0x00000020
+#define ACPI_ALL 0x0000003F
+
+
+/* Trace level -- also used in the global "Debug_level" */
+
+#define TRACE_PARSE 0x00000100
+#define TRACE_DISPATCH 0x00000200
+#define TRACE_LOAD 0x00000400
+#define TRACE_EXEC 0x00000800
+#define TRACE_NAMES 0x00001000
+#define TRACE_OPREGION 0x00002000
+#define TRACE_BFIELD 0x00004000
+#define TRACE_TRASH 0x00008000
+#define TRACE_TABLES 0x00010000
+#define TRACE_FUNCTIONS 0x00020000
+#define TRACE_VALUES 0x00040000
+#define TRACE_OBJECTS 0x00080000
+#define TRACE_ALLOCATIONS 0x00100000
+#define TRACE_RESOURCES 0x00200000
+#define TRACE_IO 0x00400000
+#define TRACE_INTERRUPTS 0x00800000
+#define TRACE_USER_REQUESTS 0x01000000
+#define TRACE_PACKAGE 0x02000000
+#define TRACE_MUTEX 0x04000000
+
+#define TRACE_ALL 0x0FFFFF00
+
+
+/* Exceptionally verbose output -- also used in the global "Debug_level" */
+
+#define VERBOSE_AML_DISASSEMBLE 0x10000000
+#define VERBOSE_INFO 0x20000000
+#define VERBOSE_TABLES 0x40000000
+#define VERBOSE_EVENTS 0x80000000
+
+#define VERBOSE_ALL 0x70000000
+
+
+/* Defaults for Debug_level, debug and normal */
+
+#define DEBUG_DEFAULT (ACPI_OK | ACPI_WARN | ACPI_ERROR | ACPI_DEBUG_OBJECT | TRACE_TABLES | TRACE_IO)
+#define NORMAL_DEFAULT (ACPI_OK | ACPI_WARN | ACPI_ERROR | ACPI_DEBUG_OBJECT)
+#define DEBUG_ALL (VERBOSE_AML_DISASSEMBLE | TRACE_ALL | ACPI_ALL)
+
+/* Misc defines */
+
+#define HEX 0x01
+#define ASCII 0x02
+#define FULL_ADDRESS 0x04
+#define CHARS_PER_LINE 16 /* used in Dump_buf function */
+
+
+#endif /* __ACOUTPUT_H__ */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/acparser.h linux/drivers/acpi/include/acparser.h
--- v2.4.0-test8/linux/drivers/acpi/include/acparser.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/include/acparser.h Fri Sep 15 14:30:30 2000
@@ -0,0 +1,345 @@
+/******************************************************************************
+ *
+ * Module Name: acparser.h - AML Parser subcomponent prototypes and defines
+ * $Revision: 46 $


+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 R. Byron Moore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+

+#ifndef __ACPARSER_H__
+#define __ACPARSER_H__
+
+
+#define OP_HAS_RETURN_VALUE 1
+
+/* variable # arguments */
+
+#define ACPI_VAR_ARGS ACPI_UINT32_MAX
+
+/* maximum virtual address */
+
+#define ACPI_MAX_AML ((u8 *)(~0UL))
+
+
+#define ACPI_PARSE_DELETE_TREE 0x0001
+#define ACPI_PARSE_NO_TREE_DELETE 0x0000
+#define ACPI_PARSE_TREE_MASK 0x0001
+
+#define ACPI_PARSE_LOAD_PASS1 0x0010
+#define ACPI_PARSE_LOAD_PASS2 0x0020
+#define ACPI_PARSE_EXECUTE 0x0030
+#define ACPI_PARSE_MODE_MASK 0x0030
+
+/* psapi - Parser external interfaces */
+
+ACPI_STATUS
+acpi_psx_load_table (
+ u8 *pcode_addr,
+ u32 pcode_length);
+
+ACPI_STATUS
+acpi_psx_execute (


+ ACPI_NAMESPACE_NODE *method_node,
+ ACPI_OPERAND_OBJECT **params,
+ ACPI_OPERAND_OBJECT **return_obj_desc);
+
+

+u8
+acpi_ps_is_namespace_object_op (
+ u16 opcode);
+u8
+acpi_ps_is_namespace_op (


+ u16 opcode);
+
+

+/******************************************************************************
+ *
+ * Parser interfaces


+ *
+ *****************************************************************************/
+
+

+/* psargs - Parse AML opcode arguments */
+
+u8 *
+acpi_ps_get_next_package_end (
+ ACPI_PARSE_STATE *parser_state);
+
+u32
+acpi_ps_get_next_package_length (
+ ACPI_PARSE_STATE *parser_state);
+
+NATIVE_CHAR *
+acpi_ps_get_next_namestring (
+ ACPI_PARSE_STATE *parser_state);
+
+void
+acpi_ps_get_next_simple_arg (
+ ACPI_PARSE_STATE *parser_state,
+ u32 arg_type, /* type of argument */
+ ACPI_PARSE_OBJECT *arg); /* (OUT) argument data */
+
+void
+acpi_ps_get_next_namepath (
+ ACPI_PARSE_STATE *parser_state,
+ ACPI_PARSE_OBJECT *arg,
+ u32 *arg_count,
+ u8 method_call);
+
+ACPI_PARSE_OBJECT *
+acpi_ps_get_next_field (
+ ACPI_PARSE_STATE *parser_state);
+
+ACPI_PARSE_OBJECT *
+acpi_ps_get_next_arg (
+ ACPI_PARSE_STATE *parser_state,
+ u32 arg_type,
+ u32 *arg_count);
+
+
+/* psopcode - AML Opcode information */
+
+ACPI_OPCODE_INFO *
+acpi_ps_get_opcode_info (
+ u16 opcode);
+
+NATIVE_CHAR *
+acpi_ps_get_opcode_name (


+ u16 opcode);
+
+

+/* psparse - top level parsing routines */
+
+ACPI_STATUS
+acpi_ps_find_object (
+ u16 opcode,


+ ACPI_PARSE_OBJECT *op,
+ ACPI_WALK_STATE *walk_state,
+ ACPI_PARSE_OBJECT **out_op);
+

+void
+acpi_ps_delete_parse_tree (
+ ACPI_PARSE_OBJECT *root);
+
+ACPI_STATUS
+acpi_ps_parse_loop (


+ ACPI_WALK_STATE *walk_state);
+
+ACPI_STATUS

+acpi_ps_parse_aml (
+ ACPI_PARSE_OBJECT *start_scope,
+ u8 *aml,
+ u32 aml_size,
+ u32 parse_flags,


+ ACPI_NAMESPACE_NODE *method_node,
+ ACPI_OPERAND_OBJECT **params,

+ ACPI_OPERAND_OBJECT **caller_return_desc,
+ ACPI_PARSE_DOWNWARDS descending_callback,
+ ACPI_PARSE_UPWARDS ascending_callback);
+
+ACPI_STATUS
+acpi_ps_parse_table (
+ u8 *aml,
+ u32 aml_size,
+ ACPI_PARSE_DOWNWARDS descending_callback,
+ ACPI_PARSE_UPWARDS ascending_callback,
+ ACPI_PARSE_OBJECT **root_object);
+
+u16
+acpi_ps_peek_opcode (
+ ACPI_PARSE_STATE *state);
+
+
+/* psscope - Scope stack management routines */
+
+
+ACPI_STATUS
+acpi_ps_init_scope (
+ ACPI_PARSE_STATE *parser_state,
+ ACPI_PARSE_OBJECT *root);
+
+ACPI_PARSE_OBJECT *
+acpi_ps_get_parent_scope (
+ ACPI_PARSE_STATE *state);
+
+u8
+acpi_ps_has_completed_scope (
+ ACPI_PARSE_STATE *parser_state);
+
+void
+acpi_ps_pop_scope (
+ ACPI_PARSE_STATE *parser_state,
+ ACPI_PARSE_OBJECT **op,
+ u32 *arg_list);
+
+ACPI_STATUS
+acpi_ps_push_scope (
+ ACPI_PARSE_STATE *parser_state,
+ ACPI_PARSE_OBJECT *op,
+ u32 remaining_args,
+ u32 arg_count);
+
+void
+acpi_ps_cleanup_scope (
+ ACPI_PARSE_STATE *state);
+
+
+/* pstree - parse tree manipulation routines */
+
+void
+acpi_ps_append_arg(
+ ACPI_PARSE_OBJECT *op,
+ ACPI_PARSE_OBJECT *arg);
+
+ACPI_PARSE_OBJECT*
+acpi_ps_find (
+ ACPI_PARSE_OBJECT *scope,
+ NATIVE_CHAR *path,
+ u16 opcode,
+ u32 create);
+
+ACPI_PARSE_OBJECT *
+acpi_ps_get_arg(
+ ACPI_PARSE_OBJECT *op,
+ u32 argn);
+
+ACPI_PARSE_OBJECT *
+acpi_ps_get_child (
+ ACPI_PARSE_OBJECT *op);
+
+ACPI_PARSE_OBJECT *
+acpi_ps_get_depth_next (
+ ACPI_PARSE_OBJECT *origin,


+ ACPI_PARSE_OBJECT *op);
+
+

+/* pswalk - parse tree walk routines */
+
+ACPI_STATUS
+acpi_ps_walk_parsed_aml (
+ ACPI_PARSE_OBJECT *start_op,
+ ACPI_PARSE_OBJECT *end_op,
+ ACPI_OPERAND_OBJECT *mth_desc,
+ ACPI_NAMESPACE_NODE *start_node,
+ ACPI_OPERAND_OBJECT **params,
+ ACPI_OPERAND_OBJECT **caller_return_desc,
+ ACPI_OWNER_ID owner_id,
+ ACPI_PARSE_DOWNWARDS descending_callback,
+ ACPI_PARSE_UPWARDS ascending_callback);
+
+ACPI_STATUS
+acpi_ps_get_next_walk_op (
+ ACPI_WALK_STATE *walk_state,
+ ACPI_PARSE_OBJECT *op,
+ ACPI_PARSE_UPWARDS ascending_callback);
+
+
+/* psutils - parser utilities */
+
+
+ACPI_PARSE_STATE *
+acpi_ps_create_state (
+ u8 *aml,
+ u32 aml_size);
+
+void
+acpi_ps_init_op (
+ ACPI_PARSE_OBJECT *op,
+ u16 opcode);
+
+ACPI_PARSE_OBJECT *
+acpi_ps_alloc_op (
+ u16 opcode);
+
+void
+acpi_ps_free_op (


+ ACPI_PARSE_OBJECT *op);
+
+void

+acpi_ps_delete_parse_cache (
+ void);
+
+u8
+acpi_ps_is_leading_char (
+ u32 c);
+
+u8
+acpi_ps_is_prefix_char (
+ u32 c);
+
+u8
+acpi_ps_is_named_op (
+ u16 opcode);
+
+u8
+acpi_ps_is_node_op (
+ u16 opcode);
+
+u8
+acpi_ps_is_deferred_op (
+ u16 opcode);
+
+u8
+acpi_ps_is_bytelist_op(
+ u16 opcode);
+
+u8
+acpi_ps_is_field_op(
+ u16 opcode);
+
+u8
+acpi_ps_is_create_field_op (
+ u16 opcode);
+
+ACPI_PARSE2_OBJECT*
+acpi_ps_to_extended_op(
+ ACPI_PARSE_OBJECT *op);
+
+u32
+acpi_ps_get_name(


+ ACPI_PARSE_OBJECT *op);
+
+void

+acpi_ps_set_name(
+ ACPI_PARSE_OBJECT *op,
+ u32 name);
+
+
+/* psdump - display parser tree */
+
+u32
+acpi_ps_sprint_path (
+ NATIVE_CHAR *buffer_start,
+ u32 buffer_size,
+ ACPI_PARSE_OBJECT *op);
+
+u32
+acpi_ps_sprint_op (
+ NATIVE_CHAR *buffer_start,
+ u32 buffer_size,


+ ACPI_PARSE_OBJECT *op);
+
+void

+acpi_ps_show (


+ ACPI_PARSE_OBJECT *op);
+
+

+#endif /* __ACPARSER_H__ */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/acpi.h linux/drivers/acpi/include/acpi.h
--- v2.4.0-test8/linux/drivers/acpi/include/acpi.h Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/include/acpi.h Fri Sep 15 14:30:30 2000


@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *

X * Name: acpi.h - Master include file, Publics and external data.


+ * $Revision: 48 $

X *
X *****************************************************************************/
X

@@ -31,20 +31,20 @@
X * We put them here because we don't want to duplicate them
X * in the rest of the source code again and again.
X */
-#include "config.h" /* Configuration constants */
+#include "acconfig.h" /* Configuration constants */
X #include "acenv.h" /* Target environment specific items */
X #include "actypes.h" /* Fundamental data types */
X #include "acexcep.h" /* Local exception codes */
-#include "macros.h" /* C macros */
-#include "actables.h" /* Acpi table definitions */
-#include "internal.h" /* Internal data types */
-#include "output.h" /* Error output and Debug macros */
+#include "acmacros.h" /* C macros */
+#include "actbl.h" /* Acpi table definitions */
+#include "aclocal.h" /* Internal data types */
+#include "acoutput.h" /* Error output and Debug macros */
X #include "acpiosxf.h" /* Interfaces to the Acpi-to-OS layer*/
X #include "acpixf.h" /* Acpi core external interfaces */
X #include "acobject.h" /* Acpi internal object */
-#include "globals.h" /* All global variables */
-#include "hardware.h" /* Hardware defines and interfaces */
-#include "common.h" /* Common (global) interfaces */
+#include "acglobal.h" /* All global variables */
+#include "achware.h" /* Hardware defines and interfaces */
+#include "accommon.h" /* Common (global) interfaces */
X
X
X #endif /* __ACPI_H__ */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/acpiosxf.h linux/drivers/acpi/include/acpiosxf.h
--- v2.4.0-test8/linux/drivers/acpi/include/acpiosxf.h Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/include/acpiosxf.h Fri Sep 15 14:30:30 2000
@@ -244,7 +244,7 @@
X
X ACPI_STATUS
X acpi_os_breakpoint (
- char *message);
+ NATIVE_CHAR *message);
X
X u8
X acpi_os_readable (


@@ -264,12 +264,12 @@
X

X s32
X acpi_os_printf (
- const char *format,
+ const NATIVE_CHAR *format,
X ...);
X
X s32
X acpi_os_vprintf (
- const char *format,
+ const NATIVE_CHAR *format,
X va_list args);
X
X /*
@@ -278,7 +278,7 @@
X
X u32
X acpi_os_get_line (
- char *buffer);
+ NATIVE_CHAR *buffer);
X
X
X /*
@@ -290,7 +290,7 @@
X void *failed_assertion,
X void *file_name,
X u32 line_number,
- char *message);
+ NATIVE_CHAR *message);
X
X
X #endif /* __ACPIOSD_H__ */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/acpixf.h linux/drivers/acpi/include/acpixf.h
--- v2.4.0-test8/linux/drivers/acpi/include/acpixf.h Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/include/acpixf.h Fri Sep 15 14:30:30 2000
@@ -28,7 +28,7 @@
X #define __ACXFACE_H__
X
X #include "actypes.h"
-#include "actables.h"
+#include "actbl.h"
X
X /*
X * Global interfaces
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/acresrc.h linux/drivers/acpi/include/acresrc.h
--- v2.4.0-test8/linux/drivers/acpi/include/acresrc.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/include/acresrc.h Fri Sep 15 14:30:30 2000
@@ -0,0 +1,304 @@
+/******************************************************************************
+ *
+ * Name: acresrc.h - Resource Manager function prototypes
+ * $Revision: 20 $


+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 R. Byron Moore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+

+#ifndef __ACRESRC_H__
+#define __ACRESRC_H__
+
+
+/*
+ * Function prototypes called from Acpi* APIs
+ */
+
+ACPI_STATUS
+acpi_rs_get_prt_method_data (
+ ACPI_HANDLE handle,
+ ACPI_BUFFER *ret_buffer);
+
+
+ACPI_STATUS
+acpi_rs_get_crs_method_data (
+ ACPI_HANDLE handle,
+ ACPI_BUFFER *ret_buffer);
+
+ACPI_STATUS
+acpi_rs_get_prs_method_data (
+ ACPI_HANDLE handle,
+ ACPI_BUFFER *ret_buffer);
+
+ACPI_STATUS
+acpi_rs_set_srs_method_data (
+ ACPI_HANDLE handle,
+ ACPI_BUFFER *ret_buffer);
+
+ACPI_STATUS
+acpi_rs_create_resource_list (
+ ACPI_OPERAND_OBJECT *byte_stream_buffer,
+ u8 *output_buffer,
+ u32 *output_buffer_length);
+
+ACPI_STATUS
+acpi_rs_create_byte_stream (
+ RESOURCE *linked_list_buffer,
+ u8 *output_buffer,
+ u32 *output_buffer_length);
+
+ACPI_STATUS
+acpi_rs_create_pci_routing_table (
+ ACPI_OPERAND_OBJECT *method_return_object,
+ u8 *output_buffer,
+ u32 *output_buffer_length);
+
+
+/*
+ *Function prototypes called from Acpi_rs_create*APIs
+ */
+
+void
+acpi_rs_dump_resource_list (
+ RESOURCE *resource);
+
+void
+acpi_rs_dump_irq_list (
+ u8 *route_table);
+
+ACPI_STATUS
+acpi_rs_get_byte_stream_start (
+ u8 *byte_stream_buffer,
+ u8 **byte_stream_start,
+ u32 *size);
+
+ACPI_STATUS
+acpi_rs_calculate_list_length (
+ u8 *byte_stream_buffer,
+ u32 byte_stream_buffer_length,
+ u32 *size_needed);
+
+ACPI_STATUS
+acpi_rs_calculate_byte_stream_length (
+ RESOURCE *linked_list_buffer,
+ u32 *size_needed);
+
+ACPI_STATUS
+acpi_rs_calculate_pci_routing_table_length (
+ ACPI_OPERAND_OBJECT *package_object,
+ u32 *buffer_size_needed);
+
+ACPI_STATUS
+acpi_rs_byte_stream_to_list (
+ u8 *byte_stream_buffer,
+ u32 byte_stream_buffer_length,
+ u8 **output_buffer);
+
+ACPI_STATUS
+acpi_rs_list_to_byte_stream (
+ RESOURCE *linked_list,
+ u32 byte_stream_size_needed,
+ u8 **output_buffer);
+
+ACPI_STATUS
+acpi_rs_io_resource (
+ u8 *byte_stream_buffer,
+ u32 *bytes_consumed,
+ u8 **output_buffer,
+ u32 *structure_size);
+
+ACPI_STATUS
+acpi_rs_fixed_io_resource (
+ u8 *byte_stream_buffer,
+ u32 *bytes_consumed,
+ u8 **output_buffer,
+ u32 *structure_size);
+
+ACPI_STATUS
+acpi_rs_io_stream (
+ RESOURCE *linked_list,
+ u8 **output_buffer,
+ u32 *bytes_consumed);
+
+ACPI_STATUS
+acpi_rs_fixed_io_stream (
+ RESOURCE *linked_list,
+ u8 **output_buffer,
+ u32 *bytes_consumed);
+
+ACPI_STATUS
+acpi_rs_irq_resource (
+ u8 *byte_stream_buffer,
+ u32 *bytes_consumed,
+ u8 **output_buffer,
+ u32 *structure_size);
+
+ACPI_STATUS
+acpi_rs_irq_stream (
+ RESOURCE *linked_list,
+ u8 **output_buffer,
+ u32 *bytes_consumed);
+
+ACPI_STATUS
+acpi_rs_dma_resource (
+ u8 *byte_stream_buffer,
+ u32 *bytes_consumed,
+ u8 **output_buffer,
+ u32 *structure_size);
+
+ACPI_STATUS
+acpi_rs_dma_stream (
+ RESOURCE *linked_list,
+ u8 **output_buffer,
+ u32 *bytes_consumed);
+
+ACPI_STATUS
+acpi_rs_address16_resource (
+ u8 *byte_stream_buffer,
+ u32 *bytes_consumed,
+ u8 **output_buffer,
+ u32 *structure_size);
+
+ACPI_STATUS
+acpi_rs_address16_stream (
+ RESOURCE *linked_list,
+ u8 **output_buffer,
+ u32 *bytes_consumed);
+
+ACPI_STATUS
+acpi_rs_address32_resource (
+ u8 *byte_stream_buffer,
+ u32 *bytes_consumed,
+ u8 **output_buffer,
+ u32 *structure_size);
+
+ACPI_STATUS
+acpi_rs_address32_stream (
+ RESOURCE *linked_list,
+ u8 **output_buffer,
+ u32 *bytes_consumed);
+
+ACPI_STATUS
+acpi_rs_start_dependent_functions_resource (
+ u8 *byte_stream_buffer,
+ u32 *bytes_consumed,
+ u8 **output_buffer,
+ u32 *structure_size);
+
+ACPI_STATUS
+acpi_rs_end_dependent_functions_resource (
+ u8 *byte_stream_buffer,
+ u32 *bytes_consumed,
+ u8 **output_buffer,
+ u32 *structure_size);
+
+ACPI_STATUS
+acpi_rs_start_dependent_functions_stream (
+ RESOURCE *linked_list,
+ u8 **output_buffer,
+ u32 *bytes_consumed);
+
+ACPI_STATUS
+acpi_rs_end_dependent_functions_stream (
+ RESOURCE *linked_list,
+ u8 **output_buffer,
+ u32 *bytes_consumed);
+
+ACPI_STATUS
+acpi_rs_memory24_resource (
+ u8 *byte_stream_buffer,
+ u32 *bytes_consumed,
+ u8 **output_buffer,
+ u32 *structure_size);
+
+ACPI_STATUS
+acpi_rs_memory24_stream (
+ RESOURCE *linked_list,
+ u8 **output_buffer,
+ u32 *bytes_consumed);
+
+ACPI_STATUS
+acpi_rs_memory32_range_resource (
+ u8 *byte_stream_buffer,
+ u32 *bytes_consumed,
+ u8 **output_buffer,
+ u32 *structure_size
+);
+
+ACPI_STATUS
+acpi_rs_fixed_memory32_resource (
+ u8 *byte_stream_buffer,
+ u32 *bytes_consumed,
+ u8 **output_buffer,
+ u32 *structure_size);
+
+ACPI_STATUS
+acpi_rs_memory32_range_stream (
+ RESOURCE *linked_list,
+ u8 **output_buffer,
+ u32 *bytes_consumed);
+
+ACPI_STATUS
+acpi_rs_fixed_memory32_stream (
+ RESOURCE *linked_list,
+ u8 **output_buffer,
+ u32 *bytes_consumed);
+
+ACPI_STATUS
+acpi_rs_extended_irq_resource (
+ u8 *byte_stream_buffer,
+ u32 *bytes_consumed,
+ u8 **output_buffer,
+ u32 *structure_size);
+
+ACPI_STATUS
+acpi_rs_extended_irq_stream (
+ RESOURCE *linked_list,
+ u8 **output_buffer,
+ u32 *bytes_consumed);
+
+ACPI_STATUS
+acpi_rs_end_tag_resource (
+ u8 *byte_stream_buffer,
+ u32 *bytes_consumed,
+ u8 **output_buffer,
+ u32 *structure_size);
+
+ACPI_STATUS
+acpi_rs_end_tag_stream (
+ RESOURCE *linked_list,
+ u8 **output_buffer,
+ u32 *bytes_consumed);
+
+ACPI_STATUS
+acpi_rs_vendor_resource (
+ u8 *byte_stream_buffer,
+ u32 *bytes_consumed,
+ u8 **output_buffer,
+ u32 *structure_size);
+
+ACPI_STATUS
+acpi_rs_vendor_stream (
+ RESOURCE *linked_list,
+ u8 **output_buffer,
+ u32 *bytes_consumed);
+
+
+#endif /* __ACRESRC_H__ */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/actables.h linux/drivers/acpi/include/actables.h
--- v2.4.0-test8/linux/drivers/acpi/include/actables.h Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/include/actables.h Fri Sep 15 14:30:30 2000


@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *

- * Name: actables.h - Table data structures defined in ACPI specification
+ * Name: actables.h - ACPI table management
+ * $Revision: 20 $


X *
X *****************************************************************************/
X

@@ -27,162 +27,139 @@
X #define __ACTABLES_H__
X
X
-/*
- * Values for description table header signatures
- */
-
-#define RSDP_SIG "RSD PTR " /* RSDT Pointer signature */
-#define APIC_SIG "APIC" /* Multiple APIC Description Table */
-#define DSDT_SIG "DSDT" /* Differentiated System Description Table */
-#define FACP_SIG "FACP" /* Fixed ACPI Description Table */
-#define FACS_SIG "FACS" /* Firmware ACPI Control Structure */
-#define PSDT_SIG "PSDT" /* Persistent System Description Table */
-#define RSDT_SIG "RSDT" /* Root System Description Table */
-#define SSDT_SIG "SSDT" /* Secondary System Description Table */
-#define SBST_SIG "SBST" /* Smart Battery Specification Table */
-#define BOOT_SIG "BOOT" /* Boot table */
-
-
-#define GL_OWNED 0x02 /* Ownership of global lock is bit 1 */
+/* Used in Acpi_tb_map_acpi_table for size parameter if table header is to be used */
X
-/* values of Mapic.Model */
+#define SIZE_IN_HEADER 0
X
-#define DUAL_PIC 0
-#define MULTIPLE_APIC 1
X
-/* values of Type in APIC_HEADER */
-
-#define APIC_PROC 0
-#define APIC_IO 1
+ACPI_STATUS
+acpi_tb_handle_to_object (
+ u16 table_id,
+ ACPI_TABLE_DESC **table_desc);
X
X
X /*
- * Architecture-independent tables
- * The architecture dependent tables are in separate files
+ * Acpi_tbfac - FACP, FACS utilities
X */
X
-typedef struct /* Root System Descriptor Pointer */
-{
- char signature [8]; /* contains "RSD PTR " */
- u8 checksum; /* to make sum of struct == 0 */
- char oem_id [6]; /* OEM identification */
- u8 reserved; /* reserved - must be zero */
- u32 rsdt_physical_address; /* physical address of RSDT */
-
-} ROOT_SYSTEM_DESCRIPTOR_POINTER;
+ACPI_STATUS
+acpi_tb_get_table_facs (
+ ACPI_TABLE_HEADER *buffer_ptr,
+ ACPI_TABLE_DESC *table_info);
X
X
-typedef struct /* ACPI common table header */
-{
- char signature [4]; /* identifies type of table */
- u32 length; /* length of table, in bytes,
- * including header */
- u8 revision; /* specification minor version # */
- u8 checksum; /* to make sum of entire table == 0 */
- char oem_id [6]; /* OEM identification */
- char oem_table_id [8]; /* OEM table identification */
- u32 oem_revision; /* OEM revision number */
- char asl_compiler_id [4]; /* ASL compiler vendor ID */
- u32 asl_compiler_revision; /* ASL compiler revision number */
+/*
+ * Acpi_tbget - Table "get" routines
+ */
X
-} ACPI_TABLE_HEADER;
+ACPI_STATUS
+acpi_tb_get_table_ptr (
+ ACPI_TABLE_TYPE table_type,
+ u32 instance,
+ ACPI_TABLE_HEADER **table_ptr_loc);
X
+ACPI_STATUS
+acpi_tb_get_table (
+ void *physical_address,
+ ACPI_TABLE_HEADER *buffer_ptr,
+ ACPI_TABLE_DESC *table_info);
X
-typedef struct /* APIC Table */
-{
- ACPI_TABLE_HEADER header; /* table header */
- u32 local_apic_address; /* Physical address for accessing local APICs */
- u32 PCATcompat : 1; /* a one indicates system also has dual 8259s */
- u32 reserved1 : 31;
X
-} APIC_TABLE;
+/*
+ * Acpi_tbgetall - Get all firmware ACPI tables
+ */
X
+ACPI_STATUS
+acpi_tb_get_all_tables (
+ u32 number_of_tables,
+ ACPI_TABLE_HEADER *buffer_ptr);
X
-typedef struct /* APIC Header */
-{
- u8 type; /* APIC type. Either APIC_PROC or APIC_IO */
- u8 length; /* Length of APIC structure */
X
-} APIC_HEADER;
+/*
+ * Acpi_tbinstall - Table installation
+ */
X
+ACPI_STATUS
+acpi_tb_install_table (
+ ACPI_TABLE_HEADER *table_ptr,
+ ACPI_TABLE_DESC *table_info);
X
-typedef struct /* Processor APIC */
-{
- APIC_HEADER header;
- u8 processor_apic_id; /* ACPI processor id */
- u8 local_apic_id; /* processor's local APIC id */
- u32 processor_enabled: 1; /* Processor is usable if set */
- u32 reserved1 : 32;
+ACPI_STATUS
+acpi_tb_recognize_table (
+ ACPI_TABLE_HEADER *table_ptr,
+ ACPI_TABLE_DESC *table_info);
X
-} PROCESSOR_APIC;
+ACPI_STATUS
+acpi_tb_init_table_descriptor (
+ ACPI_TABLE_TYPE table_type,
+ ACPI_TABLE_DESC *table_info);
X
X
-typedef struct /* IO APIC */
-{
- APIC_HEADER header;
- u8 io_apic_id; /* I/O APIC ID */
- u8 reserved; /* reserved - must be zero */
- u32 io_apic_address; /* APIC's physical address */
- u32 vector; /* interrupt vector index where INTI
- * lines start */
-} IO_APIC;
+/*
+ * Acpi_tbremove - Table removal and deletion
+ */
X
+void
+acpi_tb_delete_acpi_tables (
+ void);
X
-/*
-** IA64 TODO: Add SAPIC Tables
-*/
+void
+acpi_tb_delete_acpi_table (
+ ACPI_TABLE_TYPE type);
X
-/*
-** IA64 TODO: Modify Smart Battery Description to comply with ACPI IA64
-** extensions.
-*/
-typedef struct /* Smart Battery Description Table */
-{
- ACPI_TABLE_HEADER header;
- u32 warning_level;
- u32 low_level;
- u32 critical_level;
+ACPI_TABLE_DESC *
+acpi_tb_delete_single_table (
+ ACPI_TABLE_DESC *table_desc);
X
-} SMART_BATTERY_DESCRIPTION_TABLE;
+void
+acpi_tb_free_acpi_tables_of_type (
+ ACPI_TABLE_DESC *table_info);
X
X
X /*
- * ACPI Table information. We save the table address, length,
- * and type of memory allocation (mapped or allocated) for each
- * table for 1) when we exit, and 2) if a new table is installed
+ * Acpi_tbrsd - RSDP, RSDT utilities
X */
X
-#define ACPI_MEM_NOT_ALLOCATED 0
-#define ACPI_MEM_ALLOCATED 1
-#define ACPI_MEM_MAPPED 2
-
-#define ACPI_TABLE_SINGLE 0
-#define ACPI_TABLE_MULTIPLE 1
-
-
-/* Data about each known table type */
+ACPI_STATUS
+acpi_tb_get_table_rsdt (
+ u32 *number_of_tables);
X
-typedef struct _acpi_table_support
-{
- char *name;
- char *signature;
- u8 sig_length;
- u8 flags;
- u16 status;
- void **global_ptr;
+u8 *
+acpi_tb_scan_memory_for_rsdp (
+ u8 *start_address,
+ u32 length);
X
-} ACPI_TABLE_SUPPORT;
+ACPI_STATUS
+acpi_tb_find_rsdp (
+ ACPI_TABLE_DESC *table_info);
X
X
X /*
- * Get the architecture-specific tables
+ * Acpi_tbutils - common table utilities
X */
X
-#ifdef IA64
-#include "actbl64.h"
-#else
-#include "actbl32.h"
-#endif
+u8
+acpi_tb_system_table_pointer (
+ void *where);
+
+ACPI_STATUS
+acpi_tb_map_acpi_table (
+ void *physical_address,
+ u32 *size,
+ void **logical_address);
+
+ACPI_STATUS
+acpi_tb_verify_table_checksum (
+ ACPI_TABLE_HEADER *table_header);
+
+u8
+acpi_tb_checksum (


+ void *buffer,
+ u32 length);
+

+ACPI_STATUS
+acpi_tb_validate_table_header (
+ ACPI_TABLE_HEADER *table_header);
X
X
X #endif /* __ACTABLES_H__ */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/actbl.h linux/drivers/acpi/include/actbl.h
--- v2.4.0-test8/linux/drivers/acpi/include/actbl.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/include/actbl.h Fri Sep 15 14:30:30 2000
@@ -0,0 +1,190 @@
+/******************************************************************************
+ *
+ * Name: actbl.h - Table data structures defined in ACPI specification
+ * $Revision: 34 $


+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 R. Byron Moore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+

+#ifndef __ACTBL_H__
+#define __ACTBL_H__
+
+
+/*
+ * Values for description table header signatures


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 026'
echo 'File patch-2.4.0-test9 is continued in part 027'
echo "027" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part029

#!/bin/sh -x
# this is part 029 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 029; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

- *
- * Name: interp.h - Interpreter subcomponent prototypes and defines
- *
- *****************************************************************************/
-
-/*
- * Copyright (C) 2000 R. Byron Moore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __INTERP_H__
-#define __INTERP_H__
-
-
-#include "actypes.h"
-#include "acobject.h"
-
-
-#define WALK_OPERANDS &(walk_state->operands [walk_state->num_operands -1])
-
-
-/* Interpreter constants */
-
-#define AML_END_OF_BLOCK -1
-#define PUSH_PKG_LENGTH 1
-#define DO_NOT_PUSH_PKG_LENGTH 0
-
-
-#define STACK_TOP 0
-#define STACK_BOTTOM (u32) -1
-
-/* Constants for global "When_to_parse_methods" */
-
-#define METHOD_PARSE_AT_INIT 0x0
-#define METHOD_PARSE_JUST_IN_TIME 0x1
-#define METHOD_DELETE_AT_COMPLETION 0x2
-
-
-ACPI_STATUS
-acpi_aml_resolve_operands (
- u16 opcode,
- ACPI_OBJECT_INTERNAL **stack_ptr);
-
-
-/*
- * amxface - External interpreter interfaces
- */
-
-ACPI_STATUS
-acpi_aml_load_table (
- ACPI_TABLE_TYPE table_id);
-
-ACPI_STATUS
-acpi_aml_execute_method (
- ACPI_NAMED_OBJECT *method_entry,
- ACPI_OBJECT_INTERNAL **params,
- ACPI_OBJECT_INTERNAL **return_obj_desc);
-
-
-/*
- * amcopy - Interpreter object copy support
- */
-
-ACPI_STATUS
-acpi_aml_build_copy_internal_package_object (
- ACPI_OBJECT_INTERNAL *source_obj,
- ACPI_OBJECT_INTERNAL *dest_obj);
-
-
-/*
- * amfield - ACPI AML (p-code) execution - field manipulation
- */
-
-
-ACPI_STATUS
-acpi_aml_read_field (
- ACPI_OBJECT_INTERNAL *obj_desc,
- void *buffer,
- u32 buffer_length,
- u32 byte_length,
- u32 datum_length,
- u32 bit_granularity,
- u32 byte_granularity);
-
-ACPI_STATUS
-acpi_aml_write_field (
- ACPI_OBJECT_INTERNAL *obj_desc,
- void *buffer,
- u32 buffer_length,
- u32 byte_length,
- u32 datum_length,
- u32 bit_granularity,
- u32 byte_granularity);
-
-ACPI_STATUS
-acpi_aml_setup_field (
- ACPI_OBJECT_INTERNAL *obj_desc,
- ACPI_OBJECT_INTERNAL *rgn_desc,
- s32 field_bit_width);
-
-ACPI_STATUS
-acpi_aml_read_field_data (
- ACPI_OBJECT_INTERNAL *obj_desc,
- u32 field_byte_offset,
- u32 field_bit_width,
- u32 *value);
-
-ACPI_STATUS
-acpi_aml_access_named_field (
- s32 mode,
- ACPI_HANDLE named_field,
- void *buffer,
- u32 length);
-
-ACPI_STATUS
-acpi_aml_set_named_field_value (
- ACPI_HANDLE named_field,
- void *buffer,
- u32 length);
-
-ACPI_STATUS
-acpi_aml_get_named_field_value (
- ACPI_HANDLE named_field,
- void *buffer,
- u32 length);
-
-
-/*
- * ammisc - ACPI AML (p-code) execution - specific opcodes
- */
-
-ACPI_STATUS
-acpi_aml_exec_create_field (
- u16 opcode,
- ACPI_WALK_STATE *walk_state);
-
-ACPI_STATUS
-acpi_aml_exec_reconfiguration (
- u16 opcode,
- ACPI_WALK_STATE *walk_state);
-
-ACPI_STATUS
-acpi_aml_exec_fatal (
- ACPI_WALK_STATE *walk_state);
-
-ACPI_STATUS
-acpi_aml_exec_index (
- ACPI_WALK_STATE *walk_state,
- ACPI_OBJECT_INTERNAL **return_desc);
-
-ACPI_STATUS
-acpi_aml_exec_match (
- ACPI_WALK_STATE *walk_state,
- ACPI_OBJECT_INTERNAL **return_desc);
-
-ACPI_STATUS
-acpi_aml_exec_create_mutex (
- ACPI_WALK_STATE *walk_state);
-
-ACPI_STATUS
-acpi_aml_exec_create_processor (
- ACPI_GENERIC_OP *op,
- ACPI_HANDLE processor_nTE);
-
-ACPI_STATUS
-acpi_aml_exec_create_power_resource (
- ACPI_GENERIC_OP *op,
- ACPI_HANDLE processor_nTE);
-
-ACPI_STATUS
-acpi_aml_exec_create_region (
- u8 *aml_ptr,
- u32 acpi_aml_length,
- u32 region_space,
- ACPI_WALK_STATE *walk_state);
-
-ACPI_STATUS
-acpi_aml_exec_create_event (
- ACPI_WALK_STATE *walk_state);
-
-ACPI_STATUS
-acpi_aml_exec_create_alias (
- ACPI_WALK_STATE *walk_state);
-
-ACPI_STATUS
-acpi_aml_exec_create_method (
- u8 *aml_ptr,
- u32 acpi_aml_length,
- u32 method_flags,
- ACPI_HANDLE method);
-
-
-/*
- * amprep - ACPI AML (p-code) execution - prep utilities
- */
-
-ACPI_STATUS
-acpi_aml_prep_def_field_value (
- ACPI_NAMED_OBJECT *this_entry,
- ACPI_HANDLE region,
- u8 field_flags,
- u8 field_attribute,
- u32 field_position,
- u32 field_length);
-
-ACPI_STATUS
-acpi_aml_prep_bank_field_value (
- ACPI_NAMED_OBJECT *this_entry,
- ACPI_HANDLE region,
- ACPI_HANDLE bank_reg,
- u32 bank_val,
- u8 field_flags,
- u8 field_attribute,
- u32 field_position,
- u32 field_length);
-
-ACPI_STATUS
-acpi_aml_prep_index_field_value (
- ACPI_NAMED_OBJECT *this_entry,
- ACPI_HANDLE index_reg,
- ACPI_HANDLE data_reg,
- u8 field_flags,
- u8 field_attribute,
- u32 field_position,
- u32 field_length);
-
-ACPI_STATUS
-acpi_aml_prep_operands (
- char *types,
- ACPI_OBJECT_INTERNAL **stack_ptr);
-
-
-/*
- * iepstack - package stack utilities
- */
-
-/*
-u32
-Acpi_aml_pkg_stack_level (
- void);
-
-void
-Acpi_aml_clear_pkg_stack (
- void);
-
-ACPI_STATUS
-Acpi_aml_pkg_push_length (
- u32 Length,
- OPERATING_MODE Load_exec_mode);
-
-ACPI_STATUS
-Acpi_aml_pkg_push_exec_length (
- u32 Length);
-
-ACPI_STATUS
-Acpi_aml_pkg_push_exec (
- u8 *Code,
- u32 Len);
-
-ACPI_STATUS
-Acpi_aml_pkg_pop_length (
- s32 No_err_under,
- OPERATING_MODE Load_exec_mode);
-
-ACPI_STATUS
-Acpi_aml_pkg_pop_exec_length (
- void);
-
-ACPI_STATUS
-Acpi_aml_pkg_pop_exec (
- void);
-
-*/
-
-/*
- * amsystem - Interface to OS services
- */
-
-u16
-acpi_aml_system_thread_id (
- void);
-
-ACPI_STATUS
-acpi_aml_system_do_notify_op (
- ACPI_OBJECT_INTERNAL *value,
- ACPI_OBJECT_INTERNAL *obj_desc);
-
-void
-acpi_aml_system_do_suspend(
- u32 time);
-
-void
-acpi_aml_system_do_stall (
- u32 time);
-
-ACPI_STATUS
-acpi_aml_system_acquire_mutex(
- ACPI_OBJECT_INTERNAL *time,
- ACPI_OBJECT_INTERNAL *obj_desc);
-
-ACPI_STATUS
-acpi_aml_system_release_mutex(
- ACPI_OBJECT_INTERNAL *obj_desc);
-
-ACPI_STATUS
-acpi_aml_system_signal_event(
- ACPI_OBJECT_INTERNAL *obj_desc);
-
-ACPI_STATUS
-acpi_aml_system_wait_event(
- ACPI_OBJECT_INTERNAL *time,
- ACPI_OBJECT_INTERNAL *obj_desc);
-
-ACPI_STATUS
-acpi_aml_system_reset_event(
- ACPI_OBJECT_INTERNAL *obj_desc);
-
-ACPI_STATUS
-acpi_aml_system_wait_semaphore (
- ACPI_HANDLE semaphore,
- u32 timeout);
-
-
-/*
- * ammonadic - ACPI AML (p-code) execution, monadic operators
- */
-
-ACPI_STATUS
-acpi_aml_exec_monadic1 (
- u16 opcode,
- ACPI_WALK_STATE *walk_state);
-
-ACPI_STATUS
-acpi_aml_exec_monadic2 (
- u16 opcode,
- ACPI_WALK_STATE *walk_state,
- ACPI_OBJECT_INTERNAL **return_desc);
-
-ACPI_STATUS
-acpi_aml_exec_monadic2_r (
- u16 opcode,
- ACPI_WALK_STATE *walk_state,
- ACPI_OBJECT_INTERNAL **return_desc);
-
-
-/*
- * amdyadic - ACPI AML (p-code) execution, dyadic operators
- */
-
-ACPI_STATUS
-acpi_aml_exec_dyadic1 (
- u16 opcode,
- ACPI_WALK_STATE *walk_state);
-
-ACPI_STATUS
-acpi_aml_exec_dyadic2 (
- u16 opcode,
- ACPI_WALK_STATE *walk_state,
- ACPI_OBJECT_INTERNAL **return_desc);
-
-ACPI_STATUS
-acpi_aml_exec_dyadic2_r (
- u16 opcode,
- ACPI_WALK_STATE *walk_state,
- ACPI_OBJECT_INTERNAL **return_desc);
-
-ACPI_STATUS
-acpi_aml_exec_dyadic2_s (
- u16 opcode,
- ACPI_WALK_STATE *walk_state,
- ACPI_OBJECT_INTERNAL **return_desc);
-
-
-/*
- * amresolv - Object resolution and get value functions
- */
-
-ACPI_STATUS
-acpi_aml_resolve_to_value (
- ACPI_OBJECT_INTERNAL **stack_ptr);
-
-ACPI_STATUS
-acpi_aml_resolve_entry_to_value (
- ACPI_NAMED_OBJECT **stack_ptr);
-
-ACPI_STATUS
-acpi_aml_resolve_object_to_value (
- ACPI_OBJECT_INTERNAL **stack_ptr);
-
-ACPI_STATUS
-acpi_aml_get_field_unit_value (
- ACPI_OBJECT_INTERNAL *field_desc,
- ACPI_OBJECT_INTERNAL *result_desc);
-
-
-/*
- * amcode - Scanner AML code manipulation routines
- */
-
-s32
-acpi_aml_avail (
- ACPI_SIZE n);
-
-s32
-acpi_aml_peek (
- void);
-
-s32
-acpi_aml_get_pcode_byte (
- u8 *pcode);
-
-u16
-acpi_aml_peek_op (
- void);
-
-u8 *
-acpi_aml_consume_bytes (
- ACPI_SIZE bytes);
-
-ACPI_SIZE
-acpi_aml_consume_stream_bytes (
- ACPI_SIZE bytes_to_get,
- u8 *aml_buffer);
-
-void
-acpi_aml_consume_package (
- OPERATING_MODE load_exec_mode);
-
-void
-acpi_aml_set_pcode_input (
- u8 *base,
- u32 length);
-
-ACPI_STATUS
-acpi_aml_set_method (
- void *object);
-
-ACPI_STATUS
-acpi_aml_prep_exec (
- u8 *pcode,
- u32 pcode_length);
-
-ACPI_HANDLE
-acpi_aml_get_pcode_handle (
- void);
-
-void
-acpi_aml_get_current_location (
- ACPI_OBJECT_INTERNAL *method_desc);
-
-void
-acpi_aml_set_current_location (
- ACPI_OBJECT_INTERNAL *method_desc);
-
-
-/*
- * amdump - Scanner debug output routines
- */
-
-void
-acpi_aml_show_hex_value (
- s32 byte_count,
- u8 *aml_ptr,
- s32 lead_space);
-
-void
-acpi_aml_dump_buffer (
- ACPI_SIZE length);
-
-
-ACPI_STATUS
-acpi_aml_dump_operand (
- ACPI_OBJECT_INTERNAL *entry_desc);
-
-void
-acpi_aml_dump_operands (
- ACPI_OBJECT_INTERNAL **operands,
- OPERATING_MODE interpreter_mode,
- char *ident,
- s32 num_levels,
- char *note,
- char *module_name,
- s32 line_number);
-
-void
-acpi_aml_dump_object_descriptor (
- ACPI_OBJECT_INTERNAL *object,
- u32 flags);
-
-
-void
-acpi_aml_dump_acpi_named_object (
- ACPI_NAMED_OBJECT *entry,
- u32 flags);
-
-
-/*
- * amnames - interpreter/scanner name load/execute
- */
-
-char *
-acpi_aml_allocate_name_string (
- u32 prefix_count,
- u32 num_name_segs);
-
-s32
-acpi_aml_good_char (
- s32 character);
-
-ACPI_STATUS
-acpi_aml_exec_name_segment (
- u8 **in_aml_address,
- char *name_string);
-
-ACPI_STATUS
-acpi_aml_get_name_string (
- OBJECT_TYPE_INTERNAL data_type,
- u8 *in_aml_address,
- char **out_name_string,
- u32 *out_name_length);
-
-u32
-acpi_aml_decode_package_length (
- u32 last_pkg_len);
-
-
-ACPI_STATUS
-acpi_aml_do_name (
- ACPI_OBJECT_TYPE data_type,
- OPERATING_MODE load_exec_mode);
-
-
-/*
- * amstore - Object store support
- */
-
-ACPI_STATUS
-acpi_aml_exec_store (
- ACPI_OBJECT_INTERNAL *op1,
- ACPI_OBJECT_INTERNAL *res);
-
-ACPI_STATUS
-acpi_aml_store_object_to_object (
- ACPI_OBJECT_INTERNAL *val_desc,
- ACPI_OBJECT_INTERNAL *dest_desc);
-
-ACPI_STATUS
-acpi_aml_store_object_to_nte (
- ACPI_OBJECT_INTERNAL *val_desc,
- ACPI_NAMED_OBJECT *entry);
-
-
-/*
- * amutils - interpreter/scanner utilities
- */
-
-void
-acpi_aml_enter_interpreter (
- void);
-
-void
-acpi_aml_exit_interpreter (
- void);
-
-u8
-acpi_aml_validate_object_type (
- ACPI_OBJECT_TYPE type);
-
-u8
-acpi_aml_acquire_global_lock (
- u32 rule);
-
-ACPI_STATUS
-acpi_aml_release_global_lock (
- u8 locked);
-
-void
-acpi_aml_append_operand_diag(
- char *name,
- s32 line,
- u16 op_code,
- ACPI_OBJECT_INTERNAL **operands,
- s32 Noperands);
-
-u32
-acpi_aml_buf_seq (
- void);
-
-s32
-acpi_aml_digits_needed (
- s32 value,
- s32 base);
-
-ACPI_STATUS
-acpi_aml_eisa_id_to_string (
- u32 numeric_id,
- char *out_string);
-
-
-/*
- * amregion - default Op_region handlers
- */
-
-ACPI_STATUS
-acpi_aml_system_memory_space_handler (
- u32 function,
- u32 address,
- u32 bit_width,
- u32 *value,
- void *context);
-
-ACPI_STATUS
-acpi_aml_system_io_space_handler (
- u32 function,
- u32 address,
- u32 bit_width,
- u32 *value,
- void *context);
-
-ACPI_STATUS
-acpi_aml_pci_config_space_handler (
- u32 function,
- u32 address,
- u32 bit_width,
- u32 *value,
- void *context);
-
-ACPI_STATUS
-acpi_aml_embedded_controller_space_handler (
- u32 function,
- u32 address,
- u32 bit_width,
- u32 *value,
- void *context);
-
-ACPI_STATUS
-acpi_aml_sm_bus_space_handler (
- u32 function,
- u32 address,
- u32 bit_width,
- u32 *value,
- void *context);
-
-
-#endif /* __INTERP_H__ */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/macros.h linux/drivers/acpi/include/macros.h
--- v2.4.0-test8/linux/drivers/acpi/include/macros.h Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/include/macros.h Wed Dec 31 16:00:00 1969
@@ -1,423 +0,0 @@
-
-/******************************************************************************
- *
- * Name: macros.h - C macros for the entire subsystem.
- *
- *****************************************************************************/
-
-/*
- * Copyright (C) 2000 R. Byron Moore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __MACROS_H__
-#define __MACROS_H__
-
-/*
- * Data manipulation macros
- */
-
-#ifndef LOWORD
-#define LOWORD(l) ((u16)(NATIVE_UINT)(l))
-#endif
-
-#ifndef HIWORD
-#define HIWORD(l) ((u16)((((NATIVE_UINT)(l)) >> 16) & 0xFFFF))
-#endif
-
-#ifndef LOBYTE
-#define LOBYTE(l) ((u8)(u16)(l))
-#endif
-
-#ifndef HIBYTE
-#define HIBYTE(l) ((u8)((((u16)(l)) >> 8) & 0xFF))
-#endif
-
-#define BIT0(x) ((((x) & 0x01) > 0) ? 1 : 0)
-#define BIT1(x) ((((x) & 0x02) > 0) ? 1 : 0)
-#define BIT2(x) ((((x) & 0x04) > 0) ? 1 : 0)
-
-#define BIT3(x) ((((x) & 0x08) > 0) ? 1 : 0)
-#define BIT4(x) ((((x) & 0x10) > 0) ? 1 : 0)
-#define BIT5(x) ((((x) & 0x20) > 0) ? 1 : 0)
-#define BIT6(x) ((((x) & 0x40) > 0) ? 1 : 0)
-#define BIT7(x) ((((x) & 0x80) > 0) ? 1 : 0)
-
-#define LOW_BASE(w) ((u16) ((w) & 0x0000FFFF))
-#define MID_BASE(b) ((u8) (((b) & 0x00FF0000) >> 16))
-#define HI_BASE(b) ((u8) (((b) & 0xFF000000) >> 24))
-#define LOW_LIMIT(w) ((u16) ((w) & 0x0000FFFF))
-#define HI_LIMIT(b) ((u8) (((b) & 0x00FF0000) >> 16))
-
-
- /*
- * Extract a byte of data using a pointer. Any more than a byte and we
- * get into potential aligment issues -- see the STORE macros below
- */
-#define GET8(addr) (*(u8*)(addr))
-
-
-/*
- * Macros for moving data around to/from buffers that are possibly unaligned.
- * If the hardware supports the transfer of unaligned data, just do the store.
- * Otherwise, we have to move one byte at a time.
- */
-
-#ifdef _HW_ALIGNMENT_SUPPORT
-
-/* The hardware supports unaligned transfers, just do the move */
-
-#define MOVE_UNALIGNED16_TO_16(d,s) *(u16*)(d) = *(u16*)(s)
-#define MOVE_UNALIGNED32_TO_32(d,s) *(u32*)(d) = *(u32*)(s)
-#define MOVE_UNALIGNED16_TO_32(d,s) *(u32*)(d) = *(u16*)(s)
-
-#else
-/*
- * The hardware does not support unaligned transfers. We must move the
- * data one byte at a time. These macros work whether the source or
- * the destination (or both) is/are unaligned.
- */
-
-#define MOVE_UNALIGNED16_TO_16(d,s) {((char *)(d))[0] = ((char *)(s))[0];\
- ((char *)(d))[1] = ((char *)(s))[1];}
-
-#define MOVE_UNALIGNED32_TO_32(d,s) {((char *)(d))[0] = ((char *)(s))[0];\
- ((char *)(d))[1] = ((char *)(s))[1];\
- ((char *)(d))[2] = ((char *)(s))[2];\
- ((char *)(d))[3] = ((char *)(s))[3];}
-
-#define MOVE_UNALIGNED16_TO_32(d,s) {(*(u32*)(d)) = 0; MOVE_UNALIGNED16_TO_16(d,s);}
-
-#endif
-
-
-/*
- * Fast power-of-two math macros for non-optimized compilers
- */
-
-#define _DIV(value,power_of2) ((value) >> (power_of2))
-#define _MUL(value,power_of2) ((value) << (power_of2))
-#define _MOD(value,divisor) ((value) & ((divisor) -1))
-
-#define DIV_2(a) _DIV(a,1)
-#define MUL_2(a) _MUL(a,1)
-#define MOD_2(a) _MOD(a,2)
-
-#define DIV_4(a) _DIV(a,2)
-#define MUL_4(a) _MUL(a,2)
-#define MOD_4(a) _MOD(a,4)
-
-#define DIV_8(a) _DIV(a,3)
-#define MUL_8(a) _MUL(a,3)
-#define MOD_8(a) _MOD(a,8)
-
-#define DIV_16(a) _DIV(a,4)
-#define MUL_16(a) _MUL(a,4)
-#define MOD_16(a) _MOD(a,16)
-
-
-/*
- * Rounding macros (Power of two boundaries only)
- */
-
-#define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1)))
-#define ROUND_UP(value,boundary) (((value) + ((boundary)-1)) & (~((boundary)-1)))
-
-#define ROUND_DOWN_TO_32_BITS(a) ROUND_DOWN(a,4)
-#define ROUND_DOWN_TO_NATIVE_WORD(a) ROUND_DOWN(a,ALIGNED_ADDRESS_BOUNDARY)
-
-#define ROUND_UP_TO_32_bITS(a) ROUND_UP(a,4)
-#define ROUND_UP_TO_NATIVE_WORD(a) ROUND_UP(a,ALIGNED_ADDRESS_BOUNDARY)
-
-
-#ifdef DEBUG_ASSERT
-#undef DEBUG_ASSERT
-#endif
-
-
-/*
- * An ACPI_HANDLE (which is actually an ACPI_NAMED_OBJECT*) can appear in some contexts,
- * such as on ap_obj_stack, where a pointer to an ACPI_OBJECT_INTERNAL can also
- * appear. This macro is used to distinguish them.
- *
- * The Data_type field is the first field in both structures.
- */
-
-#define VALID_DESCRIPTOR_TYPE(d,t) (((ACPI_NAMED_OBJECT*)d)->data_type == t)
-
-
-/* Macro to test the object type */
-
-#define IS_THIS_OBJECT_TYPE(d,t) (((ACPI_OBJECT_INTERNAL *)d)->common.type == (u8)t)
-
-
-/*
- * Macro to check if a pointer is within an ACPI table.
- * Parameter (a) is the pointer to check. Parameter (b) must be defined
- * as a pointer to an ACPI_TABLE_HEADER. (b+1) then points past the header,
- * and ((u8 *)b+b->Length) points one byte past the end of the table.
- */
-
-#ifndef _IA16
-#define IS_IN_ACPI_TABLE(a,b) (((u8 *)(a) >= (u8 *)(b + 1)) &&\
- ((u8 *)(a) < ((u8 *)b + b->length)))
-
-#else
-#define IS_IN_ACPI_TABLE(a,b) (_segment)(a) == (_segment)(b) &&\
- (((u8 *)(a) >= (u8 *)(b + 1)) &&\
- ((u8 *)(a) < ((u8 *)b + b->length)))
-#endif
-
-/*
- * Macros for the master AML opcode table
- */
-
-#ifdef ACPI_DEBUG
-#define OP_INFO_ENTRY(opcode,flags,name,Pargs,Iargs) {opcode,flags,Pargs,Iargs,name}
-#else
-#define OP_INFO_ENTRY(opcode,flags,name,Pargs,Iargs) {opcode,flags,Pargs,Iargs}
-#endif
-
-#define ARG_TYPE_WIDTH 5
-#define ARG_1(x) ((u32)(x))
-#define ARG_2(x) ((u32)(x) << (1 * ARG_TYPE_WIDTH))
-#define ARG_3(x) ((u32)(x) << (2 * ARG_TYPE_WIDTH))
-#define ARG_4(x) ((u32)(x) << (3 * ARG_TYPE_WIDTH))
-#define ARG_5(x) ((u32)(x) << (4 * ARG_TYPE_WIDTH))
-#define ARG_6(x) ((u32)(x) << (5 * ARG_TYPE_WIDTH))
-
-#define ARGI_LIST1(a) (ARG_1(a))
-#define ARGI_LIST2(a,b) (ARG_1(b)|ARG_2(a))
-#define ARGI_LIST3(a,b,c) (ARG_1(c)|ARG_2(b)|ARG_3(a))
-#define ARGI_LIST4(a,b,c,d) (ARG_1(d)|ARG_2(c)|ARG_3(b)|ARG_4(a))
-#define ARGI_LIST5(a,b,c,d,e) (ARG_1(e)|ARG_2(d)|ARG_3(c)|ARG_4(b)|ARG_5(a))
-#define ARGI_LIST6(a,b,c,d,e,f) (ARG_1(f)|ARG_2(e)|ARG_3(d)|ARG_4(c)|ARG_5(b)|ARG_6(a))
-
-#define ARGP_LIST1(a) (ARG_1(a))
-#define ARGP_LIST2(a,b) (ARG_1(a)|ARG_2(b))
-#define ARGP_LIST3(a,b,c) (ARG_1(a)|ARG_2(b)|ARG_3(c))
-#define ARGP_LIST4(a,b,c,d) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d))
-#define ARGP_LIST5(a,b,c,d,e) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e))
-#define ARGP_LIST6(a,b,c,d,e,f) (ARG_1(a)|ARG_2(b)|ARG_3(c)|ARG_4(d)|ARG_5(e)|ARG_6(f))
-
-#define GET_CURRENT_ARG_TYPE(list) (list & 0x1F)
-#define INCREMENT_ARG_LIST(list) (list >>= ARG_TYPE_WIDTH)
-
-
-/*
- * Reporting macros that are never compiled out
- */
-
-/*
- * Error reporting. These versions add callers module and line#. Since
- * _THIS_MODULE gets compiled out when ACPI_DEBUG isn't defined, only
- * use it in debug mode.
- */
-
-#ifdef ACPI_DEBUG
-
-#define REPORT_INFO(a) _report_info(_THIS_MODULE,__LINE__,_COMPONENT,a)
-#define REPORT_ERROR(a) _report_error(_THIS_MODULE,__LINE__,_COMPONENT,a)
-#define REPORT_WARNING(a) _report_warning(_THIS_MODULE,__LINE__,_COMPONENT,a)
-#define REPORT_SUCCESS(a) _report_success(_THIS_MODULE,__LINE__,_COMPONENT,a)
-
-#else
-
-#define REPORT_INFO(a) _report_info("",__LINE__,_COMPONENT,a)
-#define REPORT_ERROR(a) _report_error("",__LINE__,_COMPONENT,a)
-#define REPORT_WARNING(a) _report_warning("",__LINE__,_COMPONENT,a)
-#define REPORT_SUCCESS(a) _report_success("",__LINE__,_COMPONENT,a)
-
-#endif
-
-/* Error reporting. These versions pass thru the module and line# */
-
-#define _REPORT_INFO(a,b,c,d) _report_info(a,b,c,d)
-#define _REPORT_ERROR(a,b,c,d) _report_error(a,b,c,d)
-#define _REPORT_WARNING(a,b,c,d) _report_warning(a,b,c,d)
-
-/* Buffer dump macros */
-
-#define DUMP_BUFFER(a,b) acpi_cm_dump_buffer((char *)a,b,DB_BYTE_DISPLAY,_COMPONENT)
-
-/*
- * Debug macros that are conditionally compiled
- */
-
-#ifdef ACPI_DEBUG
-
-#define MODULE_NAME(name) static char *_THIS_MODULE = name
-
-/*
- * Function entry tracing.
- * The first parameter should be the procedure name as a quoted string. This is declared
- * as a local string ("_Proc_name) so that it can be also used by the function exit macros below.
- */
-
-#define FUNCTION_TRACE(a) char * _proc_name = a;\
- function_trace(_THIS_MODULE,__LINE__,_COMPONENT,a)
-#define FUNCTION_TRACE_PTR(a,b) char * _proc_name = a;\
- function_trace_ptr(_THIS_MODULE,__LINE__,_COMPONENT,a,(void *)b)
-#define FUNCTION_TRACE_U32(a,b) char * _proc_name = a;\
- function_trace_u32(_THIS_MODULE,__LINE__,_COMPONENT,a,(u32)b)
-#define FUNCTION_TRACE_STR(a,b) char * _proc_name = a;\
- function_trace_str(_THIS_MODULE,__LINE__,_COMPONENT,a,(char *)b)
-/*
- * Function exit tracing.
- * WARNING: These macros include a return statement. This is usually considered
- * bad form, but having a separate exit macro is very ugly and difficult to maintain.
- * One of the FUNCTION_TRACE macros above must be used in conjunction with these macros
- * so that "_Proc_name" is defined.
- */
-#define return_VOID {function_exit(_THIS_MODULE,__LINE__,_COMPONENT,_proc_name);return;}
-#define return_ACPI_STATUS(s) {function_status_exit(_THIS_MODULE,__LINE__,_COMPONENT,_proc_name,s);return(s);}
-#define return_VALUE(s) {function_value_exit(_THIS_MODULE,__LINE__,_COMPONENT,_proc_name,(NATIVE_UINT)s);return(s);}
-#define return_PTR(s) {function_ptr_exit(_THIS_MODULE,__LINE__,_COMPONENT,_proc_name,(char *)s);return(s);}
-
-
-/* Conditional execution */
-
-#define DEBUG_EXEC(a) a;
-#define NORMAL_EXEC(a)
-
-#define DEBUG_DEFINE(a) a;
-#define DEBUG_ONLY_MEMBERS(a) a;
-
-
-/* Stack and buffer dumping */
-
-#define DUMP_STACK_ENTRY(a) acpi_aml_dump_operand(a)
-#define DUMP_OPERANDS(a,b,c,d,e) acpi_aml_dump_operands(a,b,c,d,e,_THIS_MODULE,__LINE__)
-
-
-#define DUMP_ENTRY(a,b) acpi_ns_dump_entry (a,b)
-#define DUMP_TABLES(a,b) acpi_ns_dump_tables(a,b)
-#define DUMP_PATHNAME(a,b,c,d) acpi_ns_dump_pathname(a,b,c,d)
-#define BREAK_MSG(a) acpi_os_breakpoint (a)
-
-/*
- * Generate INT3 on ACPI_ERROR (Debug only!)
- */
-
-#define ERROR_BREAK
-#ifdef ERROR_BREAK
-#define BREAK_ON_ERROR(lvl) if ((lvl)&ACPI_ERROR) acpi_os_breakpoint("Fatal error encountered\n")
-#else
-#define BREAK_ON_ERROR(lvl)
-#endif
-
-/*
- * Master debug print macros
- * Print iff:
- * 1) Debug print for the current component is enabled
- * 2) Debug error level or trace level for the print statement is enabled
- *
- */
-
-#define PARAM_LIST(pl) pl
-
-#define TEST_DEBUG_SWITCH(lvl) if (((lvl) & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer))
-
-#define DEBUG_PRINT(lvl,fp) TEST_DEBUG_SWITCH(lvl) {\
- debug_print_prefix (_THIS_MODULE,__LINE__);\
- debug_print_raw PARAM_LIST(fp);\
- BREAK_ON_ERROR(lvl);}
-
-#define DEBUG_PRINT_RAW(lvl,fp) TEST_DEBUG_SWITCH(lvl) {\
- debug_print_raw PARAM_LIST(fp);}
-
-
-/* Assert macros */
-
-#define ACPI_ASSERT(exp) if(!(exp)) \
- acpi_os_dbg_assert(#exp, __FILE__, __LINE__, "Failed Assertion")
-
-#define DEBUG_ASSERT(msg, exp) if(!(exp)) \
- acpi_os_dbg_assert(#exp, __FILE__, __LINE__, msg)
-
-
-#else
-/*
- * This is the non-debug case -- make everything go away,
- * leaving no executable debug code!
- */
-
-#define MODULE_NAME(name)
-#define _THIS_MODULE ""
-
-#define DEBUG_EXEC(a)
-#define NORMAL_EXEC(a) a;
-
-#define DEBUG_DEFINE(a)
-#define DEBUG_ONLY_MEMBERS(a)
-#define FUNCTION_TRACE(a)
-#define FUNCTION_TRACE_PTR(a,b)
-#define FUNCTION_TRACE_U32(a,b)
-#define FUNCTION_TRACE_STR(a,b)
-#define FUNCTION_EXIT
-#define FUNCTION_STATUS_EXIT(s)
-#define FUNCTION_VALUE_EXIT(s)
-#define DUMP_STACK_ENTRY(a)
-#define DUMP_OPERANDS(a,b,c,d,e)
-#define DUMP_ENTRY(a,b)
-#define DUMP_TABLES(a,b)
-#define DUMP_PATHNAME(a,b,c,d)
-#define DEBUG_PRINT(l,f)
-#define DEBUG_PRINT_RAW(l,f)
-#define BREAK_MSG(a)
-
-#define return_VOID return
-#define return_ACPI_STATUS(s) return(s)
-#define return_VALUE(s) return(s)
-#define return_PTR(s) return(s)
-
-#define ACPI_ASSERT(exp)
-#define DEBUG_ASSERT(msg, exp)
-
-#endif
-
-
-/*
- * For 16-bit code, we want to shrink some things even though
- * we are using ACPI_DEBUG to get the debug output
- */
-#ifdef _IA16
-#undef DEBUG_ONLY_MEMBERS
-#define DEBUG_ONLY_MEMBERS(a)
-#undef OP_INFO_ENTRY
-#define OP_INFO_ENTRY(opcode,flags,name,Pargs,Iargs) {opcode,flags,Pargs,Iargs}
-#endif
-
-
-#ifndef ACPI_DEBUG
-
-#define ADD_OBJECT_NAME(a,b)
-
-#else
-
-
-/*
- * 1) Set name to blanks
- * 2) Copy the object name
- */
-
-#define ADD_OBJECT_NAME(a,b) MEMSET (a->common.name, ' ', sizeof (a->common.name));\
- STRNCPY (a->common.name, acpi_gbl_ns_type_names[b], sizeof (a->common.name))
-
-#endif
-
-
-#endif /* MACROS_H */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/namesp.h linux/drivers/acpi/include/namesp.h
--- v2.4.0-test8/linux/drivers/acpi/include/namesp.h Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/include/namesp.h Wed Dec 31 16:00:00 1969
@@ -1,424 +0,0 @@
-
-/******************************************************************************
- *
- * Name: namesp.h - Namespace subcomponent prototypes and defines
- *
- *****************************************************************************/
-
-/*
- * Copyright (C) 2000 R. Byron Moore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __NAMESPACE_H__
-#define __NAMESPACE_H__
-
-#include "actables.h"
-
-
-/* To search the entire name space, pass this as Search_base */
-
-#define NS_ALL ((ACPI_HANDLE)0)
-
-/*
- * Elements of Acpi_ns_properties are bit significant
- * and should be one-to-one with values of ACPI_OBJECT_TYPE
- */
-#define NSP_NORMAL 0
-#define NSP_NEWSCOPE 1 /* a definition of this type opens a name scope */
-#define NSP_LOCAL 2 /* suppress search of enclosing scopes */
-
-
-/* Definitions of the predefined namespace names */
-
-#define ACPI_UNKNOWN_NAME (u32) 0x3F3F3F3F /* Unknown name is "????" */
-#define ACPI_ROOT_NAME (u32) 0x2F202020 /* Root name is "/ " */
-#define ACPI_SYS_BUS_NAME (u32) 0x5F53425F /* Sys bus name is "_SB_" */
-
-#define NS_ROOT_PATH "/"
-#define NS_SYSTEM_BUS "_SB_"
-
-
-/* Flags for Acpi_ns_lookup, Acpi_ns_search_and_enter */
-
-#define NS_NO_UPSEARCH 0
-#define NS_SEARCH_PARENT 0x01
-#define NS_DONT_OPEN_SCOPE 0x02
-#define NS_NO_PEER_SEARCH 0x04
-
-#define NS_WALK_UNLOCK TRUE
-#define NS_WALK_NO_UNLOCK FALSE
-
-
-ACPI_STATUS
-acpi_ns_walk_namespace (
- OBJECT_TYPE_INTERNAL type,
- ACPI_HANDLE start_object,
- u32 max_depth,
- u8 unlock_before_callback,
- WALK_CALLBACK user_function,
- void *context,
- void **return_value);
-
-
-ACPI_NAMED_OBJECT*
-acpi_ns_get_next_object (
- OBJECT_TYPE_INTERNAL type,
- ACPI_NAMED_OBJECT *parent,
- ACPI_NAMED_OBJECT *child);
-
-
-ACPI_STATUS
-acpi_ns_delete_namespace_by_owner (
- u16 table_id);
-
-void
-acpi_ns_free_table_entry (
- ACPI_NAMED_OBJECT *entry);
-
-
-/* Namespace loading - nsload */
-
-ACPI_STATUS
-acpi_ns_parse_table (
- ACPI_TABLE_DESC *table_desc,
- ACPI_NAME_TABLE *scope);
-
-ACPI_STATUS
-acpi_ns_load_table (
- ACPI_TABLE_DESC *table_desc,
- ACPI_NAMED_OBJECT *entry);
-
-ACPI_STATUS
-acpi_ns_load_table_by_type (
- ACPI_TABLE_TYPE table_type);
-
-
-/*
- * Top-level namespace access - nsaccess
- */
-
-
-ACPI_STATUS
-acpi_ns_root_initialize (
- void);
-
-ACPI_STATUS
-acpi_ns_lookup (
- ACPI_GENERIC_STATE *scope_info,
- char *name,
- OBJECT_TYPE_INTERNAL type,
- OPERATING_MODE interpreter_mode,
- u32 flags,
- ACPI_WALK_STATE *walk_state,
- ACPI_NAMED_OBJECT **ret_entry);
-
-
-/*
- * Table allocation/deallocation - nsalloc
- */
-
-ACPI_NAME_TABLE *
-acpi_ns_allocate_name_table (
- u32 num_entries);
-
-ACPI_STATUS
-acpi_ns_delete_namespace_subtree (
- ACPI_NAMED_OBJECT *parent_handle);
-
-void
-acpi_ns_detach_object (
- ACPI_HANDLE object);
-
-void
-acpi_ns_delete_name_table (
- ACPI_NAME_TABLE *name_table);
-
-
-/*
- * Namespace modification - nsmodify
- */
-
-ACPI_STATUS
-acpi_ns_unload_namespace (
- ACPI_HANDLE handle);
-
-ACPI_STATUS
-acpi_ns_delete_subtree (
- ACPI_HANDLE start_handle);
-
-
-/*
- * Namespace dump/print utilities - nsdump
- */
-
-void
-acpi_ns_dump_tables (
- ACPI_HANDLE search_base,
- s32 max_depth);
-
-void
-acpi_ns_dump_entry (
- ACPI_HANDLE handle,
- u32 debug_level);
-
-ACPI_STATUS
-acpi_ns_dump_pathname (
- ACPI_HANDLE handle,
- char *msg,
- u32 level,
- u32 component);
-
-void
-acpi_ns_dump_root_devices (
- void);
-
-void
-acpi_ns_dump_objects (
- OBJECT_TYPE_INTERNAL type,
- u32 max_depth,
- u32 ownder_id,
- ACPI_HANDLE start_handle);
-
-
-/*
- * Namespace evaluation functions - nseval
- */
-
-ACPI_STATUS
-acpi_ns_evaluate_by_handle (
- ACPI_NAMED_OBJECT *object_nte,
- ACPI_OBJECT_INTERNAL **params,
- ACPI_OBJECT_INTERNAL **return_object);
-
-ACPI_STATUS
-acpi_ns_evaluate_by_name (
- char *pathname,
- ACPI_OBJECT_INTERNAL **params,
- ACPI_OBJECT_INTERNAL **return_object);
-
-ACPI_STATUS
-acpi_ns_evaluate_relative (
- ACPI_NAMED_OBJECT *object_nte,
- char *pathname,
- ACPI_OBJECT_INTERNAL **params,
- ACPI_OBJECT_INTERNAL **return_object);
-
-ACPI_STATUS
-acpi_ns_execute_control_method (
- ACPI_NAMED_OBJECT *method_entry,
- ACPI_OBJECT_INTERNAL **params,
- ACPI_OBJECT_INTERNAL **return_obj_desc);
-
-ACPI_STATUS
-acpi_ns_get_object_value (
- ACPI_NAMED_OBJECT *object_entry,
- ACPI_OBJECT_INTERNAL **return_obj_desc);
-
-
-/*
- * Parent/Child/Peer utility functions - nsfamily
- */
-
-ACPI_NAME
-acpi_ns_find_parent_name (
- ACPI_NAMED_OBJECT *entry_to_search);
-
-u8
-acpi_ns_exist_downstream_sibling (
- ACPI_NAMED_OBJECT *this_entry);
-
-
-/*
- * Scope manipulation - nsscope
- */
-
-s32
-acpi_ns_opens_scope (
- OBJECT_TYPE_INTERNAL type);
-
-char *
-acpi_ns_name_of_scope (
- ACPI_NAME_TABLE *scope);
-
-char *
-acpi_ns_name_of_current_scope (
- ACPI_WALK_STATE *walk_state);
-
-ACPI_STATUS
-acpi_ns_handle_to_pathname (
- ACPI_HANDLE obj_handle,
- u32 *buf_size,
- char *user_buffer);
-
-u8
-acpi_ns_pattern_match (
- ACPI_NAMED_OBJECT *obj_entry,
- char *search_for);
-
-ACPI_STATUS
-acpi_ns_name_compare (
- ACPI_HANDLE obj_handle,
- u32 level,
- void *context,
- void **return_value);
-
-void
-acpi_ns_low_find_names (
- ACPI_NAMED_OBJECT *this_entry,
- char *search_for,
- s32 *count,
- ACPI_HANDLE list[],
- s32 max_depth);
-
-ACPI_HANDLE *
-acpi_ns_find_names (
- char *search_for,
- ACPI_HANDLE search_base,
- s32 max_depth);
-
-ACPI_STATUS
-acpi_ns_get_named_object (
- char *pathname,
- ACPI_NAME_TABLE *in_scope,
- ACPI_NAMED_OBJECT **out_nte);
-
-/*
- * Object management for NTEs - nsobject
- */
-
-ACPI_STATUS
-acpi_ns_attach_method (
- ACPI_HANDLE obj_handle,
- u8 *pcode_addr,
- u32 pcode_length);
-
-ACPI_STATUS
-acpi_ns_attach_object (
- ACPI_HANDLE obj_handle,
- ACPI_HANDLE value,
- OBJECT_TYPE_INTERNAL type);
-
-
-void *
-acpi_ns_compare_value (
- ACPI_HANDLE obj_handle,
- u32 level,
- void *obj_desc);
-
-ACPI_HANDLE
-acpi_ns_find_attached_object (
- ACPI_OBJECT_INTERNAL *obj_desc,
- ACPI_HANDLE search_base,
- s32 max_depth);
-
-
-/*
- * Namespace searching and entry - nssearch
- */
-
-ACPI_STATUS
-acpi_ns_search_and_enter (
- u32 entry_name,
- ACPI_WALK_STATE *walk_state,
- ACPI_NAME_TABLE *name_table,
- OPERATING_MODE interpreter_mode,
- OBJECT_TYPE_INTERNAL type,
- u32 flags,
- ACPI_NAMED_OBJECT **ret_entry);
-
-void
-acpi_ns_initialize_table (
- ACPI_NAME_TABLE *new_table,
- ACPI_NAME_TABLE *parent_scope,
- ACPI_NAMED_OBJECT *parent_entry);
-
-ACPI_STATUS
-acpi_ns_search_one_scope (
- u32 entry_name,
- ACPI_NAME_TABLE *name_table,
- OBJECT_TYPE_INTERNAL type,
- ACPI_NAMED_OBJECT **ret_entry,
- NS_SEARCH_DATA *ret_info);
-
-
-/*
- * Utility functions - nsutils
- */
-
-u8
-acpi_ns_valid_root_prefix (
- char prefix);
-
-u8
-acpi_ns_valid_path_separator (
- char sep);
-
-OBJECT_TYPE_INTERNAL
-acpi_ns_get_type (
- ACPI_HANDLE obj_handle);
-
-void *
-acpi_ns_get_attached_object (
- ACPI_HANDLE obj_handle);
-
-s32
-acpi_ns_local (
- OBJECT_TYPE_INTERNAL type);
-
-ACPI_STATUS
-acpi_ns_internalize_name (
- char *dotted_name,
- char **converted_name);
-
-ACPI_STATUS
-acpi_ns_externalize_name (
- u32 internal_name_length,
- char *internal_name,
- u32 *converted_name_length,
- char **converted_name);
-
-s32
-is_ns_object (
- ACPI_OBJECT_INTERNAL *p_oD);
-
-s32
-acpi_ns_mark_nS(
- void);
-
-ACPI_NAMED_OBJECT*
-acpi_ns_convert_handle_to_entry (
- ACPI_HANDLE handle);
-
-ACPI_HANDLE
-acpi_ns_convert_entry_to_handle(
- ACPI_NAMED_OBJECT*nte);
-
-void
-acpi_ns_terminate (
- void);
-
-ACPI_NAMED_OBJECT *
-acpi_ns_get_parent_entry (
- ACPI_NAMED_OBJECT *this_entry);
-
-
-ACPI_NAMED_OBJECT *
-acpi_ns_get_next_valid_entry (
- ACPI_NAMED_OBJECT *this_entry);
-
-
-#endif /* __NAMESPACE_H__ */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/output.h linux/drivers/acpi/include/output.h
--- v2.4.0-test8/linux/drivers/acpi/include/output.h Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/include/output.h Wed Dec 31 16:00:00 1969
@@ -1,124 +0,0 @@
-
-/******************************************************************************
- *
- * Name: output.h -- debug output
- *
- *****************************************************************************/
-
-/*
- * Copyright (C) 2000 R. Byron Moore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _OUTPUT_H
-#define _OUTPUT_H
-
-/*
- * Debug levels and component IDs. These are used to control the
- * granularity of the output of the DEBUG_PRINT macro -- on a per-
- * component basis and a per-exception-type basis.
- */
-
-/* Component IDs -- used in the global "Debug_layer" */
-
-#define GLOBAL 0x00000001
-#define COMMON 0x00000002
-#define PARSER 0x00000004
-#define DISPATCHER 0x00000008
-#define INTERPRETER 0x00000010
-#define NAMESPACE 0x00000020
-#define RESOURCE_MANAGER 0x00000040
-#define TABLE_MANAGER 0x00000080
-#define EVENT_HANDLING 0x00000100
-#define HARDWARE 0x00000200
-#define MISCELLANEOUS 0x00000400
-#define OS_DEPENDENT 0x00000800
-
-#define BUS_MANAGER 0x00001000
-
-#define PROCESSOR_CONTROL 0x00002000
-#define SYSTEM_CONTROL 0x00004000
-#define THERMAL_CONTROL 0x00008000
-#define POWER_CONTROL 0x00010000
-
-#define EMBEDDED_CONTROLLER 0x00020000
-#define BATTERY 0x00040000
-
-#define DEBUGGER 0x00100000
-#define ALL_COMPONENTS 0x001FFFFF
-
-
-/* Exception level -- used in the global "Debug_level" */
-
-#define ACPI_OK 0x00000001
-#define ACPI_INFO 0x00000002
-#define ACPI_WARN 0x00000004
-#define ACPI_ERROR 0x00000008
-#define ACPI_FATAL 0x00000010
-#define ACPI_DEBUG_OBJECT 0x00000020
-#define ACPI_ALL 0x0000003F
-
-
-/* Trace level -- also used in the global "Debug_level" */
-
-#define TRACE_PARSE 0x00000100
-#define TRACE_DISPATCH 0x00000200
-#define TRACE_LOAD 0x00000400
-#define TRACE_EXEC 0x00000800
-#define TRACE_NAMES 0x00001000
-#define TRACE_OPREGION 0x00002000
-#define TRACE_BFIELD 0x00004000
-#define TRACE_TRASH 0x00008000
-#define TRACE_TABLES 0x00010000
-#define TRACE_FUNCTIONS 0x00020000
-#define TRACE_VALUES 0x00040000
-#define TRACE_OBJECTS 0x00080000
-#define TRACE_ALLOCATIONS 0x00100000
-#define TRACE_RESOURCES 0x00200000
-#define TRACE_IO 0x00400000
-#define TRACE_INTERRUPTS 0x00800000
-#define TRACE_USER_REQUESTS 0x01000000
-#define TRACE_PACKAGE 0x02000000
-#define TRACE_MUTEX 0x04000000
-
-#define TRACE_ALL 0x0FFFFF00
-
-
-/* Exceptionally verbose output -- also used in the global "Debug_level" */
-
-#define VERBOSE_AML_DISASSEMBLE 0x10000000
-#define VERBOSE_INFO 0x20000000
-#define VERBOSE_TABLES 0x40000000
-#define VERBOSE_EVENTS 0x80000000
-
-#define VERBOSE_ALL 0x70000000
-
-
-/* Defaults for Debug_level, debug and normal */
-
-#define DEBUG_DEFAULT (ACPI_OK | ACPI_WARN | ACPI_ERROR | ACPI_DEBUG_OBJECT | TRACE_TABLES | TRACE_IO)
-#define NORMAL_DEFAULT (ACPI_OK | ACPI_WARN | ACPI_ERROR | ACPI_DEBUG_OBJECT)
-#define DEBUG_ALL (VERBOSE_AML_DISASSEMBLE | TRACE_ALL | ACPI_ALL)
-
-/* Misc defines */
-
-#define HEX 0x01
-#define ASCII 0x02
-#define FULL_ADDRESS 0x04
-#define CHARS_PER_LINE 16 /* used in Dump_buf function */
-
-
-#endif /* _OUTPUT_H */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/parser.h linux/drivers/acpi/include/parser.h
--- v2.4.0-test8/linux/drivers/acpi/include/parser.h Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/include/parser.h Wed Dec 31 16:00:00 1969
@@ -1,327 +0,0 @@
-/******************************************************************************
- *
- * Module Name: parser.h - AML Parser subcomponent prototypes and defines
- *
- *****************************************************************************/
-
-/*
- * Copyright (C) 2000 R. Byron Moore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#ifndef _PARSER_H_
-#define _PARSER_H_
-
-
-#define OP_HAS_RETURN_VALUE 1
-
-/* variable # arguments */
-
-#define ACPI_VAR_ARGS ACPI_UINT32_MAX
-
-/* maximum virtual address */
-
-#define ACPI_MAX_AML ((u8 *)(~0UL))
-
-
-#define PARSE_DELETE_TREE 1
-
-
-/* psapi - Parser external interfaces */
-
-ACPI_STATUS
-acpi_psx_load_table (
- u8 *pcode_addr,
- s32 pcode_length);
-
-ACPI_STATUS
-acpi_psx_execute (
- ACPI_NAMED_OBJECT *method_entry,
- ACPI_OBJECT_INTERNAL **params,
- ACPI_OBJECT_INTERNAL **return_obj_desc);
-
-
-u8
-acpi_ps_is_namespace_object_op (
- u16 opcode);
-u8
-acpi_ps_is_namespace_op (
- u16 opcode);
-
-
-/******************************************************************************
- *
- * Parser interfaces
- *
- *****************************************************************************/
-
-
-/* psargs - Parse AML opcode arguments */
-
-u8 *
-acpi_ps_get_next_package_end (
- ACPI_PARSE_STATE *parser_state);
-
-char *
-acpi_ps_get_next_namestring (
- ACPI_PARSE_STATE *parser_state);
-
-void
-acpi_ps_get_next_simple_arg (
- ACPI_PARSE_STATE *parser_state,
- s32 arg_type, /* type of argument */
- ACPI_GENERIC_OP *arg); /* (OUT) argument data */
-
-void
-acpi_ps_get_next_namepath (
- ACPI_PARSE_STATE *parser_state,
- ACPI_GENERIC_OP *arg,
- u32 *arg_count,
- u8 method_call);
-
-ACPI_GENERIC_OP *
-acpi_ps_get_next_field (
- ACPI_PARSE_STATE *parser_state);
-
-ACPI_GENERIC_OP *
-acpi_ps_get_next_arg (
- ACPI_PARSE_STATE *parser_state,
- s32 arg_type,
- u32 *arg_count);
-
-
-/* psopcode - AML Opcode information */
-
-ACPI_OP_INFO *
-acpi_ps_get_opcode_info (
- u16 opcode);
-
-char *
-acpi_ps_get_opcode_name (
- u16 opcode);
-
-
-/* psparse - top level parsing routines */
-
-void
-acpi_ps_delete_parse_tree (
- ACPI_GENERIC_OP *root);
-
-ACPI_STATUS
-acpi_ps_parse_loop (
- ACPI_PARSE_STATE *parser_state,
- ACPI_WALK_STATE *walk_state,
- u32 parse_flags);
-
-
-ACPI_STATUS
-acpi_ps_parse_aml (
- ACPI_GENERIC_OP *start_scope,
- u8 *aml,
- u32 acpi_aml_size,
- u32 parse_flags);
-
-ACPI_STATUS
-acpi_ps_parse_table (
- u8 *aml,
- s32 aml_size,
- INTERPRETER_CALLBACK descending_callback,
- INTERPRETER_CALLBACK ascending_callback,
- ACPI_GENERIC_OP **root_object);
-
-u16
-acpi_ps_peek_opcode (
- ACPI_PARSE_STATE *state);
-
-
-/* psscope - Scope stack management routines */
-
-
-ACPI_STATUS
-acpi_ps_init_scope (
- ACPI_PARSE_STATE *parser_state,
- ACPI_GENERIC_OP *root);
-
-ACPI_GENERIC_OP *
-acpi_ps_get_parent_scope (
- ACPI_PARSE_STATE *state);
-
-u8
-acpi_ps_has_completed_scope (
- ACPI_PARSE_STATE *parser_state);
-
-void
-acpi_ps_pop_scope (
- ACPI_PARSE_STATE *parser_state,
- ACPI_GENERIC_OP **op,
- u32 *arg_list);
-
-ACPI_STATUS
-acpi_ps_push_scope (
- ACPI_PARSE_STATE *parser_state,
- ACPI_GENERIC_OP *op,
- u32 remaining_args,
- u32 arg_count);
-
-void
-acpi_ps_cleanup_scope (
- ACPI_PARSE_STATE *state);
-
-
-/* pstree - parse tree manipulation routines */
-
-void
-acpi_ps_append_arg(
- ACPI_GENERIC_OP *op,
- ACPI_GENERIC_OP *arg);
-
-ACPI_GENERIC_OP*
-acpi_ps_find (
- ACPI_GENERIC_OP *scope,
- char *path,
- u16 opcode,
- u32 create);
-
-ACPI_GENERIC_OP *
-acpi_ps_get_arg(
- ACPI_GENERIC_OP *op,
- u32 argn);
-
-ACPI_GENERIC_OP *
-acpi_ps_get_child (
- ACPI_GENERIC_OP *op);
-
-ACPI_GENERIC_OP *
-acpi_ps_get_depth_next (
- ACPI_GENERIC_OP *origin,
- ACPI_GENERIC_OP *op);
-
-
-/* pswalk - parse tree walk routines */
-
-ACPI_STATUS
-acpi_ps_walk_parsed_aml (
- ACPI_GENERIC_OP *start_op,
- ACPI_GENERIC_OP *end_op,
- ACPI_OBJECT_INTERNAL *mth_desc,
- ACPI_NAME_TABLE *start_scope,
- ACPI_OBJECT_INTERNAL **params,
- ACPI_OBJECT_INTERNAL **caller_return_desc,
- ACPI_OWNER_ID owner_id,
- INTERPRETER_CALLBACK descending_callback,
- INTERPRETER_CALLBACK ascending_callback);
-
-ACPI_STATUS
-acpi_ps_get_next_walk_op (
- ACPI_WALK_STATE *walk_state,
- ACPI_GENERIC_OP *op,
- INTERPRETER_CALLBACK ascending_callback);
-
-
-/* psutils - parser utilities */
-
-void
-acpi_ps_init_op (
- ACPI_GENERIC_OP *op,
- u16 opcode);
-
-ACPI_GENERIC_OP *
-acpi_ps_alloc_op (
- u16 opcode);
-
-void
-acpi_ps_free_op (
- ACPI_GENERIC_OP *op);
-
-void
-acpi_ps_delete_parse_cache (
- void);
-
-u8
-acpi_ps_is_leading_char (
- s32 c);
-
-u8
-acpi_ps_is_prefix_char (
- s32 c);
-
-u8
-acpi_ps_is_named_op (
- u16 opcode);
-
-u8
-acpi_ps_is_named_object_op (
- u16 opcode);
-
-u8
-acpi_ps_is_deferred_op (
- u16 opcode);
-
-u8
-acpi_ps_is_bytelist_op(
- u16 opcode);
-
-u8
-acpi_ps_is_field_op(
- u16 opcode);
-
-u8
-acpi_ps_is_create_field_op (
- u16 opcode);
-
-ACPI_NAMED_OP*
-acpi_ps_to_named_op(
- ACPI_GENERIC_OP *op);
-
-ACPI_DEFERRED_OP *
-acpi_ps_to_deferred_op (
- ACPI_GENERIC_OP *op);
-
-ACPI_BYTELIST_OP*
-acpi_ps_to_bytelist_op(
- ACPI_GENERIC_OP *op);
-
-u32
-acpi_ps_get_name(
- ACPI_GENERIC_OP *op);
-
-void
-acpi_ps_set_name(
- ACPI_GENERIC_OP *op,
- u32 name);
-
-
-/* psdump - display parser tree */
-
-s32
-acpi_ps_sprint_path (
- char *buffer_start,
- u32 buffer_size,
- ACPI_GENERIC_OP *op);
-
-s32
-acpi_ps_sprint_op (
- char *buffer_start,
- u32 buffer_size,
- ACPI_GENERIC_OP *op);
-
-void
-acpi_ps_show (
- ACPI_GENERIC_OP *op);
-
-
-#endif /* _PARSER_H_ */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/resource.h linux/drivers/acpi/include/resource.h
--- v2.4.0-test8/linux/drivers/acpi/include/resource.h Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/include/resource.h Wed Dec 31 16:00:00 1969
@@ -1,300 +0,0 @@
-/******************************************************************************
- *
- * Name: resource.h - Resource Manager function prototypes
- *
- *****************************************************************************/
-
-/*
- * Copyright (C) 2000 R. Byron Moore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __RESOURCE_H__
-#define __RESOURCE_H__
-
-#include "actypes.h"
-#include "acobject.h"
-
-/*
- * Function prototypes called from Acpi* APIs
- */
-
-ACPI_STATUS
-acpi_rs_get_prt_method_data (
- ACPI_HANDLE handle,
- ACPI_BUFFER *ret_buffer);
-
-
-ACPI_STATUS
-acpi_rs_get_crs_method_data (
- ACPI_HANDLE handle,
- ACPI_BUFFER *ret_buffer);
-
-ACPI_STATUS
-acpi_rs_get_prs_method_data (
- ACPI_HANDLE handle,
- ACPI_BUFFER *ret_buffer);
-
-ACPI_STATUS
-acpi_rs_set_srs_method_data (
- ACPI_HANDLE handle,
- ACPI_BUFFER *ret_buffer);
-
-ACPI_STATUS
-acpi_rs_create_resource_list (
- ACPI_OBJECT_INTERNAL *byte_stream_buffer,
- u8 *output_buffer,
- u32 *output_buffer_length);
-
-ACPI_STATUS
-acpi_rs_create_byte_stream (
- RESOURCE *linked_list_buffer,
- u8 *output_buffer,
- u32 *output_buffer_length);
-
-ACPI_STATUS
-acpi_rs_create_pci_routing_table (
- ACPI_OBJECT_INTERNAL *method_return_object,
- u8 *output_buffer,
- u32 *output_buffer_length);
-
-
-/*
- *Function prototypes called from Acpi_rs_create*APIs
- */
-
-void
-acpi_rs_dump_resource_list (
- RESOURCE *resource);
-
-void
-acpi_rs_dump_irq_list (
- u8 *route_table);
-
-ACPI_STATUS
-acpi_rs_get_byte_stream_start (
- u8 *byte_stream_buffer,
- u8 **byte_stream_start,
- u32 *size);
-
-ACPI_STATUS
-acpi_rs_calculate_list_length (
- u8 *byte_stream_buffer,
- u32 byte_stream_buffer_length,
- u32 *size_needed);
-
-ACPI_STATUS
-acpi_rs_calculate_byte_stream_length (
- RESOURCE *linked_list_buffer,
- u32 *size_needed);
-
-ACPI_STATUS
-acpi_rs_byte_stream_to_list (
- u8 *byte_stream_buffer,
- u32 byte_stream_buffer_length,
- u8 **output_buffer);
-
-ACPI_STATUS
-acpi_rs_list_to_byte_stream (
- RESOURCE *linked_list,
- u32 byte_stream_size_needed,
- u8 **output_buffer);
-
-ACPI_STATUS
-acpi_rs_io_resource (
- u8 *byte_stream_buffer,
- u32 *bytes_consumed,
- u8 **output_buffer,
- u32 *structure_size);
-
-ACPI_STATUS
-acpi_rs_fixed_io_resource (
- u8 *byte_stream_buffer,
- u32 *bytes_consumed,
- u8 **output_buffer,
- u32 *structure_size);
-
-ACPI_STATUS
-acpi_rs_io_stream (
- RESOURCE *linked_list,
- u8 **output_buffer,
- u32 *bytes_consumed);
-
-ACPI_STATUS
-acpi_rs_fixed_io_stream (
- RESOURCE *linked_list,
- u8 **output_buffer,
- u32 *bytes_consumed);
-
-ACPI_STATUS
-acpi_rs_irq_resource (
- u8 *byte_stream_buffer,
- u32 *bytes_consumed,
- u8 **output_buffer,
- u32 *structure_size);
-
-ACPI_STATUS
-acpi_rs_irq_stream (
- RESOURCE *linked_list,
- u8 **output_buffer,
- u32 *bytes_consumed);
-
-ACPI_STATUS
-acpi_rs_dma_resource (
- u8 *byte_stream_buffer,
- u32 *bytes_consumed,
- u8 **output_buffer,
- u32 *structure_size);
-
-ACPI_STATUS
-acpi_rs_dma_stream (
- RESOURCE *linked_list,
- u8 **output_buffer,


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 029'
echo 'File patch-2.4.0-test9 is continued in part 030'
echo "030" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part027

#!/bin/sh -x
# this is part 027 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 027; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ */
+
+#define RSDP_SIG "RSD PTR " /* RSDT Pointer signature */
+#define APIC_SIG "APIC" /* Multiple APIC Description Table */
+#define DSDT_SIG "DSDT" /* Differentiated System Description Table */
+#define FACP_SIG "FACP" /* Fixed ACPI Description Table */
+#define FACS_SIG "FACS" /* Firmware ACPI Control Structure */
+#define PSDT_SIG "PSDT" /* Persistent System Description Table */
+#define RSDT_SIG "RSDT" /* Root System Description Table */
+#define SSDT_SIG "SSDT" /* Secondary System Description Table */
+#define SBST_SIG "SBST" /* Smart Battery Specification Table */
+#define BOOT_SIG "BOOT" /* Boot table */
+
+
+#define GL_OWNED 0x02 /* Ownership of global lock is bit 1 */
+
+/* values of Mapic.Model */
+
+#define DUAL_PIC 0
+#define MULTIPLE_APIC 1
+
+/* values of Type in APIC_HEADER */
+
+#define APIC_PROC 0
+#define APIC_IO 1
+
+
+/*
+ * Architecture-independent tables
+ * The architecture dependent tables are in separate files
+ */
+
+typedef struct /* Root System Descriptor Pointer */
+{
+ NATIVE_CHAR signature [8]; /* contains "RSD PTR " */
+ u8 checksum; /* to make sum of struct == 0 */
+ NATIVE_CHAR oem_id [6]; /* OEM identification */
+ u8 reserved; /* reserved - must be zero */
+ u32 rsdt_physical_address; /* physical address of RSDT */
+
+} ROOT_SYSTEM_DESCRIPTOR_POINTER;
+
+
+typedef struct /* ACPI common table header */
+{
+ NATIVE_CHAR signature [4]; /* identifies type of table */
+ u32 length; /* length of table, in bytes,
+ * including header */
+ u8 revision; /* specification minor version # */
+ u8 checksum; /* to make sum of entire table == 0 */
+ NATIVE_CHAR oem_id [6]; /* OEM identification */
+ NATIVE_CHAR oem_table_id [8]; /* OEM table identification */
+ u32 oem_revision; /* OEM revision number */
+ NATIVE_CHAR asl_compiler_id [4]; /* ASL compiler vendor ID */
+ u32 asl_compiler_revision; /* ASL compiler revision number */
+
+} ACPI_TABLE_HEADER;
+
+
+typedef struct /* APIC Table */
+{
+ ACPI_TABLE_HEADER header; /* table header */
+ u32 local_apic_address; /* Physical address for accessing local APICs */
+ u32 PCATcompat : 1; /* a one indicates system also has dual 8259s */
+ u32 reserved1 : 31;
+
+} APIC_TABLE;
+
+
+typedef struct /* APIC Header */
+{
+ u8 type; /* APIC type. Either APIC_PROC or APIC_IO */
+ u8 length; /* Length of APIC structure */
+
+} APIC_HEADER;
+
+
+typedef struct /* Processor APIC */
+{
+ APIC_HEADER header;
+ u8 processor_apic_id; /* ACPI processor id */
+ u8 local_apic_id; /* processor's local APIC id */
+ u32 processor_enabled: 1; /* Processor is usable if set */
+ u32 reserved1 : 32;
+
+} PROCESSOR_APIC;
+
+
+typedef struct /* IO APIC */
+{
+ APIC_HEADER header;
+ u8 io_apic_id; /* I/O APIC ID */
+ u8 reserved; /* reserved - must be zero */
+ u32 io_apic_address; /* APIC's physical address */
+ u32 vector; /* interrupt vector index where INTI
+ * lines start */
+} IO_APIC;
+
+
+/*
+** IA64 TODO: Add SAPIC Tables
+*/
+
+/*
+** IA64 TODO: Modify Smart Battery Description to comply with ACPI IA64
+** extensions.
+*/
+typedef struct /* Smart Battery Description Table */
+{
+ ACPI_TABLE_HEADER header;
+ u32 warning_level;
+ u32 low_level;
+ u32 critical_level;
+
+} SMART_BATTERY_DESCRIPTION_TABLE;
+
+
+/*
+ * ACPI Table information. We save the table address, length,
+ * and type of memory allocation (mapped or allocated) for each
+ * table for 1) when we exit, and 2) if a new table is installed
+ */
+
+#define ACPI_MEM_NOT_ALLOCATED 0
+#define ACPI_MEM_ALLOCATED 1
+#define ACPI_MEM_MAPPED 2
+
+/* Definitions for the Flags bitfield member of ACPI_TABLE_SUPPORT */
+
+#define ACPI_TABLE_SINGLE 0
+#define ACPI_TABLE_MULTIPLE 1
+
+
+/* Data about each known table type */
+
+typedef struct _acpi_table_support
+{
+ NATIVE_CHAR *name;
+ NATIVE_CHAR *signature;
+ u8 sig_length;
+ u8 flags;
+ u16 status;
+ void **global_ptr;
+
+} ACPI_TABLE_SUPPORT;
+
+
+/*
+ * Get the architecture-specific tables
+ */
+
+#ifdef IA64
+#include "actbl64.h"
+#else
+#include "actbl32.h"
+#endif
+
+
+#endif /* __ACTBL_H__ */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/actbl32.h linux/drivers/acpi/include/actbl32.h
--- v2.4.0-test8/linux/drivers/acpi/include/actbl32.h Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/include/actbl32.h Fri Sep 15 14:30:30 2000
@@ -1,6 +1,7 @@
X /******************************************************************************
X *
X * Name: actbl32.h - ACPI tables specific to IA32
+ * $Revision: 11 $


X *
X *****************************************************************************/
X

@@ -40,7 +41,7 @@
X
X typedef struct
X {
- char signature[4]; /* signature "FACS" */
+ NATIVE_CHAR signature[4]; /* signature "FACS" */
X u32 length; /* length of structure, in bytes */
X u32 hardware_signature; /* hardware configuration signature */
X u32 firmware_waking_vector; /* ACPI OS waking vector */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/actbl64.h linux/drivers/acpi/include/actbl64.h
--- v2.4.0-test8/linux/drivers/acpi/include/actbl64.h Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/include/actbl64.h Fri Sep 15 14:30:30 2000


@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *

X * Name: actbl64.h - ACPI tables specific to IA64
+ * $Revision: 12 $


X *
X *****************************************************************************/
X

@@ -45,7 +45,7 @@
X

X typedef struct
X {
- char signature[4]; /* signature "FACS" */
+ NATIVE_CHAR signature[4]; /* signature "FACS" */
X u32 length; /* length of structure, in bytes */
X u32 hardware_signature; /* hardware configuration signature */
X u32 reserved4; /* must be 0 */
@@ -65,7 +65,7 @@
X ACPI_TABLE_HEADER header; /* table header */
X u32 reserved_pad; /* IA64 alignment, must be 0 */
X ACPI_TBLPTR firmware_ctrl; /* Physical address of FACS */
- ACPI_TBLPTR acpi_dsdt; /* Physical address of DSDT */
+ ACPI_TBLPTR dsdt; /* Physical address of DSDT */
X u8 model; /* System Interrupt Model */
X u8 address_space; /* Address Space Bitmask */
X u16 sci_int; /* System vector of SCI interrupt */
@@ -90,8 +90,8 @@
X u8 gpe1_blk_len; /* Byte Length of ports at gpe1_blk */
X u8 gpe1_base; /* offset in gpe model where gpe1 events start */
X u8 reserved3; /* reserved */
- u16 Plvl2_lat; /* worst case HW latency to enter/exit C2 state */
- u16 Plvl3_lat; /* worst case HW latency to enter/exit C3 state */
+ u16 plvl2_lat; /* worst case HW latency to enter/exit C2 state */
+ u16 plvl3_lat; /* worst case HW latency to enter/exit C3 state */
X u8 day_alrm; /* index to day-of-month alarm in RTC CMOS RAM */
X u8 mon_alrm; /* index to month-of-year alarm in RTC CMOS RAM */
X u8 century; /* index to century in RTC CMOS RAM */
@@ -99,11 +99,11 @@
X u32 flush_cash : 1; /* PAL_FLUSH_CACHE is correctly supported */
X u32 reserved5 : 1; /* reserved - must be zero */
X u32 proc_c1 : 1; /* all processors support C1 state */
- u32 Plvl2_up : 1; /* C2 state works on MP system */
+ u32 plvl2_up : 1; /* C2 state works on MP system */
X u32 pwr_button : 1; /* Power button is handled as a generic feature */
X u32 sleep_button : 1; /* Sleep button is handled as a generic feature, or not present */
X u32 fixed_rTC : 1; /* RTC wakeup stat not in fixed register space */
- u32 RTCS4 : 1; /* RTC wakeup stat not possible from S4 */
+ u32 rtcs4 : 1; /* RTC wakeup stat not possible from S4 */
X u32 tmr_val_ext : 1; /* tmr_val is 32 bits */
X u32 dock_cap : 1; /* Supports Docking */
X u32 reserved6 : 22; /* reserved - must be zero */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/actypes.h linux/drivers/acpi/include/actypes.h
--- v2.4.0-test8/linux/drivers/acpi/include/actypes.h Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/include/actypes.h Fri Sep 15 14:30:30 2000


@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *

X * Name: actypes.h - Common data types for the entire ACPI subsystem
+ * $Revision: 131 $


X *
X *****************************************************************************/
X

@@ -23,15 +23,18 @@
X * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
X */
X
-#ifndef _ACTYPES_H
-#define _ACTYPES_H
+#ifndef __ACTYPES_H__
+#define __ACTYPES_H__
X
X /*! [Begin] no source code translation (keep the typedefs) */
X
X /*
X * Data types - Fixed across all compilation models
X *
- * BOOLEAN Logical Boolean. 1 byte value containing a 0 for FALSE or a 1 for TRUE. Other values are undefined.
+ * BOOLEAN Logical Boolean.
+ * 1 byte value containing a 0 for FALSE or a 1 for TRUE.
+ * Other values are undefined.
+ *
X * INT8 8-bit (1 byte) signed value
X * UINT8 8-bit (1 byte) unsigned value
X * INT16 16-bit (2 byte) signed value
@@ -45,14 +48,17 @@
X * UCHAR Character. 1 byte unsigned value.
X */
X
+#ifdef __ia64__
+#define _IA64
+#endif
+
X #ifdef _IA64
X /*
X * 64-bit type definitions
X */
-typedef signed char INT8;
X typedef unsigned char UINT8;
+typedef unsigned char BOOLEAN;
X typedef unsigned char UCHAR;
-typedef short INT16;
X typedef unsigned short UINT16;
X typedef int INT32;
X typedef unsigned int UINT32;
@@ -74,10 +80,9 @@
X /*
X * 16-bit type definitions
X */
-typedef signed char INT8;
X typedef unsigned char UINT8;
+typedef unsigned char BOOLEAN;
X typedef unsigned char UCHAR;
-typedef int INT16;
X typedef unsigned int UINT16;
X typedef long INT32;
X typedef unsigned long UINT32;
@@ -96,10 +101,9 @@
X /*
X * 32-bit type definitions (default)
X */
-typedef signed char INT8;
X typedef unsigned char UINT8;
+typedef unsigned char BOOLEAN;
X typedef unsigned char UCHAR;
-typedef short INT16;
X typedef unsigned short UINT16;
X typedef int INT32;
X typedef unsigned int UINT32;
@@ -113,19 +117,15 @@
X #define ALIGNED_ADDRESS_BOUNDARY 0x00000004
X #define _HW_ALIGNMENT_SUPPORT
X
-
X #endif
X
-
-
X /*
X * Miscellaneous common types
X */
X
-typedef UINT8 BOOLEAN;
X typedef UINT32 UINT32_BIT;
-typedef NATIVE_INT ACPI_PTRDIFF;
-typedef NATIVE_UINT ACPI_SIZE;
+typedef NATIVE_UINT ACPI_PTRDIFF;
+typedef char NATIVE_CHAR;
X
X
X /*
@@ -133,7 +133,6 @@
X */
X
X #define ACPI_UCHAR_MAX (UCHAR) 0xFF
-#define ACPI_INT32_MAX (INT32) 0x7FFFFFFF
X #define ACPI_UINT32_MAX (UINT32) 0xFFFFFFFF
X
X
@@ -141,14 +140,11 @@
X /*
X * Types used only in translated source
X */
-typedef INT8 s8;
-typedef INT16 s16;
X typedef INT32 s32;
X typedef UINT8 u8;
X typedef UINT16 u16;
X typedef UINT32 u32;
X #endif
-


X /*! [End] no source code translation !*/
X

X
@@ -176,9 +172,9 @@
X */
X
X typedef u32 ACPI_STATUS; /* All ACPI Exceptions */
-typedef u32 ACPI_NAME; /* 4-char ACPI name */
+typedef u32 ACPI_NAME; /* 4-s8 ACPI name */
X typedef char* ACPI_STRING; /* Null terminated ASCII string */
-typedef void* ACPI_HANDLE; /* Actually a ptr to an NTE */
+typedef void* ACPI_HANDLE; /* Actually a ptr to an Node */
X
X
X /*
@@ -223,10 +219,12 @@
X
X /*
X * Types associated with names. The first group of
- * values correspond to the definition of the ACPI Object_type operator (See the ACPI Spec).
- * Therefore, only add to the first group if the spec changes!
+ * values correspond to the definition of the ACPI
+ * Object_type operator (See the ACPI Spec). Therefore,
+ * only add to the first group if the spec changes!
X *
- * Types must be kept in sync with the Acpi_ns_properties and Acpi_ns_type_names arrays
+ * Types must be kept in sync with the Acpi_ns_properties
+ * and Acpi_ns_type_names arrays
X */
X
X typedef u32 ACPI_OBJECT_TYPE;
@@ -238,14 +236,14 @@
X #define ACPI_TYPE_BUFFER 3 /* 0x03 */
X #define ACPI_TYPE_PACKAGE 4 /* 0x04 Byte_const, multiple Data_term/Constant/Super_name */
X #define ACPI_TYPE_FIELD_UNIT 5 /* 0x05 */
-#define ACPI_TYPE_DEVICE 6 /* 0x06 Name, multiple Named_object */
+#define ACPI_TYPE_DEVICE 6 /* 0x06 Name, multiple Node */
X #define ACPI_TYPE_EVENT 7 /* 0x07 */
X #define ACPI_TYPE_METHOD 8 /* 0x08 Name, Byte_const, multiple Code */
X #define ACPI_TYPE_MUTEX 9 /* 0x09 */
X #define ACPI_TYPE_REGION 10 /* 0x0A */
-#define ACPI_TYPE_POWER 11 /* 0x0B Name,Byte_const,Word_const,multi Named_object */
+#define ACPI_TYPE_POWER 11 /* 0x0B Name,Byte_const,Word_const,multi Node */
X #define ACPI_TYPE_PROCESSOR 12 /* 0x0C Name,Byte_const,DWord_const,Byte_const,multi Nm_o */
-#define ACPI_TYPE_THERMAL 13 /* 0x0D Name, multiple Named_object */
+#define ACPI_TYPE_THERMAL 13 /* 0x0D Name, multiple Node */
X #define ACPI_TYPE_BUFFER_FIELD 14 /* 0x0E */
X #define ACPI_TYPE_DDB_HANDLE 15 /* 0x0F */
X #define ACPI_TYPE_DEBUG_OBJECT 16 /* 0x10 */
@@ -254,32 +252,39 @@
X
X /*
X * This section contains object types that do not relate to the ACPI Object_type operator.
- * They are used for various internal purposes only. A numerical gap is provided in
- * case additional "official" Object_types are added in the future. Also, values exceeding
- * the largest official ACPI Object_type must not overlap with defined AML opcodes.
- */
-#define INTERNAL_TYPE_BEGIN 25
-#define INTERNAL_TYPE_DEF_FIELD 25 /* 0x19 */
-#define INTERNAL_TYPE_BANK_FIELD 26 /* 0x1A */
-#define INTERNAL_TYPE_INDEX_FIELD 27 /* 0x1B */
-#define INTERNAL_TYPE_DEF_FIELD_DEFN 28 /* 0x1C Name, Byte_const, multiple Field_element */
-#define INTERNAL_TYPE_BANK_FIELD_DEFN 29 /* 0x1D 2 Name,DWord_const,Byte_const,multi Field_element */
-#define INTERNAL_TYPE_INDEX_FIELD_DEFN 30 /* 0x1E 2 Name, Byte_const, multiple Field_element */
-#define INTERNAL_TYPE_IF 31 /* 0x1F Op_code, multiple Code */
-#define INTERNAL_TYPE_ELSE 32 /* 0x20 multiple Code */
-#define INTERNAL_TYPE_WHILE 33 /* 0x21 Op_code, multiple Code */
-#define INTERNAL_TYPE_SCOPE 34 /* 0x22 Name, multiple Named_object */
-#define INTERNAL_TYPE_DEF_ANY 35 /* 0x23 type is Any, suppress search of enclosing scopes */
-#define INTERNAL_TYPE_REFERENCE 36 /* 0x24 Arg#, Local#, Name, Debug; used only in descriptors */
-#define INTERNAL_TYPE_ALIAS 37 /* 0x25 */
-#define INTERNAL_TYPE_NOTIFY 38 /* 0x26 */
-#define INTERNAL_TYPE_ADDRESS_HANDLER 39 /* 0x27 */
-#define INTERNAL_TYPE_METHOD_ARGUMENT 40 /* 0x28 */
-#define INTERNAL_TYPE_METHOD_LOCAL_VAR 41 /* 0x29 */
+ * They are used for various internal purposes only. If new predefined ACPI_TYPEs are
+ * added (via the ACPI specification), these internal types must move upwards.
+ * Also, values exceeding the largest official ACPI Object_type must not overlap with
+ * defined AML opcodes.
+ */
+#define INTERNAL_TYPE_BEGIN 17
+
+#define INTERNAL_TYPE_DEF_FIELD 17 /* 0x11 */
+#define INTERNAL_TYPE_BANK_FIELD 18 /* 0x12 */
+#define INTERNAL_TYPE_INDEX_FIELD 19 /* 0x13 */
+#define INTERNAL_TYPE_REFERENCE 20 /* 0x14 Arg#, Local#, Name, Debug; used only in descriptors */
+#define INTERNAL_TYPE_ALIAS 21 /* 0x15 */
+#define INTERNAL_TYPE_NOTIFY 22 /* 0x16 */
+#define INTERNAL_TYPE_ADDRESS_HANDLER 23 /* 0x17 */
+
+#define INTERNAL_TYPE_NODE_MAX 23
+
+/* These are pseudo-types because there are never any namespace nodes with these types */
+
+#define INTERNAL_TYPE_DEF_FIELD_DEFN 24 /* 0x18 Name, Byte_const, multiple Field_element */
+#define INTERNAL_TYPE_BANK_FIELD_DEFN 25 /* 0x19 2 Name,DWord_const,Byte_const,multi Field_element */
+#define INTERNAL_TYPE_INDEX_FIELD_DEFN 26 /* 0x1A 2 Name, Byte_const, multiple Field_element */
+#define INTERNAL_TYPE_IF 27 /* 0x1B Op_code, multiple Code */
+#define INTERNAL_TYPE_ELSE 28 /* 0x1C multiple Code */
+#define INTERNAL_TYPE_WHILE 29 /* 0x1D Op_code, multiple Code */
+#define INTERNAL_TYPE_SCOPE 30 /* 0x1E Name, multiple Node */
+#define INTERNAL_TYPE_DEF_ANY 31 /* 0x1F type is Any, suppress search of enclosing scopes */
+#define INTERNAL_TYPE_METHOD_ARGUMENT 32 /* 0x20 */
+#define INTERNAL_TYPE_METHOD_LOCAL_VAR 33 /* 0x21 */
X
-#define INTERNAL_TYPE_MAX 41
+#define INTERNAL_TYPE_MAX 33
X
-#define INTERNAL_TYPE_INVALID 42
+#define INTERNAL_TYPE_INVALID 34
X #define ACPI_TYPE_NOT_FOUND 0xFF
X
X /*
@@ -375,7 +380,7 @@
X {
X ACPI_OBJECT_TYPE type;
X u32 length; /* # of bytes in string, excluding trailing null */
- char *pointer; /* points to the string value */
+ NATIVE_CHAR *pointer; /* points to the string value */
X } string;
X
X struct
@@ -551,7 +556,8 @@


X u32 address,
X u32 bit_width,

X u32 *value,
- void *context);


+ void *handler_context,
+ void *region_context);

X
X #define ACPI_DEFAULT_HANDLER ((ADDRESS_SPACE_HANDLER) NULL)


X
@@ -561,7 +567,7 @@

X ACPI_HANDLE region_handle,


X u32 function,
X void *handler_context,
- void **return_context);
+ void **region_context);
X

X #define ACPI_REGION_ACTIVATE 0
X #define ACPI_REGION_DEACTIVATE 1
@@ -589,13 +595,11 @@
X
X
X #define ACPI_COMMON_OBJ_INFO \
- ACPI_OBJECT_TYPE type; /* ACPI object type */\
- ACPI_NAME name; /* ACPI object Name */\
- /*\
- * TBD: [Restructure] Do we want or need these next two??\
- */\
- ACPI_HANDLE parent; /* Parent object */\
- ACPI_HANDLE children; /* Linked list of children */\
+ ACPI_OBJECT_TYPE type; /* ACPI object type */ \
+ ACPI_NAME name; /* ACPI object Name */ \
+ /* TBD: [Restructure] Do we want or need these next two??*/ \
+ ACPI_HANDLE parent; /* Parent object */ \
+ ACPI_HANDLE children; /* Linked list of children */ \
X u32 valid /* ????? */
X
X typedef struct
@@ -611,8 +615,8 @@
X /*
X * TBD: [Restructure]: a HID or a _UID can return either a number or a string
X */
- char hardware_id [9]; /* _HID value if any */
- char unique_id[9]; /* _UID value if any */
+ NATIVE_CHAR hardware_id [9]; /* _HID value if any */
+ NATIVE_CHAR unique_id[9]; /* _UID value if any */
X u32 address; /* _ADR value if any */
X u32 current_status; /* _STA value */
X } ACPI_DEVICE_INFO;
@@ -622,7 +626,6 @@
X
X typedef struct
X {
- void *handler_context;
X u32 seg;
X u32 bus;
X u32 dev_func;
@@ -631,11 +634,9 @@
X
X typedef struct
X {
- void *handler_context;
- char *mapped_physical_address;
- char *mapped_logical_address;
+ u8 *mapped_physical_address;
+ u8 *mapped_logical_address;
X u32 mapped_length;
-
X } MEM_HANDLER_CONTEXT;
X
X
@@ -858,7 +859,7 @@
X u32 address_length;
X u32 resource_source_index;
X u32 resource_source_string_length;
- u8 resource_source[1];
+ NATIVE_CHAR resource_source[1];
X
X } ADDRESS16_RESOURCE;
X
@@ -877,7 +878,7 @@
X u32 address_length;
X u32 resource_source_index;
X u32 resource_source_string_length;
- u8 resource_source[1];
+ NATIVE_CHAR resource_source[1];
X
X } ADDRESS32_RESOURCE;
X
@@ -891,7 +892,7 @@
X u32 interrupts[1];
X u32 resource_source_index;
X u32 resource_source_string_length;
- u8 resource_source[1];
+ NATIVE_CHAR resource_source[1];
X
X } EXTENDED_IRQ_RESOURCE;
X
@@ -951,7 +952,7 @@
X u32 address;
X u32 pin;
X u32 source_index;
- u8 source[1];
+ NATIVE_CHAR source[1];
X
X } PRT_ENTRY;
X
@@ -967,4 +968,4 @@
X * END: Definitions for PCI Routing tables
X */
X
-#endif /* ACTYPES_H */
+#endif /* __ACTYPES_H__ */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/amlcode.h linux/drivers/acpi/include/amlcode.h
--- v2.4.0-test8/linux/drivers/acpi/include/amlcode.h Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/include/amlcode.h Fri Sep 15 14:30:30 2000
@@ -1,9 +1,9 @@


-
X /******************************************************************************
X *

X * Name: amlcode.h - Definitions for AML, as included in "definition blocks"
X * Declarations and definitions contained herein are derived
X * directly from the ACPI specification.
+ * $Revision: 39 $


X *
X *****************************************************************************/
X

@@ -108,7 +108,7 @@
X #define AML_IF_OP (u16) 0xa0
X #define AML_ELSE_OP (u16) 0xa1
X #define AML_WHILE_OP (u16) 0xa2
-#define AML_NOOP_CODE (u16) 0xa3
+#define AML_NOOP_OP (u16) 0xa3
X #define AML_RETURN_OP (u16) 0xa4
X #define AML_BREAK_OP (u16) 0xa5
X #define AML_BREAK_POINT_OP (u16) 0xcc
@@ -133,9 +133,9 @@
X #define AML_WAIT_OP (u16) 0x5b25
X #define AML_RESET_OP (u16) 0x5b26
X #define AML_RELEASE_OP (u16) 0x5b27
-#define AML_FROM_BCDOP (u16) 0x5b28
-#define AML_TO_BCDOP (u16) 0x5b29
-#define AML_UN_LOAD_OP (u16) 0x5b2a
+#define AML_FROM_BCD_OP (u16) 0x5b28
+#define AML_TO_BCD_OP (u16) 0x5b29
+#define AML_UNLOAD_OP (u16) 0x5b2a
X #define AML_REVISION_OP (u16) 0x5b30
X #define AML_DEBUG_OP (u16) 0x5b31
X #define AML_FATAL_OP (u16) 0x5b32
@@ -156,7 +156,11 @@
X #define AML_LNOTEQUAL_OP (u16) 0x9293
X
X
-/* Internal opcodes */
+/*
+ * Internal opcodes
+ * Use only "Unknown" AML opcodes, don't attempt to use
+ * any valid ACPI ASCII values (A-Z, 0-9, '-')
+ */
X
X #define AML_NAMEPATH_OP (u16) 0x002d
X #define AML_NAMEDFIELD_OP (u16) 0x0030
@@ -165,29 +169,7 @@
X #define AML_BYTELIST_OP (u16) 0x0033
X #define AML_STATICSTRING_OP (u16) 0x0034
X #define AML_METHODCALL_OP (u16) 0x0035
-
-
-/*
- * argument types
- */
-
-/*
-#define AML_ASCIICHARLIST_ARG 'A'
-#define AML_BYTEDATA_ARG 'b'
-#define AML_BYTELIST_ARG 'B'
-#define AML_DWORDDATA_ARG 'd'
-#define AML_DATAOBJECT_ARG 'o'
-#define AML_DATAOBJECTLIST_ARG 'O'
-#define AML_FIELDLIST_ARG 'F'
-#define AML_NAMESTRING_ARG 'n'
-#define AML_OBJECTLIST_ARG 'P'
-#define AML_PKGLENGTH_ARG 'p'
-#define AML_SUPERNAME_ARG 's'
-#define AML_TARGET_ARG 'l'
-#define AML_TERMARG_ARG 't'
-#define AML_TERMLIST_ARG 'T'
-#define AML_WORDDATA_ARG 'w'
-*/
+#define AML_RETURN_VALUE_OP (u16) 0x0036
X
X
X #define ARG_NONE 0x0
@@ -229,7 +211,7 @@
X #define ARGI_STRING 0x06
X #define ARGI_BUFFER 0x07
X #define ARGI_PACKAGE 0x08
-#define ARGI_DATAOBJECT 0x09 /* Buffer, string, package or NTE reference - Used only by Size_of operator*/
+#define ARGI_DATAOBJECT 0x09 /* Buffer, string, package or reference to a Node - Used only by Size_of operator*/
X #define ARGI_COMPLEXOBJ 0x0A /* Buffer or package */
X #define ARGI_MUTEX 0x0B
X #define ARGI_EVENT 0x0C
@@ -291,8 +273,9 @@
X #define OPTYPE_CONTROL 18
X #define OPTYPE_RECONFIGURATION 19
X #define OPTYPE_NAMED_OBJECT 20
+#define OPTYPE_RETURN 21
X
-#define OPTYPE_BOGUS 21
+#define OPTYPE_BOGUS 22
X
X
X /* Comparison operation codes for Match_op operator */
@@ -375,13 +358,11 @@
X
X extern u8 acpi_gbl_aml [NUM_OPCODES];
X extern u16 acpi_gbl_pfx [NUM_OPCODES];
-extern char *acpi_gbl_short_ops [NUM_OPCODES];
-extern char *acpi_gbl_long_ops [NUM_OPCODES];
-extern char *acpi_gbl_region_types [NUM_REGION_TYPES];
-extern char *acpi_gbl_match_ops [NUM_MATCH_OPS];
-extern char *acpi_gbl_access_types [NUM_ACCESS_TYPES];
-extern char *acpi_gbl_update_rules [NUM_UPDATE_RULES];
-extern char *acpi_gbl_FEnames [NUM_FIELD_NAMES];
+extern NATIVE_CHAR *acpi_gbl_region_types [NUM_REGION_TYPES];
+extern NATIVE_CHAR *acpi_gbl_match_ops [NUM_MATCH_OPS];
+extern NATIVE_CHAR *acpi_gbl_access_types [NUM_ACCESS_TYPES];
+extern NATIVE_CHAR *acpi_gbl_update_rules [NUM_UPDATE_RULES];
+extern NATIVE_CHAR *acpi_gbl_FEnames [NUM_FIELD_NAMES];
X
X
X /*
@@ -392,7 +373,7 @@
X
X /* Data used in keeping track of fields */
X
-char *acpi_gbl_FEnames[NUM_FIELD_NAMES] =
+NATIVE_CHAR *acpi_gbl_FEnames[NUM_FIELD_NAMES] =
X {
X "skip",
X "?access?"
@@ -401,7 +382,7 @@
X
X /* Region type decoding */
X
-char *acpi_gbl_region_types[NUM_REGION_TYPES] =
+NATIVE_CHAR *acpi_gbl_region_types[NUM_REGION_TYPES] =
X {
X "System_memory",
X "System_iO",


@@ -411,7 +392,7 @@
X };
X
X

-char *acpi_gbl_match_ops[NUM_MATCH_OPS] =
+NATIVE_CHAR *acpi_gbl_match_ops[NUM_MATCH_OPS] =
X {
X "Error",
X "MTR",
@@ -425,7 +406,7 @@
X
X /* Access type decoding */
X
-char *acpi_gbl_access_types[NUM_ACCESS_TYPES] =
+NATIVE_CHAR *acpi_gbl_access_types[NUM_ACCESS_TYPES] =
X {
X "Any_acc",
X "Byte_acc",
@@ -439,7 +420,7 @@
X
X /* Update rule decoding */
X
-char *acpi_gbl_update_rules[NUM_UPDATE_RULES] =
+NATIVE_CHAR *acpi_gbl_update_rules[NUM_UPDATE_RULES] =
X {
X "Preserve",
X "Write_as_ones",
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/common.h linux/drivers/acpi/include/common.h
--- v2.4.0-test8/linux/drivers/acpi/include/common.h Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/include/common.h Wed Dec 31 16:00:00 1969
@@ -1,650 +0,0 @@
-
-/******************************************************************************
- *
- * Name: common.h -- prototypes for the common (subsystem-wide) procedures


- *
- *****************************************************************************/
-
-/*

- * Copyright (C) 2000 R. Byron Moore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _COMMON_H
-#define _COMMON_H
-
-
-#define REF_INCREMENT (u16) 0
-#define REF_DECREMENT (u16) 1
-#define REF_FORCE_DELETE (u16) 2
-
-/* Acpi_cm_dump_buffer */
-
-#define DB_BYTE_DISPLAY 1
-#define DB_WORD_DISPLAY 2
-#define DB_DWORD_DISPLAY 4
-#define DB_QWORD_DISPLAY 8
-
-
-/* Global initialization interfaces */
-
-void
-acpi_cm_init_globals (
- ACPI_INIT_DATA *init_data);
-
-void
-acpi_cm_terminate (
- void);
-
-
-/*
- * Acpi_cm_init - miscellaneous initialization and shutdown
- */
-
-ACPI_STATUS
-acpi_cm_hardware_initialize (
- void);
-
-ACPI_STATUS
-acpi_cm_subsystem_shutdown (
- void);
-
-/*
- * Acpi_cm_global - Global data structures and procedures


- */
-
-char *

-acpi_cm_get_mutex_name (
- u32 mutex_id);
-
-char *
-acpi_cm_get_type_name (
- u32 type);
-
-u8
-acpi_cm_valid_object_type (
- u32 type);
-
-ACPI_OWNER_ID
-acpi_cm_allocate_owner_id (
- u32 id_type);
-
-
-/*
- * Acpi_cm_clib - Local implementations of C library functions
- */
-
-ACPI_SIZE
-acpi_cm_strlen (
- const char *string);
-
-char *
-acpi_cm_strcpy (
- char *dst_string,
- const char *src_string);
-
-char *
-acpi_cm_strncpy (
- char *dst_string,
- const char *src_string,
- ACPI_SIZE count);
-
-u32
-acpi_cm_strncmp (
- const char *string1,
- const char *string2,
- ACPI_SIZE count);
-
-u32
-acpi_cm_strcmp (
- const char *string1,
- const char *string2);
-
-char *
-acpi_cm_strcat (
- char *dst_string,
- const char *src_string);
-
-char *
-acpi_cm_strncat (
- char *dst_string,
- const char *src_string,
- ACPI_SIZE count);
-
-u32
-acpi_cm_strtoul (
- const char *string,
- char **terminator,
- s32 base);
-
-char *
-acpi_cm_strstr (
- char *string1,
- char *string2);
-
-char *
-acpi_cm_strupr (
- char *src_string);
-
-void *
-acpi_cm_memcpy (
- void *dest,
- const void *src,
- ACPI_SIZE count);
-
-void *
-acpi_cm_memset (
- void *dest,
- s32 value,
- ACPI_SIZE count);
-
-s32
-acpi_cm_to_upper (
- s32 c);
-
-s32
-acpi_cm_to_lower (


- s32 c);
-
-

-/*
- * Acpi_cm_copy - Object construction and conversion interfaces
- */
-
-ACPI_STATUS
-acpi_cm_build_simple_object(
- ACPI_OBJECT_INTERNAL *obj,
- ACPI_OBJECT *user_obj,
- char *data_space,
- u32 *buffer_space_used);
-
-ACPI_STATUS
-acpi_cm_build_package_object (
- ACPI_OBJECT_INTERNAL *obj,
- char *buffer,
- u32 *space_used);
-
-ACPI_STATUS
-acpi_cm_build_external_object (
- ACPI_OBJECT_INTERNAL *obj,


- ACPI_BUFFER *ret_buffer);
-
-ACPI_STATUS

-acpi_cm_build_internal_simple_object(
- ACPI_OBJECT *user_obj,
- ACPI_OBJECT_INTERNAL *obj);
-
-ACPI_STATUS
-acpi_cm_build_internal_object (
- ACPI_OBJECT *obj,
- ACPI_OBJECT_INTERNAL *internal_obj);
-
-ACPI_STATUS
-acpi_cm_copy_internal_simple_object (


- ACPI_OBJECT_INTERNAL *source_obj,
- ACPI_OBJECT_INTERNAL *dest_obj);
-

-ACPI_STATUS
-acpi_cm_build_copy_internal_package_object (


- ACPI_OBJECT_INTERNAL *source_obj,
- ACPI_OBJECT_INTERNAL *dest_obj);
-
-
-/*

- * Acpi_cm_create - Object creation
- */
-
-ACPI_STATUS
-acpi_cm_update_object_reference (
- ACPI_OBJECT_INTERNAL *object,
- u16 action);
-
-ACPI_OBJECT_INTERNAL *
-_cm_create_internal_object (
- char *module_name,
- s32 line_number,
- s32 component_id,


- OBJECT_TYPE_INTERNAL type);
-
-

-/*
- * Acpi_cm_debug - Debug interfaces
- */
-
-s32
-get_debug_level (
- void);
-
-void
-set_debug_level (
- s32 level);
-
-void
-function_trace (
- ACPI_STRING module_name,


- s32 line_number,
- s32 component_id,

- ACPI_STRING function_name);
-
-void
-function_trace_ptr (
- ACPI_STRING module_name,


- s32 line_number,
- s32 component_id,

- ACPI_STRING function_name,
- void *pointer);
-
-void
-function_trace_u32 (
- ACPI_STRING module_name,


- s32 line_number,
- s32 component_id,

- ACPI_STRING function_name,
- u32 integer);
-
-void
-function_trace_str (
- ACPI_STRING module_name,


- s32 line_number,
- s32 component_id,

- ACPI_STRING function_name,
- char *string);
-
-void
-function_exit (
- ACPI_STRING module_name,


- s32 line_number,
- s32 component_id,

- ACPI_STRING function_name);
-
-void
-function_status_exit (
- ACPI_STRING module_name,


- s32 line_number,
- s32 component_id,

- ACPI_STRING function_name,
- ACPI_STATUS status);
-
-void
-function_value_exit (
- ACPI_STRING module_name,


- s32 line_number,
- s32 component_id,

- ACPI_STRING function_name,
- NATIVE_UINT value);
-
-void
-function_ptr_exit (
- ACPI_STRING module_name,


- s32 line_number,
- s32 component_id,

- ACPI_STRING function_name,
- char *ptr);
-
-void
-debug_print_prefix (
- ACPI_STRING module_name,


- s32 line_number);
-
-void

-debug_print (
- ACPI_STRING module_name,


- s32 line_number,
- s32 component_id,

- s32 print_level,
- char *format, ...);
-
-void
-debug_print_raw (
- char *format, ...);
-
-void
-_report_info (
- ACPI_STRING module_name,


- s32 line_number,
- s32 component_id,

- ACPI_STRING message);
-
-void
-_report_error (
- ACPI_STRING module_name,


- s32 line_number,
- s32 component_id,

- ACPI_STRING message);
-
-void
-_report_warning (
- ACPI_STRING module_name,


- s32 line_number,
- s32 component_id,

- ACPI_STRING message);
-
-void
-_report_success (
- ACPI_STRING module_name,


- s32 line_number,
- s32 component_id,

- ACPI_STRING message);
-
-void
-acpi_cm_dump_buffer (
- char *buffer,
- u32 count,
- u32 display,
- s32 component_id);
-
-
-/*
- * Acpi_cm_delete - Object deletion
- */
-
-void
-acpi_cm_delete_internal_obj (
- ACPI_OBJECT_INTERNAL *object);
-
-void
-acpi_cm_delete_internal_package_object (
- ACPI_OBJECT_INTERNAL *object);
-
-void
-acpi_cm_delete_internal_simple_object (
- ACPI_OBJECT_INTERNAL *object);
-
-ACPI_STATUS
-acpi_cm_delete_internal_object_list (
- ACPI_OBJECT_INTERNAL **obj_list);
-
-
-/*
- * Acpi_cm_eval - object evaluation
- */
-
-/* Method name strings */
-
-#define METHOD_NAME__HID "_HID"
-#define METHOD_NAME__UID "_UID"
-#define METHOD_NAME__ADR "_ADR"
-#define METHOD_NAME__STA "_STA"
-#define METHOD_NAME__REG "_REG"
-#define METHOD_NAME__SEG "_SEG"
-#define METHOD_NAME__BBN "_BBN"
-
-
-ACPI_STATUS
-acpi_cm_evaluate_numeric_object (
- char *method_name,
- ACPI_NAMED_OBJECT *acpi_device,
- u32 *address);
-
-ACPI_STATUS
-acpi_cm_execute_HID (
- ACPI_NAMED_OBJECT *acpi_device,
- DEVICE_ID *hid);
-
-ACPI_STATUS
-acpi_cm_execute_STA (
- ACPI_NAMED_OBJECT *acpi_device,
- u32 *status_flags);
-
-ACPI_STATUS
-acpi_cm_execute_UID (
- ACPI_NAMED_OBJECT *acpi_device,
- DEVICE_ID *uid);
-
-
-/*
- * Acpi_cm_error - exception interfaces


- */
-
-char *

-acpi_cm_format_exception (
- ACPI_STATUS status);
-
-
-/*
- * Acpi_cm_mutex - mutual exclusion interfaces
- */
-
-ACPI_STATUS
-acpi_cm_mutex_initialize (
- void);
-
-void
-acpi_cm_mutex_terminate (
- void);
-
-ACPI_STATUS
-acpi_cm_create_mutex (
- ACPI_MUTEX_HANDLE mutex_id);
-
-ACPI_STATUS
-acpi_cm_delete_mutex (
- ACPI_MUTEX_HANDLE mutex_id);
-
-ACPI_STATUS
-acpi_cm_acquire_mutex (
- ACPI_MUTEX_HANDLE mutex_id);
-
-ACPI_STATUS
-acpi_cm_release_mutex (
- ACPI_MUTEX_HANDLE mutex_id);
-
-
-/*
- * Acpi_cm_object - internal object create/delete/cache routines
- */
-
-#define acpi_cm_create_internal_object(t) _cm_create_internal_object(_THIS_MODULE,__LINE__,_COMPONENT,t)
-#define acpi_cm_allocate_object_desc() _cm_allocate_object_desc(_THIS_MODULE,__LINE__,_COMPONENT)
-
-void *
-_cm_allocate_object_desc (
- char *module_name,
- s32 line_number,
- s32 component_id);
-
-void
-acpi_cm_delete_object_desc (
- ACPI_OBJECT_INTERNAL *object);
-
-u8
-acpi_cm_valid_internal_object (


- void *object);
-
-

-/*
- * Acpi_cm_ref_cnt - Object reference count management
- */
-
-void
-acpi_cm_add_reference (
- ACPI_OBJECT_INTERNAL *object);
-
-void
-acpi_cm_remove_reference (
- ACPI_OBJECT_INTERNAL *object);
-
-/*
- * Acpi_cm_size - Object size routines
- */
-
-ACPI_STATUS
-acpi_cm_get_simple_object_size (
- ACPI_OBJECT_INTERNAL *obj,
- u32 *obj_length);
-
-ACPI_STATUS
-acpi_cm_get_package_object_size (
- ACPI_OBJECT_INTERNAL *obj,
- u32 *obj_length);
-
-ACPI_STATUS
-acpi_cm_get_object_size(
- ACPI_OBJECT_INTERNAL *obj,
- u32 *obj_length);
-
-
-/*
- * Acpi_cm_state - Generic state creation/cache routines
- */
-
-void
-acpi_cm_push_generic_state (
- ACPI_GENERIC_STATE **list_head,
- ACPI_GENERIC_STATE *state);
-
-ACPI_GENERIC_STATE *
-acpi_cm_pop_generic_state (
- ACPI_GENERIC_STATE **list_head);
-
-
-ACPI_GENERIC_STATE *
-acpi_cm_create_generic_state (
- void);
-
-ACPI_GENERIC_STATE *
-acpi_cm_create_update_state (
- ACPI_OBJECT_INTERNAL *object,
- u16 action);
-
-ACPI_STATUS
-acpi_cm_create_update_state_and_push (
- ACPI_OBJECT_INTERNAL *object,
- u16 action,
- ACPI_GENERIC_STATE **state_list);
-
-ACPI_GENERIC_STATE *
-acpi_cm_create_control_state (
- void);
-
-void
-acpi_cm_delete_generic_state (
- ACPI_GENERIC_STATE *state);
-
-void
-acpi_cm_delete_generic_state_cache (
- void);
-
-void
-acpi_cm_delete_object_cache (
- void);
-
-/*
- * Acpi_cmutils
- */
-
-u8
-acpi_cm_valid_acpi_name (
- u32 name);
-
-u8
-acpi_cm_valid_acpi_character (
- char character);
-
-
-/*
- * Memory allocation functions and related macros.
- * Macros that expand to include filename and line number
- */
-
-void *
-_cm_allocate (
- u32 size,
- u32 component,
- ACPI_STRING module,
- s32 line);
-
-void *
-_cm_callocate (
- u32 size,
- u32 component,
- ACPI_STRING module,
- s32 line);
-
-void
-_cm_free (
- void *address,
- u32 component,
- ACPI_STRING module,
- s32 line);
-
-void
-acpi_cm_init_static_object (
- ACPI_OBJECT_INTERNAL *obj_desc);
-
-#define acpi_cm_allocate(a) _cm_allocate(a,_COMPONENT,_THIS_MODULE,__LINE__)
-#define acpi_cm_callocate(a) _cm_callocate(a, _COMPONENT,_THIS_MODULE,__LINE__)
-#define acpi_cm_free(a) _cm_free(a,_COMPONENT,_THIS_MODULE,__LINE__)
-
-#ifndef ACPI_DEBUG
-
-#define acpi_cm_add_element_to_alloc_list(a,b,c,d,e,f)
-#define acpi_cm_delete_element_from_alloc_list(a,b,c,d)
-#define acpi_cm_dump_current_allocations(a,b)
-#define acpi_cm_dump_allocation_info()
-
-#define DECREMENT_OBJECT_METRICS(a)
-#define INCREMENT_OBJECT_METRICS(a)
-#define INITIALIZE_ALLOCATION_METRICS()
-
-#else
-
-#define INITIALIZE_ALLOCATION_METRICS() \
- acpi_gbl_current_object_count = 0; \
- acpi_gbl_current_object_size = 0; \
- acpi_gbl_running_object_count = 0; \
- acpi_gbl_running_object_size = 0; \
- acpi_gbl_max_concurrent_object_count = 0; \
- acpi_gbl_max_concurrent_object_size = 0; \
- acpi_gbl_current_alloc_size = 0; \
- acpi_gbl_current_alloc_count = 0; \
- acpi_gbl_running_alloc_size = 0; \
- acpi_gbl_running_alloc_count = 0; \
- acpi_gbl_max_concurrent_alloc_size = 0; \
- acpi_gbl_max_concurrent_alloc_count = 0
-
-#define DECREMENT_OBJECT_METRICS(a) \
- acpi_gbl_current_object_count--; \
- acpi_gbl_current_object_size -= a
-
-#define INCREMENT_OBJECT_METRICS(a) \
- acpi_gbl_current_object_count++; \
- acpi_gbl_running_object_count++; \
- if (acpi_gbl_max_concurrent_object_count < acpi_gbl_current_object_count) \
- { \
- acpi_gbl_max_concurrent_object_count = acpi_gbl_current_object_count; \
- } \
- acpi_gbl_running_object_size += a; \
- acpi_gbl_current_object_size += a; \
- if (acpi_gbl_max_concurrent_object_size < acpi_gbl_current_object_size) \
- { \
- acpi_gbl_max_concurrent_object_size = acpi_gbl_current_object_size; \
- }
-
-
-void
-acpi_cm_dump_allocation_info (
- void);
-
-void
-acpi_cm_dump_current_allocations (
- u32 component,
- ACPI_STRING module);
-
-#endif
-
-
-#endif /* _COMMON_H */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/config.h linux/drivers/acpi/include/config.h
--- v2.4.0-test8/linux/drivers/acpi/include/config.h Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/include/config.h Wed Dec 31 16:00:00 1969
@@ -1,185 +0,0 @@
-
-/******************************************************************************
- *
- * Name: config.h - Global configuration constants


- *
- *****************************************************************************/
-
-/*

- * Copyright (C) 2000 R. Byron Moore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _CONFIG_H
-#define _CONFIG_H


-
-
-/******************************************************************************
- *

- * Compile-time options


- *
- *****************************************************************************/
-
-/*

- * ACPI_DEBUG - This switch enables all the debug facilities of the ACPI
- * subsystem. This includes the DEBUG_PRINT output statements
- * When disabled, all DEBUG_PRINT statements are compiled out.
- *
- * ACPI_APPLICATION - Use this switch if the subsystem is going to be run
- * at the application level.


- *
- */
-

-
-/******************************************************************************
- *
- * Subsystem Constants


- *
- *****************************************************************************/
-
-

-/* Version string */
-
-#define ACPI_CA_VERSION __DATE__
-
-/* Name of host operating system (returned by the _OS_ namespace object) */
-
-#ifdef _LINUX
-#define ACPI_OS_NAME "Linux"
-#else
-#define ACPI_OS_NAME "Intel ACPI/CA Core Subsystem"
-#endif
-
-
-/*
- * How and when control methods will be parsed
- * The default action is to parse all methods at table load time to verify them, but delete the parse trees
- * to conserve memory. Methods are parsed just in time before execution and the parse tree is deleted
- * when execution completes.
- */
-#define METHOD_PARSE_AT_INIT 0x0 /* Parse at table init, never delete the method parse tree */
-#define METHOD_PARSE_JUST_IN_TIME 0x1 /* Parse only when a method is invoked */
-#define METHOD_DELETE_AT_COMPLETION 0x2 /* Delete parse tree on method completion */
-
-/* Default parsing configuration */
-
-#define METHOD_PARSE_CONFIGURATION (METHOD_PARSE_JUST_IN_TIME | METHOD_DELETE_AT_COMPLETION)
-
-
-/* Maximum objects in the various object caches */
-
-#define MAX_STATE_CACHE_DEPTH 24 /* State objects for stacks */
-#define MAX_PARSE_CACHE_DEPTH 512 /* Parse tree objects */
-#define MAX_OBJECT_CACHE_DEPTH 32 /* Interpreter operand objects */
-#define MAX_WALK_CACHE_DEPTH 2 /* Objects for parse tree walks (method execution) */
-
-/*
- * Name_space Table size
- *
- * All tables are the same size to simplify the implementation.
- * Tables may be extended by allocating additional tables that
- * are in turn linked together to form a chain of tables.
- */
-
-#define NS_TABLE_SIZE 16
-
-/* String size constants */
-
-#define MAX_STRING_LENGTH 512
-#define PATHNAME_MAX 256 /* A full namespace pathname */
-
-
-/* Maximum count for a semaphore object */
-
-#define MAX_SEMAPHORE_COUNT 256
-
-
-/* Max reference count (for debug only) */
-
-#define MAX_REFERENCE_COUNT 0x200
-
-
-/* Size of cached memory mapping for system memory operation region */
-
-#define SYSMEM_REGION_WINDOW_SIZE 4096
-
-
-/*
- * Debugger threading model
- * Use single threaded if the entire subsystem is contained in an application
- * Use multiple threaded when the the subsystem is running in the kernel.
- *
- * By default the model is single threaded if ACPI_APPLICATION is set,
- * multi-threaded if ACPI_APPLICATION is not set.
- */
-
-#define DEBUGGER_SINGLE_THREADED 0
-#define DEBUGGER_MULTI_THREADED 1
-
-#ifdef ACPI_APPLICATION
-#define DEBUGGER_THREADING DEBUGGER_SINGLE_THREADED
-
-#else
-#define DEBUGGER_THREADING DEBUGGER_MULTI_THREADED
-#endif


-
-
-/******************************************************************************
- *

- * ACPI Specification constants (Do not change unless the specification changes)


- *
- *****************************************************************************/
-
-/*

- * Method info (in WALK_STATE), containing local variables and argumetns
- */
-
-#define MTH_NUM_LOCALS 8
-#define MTH_MAX_LOCAL 7
-
-#define MTH_NUM_ARGS 7
-#define MTH_MAX_ARG 6
-
-/*
- * Operand Stack (in WALK_STATE), Must be large enough to contain MTH_MAX_ARG
- */
-
-#define OBJ_NUM_OPERANDS 8
-#define OBJ_MAX_OPERAND 7
-
-/* Names within the namespace are 4 bytes long */
-
-#define ACPI_NAME_SIZE 4
-#define PATH_SEGMENT_LENGTH 5 /* 4 chars for name + 1 char for separator */
-#define PATH_SEPARATOR '.'
-
-
-/* Constants used in searching for the RSDP in low memory */
-
-#define LO_RSDP_WINDOW_BASE (void *) 0
-#define HI_RSDP_WINDOW_BASE (void *) 0xE0000
-#define LO_RSDP_WINDOW_SIZE 0x400
-#define HI_RSDP_WINDOW_SIZE 0x20000
-#define RSDP_SCAN_STEP 16
-
-
-/* Maximum nesting of package objects */
-
-#define MAX_PACKAGE_DEPTH 16
-
-
-#endif /* _CONFIG_H */
-
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/debugger.h linux/drivers/acpi/include/debugger.h
--- v2.4.0-test8/linux/drivers/acpi/include/debugger.h Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/include/debugger.h Wed Dec 31 16:00:00 1969
@@ -1,394 +0,0 @@
-
-/******************************************************************************
- *
- * Name: debugger.h - ACPI/AML debugger


- *
- *****************************************************************************/
-
-/*

- * Copyright (C) 2000 R. Byron Moore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __DEBUGGER_H__
-#define __DEBUGGER_H__
-
-
-#define DB_MAX_ARGS 8 /* Must be max method args + 1 */
-
-#define DB_COMMAND_PROMPT '-'
-#define DB_EXECUTE_PROMPT '%'
-
-
-extern int optind;
-extern char *optarg;
-extern u8 *aml_ptr;
-extern u32 acpi_aml_length;
-
-extern u8 opt_tables;
-extern u8 opt_disasm;
-extern u8 opt_stats;
-extern u8 opt_parse_jit;
-extern u8 opt_verbose;
-
-
-extern char *args[DB_MAX_ARGS];
-extern char line_buf[80];
-extern char scope_buf[40];
-extern char debug_filename[40];
-extern u8 output_to_file;
-extern char *buffer;
-extern char *filename;
-extern char *INDENT_STRING;
-extern u32 acpi_gbl_method_breakpoint;
-extern u8 acpi_gbl_db_output_flags;
-extern u32 acpi_gbl_db_debug_level;
-extern u32 acpi_gbl_db_console_debug_level;
-
-extern u32 num_names;
-extern u32 num_methods;
-extern u32 num_regions;
-extern u32 num_packages;
-extern u32 num_aliases;
-extern u32 num_devices;
-extern u32 num_field_defs;
-extern u32 num_thermal_zones;
-extern u32 num_named_objects;
-extern u32 num_grammar_elements;
-extern u32 num_method_elements ;
-extern u32 num_mutexes;
-extern u32 num_power_resources;
-extern u32 num_bank_fields ;
-extern u32 num_index_fields;
-extern u32 num_events;
-
-extern u32 size_of_parse_tree;
-extern u32 size_of_method_trees;
-extern u32 size_of_nTes;
-extern u32 size_of_acpi_objects;
-
-
-#define BUFFER_SIZE 4196
-
-#define DB_REDIRECTABLE_OUTPUT 0x01
-#define DB_CONSOLE_OUTPUT 0x02
-#define DB_DUPLICATE_OUTPUT 0x03
-
-
-typedef struct command_info
-{
- char *name; /* Command Name */
- char min_args; /* Minimum arguments required */
-
-} COMMAND_INFO;
-
-
-typedef struct argument_info
-{
- char *name; /* Argument Name */
-
-} ARGUMENT_INFO;
-


-
-#define PARAM_LIST(pl) pl
-

-#define DBTEST_OUTPUT_LEVEL(lvl) if (opt_verbose)
-
-#define VERBOSE_PRINT(fp) DBTEST_OUTPUT_LEVEL(lvl) {\
- acpi_os_printf PARAM_LIST(fp);}
-
-#define EX_NO_SINGLE_STEP 1
-#define EX_SINGLE_STEP 2
-
-
-/* Prototypes */
-
-
-/*
- * dbapi - external debugger interfaces
- */
-
-int
-acpi_db_initialize (
- void);
-
-ACPI_STATUS
-acpi_db_single_step (


- ACPI_WALK_STATE *walk_state,
- ACPI_GENERIC_OP *op,

- u8 op_type);
-
-
-/*
- * dbcmds - debug commands and output routines
- */
-
-
-void
-acpi_db_display_table_info (
- char *table_arg);
-
-void
-acpi_db_unload_acpi_table (
- char *table_arg,
- char *instance_arg);
-
-void
-acpi_db_set_method_breakpoint (
- char *location,
- ACPI_WALK_STATE *walk_state,
- ACPI_GENERIC_OP *op);
-
-void
-acpi_db_set_method_call_breakpoint (


- ACPI_GENERIC_OP *op);
-
-void

-acpi_db_disassemble_aml (
- char *statements,


- ACPI_GENERIC_OP *op);
-
-void

-acpi_db_dump_namespace (
- char *start_arg,
- char *depth_arg);
-
-void
-acpi_db_dump_namespace_by_owner (
- char *owner_arg,
- char *depth_arg);
-
-void
-acpi_db_send_notify (
- char *name,
- u32 value);
-
-void
-acpi_db_set_method_data (
- char *type_arg,
- char *index_arg,
- char *value_arg);
-
-ACPI_STATUS
-acpi_db_display_objects (
- char *obj_type_arg,
- char *display_count_arg);
-
-ACPI_STATUS
-acpi_db_find_name_in_namespace (
- char *name_arg);
-
-void
-acpi_db_set_scope (
- char *name);
-
-void
-acpi_db_find_references (
- char *object_arg);
-
-
-/*
- * dbdisasm - AML disassembler


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 027'
echo 'File patch-2.4.0-test9 is continued in part 028'
echo "028" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part028

#!/bin/sh -x
# this is part 028 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 028; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

- */
-
-void
-acpi_db_display_op (
- ACPI_GENERIC_OP *origin,
- u32 num_opcodes);
-
-void
-acpi_db_display_namestring (


- char *name);
-
-void

-acpi_db_display_path (


- ACPI_GENERIC_OP *op);
-
-void

-acpi_db_display_opcode (


- ACPI_GENERIC_OP *op);
-
-

-/*
- * dbdisply - debug display commands


- */
-
-
-void

-acpi_db_display_method_info (


- ACPI_GENERIC_OP *op);
-
-void

-acpi_db_decode_and_display_object (
- char *target,
- char *output_type);
-
-void
-acpi_db_display_result_object (
- ACPI_OBJECT_INTERNAL *ret_desc);
-
-ACPI_STATUS
-acpi_db_display_all_methods (
- char *display_count_arg);
-
-void
-acpi_db_display_internal_object (
- ACPI_OBJECT_INTERNAL *obj_desc);
-
-void
-acpi_db_display_arguments (
- void);
-
-void
-acpi_db_display_locals (
- void);
-
-void
-acpi_db_display_results (
- void);
-
-void
-acpi_db_display_calling_tree (
- void);
-
-void
-acpi_db_display_argument_object (


- ACPI_OBJECT_INTERNAL *obj_desc);
-
-

-/*
- * dbexec - debugger control method execution
- */
-
-void
-acpi_db_execute (
- char *name,
- char **args,
- u32 flags);
-
-void
-acpi_db_create_execution_threads (
- char *num_threads_arg,
- char *num_loops_arg,
- char *method_name_arg);
-
-
-/*
- * dbfileio - Debugger file I/O commands
- */
-
-OBJECT_TYPE_INTERNAL
-acpi_db_match_argument (
- char *user_argument,
- ARGUMENT_INFO *arguments);
-
-
-void
-acpi_db_close_debug_file (
- void);
-
-void
-acpi_db_open_debug_file (
- char *name);
-
-ACPI_STATUS
-acpi_db_load_acpi_table (
- char *filename);
-
-
-/*
- * dbhistry - debugger HISTORY command
- */
-
-void
-acpi_db_add_to_history (
- char *command_line);
-
-void
-acpi_db_display_history (void);
-
-char *
-acpi_db_get_from_history (
- char *command_num_arg);
-
-
-/*
- * dbinput - user front-end to the AML debugger
- */
-
-ACPI_STATUS
-acpi_db_command_dispatch (
- char *input_buffer,


- ACPI_WALK_STATE *walk_state,
- ACPI_GENERIC_OP *op);
-
-void

-acpi_db_execute_thread (


- void *context);
-
-ACPI_STATUS

-acpi_db_user_commands (
- char prompt,
- ACPI_GENERIC_OP *op);
-
-
-/*
- * dbstats - Generation and display of ACPI table statistics
- */
-
-void
-acpi_db_generate_statistics (
- ACPI_GENERIC_OP *root,
- u8 is_method);
-
-
-ACPI_STATUS
-acpi_db_display_statistics (
- char *type_arg);
-
-
-/*
- * dbutils - AML debugger utilities
- */
-
-void
-acpi_db_set_output_destination (
- s32 where);
-
-void
-acpi_db_dump_buffer (
- u32 address);
-
-void
-acpi_db_dump_object (
- ACPI_OBJECT *obj_desc,
- u32 level);
-
-void
-acpi_db_prep_namestring (


- char *name);
-
-

-ACPI_STATUS
-acpi_db_second_pass_parse (
- ACPI_GENERIC_OP *root);
-
-ACPI_NAMED_OBJECT*
-acpi_db_local_ns_lookup (


- char *name);
-
-

-#endif /* __DEBUGGER_H__ */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/dispatch.h linux/drivers/acpi/include/dispatch.h
--- v2.4.0-test8/linux/drivers/acpi/include/dispatch.h Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/include/dispatch.h Wed Dec 31 16:00:00 1969
@@ -1,383 +0,0 @@
-/******************************************************************************
- *
- * Module Name: dispatch.h


- *
- *****************************************************************************/
-
-/*
- * Copyright (C) 2000 R. Byron Moore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-

-#ifndef _DISPATCH_H_
-#define _DISPATCH_H_
-
-
-#define NAMEOF_LOCAL_NTE "__L0"
-#define NAMEOF_ARG_NTE "__A0"
-
-
-/* For Acpi_ds_method_data_set_value */
-
-#define MTH_TYPE_LOCAL 0
-#define MTH_TYPE_ARG 1
-
-
-/* Common interfaces */
-
-ACPI_STATUS
-acpi_ds_obj_stack_push (
- void *object,


- ACPI_WALK_STATE *walk_state);
-
-ACPI_STATUS

-acpi_ds_obj_stack_pop (
- u32 pop_count,
- ACPI_WALK_STATE *walk_state);
-
-void *
-acpi_ds_obj_stack_get_value (
- u32 index,


- ACPI_WALK_STATE *walk_state);
-
-ACPI_STATUS

-acpi_ds_obj_stack_pop_object (
- ACPI_OBJECT_INTERNAL **object,
- ACPI_WALK_STATE *walk_state);
-
-
-/* dsregion - Op region support */
-
-ACPI_STATUS
-acpi_ds_get_region_arguments (
- ACPI_OBJECT_INTERNAL *rgn_desc);
-
-
-/* dsctrl - Parser/Interpreter interface, control stack routines */
-
-/*
-ACPI_CTRL_STATE *
-Acpi_ds_create_control_state (void);
-
-void
-Acpi_ds_push_control_state (
- ACPI_CTRL_STATE *Control_state,
- ACPI_WALK_STATE *Walk_state);
-
-ACPI_CTRL_STATE *
-Acpi_ds_pop_control_state (
- ACPI_WALK_STATE *Walk_state);
-*/
-
-ACPI_STATUS
-acpi_ds_exec_begin_control_op (
- ACPI_WALK_STATE *walk_state,
- ACPI_GENERIC_OP *op);
-
-ACPI_STATUS
-acpi_ds_exec_end_control_op (
- ACPI_WALK_STATE *walk_state,
- ACPI_GENERIC_OP *op);
-
-
-/* dsexec - Parser/Interpreter interface, method execution callbacks */
-
-ACPI_STATUS
-acpi_ds_exec_begin_op (
- ACPI_WALK_STATE *state,
- ACPI_GENERIC_OP *op);
-
-ACPI_STATUS
-acpi_ds_exec_end_op (
- ACPI_WALK_STATE *state,


- ACPI_GENERIC_OP *op);
-
-

-/* dsfield - Parser/Interpreter interface for AML fields */
-
-
-ACPI_STATUS
-acpi_ds_create_field (
- ACPI_GENERIC_OP *op,
- ACPI_HANDLE region,


- ACPI_WALK_STATE *walk_state);
-
-ACPI_STATUS

-acpi_ds_create_bank_field (
- ACPI_GENERIC_OP *op,
- ACPI_HANDLE region,


- ACPI_WALK_STATE *walk_state);
-
-ACPI_STATUS

-acpi_ds_create_index_field (
- ACPI_GENERIC_OP *op,
- ACPI_HANDLE region,
- ACPI_WALK_STATE *walk_state);
-
-
-/* dsload - Parser/Interpreter interface, namespace load callbacks */
-
-ACPI_STATUS
-acpi_ds_load1_begin_op (
- ACPI_WALK_STATE *walk_state,
- ACPI_GENERIC_OP *op);
-
-ACPI_STATUS
-acpi_ds_load1_end_op (
- ACPI_WALK_STATE *walk_state,
- ACPI_GENERIC_OP *op);
-
-ACPI_STATUS
-acpi_ds_load2_begin_op (
- ACPI_WALK_STATE *state,
- ACPI_GENERIC_OP *op);
-
-ACPI_STATUS
-acpi_ds_load2_end_op (
- ACPI_WALK_STATE *state,


- ACPI_GENERIC_OP *op);
-
-

-/* dsmthdat - method data (locals/args) */
-
-
-ACPI_STATUS
-acpi_ds_method_data_delete_all (
- ACPI_WALK_STATE *walk_state);
-
-u8
-acpi_ds_is_method_value (
- ACPI_OBJECT_INTERNAL *obj_desc);
-
-OBJECT_TYPE_INTERNAL
-acpi_ds_method_data_get_type (
- u32 type,
- u32 index);
-
-ACPI_STATUS
-acpi_ds_method_data_get_value (
- u32 type,
- u32 index,
- ACPI_OBJECT_INTERNAL **obj_desc);
-
-ACPI_STATUS
-acpi_ds_method_data_set_value (
- u32 type,
- u32 index,


- ACPI_OBJECT_INTERNAL *obj_desc);
-
-ACPI_STATUS

-acpi_ds_method_data_delete_value (
- u32 type,
- u32 index);
-
-ACPI_STATUS
-acpi_ds_method_data_init_args (
- ACPI_OBJECT_INTERNAL **params,
- u32 param_count);
-
-ACPI_NAMED_OBJECT*
-acpi_ds_method_data_get_nte (
- u32 type,
- u32 index);
-
-ACPI_STATUS
-acpi_ds_method_data_init (


- ACPI_WALK_STATE *walk_state);
-
-

-/* dsmethod - Parser/Interpreter interface - control method parsing */
-
-ACPI_STATUS
-acpi_ds_parse_method (
- ACPI_HANDLE obj_handle);
-
-ACPI_STATUS
-acpi_ds_call_control_method (
- ACPI_WALK_LIST *walk_list,


- ACPI_WALK_STATE *walk_state,
- ACPI_GENERIC_OP *op);
-

-ACPI_STATUS
-acpi_ds_restart_control_method (
- ACPI_WALK_STATE *walk_state,
- ACPI_OBJECT_INTERNAL *return_desc);
-
-ACPI_STATUS
-acpi_ds_terminate_control_method (


- ACPI_WALK_STATE *walk_state);
-
-ACPI_STATUS

-acpi_ds_begin_method_execution (
- ACPI_NAMED_OBJECT *method_entry,
- ACPI_OBJECT_INTERNAL *obj_desc);
-
-
-/* dsobj - Parser/Interpreter interface - object initialization and conversion */
-
-ACPI_STATUS
-acpi_ds_init_one_object (


- ACPI_HANDLE obj_handle,
- u32 level,
- void *context,
- void **return_value);
-

-ACPI_STATUS
-acpi_ds_initialize_objects (
- ACPI_TABLE_DESC *table_desc,
- ACPI_NAMED_OBJECT *start_entry);
-
-ACPI_STATUS
-acpi_ds_build_internal_package_obj (


- ACPI_WALK_STATE *walk_state,
- ACPI_GENERIC_OP *op,

- ACPI_OBJECT_INTERNAL **obj_desc);
-
-ACPI_STATUS
-acpi_ds_build_internal_object (


- ACPI_WALK_STATE *walk_state,
- ACPI_GENERIC_OP *op,

- ACPI_OBJECT_INTERNAL **obj_desc_ptr);
-
-ACPI_STATUS
-acpi_ds_init_object_from_op (


- ACPI_WALK_STATE *walk_state,
- ACPI_GENERIC_OP *op,

- u16 opcode,


- ACPI_OBJECT_INTERNAL *obj_desc);
-
-ACPI_STATUS

-acpi_ds_create_named_object (
- ACPI_WALK_STATE *walk_state,
- ACPI_NAMED_OBJECT *entry,


- ACPI_GENERIC_OP *op);
-
-

-/* dsregn - Parser/Interpreter interface - Op Region parsing */
-
-ACPI_STATUS
-acpi_ds_eval_region_operands (
- ACPI_WALK_STATE *walk_state,
- ACPI_GENERIC_OP *op);
-
-ACPI_STATUS
-acpi_ds_initialize_region (


- ACPI_HANDLE obj_handle);
-
-

-/* dsutils - Parser/Interpreter interface utility routines */
-
-void
-acpi_ds_delete_result_if_not_used (
- ACPI_GENERIC_OP *op,
- ACPI_OBJECT_INTERNAL *result_obj,


- ACPI_WALK_STATE *walk_state);
-
-ACPI_STATUS

-acpi_ds_create_operand (
- ACPI_WALK_STATE *walk_state,
- ACPI_GENERIC_OP *arg);
-
-ACPI_STATUS
-acpi_ds_create_operands (
- ACPI_WALK_STATE *walk_state,
- ACPI_GENERIC_OP *first_arg);
-
-ACPI_STATUS
-acpi_ds_resolve_operands (
- ACPI_WALK_STATE *walk_state);
-
-OBJECT_TYPE_INTERNAL
-acpi_ds_map_opcode_to_data_type (
- u16 opcode,
- u32 *out_flags);
-
-OBJECT_TYPE_INTERNAL
-acpi_ds_map_named_opcode_to_data_type (
- u16 opcode);
-
-
-/*
- * dswscope - Scope Stack manipulation
- */
-
-ACPI_STATUS
-acpi_ds_scope_stack_push (
- ACPI_NAME_TABLE *new_scope,
- OBJECT_TYPE_INTERNAL type,
- ACPI_WALK_STATE *walk_state);
-
-
-ACPI_STATUS
-acpi_ds_scope_stack_pop (
- ACPI_WALK_STATE *walk_state);
-
-void
-acpi_ds_scope_stack_clear (


- ACPI_WALK_STATE *walk_state);
-
-

-/* Acpi_dswstate - parser WALK_STATE management routines */
-
-ACPI_WALK_STATE *
-acpi_ds_create_walk_state (
- ACPI_OWNER_ID owner_id,


- ACPI_GENERIC_OP *origin,
- ACPI_OBJECT_INTERNAL *mth_desc,

- ACPI_WALK_LIST *walk_list);
-
-ACPI_STATUS
-acpi_ds_obj_stack_delete_all (


- ACPI_WALK_STATE *walk_state);
-
-ACPI_STATUS

-acpi_ds_obj_stack_pop_and_delete (
- u32 pop_count,
- ACPI_WALK_STATE *walk_state);
-
-void
-acpi_ds_delete_walk_state (
- ACPI_WALK_STATE *walk_state);
-
-ACPI_WALK_STATE *
-acpi_ds_pop_walk_state (
- ACPI_WALK_LIST *walk_list);
-
-ACPI_STATUS
-acpi_ds_result_stack_pop (
- ACPI_OBJECT_INTERNAL **object,


- ACPI_WALK_STATE *walk_state);
-
-ACPI_STATUS

-acpi_ds_result_stack_push (
- void *object,


- ACPI_WALK_STATE *walk_state);
-
-ACPI_STATUS

-acpi_ds_result_stack_clear (
- ACPI_WALK_STATE *walk_state);
-
-ACPI_WALK_STATE *
-acpi_ds_get_current_walk_state (
- ACPI_WALK_LIST *walk_list);
-
-void
-acpi_ds_delete_walk_state_cache (
- void);
-
-
-#endif /* _DISPATCH_H_ */
\ No newline at end of file
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/events.h linux/drivers/acpi/include/events.h
--- v2.4.0-test8/linux/drivers/acpi/include/events.h Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/include/events.h Wed Dec 31 16:00:00 1969
@@ -1,209 +0,0 @@
-
-/******************************************************************************
- *
- * Name: events.h - Acpi_event subcomponent prototypes and defines


- *
- *****************************************************************************/
-
-/*
- * Copyright (C) 2000 R. Byron Moore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-

-#ifndef __EVENTS_H__
-#define __EVENTS_H__
-
-
-/*
- * Acpi_evfixed - Fixed event handling
- */
-
-ACPI_STATUS
-acpi_ev_fixed_event_initialize (
- void);
-
-u32
-acpi_ev_fixed_event_detect (
- void);
-
-u32
-acpi_ev_fixed_event_dispatch (
- u32 acpi_event);
-
-
-/*
- * Acpi_evglock - Global Lock support
- */
-
-ACPI_STATUS
-acpi_ev_acquire_global_lock(
- void);
-
-void
-acpi_ev_release_global_lock(
- void);
-
-ACPI_STATUS
-acpi_ev_init_global_lock_handler (


- void);
-
-
-/*

- * Acpi_evgpe - GPE handling and dispatch
- */
-
-ACPI_STATUS
-acpi_ev_gpe_initialize (
- void);
-
-ACPI_STATUS
-acpi_ev_init_gpe_control_methods (
- void);
-
-u32
-acpi_ev_gpe_dispatch (
- u32 gpe_number);
-
-u32
-acpi_ev_gpe_detect (


- void);
-
-
-/*

- * Acpi_evnotify - Device Notify handling and dispatch
- */
-
-void
-acpi_ev_notify_dispatch (
- ACPI_HANDLE device,
- u32 notify_value);
-
-
-/*
- * Acpi_evregion - Address Space handling
- */
-
-ACPI_STATUS
-acpi_ev_install_default_address_space_handlers (
- void);
-
-ACPI_STATUS
-acpi_ev_address_space_dispatch (
- ACPI_OBJECT_INTERNAL *region_obj,


- u32 function,
- u32 address,
- u32 bit_width,

- u32 *value);
-
-
-ACPI_STATUS
-acpi_ev_addr_handler_helper (


- ACPI_HANDLE obj_handle,
- u32 level,
- void *context,
- void **return_value);
-
-void

-acpi_ev_disassociate_region_from_handler(
- ACPI_OBJECT_INTERNAL *region_obj);
-
-
-ACPI_STATUS
-acpi_ev_associate_region_and_handler(
- ACPI_OBJECT_INTERNAL *handler_obj,
- ACPI_OBJECT_INTERNAL *region_obj);
-
-
-/*
- * Acpi_evregini - Region initialization and setup
- */
-
-ACPI_STATUS
-acpi_ev_system_memory_region_setup (
- ACPI_HANDLE handle,
- u32 function,
- void *handler_context,
- void **return_context);
-
-ACPI_STATUS
-acpi_ev_io_space_region_setup (
- ACPI_HANDLE handle,
- u32 function,
- void *handler_context,
- void **return_context);
-
-ACPI_STATUS
-acpi_ev_pci_config_region_setup (
- ACPI_HANDLE handle,
- u32 function,
- void *handler_context,
- void **return_context);
-
-ACPI_STATUS
-acpi_ev_default_region_setup (
- ACPI_HANDLE handle,
- u32 function,
- void *handler_context,
- void **return_context);
-
-ACPI_STATUS
-acpi_ev_initialize_region (
- ACPI_OBJECT_INTERNAL *region_obj,
- u8 acpi_ns_locked);
-
-
-/*
- * Acpi_evsci - SCI (System Control Interrupt) handling/dispatch
- */
-
-u32
-acpi_ev_install_sci_handler (
- void);
-
-ACPI_STATUS
-acpi_ev_remove_sci_handler (
- void);
-
-s32
-acpi_ev_initialize_sCI (
- s32 program_sCI);
-
-void
-acpi_ev_restore_acpi_state (
- void);
-
-void
-acpi_ev_terminate (
- void);
-
-
-/* Debug support */
-
-#ifdef ACPI_DEBUG
-
-s32
-acpi_ev_sci_count (
- u32 acpi_event);
-
-#define DEBUG_INCREMENT_EVENT_COUNT(a) acpi_gbl_event_count[a]++;
-
-#else
-
-#define DEBUG_INCREMENT_EVENT_COUNT(a)
-#endif
-
-
-#endif /* __EVENTS_H__ */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/globals.h linux/drivers/acpi/include/globals.h
--- v2.4.0-test8/linux/drivers/acpi/include/globals.h Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/include/globals.h Wed Dec 31 16:00:00 1969
@@ -1,311 +0,0 @@
-
-/******************************************************************************
- *
- * Name: globals.h - Declarations for global variables


- *
- *****************************************************************************/
-
-/*
- * Copyright (C) 2000 R. Byron Moore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-

-#ifndef __GLOBALS_H__
-#define __GLOBALS_H__
-
-
-/*
- * Ensure that the globals are actually defined only once
- */
-#ifdef DEFINE_ACPI_GLOBALS
-#define ACPI_EXTERN
-#else
-#define ACPI_EXTERN extern
-#endif
-
-
-extern char *msg_acpi_error_break;
-
-/*****************************************************************************
- *
- * Debug support
- *
- ****************************************************************************/
-
-/* Runtime configuration of debug print levels */
-
-extern u32 acpi_dbg_level;
-extern u32 acpi_dbg_layer;
-
-
-/* Procedure nesting level for debug output */
-
-extern u32 acpi_gbl_nesting_level;
-
-
-/*****************************************************************************
- *
- * ACPI Table globals
- *
- ****************************************************************************/
-
-/*
- * Table pointers.
- * Although these pointers are somewhat redundant with the global Acpi_table,
- * they are convenient because they are typed pointers.
- *
- * These tables are single-table only; meaning that there can be at most one
- * of each in the system. Each global points to the actual table.
- *
- */
-ACPI_EXTERN ROOT_SYSTEM_DESCRIPTOR_POINTER *acpi_gbl_RSDP;
-ACPI_EXTERN ROOT_SYSTEM_DESCRIPTION_TABLE *acpi_gbl_RSDT;
-ACPI_EXTERN FIRMWARE_ACPI_CONTROL_STRUCTURE *acpi_gbl_FACS;
-ACPI_EXTERN FIXED_ACPI_DESCRIPTION_TABLE *acpi_gbl_FACP;
-ACPI_EXTERN APIC_TABLE *acpi_gbl_APIC;
-ACPI_EXTERN ACPI_TABLE_HEADER *acpi_gbl_DSDT;
-ACPI_EXTERN ACPI_TABLE_HEADER *acpi_gbl_SBST;
-/*
- * Since there may be multiple SSDTs and PSDTS, a single pointer is not
- * sufficient; Therefore, there isn't one!
- */
-
-
-/*
- * ACPI Table info arrays
- */
-extern ACPI_TABLE_DESC acpi_gbl_acpi_tables[NUM_ACPI_TABLES];
-extern ACPI_TABLE_SUPPORT acpi_gbl_acpi_table_data[NUM_ACPI_TABLES];
-
-/*
- * Predefined mutex objects. This array contains the
- * actual OS mutex handles, indexed by the local ACPI_MUTEX_HANDLEs.
- * (The table maps local handles to the real OS handles)
- */
-ACPI_EXTERN ACPI_MUTEX_INFO acpi_gbl_acpi_mutex_info [NUM_MTX];
-extern ACPI_INIT_DATA acpi_gbl_acpi_init_data;
-
-
-/*****************************************************************************
- *
- * Miscellaneous globals


- *
- ****************************************************************************/
-
-

-ACPI_EXTERN u8 *acpi_gbl_gpe0enable_register_save;
-ACPI_EXTERN u8 *acpi_gbl_gpe1_enable_register_save;
-ACPI_EXTERN ACPI_WALK_STATE *acpi_gbl_breakpoint_walk;
-ACPI_EXTERN ACPI_GENERIC_STATE *acpi_gbl_generic_state_cache;
-ACPI_EXTERN ACPI_GENERIC_OP *acpi_gbl_parse_cache;
-ACPI_EXTERN ACPI_OBJECT_INTERNAL *acpi_gbl_object_cache;
-ACPI_EXTERN ACPI_WALK_STATE *acpi_gbl_walk_state_cache;
-ACPI_EXTERN ACPI_HANDLE acpi_gbl_global_lock_semaphore;
-
-
-ACPI_EXTERN u32 acpi_gbl_global_lock_thread_count;
-ACPI_EXTERN u32 acpi_gbl_restore_acpi_chipset;
-ACPI_EXTERN u32 acpi_gbl_original_mode;
-ACPI_EXTERN u32 acpi_gbl_edge_level_save;
-ACPI_EXTERN u32 acpi_gbl_irq_enable_save;
-ACPI_EXTERN u32 acpi_gbl_rsdp_original_location;
-
-ACPI_EXTERN u32 acpi_gbl_state_cache_requests;
-ACPI_EXTERN u32 acpi_gbl_state_cache_hits;
-ACPI_EXTERN u32 acpi_gbl_parse_cache_requests;
-ACPI_EXTERN u32 acpi_gbl_parse_cache_hits;
-ACPI_EXTERN u32 acpi_gbl_object_cache_requests;
-ACPI_EXTERN u32 acpi_gbl_object_cache_hits;
-ACPI_EXTERN u32 acpi_gbl_walk_state_cache_requests;
-ACPI_EXTERN u32 acpi_gbl_walk_state_cache_hits;
-ACPI_EXTERN u32 acpi_gbl_ns_lookup_count;
-ACPI_EXTERN u32 acpi_gbl_ps_find_count;
-
-
-ACPI_EXTERN u16 acpi_gbl_generic_state_cache_depth;
-ACPI_EXTERN u16 acpi_gbl_parse_cache_depth;
-ACPI_EXTERN u16 acpi_gbl_object_cache_depth;
-ACPI_EXTERN u16 acpi_gbl_walk_state_cache_depth;
-ACPI_EXTERN u16 acpi_gbl_pm1_enable_register_save;
-ACPI_EXTERN u16 acpi_gbl_next_table_owner_id;
-ACPI_EXTERN u16 acpi_gbl_next_method_owner_id;
-
-ACPI_EXTERN u8 acpi_gbl_debugger_configuration;
-ACPI_EXTERN u8 acpi_gbl_global_lock_acquired;
-ACPI_EXTERN u8 acpi_gbl_global_lock_set; /* TBD: [Restructure] OBSOLETE?? */
-ACPI_EXTERN u8 acpi_gbl_step_to_next_call;
-ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present;
-
-
-ACPI_EXTERN ACPI_OBJECT_NOTIFY_HANDLER acpi_gbl_drv_notify;
-ACPI_EXTERN ACPI_OBJECT_NOTIFY_HANDLER acpi_gbl_sys_notify;
-
-
-extern u8 acpi_gbl_shutdown;
-extern u32 acpi_gbl_system_flags;
-extern u32 acpi_gbl_startup_flags;
-
-
-/*****************************************************************************
- *
- * Namespace globals


- *
- ****************************************************************************/
-

-#define NUM_NS_TYPES INTERNAL_TYPE_INVALID+1
-#define NUM_PREDEFINED_NAMES 9
-
-
-ACPI_EXTERN ACPI_NAME_TABLE acpi_gbl_root_name_table;
-ACPI_EXTERN ACPI_NAMED_OBJECT *acpi_gbl_root_object;
-
-extern u8 acpi_gbl_ns_properties[NUM_NS_TYPES];
-extern PREDEFINED_NAMES acpi_gbl_pre_defined_names [NUM_PREDEFINED_NAMES];
-
-
-/* Used to detect memory leaks (DEBUG ONLY) */
-
-#ifdef ACPI_DEBUG
-ACPI_EXTERN ALLOCATION_INFO *acpi_gbl_head_alloc_ptr;
-ACPI_EXTERN ALLOCATION_INFO *acpi_gbl_tail_alloc_ptr;
-#endif
-
-
-/*****************************************************************************
- *
- * Interpreter globals


- *
- ****************************************************************************/
-
-

-ACPI_EXTERN u32 acpi_gbl_when_to_parse_methods;
-ACPI_EXTERN ACPI_WALK_LIST *acpi_gbl_current_walk_list;
-
-/* Base of AML block, and pointer to current location in it */
-
-ACPI_EXTERN u8 *acpi_gbl_Pcode_base;
-ACPI_EXTERN u8 *acpi_gbl_Pcode;
-
-/*
- * Length of AML block, and remaining length of current package.
- */
-ACPI_EXTERN u32 acpi_gbl_Pcode_block_len;
-ACPI_EXTERN u32 acpi_gbl_Pcode_len;
-
-ACPI_EXTERN u32 acpi_gbl_buf_seq; /* Counts allocated Buffer descriptors */
-ACPI_EXTERN s32 acpi_gbl_named_object_err; /* Indicate if inc_error should be called */
-
-/*
- * Handle to the last method found - used during pass1 of load
- */
-ACPI_EXTERN ACPI_HANDLE acpi_gbl_last_method;
-
-/*
- * Table of Address Space handlers
- */
-
-ACPI_EXTERN ACPI_ADDRESS_SPACE_INFO acpi_gbl_address_spaces[ACPI_NUM_ADDRESS_SPACES];
-
-
-/* Control method single step flag */
-
-ACPI_EXTERN u8 acpi_gbl_cm_single_step;
-
-
-/*****************************************************************************
- *
- * Parser globals


- *
- ****************************************************************************/
-

-ACPI_EXTERN ACPI_GENERIC_OP *acpi_gbl_parsed_namespace_root;
-
-extern ACPI_OP_INFO acpi_gbl_aml_op_info[];
-extern u8 acpi_gbl_aml_op_info_index[256];
-extern char *acpi_gbl_parser_id;
-
-
-/*****************************************************************************
- *
- * Hardware globals


- *
- ****************************************************************************/
-

-extern ACPI_C_STATE_HANDLER acpi_hw_cx_handlers[MAX_CX_STATES];
-extern u32 acpi_hw_active_cx_state;
-
-
-/*****************************************************************************
- *
- * Event globals


- *
- ****************************************************************************/
-

-ACPI_EXTERN ACPI_FIXED_EVENT_INFO acpi_gbl_fixed_event_handlers[NUM_FIXED_EVENTS];
-
-ACPI_EXTERN ACPI_HANDLE acpi_gbl_gpe_obj_handle;
-ACPI_EXTERN u32 acpi_gbl_gpe_register_count;
-ACPI_EXTERN ACPI_GPE_REGISTERS *acpi_gbl_gpe_registers;
-ACPI_EXTERN ACPI_GPE_LEVEL_INFO *acpi_gbl_gpe_info;
-
-/*
- * Gpe validation and translation table
- * Indexed by the GPE number, returns GPE_INVALID if the GPE is not supported.
- * Otherwise, returns a valid index into the global GPE table.
- *
- * This table is needed because the GPE numbers supported by block 1 do not
- * have to be contiguous with the GPE numbers supported by block 0.
- */
-ACPI_EXTERN u8 acpi_gbl_gpe_valid [NUM_GPE];
-
-/* Acpi_event counter for debug only */
-
-#ifdef ACPI_DEBUG
-ACPI_EXTERN u32 acpi_gbl_event_count[NUM_FIXED_EVENTS];
-#endif
-
-
-/*****************************************************************************
- *
- * Debugger globals


- *
- ****************************************************************************/
-

-ACPI_EXTERN u8 acpi_gbl_method_executing;
-ACPI_EXTERN u8 acpi_gbl_db_terminate_threads;
-
-
-/* Memory allocation metrics - Debug Only! */
-
-#ifdef ACPI_DEBUG
-
-ACPI_EXTERN u32 acpi_gbl_current_alloc_size;
-ACPI_EXTERN u32 acpi_gbl_current_alloc_count;
-ACPI_EXTERN u32 acpi_gbl_running_alloc_size;
-ACPI_EXTERN u32 acpi_gbl_running_alloc_count;
-ACPI_EXTERN u32 acpi_gbl_max_concurrent_alloc_size;
-ACPI_EXTERN u32 acpi_gbl_max_concurrent_alloc_count;
-ACPI_EXTERN u32 acpi_gbl_current_object_count;
-ACPI_EXTERN u32 acpi_gbl_current_object_size;
-ACPI_EXTERN u32 acpi_gbl_max_concurrent_object_count;
-ACPI_EXTERN u32 acpi_gbl_max_concurrent_object_size;
-ACPI_EXTERN u32 acpi_gbl_running_object_count;
-ACPI_EXTERN u32 acpi_gbl_running_object_size;
-
-#endif
-
-
-#endif /* __GLOBALS_H__ */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/hardware.h linux/drivers/acpi/include/hardware.h
--- v2.4.0-test8/linux/drivers/acpi/include/hardware.h Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/include/hardware.h Wed Dec 31 16:00:00 1969
@@ -1,169 +0,0 @@
-
-/******************************************************************************
- *
- * Name: hardware.h -- hardware specific interfaces


- *
- *****************************************************************************/
-
-/*
- * Copyright (C) 2000 R. Byron Moore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-

-#ifndef __HARDWARE_H__
-#define __HARDWARE_H__


-
-
-/* Prototypes */
-
-

-ACPI_STATUS
-acpi_hw_initialize(
- void);
-
-ACPI_STATUS
-acpi_hw_shutdown(
- void);
-
-ACPI_STATUS
-acpi_hw_initialize_system_info(
- void);
-
-ACPI_STATUS
-acpi_hw_set_mode (
- u32 mode);
-
-u32
-acpi_hw_get_mode (
- void);
-
-u32
-acpi_hw_get_mode_capabilities (
- void);
-
-/* Register I/O Prototypes */
-
-u32
-acpi_hw_register_access (
- NATIVE_UINT read_write,
- u8 use_lock,
- u32 register_id, ... /* DWORD Value */);
-
-void
-acpi_hw_clear_acpi_status (
- void);
-
-
-/* GPE support */
-
-void
-acpi_hw_enable_gpe (
- u32 gpe_index);
-
-void
-acpi_hw_disable_gpe (
- u32 gpe_index);
-
-void
-acpi_hw_clear_gpe (
- u32 gpe_index);
-
-void
-acpi_hw_get_gpe_status (
- u32 gpe_number,
- ACPI_EVENT_STATUS *event_status);
-
-/* Sleep Prototypes */
-
-ACPI_STATUS
-acpi_hw_obtain_sleep_type_register_data (
- u8 sleep_state,
- u8 *slp_typ_a,
- u8 *slp_typ_b);
-
-
-/* Cx State Prototypes */
-
-ACPI_STATUS
-acpi_hw_enter_c1(
- ACPI_IO_ADDRESS pblk_address,
- u32 *pm_timer_ticks);
-
-ACPI_STATUS
-acpi_hw_enter_c2(
- ACPI_IO_ADDRESS pblk_address,
- u32 *pm_timer_ticks);
-
-ACPI_STATUS
-acpi_hw_enter_c3(
- ACPI_IO_ADDRESS pblk_address,
- u32 *pm_timer_ticks);
-
-ACPI_STATUS
-acpi_hw_enter_cx (
- ACPI_IO_ADDRESS pblk_address,
- u32 *pm_timer_ticks);
-
-ACPI_STATUS
-acpi_hw_set_cx (
- u32 cx_state);
-
-ACPI_STATUS
-acpi_hw_get_cx_info (
- u32 cx_states[]);
-
-
-/* Throttling Prototypes */
-
-void
-acpi_hw_enable_throttling (
- ACPI_IO_ADDRESS pblk_address);
-
-void
-acpi_hw_disable_throttling (
- ACPI_IO_ADDRESS pblk_address);
-
-u32
-acpi_hw_get_duty_cycle (
- u8 duty_offset,
- ACPI_IO_ADDRESS pblk_address,
- u32 num_throttle_states);
-
-void
-acpi_hw_program_duty_cycle (
- u8 duty_offset,
- u32 duty_cycle,
- ACPI_IO_ADDRESS pblk_address,
- u32 num_throttle_states);
-
-NATIVE_UINT
-acpi_hw_local_pow (
- NATIVE_UINT x,
- NATIVE_UINT y);
-
-
-/* ACPI Timer prototypes */
-
-u32
-acpi_hw_pmt_ticks (
- void);
-
-u32
-acpi_hw_pmt_resolution (
- void);
-
-
-#endif /* __HARDWARE_H__ */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/internal.h linux/drivers/acpi/include/internal.h
--- v2.4.0-test8/linux/drivers/acpi/include/internal.h Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/include/internal.h Wed Dec 31 16:00:00 1969
@@ -1,850 +0,0 @@
-
-/******************************************************************************
- *
- * Name: internal.h - Internal data types used across the ACPI subsystem


- *
- *****************************************************************************/
-
-/*
- * Copyright (C) 2000 R. Byron Moore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-

-#ifndef _ACPI_INTERNAL_H
-#define _ACPI_INTERNAL_H
-
-#include "config.h"
-
-
-#define WAIT_FOREVER ((u32) -1)
-
-typedef void* ACPI_MUTEX;
-typedef u32 ACPI_MUTEX_HANDLE;
-
-
-/* Object descriptor types */
-
-#define ACPI_DESC_TYPE_INTERNAL 0xAA
-#define ACPI_DESC_TYPE_PARSER 0xBB
-#define ACPI_DESC_TYPE_STATE 0xCC
-#define ACPI_DESC_TYPE_WALK 0xDD
-#define ACPI_DESC_TYPE_NAMED 0xEE
-
-
-/*****************************************************************************
- *
- * Mutex typedefs and structs
- *
- ****************************************************************************/
-
-
-/*
- * Predefined handles for the mutex objects used within the subsystem
- * All mutex objects are automatically created by Acpi_cm_mutex_initialize.
- * NOTE: any changes here must be reflected in the Acpi_gbl_Mutex_names table also!
- */
-
-#define ACPI_MTX_HARDWARE 0
-#define ACPI_MTX_MEMORY 1
-#define ACPI_MTX_CACHES 2
-#define ACPI_MTX_TABLES 3
-#define ACPI_MTX_PARSER 4
-#define ACPI_MTX_DISPATCHER 5
-#define ACPI_MTX_INTERPRETER 6
-#define ACPI_MTX_EXECUTE 7
-#define ACPI_MTX_NAMESPACE 8
-#define ACPI_MTX_EVENTS 9
-#define ACPI_MTX_OP_REGIONS 10
-#define ACPI_MTX_DEBUG_CMD_READY 11
-#define ACPI_MTX_DEBUG_CMD_COMPLETE 12
-
-#define MAX_MTX 12
-#define NUM_MTX MAX_MTX+1
-
-
-#ifdef ACPI_DEBUG
-#ifdef DEFINE_ACPI_GLOBALS
-
-/* Names for the mutexes used in the subsystem */
-
-static char *acpi_gbl_mutex_names[] =
-{
- "ACPI_MTX_Hardware",
- "ACPI_MTX_Memory",
- "ACPI_MTX_Caches",
- "ACPI_MTX_Tables",
- "ACPI_MTX_Parser",
- "ACPI_MTX_Dispatcher",
- "ACPI_MTX_Interpreter",
- "ACPI_MTX_Execute",
- "ACPI_MTX_Namespace",
- "ACPI_MTX_Events",
- "ACPI_MTX_Op_regions",
- "ACPI_MTX_Debug_cmd_ready",
- "ACPI_MTX_Debug_cmd_complete"


-};
-
-#endif
-#endif
-

-
-/* Table for the global mutexes */
-
-typedef struct acpi_mutex_info
-{
- ACPI_MUTEX mutex;
- u32 use_count;
- u8 locked;
-
-} ACPI_MUTEX_INFO;
-
-
-/* Lock flag parameter for various interfaces */
-
-#define ACPI_MTX_DO_NOT_LOCK 0
-#define ACPI_MTX_LOCK 1
-
-
-typedef u16 ACPI_OWNER_ID;
-#define OWNER_TYPE_TABLE 0x0
-#define OWNER_TYPE_METHOD 0x1
-#define FIRST_METHOD_ID 0x0000
-#define FIRST_TABLE_ID 0x8000
-
-/* TBD: [Restructure] get rid of the need for this! */
-
-#define TABLE_ID_DSDT (ACPI_OWNER_ID) 0xD1D1
-
-/*****************************************************************************
- *
- * Namespace typedefs and structs


- *
- ****************************************************************************/
-
-

-/* Operational modes of the AML interpreter/scanner */
-
-typedef enum
-{
- IMODE_LOAD_PASS1 = 0x01,
- IMODE_LOAD_PASS2 = 0x02,
- IMODE_EXECUTE = 0x0E
-
-} OPERATING_MODE;
-
-
-/*
- * The Acpi_named_object describes a named object that appears in the AML
- * An Acpi_name_table is used to store Acpi_named_objects.
- *
- * Data_type is used to differentiate between internal descriptors, and MUST
- * be the first byte in this structure.
- */
-
-typedef struct acpi_named_object
-{
- u8 data_type;
- u8 type; /* Type associated with this name */
- u8 this_index; /* Entry number */
- u8 flags;
- u32 name; /* ACPI Name, always 4 chars per ACPI spec */
-
-
- void *object; /* Pointer to attached ACPI object (optional) */
- struct acpi_name_table *child_table; /* Scope owned by this name (optional) */
- ACPI_OWNER_ID owner_id; /* ID of owner - either an ACPI table or a method */
- u16 reference_count; /* Current count of references and children */
-
-#ifdef _IA64
- u32 fill1; /* 64-bit alignment */
-#endif
-
-} ACPI_NAMED_OBJECT;
-
-
-typedef struct acpi_name_table
-{
- struct acpi_name_table *next_table;
- struct acpi_name_table *parent_table;
- ACPI_NAMED_OBJECT *parent_entry;
- ACPI_NAMED_OBJECT entries[1];
-
-} ACPI_NAME_TABLE;
-
-
-#define ENTRY_NOT_FOUND NULL
-
-
-/* NTE flags */
-
-#define NTE_AML_ATTACHMENT 0x1
-
-
-/*
- * ACPI Table Descriptor. One per ACPI table
- */
-typedef struct acpi_table_desc
-{
- struct acpi_table_desc *prev;
- struct acpi_table_desc *next;
- struct acpi_table_desc *installed_desc;
- ACPI_TABLE_HEADER *pointer;
- void *base_pointer;
- u8 *aml_pointer;
- u32 aml_length;
- u32 length;
- u32 count;
- ACPI_OWNER_ID table_id;
- u8 type;
- u8 allocation;
- u8 loaded_into_namespace;
-
-} ACPI_TABLE_DESC;
-
-
-typedef struct
-{
- char *search_for;
- ACPI_HANDLE *list;
- s32 *count;
-
-} FIND_CONTEXT;
-
-
-typedef struct
-{
- ACPI_NAME_TABLE *name_table;
- u32 position;
- u8 table_full;
-
-} NS_SEARCH_DATA;
-
-
-/*
- * Predefined Namespace items
- */
-#define ACPI_MAX_ADDRESS_SPACE 255
-#define ACPI_NUM_ADDRESS_SPACES 256
-
-
-typedef struct
-{
- char *name;
- ACPI_OBJECT_TYPE type;
- char *val;
-
-} PREDEFINED_NAMES;
-
-
-/*****************************************************************************
- *
- * Event typedefs and structs


- *
- ****************************************************************************/
-
-

-/* Status bits. */
-
-#define ACPI_STATUS_PMTIMER 0x0001
-#define ACPI_STATUS_GLOBAL 0x0020
-#define ACPI_STATUS_POWER_BUTTON 0x0100
-#define ACPI_STATUS_SLEEP_BUTTON 0x0200
-#define ACPI_STATUS_RTC_ALARM 0x0400
-
-/* Enable bits. */
-
-#define ACPI_ENABLE_PMTIMER 0x0001
-#define ACPI_ENABLE_GLOBAL 0x0020
-#define ACPI_ENABLE_POWER_BUTTON 0x0100
-#define ACPI_ENABLE_SLEEP_BUTTON 0x0200
-#define ACPI_ENABLE_RTC_ALARM 0x0400
-
-
-/*
- * Entry in the Address_space (AKA Operation Region) table
- */
-
-typedef struct
-{
- ADDRESS_SPACE_HANDLER handler;
- void *context;
-
-} ACPI_ADDRESS_SPACE_INFO;
-
-
-/* Values and addresses of the GPE registers (both banks) */
-
-typedef struct
-{
- u8 status; /* Current value of status reg */
- u8 enable; /* Current value of enable reg */
- u16 status_addr; /* Address of status reg */
- u16 enable_addr; /* Address of enable reg */
- u8 gpe_base; /* Base GPE number */
-
-} ACPI_GPE_REGISTERS;
-
-
-#define ACPI_GPE_LEVEL_TRIGGERED 1
-#define ACPI_GPE_EDGE_TRIGGERED 2
-
-
-/* Information about each particular GPE level */
-
-typedef struct
-{
- u8 type; /* Level or Edge */
-
- ACPI_HANDLE method_handle; /* Method handle for direct (fast) execution */
- GPE_HANDLER handler; /* Address of handler, if any */
- void *context; /* Context to be passed to handler */
-
-} ACPI_GPE_LEVEL_INFO;
-
-
-/* Information about each particular fixed event */
-
-typedef struct
-{
- FIXED_EVENT_HANDLER handler; /* Address of handler. */
- void *context; /* Context to be passed to handler */
-
-} ACPI_FIXED_EVENT_INFO;
-
-
-/* Information used during field processing */
-
-typedef struct
-{
- u8 skip_field;
- u8 field_flag;
- u32 pkg_length;
-
-} ACPI_FIELD_INFO;
-
-
-/*****************************************************************************
- *
- * Parser typedefs and structs


- *
- ****************************************************************************/
-
-

-#define OP_INFO_TYPE 0x1F
-#define OP_INFO_HAS_ARGS 0x20
-#define OP_INFO_CHILD_LOCATION 0xC0
-
-/*
- * AML opcode, name, and argument layout
- */
-typedef struct acpi_op_info
-{
- u16 opcode; /* AML opcode */
- u8 flags; /* Opcode type, Has_args flag */
- u32 parse_args; /* Grammar/Parse time arguments */
- u32 runtime_args; /* Interpret time arguments */
-
- DEBUG_ONLY_MEMBERS (
- char *name) /* op name (debug only) */
-
-} ACPI_OP_INFO;
-
-
-typedef union acpi_op_value
-{
- u32 integer; /* integer constant */
- u32 size; /* bytelist or field size */
- char *string; /* NULL terminated string */
- u8 *buffer; /* buffer or string */
- char *name; /* NULL terminated string */
- struct acpi_generic_op *arg; /* arguments and contained ops */
- ACPI_NAMED_OBJECT *entry; /* entry in interpreter namespace tbl */
-
-} ACPI_OP_VALUE;
-
-
-#define ACPI_COMMON_OP \


- u8 data_type; /* To differentiate various internal objs */\

- u8 flags; /* Type of Op */\
- u16 opcode; /* AML opcode */\
- u32 aml_offset; /* offset of declaration in AML */\
- struct acpi_generic_op *parent; /* parent op */\
- struct acpi_generic_op *next; /* next op */\
- DEBUG_ONLY_MEMBERS (\
- char op_name[16]) /* op name (debug only) */\
- /* NON-DEBUG members below: */\
- void *acpi_named_object;/* for use by interpreter */\
- ACPI_OP_VALUE value; /* Value or args associated with the opcode */\
-
-
-/*
- * generic operation (eg. If, While, Store)
- */
-typedef struct acpi_generic_op
-{
- ACPI_COMMON_OP
-} ACPI_GENERIC_OP;
-
-
-/*
- * operation with a name (eg. Scope, Method, Name, Named_field, ...)
- */
-typedef struct acpi_named_op
-{
- ACPI_COMMON_OP
- u32 name; /* 4-byte name or zero if no name */
-
-} ACPI_NAMED_OP;
-
-
-/*
- * special operation for methods and regions (parsing must be deferred
- * until a first pass parse is completed)
- */
-typedef struct acpi_deferred_op
-{
- ACPI_COMMON_OP
- u32 name; /* 4-byte name or 0 if none */
- u32 body_length; /* AML body size */
- u8 *body; /* AML body */
- u16 thread_count; /* Count of threads currently executing a method */
-
-} ACPI_DEFERRED_OP;
-
-
-/*
- * special operation for bytelists (Byte_list only)
- */
-typedef struct acpi_bytelist_op
-{
- ACPI_COMMON_OP
- u8 *data; /* bytelist data */
-
-} ACPI_BYTELIST_OP;
-
-
-/*
- * Parse state - one state per parser invocation and each control
- * method.
- */
-
-typedef struct acpi_parse_state
-{
- u8 *aml_start; /* first AML byte */
- u8 *aml; /* next AML byte */
- u8 *aml_end; /* (last + 1) AML byte */
- u8 *pkg_end; /* current package end */
- ACPI_GENERIC_OP *start_op; /* root of parse tree */
- struct acpi_parse_scope *scope; /* current scope */
- struct acpi_parse_scope *scope_avail; /* unused (extra) scope structs */
- struct acpi_parse_state *next;
-
-} ACPI_PARSE_STATE;
-
-
-/*
- * Parse scope - one per ACPI scope
- */
-
-typedef struct acpi_parse_scope
-{
- ACPI_GENERIC_OP *op; /* current op being parsed */
- u8 *arg_end; /* current argument end */
- u8 *pkg_end; /* current package end */
- struct acpi_parse_scope *parent; /* parent scope */
- u32 arg_list; /* next argument to parse */
- u32 arg_count; /* Number of fixed arguments */
-
-} ACPI_PARSE_SCOPE;
-
-
-/*****************************************************************************
- *
- * Generic "state" object for stacks


- *
- ****************************************************************************/
-
-

-#define CONTROL_NORMAL 0xC0
-#define CONTROL_CONDITIONAL_EXECUTING 0xC1
-#define CONTROL_PREDICATE_EXECUTING 0xC2
-#define CONTROL_PREDICATE_FALSE 0xC3
-#define CONTROL_PREDICATE_TRUE 0xC4
-
-
-#define ACPI_STATE_COMMON /* Two 32-bit fields and a pointer */\


- u8 data_type; /* To differentiate various internal objs */\

- u8 flags; \
- u16 value; \
- u16 state; \
- u16 acpi_eval; \
- void *next; \
-
-typedef struct acpi_common_state
-{
- ACPI_STATE_COMMON
-} ACPI_COMMON_STATE;
-
-
-/*
- * Update state - used to traverse complex objects such as packages
- */
-typedef struct acpi_update_state
-{
- ACPI_STATE_COMMON
- union acpi_obj_internal *object;
-
-} ACPI_UPDATE_STATE;
-
-/*
- * Control state - one per if/else and while constructs.
- * Allows nesting of these constructs
- */
-typedef struct acpi_control_state
-{
- ACPI_STATE_COMMON
- ACPI_GENERIC_OP *predicate_op; /* Start of if/while predicate */
-
-} ACPI_CONTROL_STATE;
-
-
-/*
- * Scope state - current scope during namespace lookups
- */
-
-typedef struct acpi_scope_state
-{
- ACPI_STATE_COMMON
- ACPI_NAME_TABLE *name_table;
-
-} ACPI_SCOPE_STATE;
-
-
-typedef union acpi_gen_state
-{
- ACPI_COMMON_STATE common;
- ACPI_CONTROL_STATE control;
- ACPI_UPDATE_STATE update;
- ACPI_SCOPE_STATE scope;
-
-} ACPI_GENERIC_STATE;
-
-
-/*****************************************************************************
- *
- * Tree walking typedefs and structs
- *
- ****************************************************************************/
-
-
-/*
- * Walk state - current state of a parse tree walk. Used for both a leisurely stroll through
- * the tree (for whatever reason), and for control method execution.
- */
-
-#define NEXT_OP_DOWNWARD 1
-#define NEXT_OP_UPWARD 2
-
-typedef struct acpi_walk_state
-{


- u8 data_type; /* To differentiate various internal objs */\

- ACPI_OWNER_ID owner_id; /* Owner of objects created during the walk */
- u8 last_predicate; /* Result of last predicate */
- u8 next_op_info; /* Info about Next_op */
- u8 num_operands; /* Stack pointer for Operands[] array */
- u8 num_results; /* Stack pointer for Results[] array */
- u8 current_result; /* */
-
- struct acpi_walk_state *next; /* Next Walk_state in list */
- ACPI_GENERIC_OP *origin; /* Start of walk */
- ACPI_GENERIC_OP *prev_op; /* Last op that was processed */
- ACPI_GENERIC_OP *next_op; /* next op to be processed */
- ACPI_GENERIC_STATE *control_state; /* List of control states (nested IFs) */
- ACPI_GENERIC_STATE *scope_info; /* Stack of nested scopes */
- union acpi_obj_internal *return_desc; /* Return object, if any */
- union acpi_obj_internal *method_desc; /* Method descriptor if running a method */
- ACPI_GENERIC_OP *method_call_op; /* Method_call Op if running a method */
- union acpi_obj_internal *operands[OBJ_NUM_OPERANDS]; /* Operands passed to the interpreter */
- union acpi_obj_internal *results[OBJ_NUM_OPERANDS]; /* Accumulated results */
- struct acpi_named_object arguments[MTH_NUM_ARGS]; /* Control method arguments */
- struct acpi_named_object local_variables[MTH_NUM_LOCALS]; /* Control method locals */
-
-
-} ACPI_WALK_STATE;
-
-
-/*
- * Walk list - head of a tree of walk states. Multiple walk states are created when there
- * are nested control methods executing.
- */
-typedef struct acpi_walk_list
-{
-
- ACPI_WALK_STATE *walk_state;
-
-} ACPI_WALK_LIST;
-
-
-typedef
-ACPI_STATUS (*INTERPRETER_CALLBACK) (
- ACPI_WALK_STATE *state,


- ACPI_GENERIC_OP *op);
-
-

-/* Info used by Acpi_ps_init_objects */
-
-typedef struct init_walk_info
-{
- u32 method_count;
- u32 op_region_count;
- ACPI_TABLE_DESC *table_desc;
-
-} INIT_WALK_INFO;
-
-
-/* TBD: [Restructure] Merge with struct above */
-
-typedef struct acpi_walk_info
-{
- u32 debug_level;
- u32 owner_id;
-
-} ACPI_WALK_INFO;
-
-
-/*****************************************************************************
- *
- * Hardware and PNP


- *
- ****************************************************************************/
-
-

-/* Sleep states */
-
-#define SLWA_DEBUG_LEVEL 4
-#define GTS_CALL 0
-#define GTS_WAKE 1
-
-/* Cx States */
-
-#define MAX_CX_STATE_LATENCY 0xFFFFFFFF
-#define MAX_CX_STATES 4
-
-/*
- * The #define's and enum below establish an abstract way of identifying what
- * register block and register is to be accessed. Do not change any of the
- * values as they are used in switch statements and offset calculations.
- */
-
-#define REGISTER_BLOCK_MASK 0xFF00
-#define BIT_IN_REGISTER_MASK 0x00FF
-#define PM1_EVT 0x0100
-#define PM1_CONTROL 0x0200
-#define PM2_CONTROL 0x0300
-#define PM_TIMER 0x0400
-#define PROCESSOR_BLOCK 0x0500
-#define GPE0_STS_BLOCK 0x0600
-#define GPE0_EN_BLOCK 0x0700
-#define GPE1_STS_BLOCK 0x0800
-#define GPE1_EN_BLOCK 0x0900
-
-enum
-{
- /* PM1 status register ids */
-
- TMR_STS = (PM1_EVT | 0x01),
- BM_STS,
- GBL_STS,
- PWRBTN_STS,
- SLPBTN_STS,
- RTC_STS,
- WAK_STS,
-
- /* PM1 enable register ids */
-
- TMR_EN,
- /* need to skip 1 enable number since there's no bus master enable register */
- GBL_EN = (PM1_EVT | 0x0A),
- PWRBTN_EN,
- SLPBTN_EN,
- RTC_EN,
-
- /* PM1 control register ids */
-
- SCI_EN = (PM1_CONTROL | 0x01),
- BM_RLD,
- GBL_RLS,
- SLP_TYPE_A,
- SLP_TYPE_B,
- SLP_EN,
-
- /* PM2 control register ids */
-
- ARB_DIS = (PM2_CONTROL | 0x01),
-
- /* PM Timer register ids */
-
- TMR_VAL = (PM_TIMER | 0x01),
-
- GPE0_STS = (GPE0_STS_BLOCK | 0x01),
- GPE0_EN = (GPE0_EN_BLOCK | 0x01),
-
- GPE1_STS = (GPE1_STS_BLOCK | 0x01),
- GPE1_EN = (GPE0_EN_BLOCK | 0x01),
-
- /* Last register value is one less than LAST_REG */
-
- LAST_REG
-};
-
-
-#define TMR_STS_MASK 0x0001
-#define BM_STS_MASK 0x0010
-#define GBL_STS_MASK 0x0020
-#define PWRBTN_STS_MASK 0x0100
-#define SLPBTN_STS_MASK 0x0200
-#define RTC_STS_MASK 0x0400
-#define WAK_STS_MASK 0x8000
-
-#define ALL_FIXED_STS_BITS (TMR_STS_MASK | BM_STS_MASK | GBL_STS_MASK | PWRBTN_STS_MASK | \
- SLPBTN_STS_MASK | RTC_STS_MASK | WAK_STS_MASK)
-
-#define TMR_EN_MASK 0x0001
-#define GBL_EN_MASK 0x0020
-#define PWRBTN_EN_MASK 0x0100
-#define SLPBTN_EN_MASK 0x0200
-#define RTC_EN_MASK 0x0400
-
-#define SCI_EN_MASK 0x0001
-#define BM_RLD_MASK 0x0002
-#define GBL_RLS_MASK 0x0004
-#define SLP_TYPE_X_MASK 0x1C00
-#define SLP_EN_MASK 0x2000
-
-#define ARB_DIS_MASK 0x0001
-
-#define GPE0_STS_MASK
-#define GPE0_EN_MASK
-
-#define GPE1_STS_MASK
-#define GPE1_EN_MASK
-
-
-#define ACPI_READ 1
-#define ACPI_WRITE 2
-
-#define LOW_BYTE 0x00FF
-#define ONE_BYTE 0x08
-
-#ifndef SET
- #define SET 1
-#endif
-#ifndef CLEAR
- #define CLEAR 0
-#endif
-
-
-/* Plug and play */
-
-/* Pnp and ACPI data */
-
-#define VERSION_NO 0x01
-#define LOGICAL_DEVICE_ID 0x02
-#define COMPATIBLE_DEVICE_ID 0x03
-#define IRQ_FORMAT 0x04
-#define DMA_FORMAT 0x05
-#define START_DEPENDENT_TAG 0x06
-#define END_DEPENDENT_TAG 0x07
-#define IO_PORT_DESCRIPTOR 0x08
-#define FIXED_LOCATION_IO_DESCRIPTOR 0x09
-#define RESERVED_TYPE0 0x0A
-#define RESERVED_TYPE1 0x0B
-#define RESERVED_TYPE2 0x0C
-#define RESERVED_TYPE3 0x0D
-#define SMALL_VENDOR_DEFINED 0x0E
-#define END_TAG 0x0F
-
-/* Pnp and ACPI data */
-
-#define MEMORY_RANGE_24 0x81
-#define ISA_MEMORY_RANGE 0x81
-#define LARGE_VENDOR_DEFINED 0x84
-#define EISA_MEMORY_RANGE 0x85
-#define MEMORY_RANGE_32 0x85
-#define FIXED_EISA_MEMORY_RANGE 0x86
-#define FIXED_MEMORY_RANGE_32 0x86
-
-/* ACPI only data */
-
-#define DWORD_ADDRESS_SPACE 0x87
-#define WORD_ADDRESS_SPACE 0x88
-#define EXTENDED_IRQ 0x89
-
-/* MUST HAVES */
-
-
-typedef enum
-{
- DWORD_DEVICE_ID,
- STRING_PTR_DEVICE_ID,
- STRING_DEVICE_ID
-
-} DEVICE_ID_TYPE;
-
-typedef struct
-{
- DEVICE_ID_TYPE type;
- union
- {
- u32 number;
- char *string_ptr;
- char buffer[9];
- } data;
-
-} DEVICE_ID;
-
-
-/*****************************************************************************
- *
- * Debug


- *
- ****************************************************************************/
-
-

-/* Entry for a memory allocation (debug only) */
-
-#ifdef ACPI_DEBUG
-
-#define MEM_MALLOC 0
-#define MEM_CALLOC 1
-#define MAX_MODULE_NAME 16
-
-typedef struct allocation_info
-{
- struct allocation_info *previous;
- struct allocation_info *next;
- void *address;
- u32 size;
- u32 component;
- u32 line;
- char module[MAX_MODULE_NAME];
- u8 alloc_type;
-
-} ALLOCATION_INFO;
-
-#endif
-
-#endif
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/interp.h linux/drivers/acpi/include/interp.h
--- v2.4.0-test8/linux/drivers/acpi/include/interp.h Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/include/interp.h Wed Dec 31 16:00:00 1969
@@ -1,660 +0,0 @@
-
-/******************************************************************************


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 028'
echo 'File patch-2.4.0-test9 is continued in part 029'
echo "029" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part030

#!/bin/sh -x
# this is part 030 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 030; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

- u32 *bytes_consumed);
-
-ACPI_STATUS
-acpi_rs_address16_resource (


- u8 *byte_stream_buffer,
- u32 *bytes_consumed,
- u8 **output_buffer,
- u32 *structure_size);
-
-ACPI_STATUS

-acpi_rs_address16_stream (


- RESOURCE *linked_list,
- u8 **output_buffer,
- u32 *bytes_consumed);
-
-ACPI_STATUS

-acpi_rs_address32_resource (


- u8 *byte_stream_buffer,
- u32 *bytes_consumed,
- u8 **output_buffer,
- u32 *structure_size);
-
-ACPI_STATUS

-acpi_rs_address32_stream (


- RESOURCE *linked_list,
- u8 **output_buffer,
- u32 *bytes_consumed);
-
-ACPI_STATUS

-acpi_rs_start_dependent_functions_resource (


- u8 *byte_stream_buffer,
- u32 *bytes_consumed,
- u8 **output_buffer,
- u32 *structure_size);
-
-ACPI_STATUS

-acpi_rs_end_dependent_functions_resource (


- u8 *byte_stream_buffer,
- u32 *bytes_consumed,
- u8 **output_buffer,
- u32 *structure_size);
-
-ACPI_STATUS

-acpi_rs_start_dependent_functions_stream (


- RESOURCE *linked_list,
- u8 **output_buffer,
- u32 *bytes_consumed);
-
-ACPI_STATUS

-acpi_rs_end_dependent_functions_stream (


- RESOURCE *linked_list,
- u8 **output_buffer,
- u32 *bytes_consumed);
-
-ACPI_STATUS

-acpi_rs_memory24_resource (


- u8 *byte_stream_buffer,
- u32 *bytes_consumed,
- u8 **output_buffer,
- u32 *structure_size);
-
-ACPI_STATUS

-acpi_rs_memory24_stream (


- RESOURCE *linked_list,
- u8 **output_buffer,
- u32 *bytes_consumed);
-
-ACPI_STATUS

-acpi_rs_memory32_range_resource (


- u8 *byte_stream_buffer,
- u32 *bytes_consumed,
- u8 **output_buffer,
- u32 *structure_size

-);
-
-ACPI_STATUS
-acpi_rs_fixed_memory32_resource (


- u8 *byte_stream_buffer,
- u32 *bytes_consumed,
- u8 **output_buffer,
- u32 *structure_size);
-
-ACPI_STATUS

-acpi_rs_memory32_range_stream (


- RESOURCE *linked_list,
- u8 **output_buffer,
- u32 *bytes_consumed);
-
-ACPI_STATUS

-acpi_rs_fixed_memory32_stream (


- RESOURCE *linked_list,
- u8 **output_buffer,
- u32 *bytes_consumed);
-
-ACPI_STATUS

-acpi_rs_extended_irq_resource (


- u8 *byte_stream_buffer,
- u32 *bytes_consumed,
- u8 **output_buffer,
- u32 *structure_size);
-
-ACPI_STATUS

-acpi_rs_extended_irq_stream (


- RESOURCE *linked_list,
- u8 **output_buffer,
- u32 *bytes_consumed);
-
-ACPI_STATUS

-acpi_rs_end_tag_resource (


- u8 *byte_stream_buffer,
- u32 *bytes_consumed,
- u8 **output_buffer,
- u32 *structure_size);
-
-ACPI_STATUS

-acpi_rs_end_tag_stream (


- RESOURCE *linked_list,
- u8 **output_buffer,
- u32 *bytes_consumed);
-
-ACPI_STATUS

-acpi_rs_vendor_resource (


- u8 *byte_stream_buffer,
- u32 *bytes_consumed,
- u8 **output_buffer,
- u32 *structure_size);
-
-ACPI_STATUS

-acpi_rs_vendor_stream (


- RESOURCE *linked_list,
- u8 **output_buffer,
- u32 *bytes_consumed);
-
-

-#endif /*__RESOURCE_H__ */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/include/tables.h linux/drivers/acpi/include/tables.h
--- v2.4.0-test8/linux/drivers/acpi/include/tables.h Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/include/tables.h Wed Dec 31 16:00:00 1969
@@ -1,168 +0,0 @@
-
-/******************************************************************************
- *
- * Name: tables.h - ACPI table management


- *
- *****************************************************************************/
-
-/*
- * Copyright (C) 2000 R. Byron Moore
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-

-#ifndef __TABLES_H__
-#define __TABLES_H__
-
-#include "actypes.h"
-#include "actables.h"
-
-
-/* Used in Acpi_tb_map_acpi_table for size parameter if table header is to be used */
-
-#define SIZE_IN_HEADER 0
-
-
-ACPI_STATUS
-acpi_tb_handle_to_object (
- u16 table_id,
- ACPI_TABLE_DESC **table_desc);
-
-
-/*
- * Acpi_tbfac - FACP, FACS utilities
- */
-
-ACPI_STATUS
-acpi_tb_get_table_facs (
- char *buffer_ptr,
- ACPI_TABLE_DESC *table_info);
-
-
-/*
- * Acpi_tbget - Table "get" routines
- */
-
-ACPI_STATUS
-acpi_tb_get_table_ptr (
- ACPI_TABLE_TYPE table_type,
- u32 instance,
- ACPI_TABLE_HEADER **table_ptr_loc);
-
-ACPI_STATUS
-acpi_tb_get_table (
- void *physical_address,
- char *buffer_ptr,
- ACPI_TABLE_DESC *table_info);
-
-
-/*
- * Acpi_tbgetall - Get all firmware ACPI tables
- */
-
-ACPI_STATUS
-acpi_tb_get_all_tables (
- u32 number_of_tables,
- char *buffer_ptr);
-
-
-/*
- * Acpi_tbinstall - Table installation
- */
-
-ACPI_STATUS
-acpi_tb_install_table (
- char *table_ptr,
- ACPI_TABLE_DESC *table_info);
-
-ACPI_STATUS
-acpi_tb_recognize_table (
- char *table_ptr,
- ACPI_TABLE_DESC *table_info);
-
-ACPI_STATUS
-acpi_tb_init_table_descriptor (
- ACPI_TABLE_TYPE table_type,
- ACPI_TABLE_DESC *table_info);
-
-
-/*
- * Acpi_tbremove - Table removal and deletion
- */
-
-void
-acpi_tb_delete_acpi_tables (
- void);
-
-void
-acpi_tb_delete_acpi_table (
- ACPI_TABLE_TYPE type);
-
-ACPI_TABLE_DESC *
-acpi_tb_delete_single_table (
- ACPI_TABLE_DESC *table_desc);
-
-void
-acpi_tb_free_acpi_tables_of_type (
- ACPI_TABLE_DESC *table_info);
-
-
-/*
- * Acpi_tbrsd - RSDP, RSDT utilities
- */
-
-ACPI_STATUS
-acpi_tb_get_table_rsdt (
- u32 *number_of_tables);
-
-char *
-acpi_tb_scan_memory_for_rsdp (
- char *start_address,


- u32 length);
-
-ACPI_STATUS

-acpi_tb_find_rsdp (
- ACPI_TABLE_DESC *table_info);
-
-
-/*
- * Acpi_tbutils - common table utilities
- */
-
-u8
-acpi_tb_system_table_pointer (
- void *where);
-
-ACPI_STATUS
-acpi_tb_map_acpi_table (
- void *physical_address,
- u32 *size,
- void **logical_address);
-
-ACPI_STATUS
-acpi_tb_verify_table_checksum (
- ACPI_TABLE_HEADER *table_header);
-
-u8
-acpi_tb_checksum (


- void *buffer,
- u32 length);
-
-ACPI_STATUS

-acpi_tb_validate_table_header (
- ACPI_TABLE_HEADER *table_header);
-
-
-#endif /* __TABLES_H__ */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/interpreter/Makefile linux/drivers/acpi/interpreter/Makefile
--- v2.4.0-test8/linux/drivers/acpi/interpreter/Makefile Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/interpreter/Makefile Fri Sep 15 18:21:44 2000

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/interpreter/amconfig.c linux/drivers/acpi/interpreter/amconfig.c
--- v2.4.0-test8/linux/drivers/acpi/interpreter/amconfig.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/interpreter/amconfig.c Fri Sep 15 14:30:30 2000


@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *

X * Module Name: amconfig - Namespace reconfiguration (Load/Unload opcodes)
+ * $Revision: 23 $


X *
X *****************************************************************************/
X

@@ -25,17 +25,17 @@


X
X
X #include "acpi.h"

-#include "parser.h"
-#include "interp.h"
+#include "acparser.h"
+#include "acinterp.h"
X #include "amlcode.h"


-#include "namesp.h"
-#include "events.h"
-#include "tables.h"

-#include "dispatch.h"


+#include "acnamesp.h"
+#include "acevents.h"
+#include "actables.h"

+#include "acdispat.h"
X
X
X #define _COMPONENT INTERPRETER
- MODULE_NAME ("amconfig");
+ MODULE_NAME ("amconfig")
X
X
X /*****************************************************************************
@@ -53,13 +53,13 @@
X
X ACPI_STATUS
X acpi_aml_exec_load_table (
- ACPI_OBJECT_INTERNAL *rgn_desc,
+ ACPI_OPERAND_OBJECT *rgn_desc,
X ACPI_HANDLE *ddb_handle)
X {
X ACPI_STATUS status;
- ACPI_OBJECT_INTERNAL *table_desc = NULL;
- char *table_ptr;
- char *table_data_ptr;
+ ACPI_OPERAND_OBJECT *table_desc = NULL;
+ u8 *table_ptr;
+ u8 *table_data_ptr;
X ACPI_TABLE_HEADER table_header;
X ACPI_TABLE_DESC table_info;
X u32 i;
@@ -73,7 +73,7 @@
X table_header.length = 0;
X for (i = 0; i < sizeof (ACPI_TABLE_HEADER); i++) {
X status = acpi_ev_address_space_dispatch (rgn_desc, ADDRESS_SPACE_READ,
- i, 8, (u32 *) ((char *) &table_header + i));
+ i, 8, (u32 *) ((u8 *) &table_header + i));
X if (ACPI_FAILURE (status)) {
X return (status);
X }
@@ -184,16 +184,19 @@
X ACPI_HANDLE ddb_handle)
X {
X ACPI_STATUS status = AE_NOT_IMPLEMENTED;
- ACPI_OBJECT_INTERNAL *table_desc = (ACPI_OBJECT_INTERNAL *) ddb_handle;
+ ACPI_OPERAND_OBJECT *table_desc = (ACPI_OPERAND_OBJECT *) ddb_handle;
X ACPI_TABLE_DESC *table_info;
X
X
X /* Validate the handle */
- /* TBD: [Errors] Wasn't this done earlier? */
+ /* Although the handle is partially validated in Acpi_aml_exec_reconfiguration(),
+ * when it calls Acpi_aml_resolve_operands(), the handle is more completely
+ * validated here.
+ */
X
X if ((!ddb_handle) ||
X (!VALID_DESCRIPTOR_TYPE (ddb_handle, ACPI_DESC_TYPE_INTERNAL)) ||
- (((ACPI_OBJECT_INTERNAL *)ddb_handle)->common.type !=
+ (((ACPI_OPERAND_OBJECT *)ddb_handle)->common.type !=
X INTERNAL_TYPE_REFERENCE))
X {
X return (AE_BAD_PARAMETER);
@@ -205,7 +208,7 @@
X table_info = (ACPI_TABLE_DESC *) table_desc->reference.object;
X
X /*
- * Delete the entire namespace under this table NTE
+ * Delete the entire namespace under this table Node
X * (Offset contains the Table_id)
X */
X
@@ -245,16 +248,16 @@
X ACPI_WALK_STATE *walk_state)
X {
X ACPI_STATUS status;
- ACPI_OBJECT_INTERNAL *region_desc = NULL;
+ ACPI_OPERAND_OBJECT *region_desc = NULL;
X ACPI_HANDLE *ddb_handle;
X
X
X /* Resolve the operands */
X
- status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS);
+ status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);
X /* Get the table handle, common for both opcodes */
X
- status |= acpi_ds_obj_stack_pop_object ((ACPI_OBJECT_INTERNAL **) &ddb_handle,
+ status |= acpi_ds_obj_stack_pop_object ((ACPI_OPERAND_OBJECT **) &ddb_handle,
X walk_state);
X
X switch (opcode)
@@ -265,22 +268,19 @@
X /* Get the region or field descriptor */
X
X status |= acpi_ds_obj_stack_pop_object (&region_desc, walk_state);


- if (status != AE_OK) {

- acpi_aml_append_operand_diag (_THIS_MODULE, __LINE__, opcode,
- WALK_OPERANDS, 2);
- goto cleanup2;
+ if (ACPI_FAILURE (status)) {
+ acpi_cm_remove_reference (region_desc);


+ return (status);
X }
X

X status = acpi_aml_exec_load_table (region_desc, ddb_handle);
X break;
X
X
- case AML_UN_LOAD_OP:
+ case AML_UNLOAD_OP:


X
- if (status != AE_OK) {

- acpi_aml_append_operand_diag (_THIS_MODULE, __LINE__, opcode,
- WALK_OPERANDS, 1);
- goto cleanup1;


+ if (ACPI_FAILURE (status)) {
+ return (status);
X }
X

X status = acpi_aml_exec_unload_table (ddb_handle);
@@ -294,10 +294,6 @@
X }
X
X
-cleanup2:
- acpi_cm_remove_reference (region_desc);
-
-cleanup1:
X return (status);
X }
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/interpreter/amcreate.c linux/drivers/acpi/interpreter/amcreate.c
--- v2.4.0-test8/linux/drivers/acpi/interpreter/amcreate.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/interpreter/amcreate.c Fri Sep 15 14:30:30 2000


@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *

X * Module Name: amcreate - Named object creation
+ * $Revision: 44 $


X *
X *****************************************************************************/
X

@@ -25,19 +25,19 @@
X
X

X #include "acpi.h"
-#include "parser.h"

-#include "interp.h"
+#include "acparser.h"
+#include "acinterp.h"
X #include "amlcode.h"
-#include "namesp.h"
-#include "events.h"
-#include "dispatch.h"
+#include "acnamesp.h"
+#include "acevents.h"
+#include "acdispat.h"
X
X
X #define _COMPONENT INTERPRETER
- MODULE_NAME ("amcreate");
+ MODULE_NAME ("amcreate")
X
X
-/*****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_aml_exec_create_field
X *
@@ -64,19 +64,19 @@
X * Num_bits := Term_arg=>Integer
X * Source_buff := Term_arg=>Buffer
X *
- ****************************************************************************/


+ ******************************************************************************/
X
X ACPI_STATUS

X acpi_aml_exec_create_field (
X u16 opcode,
X ACPI_WALK_STATE *walk_state)
X {
- ACPI_OBJECT_INTERNAL *res_desc = NULL;
- ACPI_OBJECT_INTERNAL *cnt_desc = NULL;
- ACPI_OBJECT_INTERNAL *off_desc = NULL;
- ACPI_OBJECT_INTERNAL *src_desc = NULL;
- ACPI_OBJECT_INTERNAL *field_desc;
- ACPI_OBJECT_INTERNAL *obj_desc;
+ ACPI_OPERAND_OBJECT *res_desc = NULL;
+ ACPI_OPERAND_OBJECT *cnt_desc = NULL;
+ ACPI_OPERAND_OBJECT *off_desc = NULL;
+ ACPI_OPERAND_OBJECT *src_desc = NULL;
+ ACPI_OPERAND_OBJECT *field_desc;
+ ACPI_OPERAND_OBJECT *obj_desc;
X OBJECT_TYPE_INTERNAL res_type;
X ACPI_STATUS status;
X u32 num_operands = 3;
@@ -88,7 +88,7 @@
X
X /* Resolve the operands */
X
- status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS);
+ status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);
X
X /* Get the operands */
X
@@ -101,11 +101,9 @@
X status |= acpi_ds_obj_stack_pop_object (&off_desc, walk_state);
X status |= acpi_ds_obj_stack_pop_object (&src_desc, walk_state);


X
- if (status != AE_OK) {
+ if (ACPI_FAILURE (status)) {

X /* Invalid parameters on object stack */
X
- acpi_aml_append_operand_diag (_THIS_MODULE, __LINE__, opcode,
- WALK_OPERANDS, 3);
X goto cleanup;
X }
X
@@ -288,16 +286,17 @@


X if (obj_desc) {
X /*

X * There is an existing object here; delete it and zero out the
- * NTE
+ * object field within the Node
X */
X
X acpi_cm_remove_reference (obj_desc);
- acpi_ns_attach_object (res_desc, NULL, ACPI_TYPE_ANY);
+ acpi_ns_attach_object ((ACPI_NAMESPACE_NODE *) res_desc, NULL,
+ ACPI_TYPE_ANY);
X }
X
X /* Set the type to ANY (or the store below will fail) */
X
- ((ACPI_NAMED_OBJECT*) res_desc)->type = ACPI_TYPE_ANY;
+ ((ACPI_NAMESPACE_NODE *) res_desc)->type = ACPI_TYPE_ANY;
X
X break;
X
@@ -310,7 +309,7 @@
X
X /* Store constructed field descriptor in result location */
X
- status = acpi_aml_exec_store (field_desc, res_desc);
+ status = acpi_aml_exec_store (field_desc, res_desc, walk_state);
X
X /*
X * If the field descriptor was not physically stored (or if a failure
@@ -358,39 +357,41 @@
X acpi_aml_exec_create_alias (
X ACPI_WALK_STATE *walk_state)
X {
- ACPI_NAMED_OBJECT *src_entry;
- ACPI_NAMED_OBJECT *alias_entry;
+ ACPI_NAMESPACE_NODE *source_node;
+ ACPI_NAMESPACE_NODE *alias_node;
X ACPI_STATUS status;
X
X
X /* Get the source/alias operands (both NTEs) */
X
- status = acpi_ds_obj_stack_pop_object ((ACPI_OBJECT_INTERNAL **) &src_entry,
+ status = acpi_ds_obj_stack_pop_object ((ACPI_OPERAND_OBJECT **) &source_node,
X walk_state);
X if (ACPI_FAILURE (status)) {


X return (status);
X }
X

- /* Don't pop it, it gets popped later */
+ /*
+ * Don't pop it, it gets removed in the calling routine
+ */
X
- alias_entry = acpi_ds_obj_stack_get_value (0, walk_state);
+ alias_node = acpi_ds_obj_stack_get_value (0, walk_state);
X
X /* Add an additional reference to the object */
X
- acpi_cm_add_reference (src_entry->object);
+ acpi_cm_add_reference (source_node->object);
X
X /*
- * Attach the original source NTE to the new Alias NTE.
+ * Attach the original source Node to the new Alias Node.
X */
- status = acpi_ns_attach_object (alias_entry, src_entry->object,
- src_entry->type);
+ status = acpi_ns_attach_object (alias_node, source_node->object,
+ source_node->type);
X
X
X /*
X * The new alias assumes the type of the source, but it points
X * to the same object. The reference count of the object has two
X * additional references to prevent deletion out from under either the
- * source or the alias NTE
+ * source or the alias Node
X */
X
X /* Since both operands are NTEs, we don't need to delete them */
@@ -416,7 +417,7 @@
X ACPI_WALK_STATE *walk_state)
X {
X ACPI_STATUS status;


- ACPI_OBJECT_INTERNAL *obj_desc;
+ ACPI_OPERAND_OBJECT *obj_desc;
X
X

X BREAKPOINT3;
@@ -438,7 +439,7 @@
X goto cleanup;
X }
X
- /* Attach object to the NTE */
+ /* Attach object to the Node */
X
X status = acpi_ns_attach_object (acpi_ds_obj_stack_get_value (0, walk_state),
X obj_desc, (u8) ACPI_TYPE_EVENT);
@@ -473,8 +474,8 @@
X ACPI_WALK_STATE *walk_state)


X {
X ACPI_STATUS status = AE_OK;

- ACPI_OBJECT_INTERNAL *sync_desc;
- ACPI_OBJECT_INTERNAL *obj_desc;
+ ACPI_OPERAND_OBJECT *sync_desc;


+ ACPI_OPERAND_OBJECT *obj_desc;
X
X

X /* Get the operand */
@@ -546,22 +547,27 @@
X ACPI_WALK_STATE *walk_state)
X {
X ACPI_STATUS status;
- ACPI_OBJECT_INTERNAL *obj_desc_region;
- ACPI_HANDLE *entry;
+ ACPI_OPERAND_OBJECT *obj_desc_region;
+ ACPI_NAMESPACE_NODE *node;
X
X
X if (region_space >= NUM_REGION_TYPES) {
- /* TBD: [Errors] should this return an error, or should we just keep
- * going? */
+ /* TBD: [Future] In ACPI 2.0, valid region space
+ * includes types 0-6 (Adding CMOS and PCIBARTarget).
+ * Also, types 0x80-0xff are defined as "OEM Region
+ * Space handler"
+ *
+ * Should this return an error, or should we just keep
+ * going? How do we handle the OEM region handlers?
+ */
X
X REPORT_WARNING ("Unable to decode the Region_space");
X }
X
X
- /* Get the NTE from the object stack */
-
- entry = acpi_ds_obj_stack_get_value (0, walk_state);
+ /* Get the Node from the object stack */
X
+ node = (ACPI_NAMESPACE_NODE *) acpi_ds_obj_stack_get_value (0, walk_state);
X
X /* Create the region descriptor */
X
@@ -583,10 +589,9 @@
X
X /* Init the region from the operands */
X
- obj_desc_region->region.space_id = (u16) region_space;
+ obj_desc_region->region.space_id = (u8) region_space;
X obj_desc_region->region.address = 0;
X obj_desc_region->region.length = 0;
- obj_desc_region->region.region_flags = 0;
X
X /*
X * Remember location in AML stream of address & length
@@ -596,19 +601,38 @@
X obj_desc_region->region.method->method.pcode_length = aml_length;
X
X
- /* Install the new region object in the parent NTE */
+ /* Install the new region object in the parent Node */
X
- obj_desc_region->region.nte = (ACPI_NAMED_OBJECT*) entry;
+ obj_desc_region->region.node = node;
X
- status = acpi_ns_attach_object (entry, obj_desc_region,
+ status = acpi_ns_attach_object (node, obj_desc_region,
X (u8) ACPI_TYPE_REGION);
+
X if (ACPI_FAILURE (status)) {
X goto cleanup;
X }
X
+ /*
+ * If we have a valid region, initialize it
+ * Namespace is NOT locked at this point.
+ */
+
+ status = acpi_ev_initialize_region (obj_desc_region, FALSE);
+
+ if (ACPI_FAILURE (status)) {
+ /*
+ * If AE_NOT_EXIST is returned, it is not fatal
+ * because many regions get created before a handler
+ * is installed for said region.
+ */
+ if (AE_NOT_EXIST == status) {
+ status = AE_OK;
+ }
+ }
+
X cleanup:


X
- if (status != AE_OK) {
+ if (ACPI_FAILURE (status)) {

X /* Delete region object and method subobject */
X
X if (obj_desc_region) {
@@ -619,22 +643,6 @@
X }
X }
X
-
- /*
- * If we have a valid region, initialize it
- */
- if (obj_desc_region) {
- /*
- * TBD: [Errors] Is there anything we can or could do when this
- * fails?
- * We need to do something useful with a failure.
- */
- /* Namespace IS locked */
-
- (void *) acpi_ev_initialize_region (obj_desc_region, TRUE);
-
- }
-


X return (status);
X }
X

@@ -645,7 +653,7 @@
X *
X * PARAMETERS: Op - Op containing the Processor definition and
X * args
- * Processor_nTE - NTE for the containing NTE
+ * Processor_nTE - Node for the containing Node
X *


X * RETURN: Status
X *

@@ -655,12 +663,12 @@
X
X ACPI_STATUS
X acpi_aml_exec_create_processor (


- ACPI_GENERIC_OP *op,
+ ACPI_PARSE_OBJECT *op,

X ACPI_HANDLE processor_nTE)


X {
X ACPI_STATUS status;
- ACPI_GENERIC_OP *arg;

- ACPI_OBJECT_INTERNAL *obj_desc;
+ ACPI_PARSE_OBJECT *arg;

+ ACPI_OPERAND_OBJECT *obj_desc;
X
X

X obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_PROCESSOR);
@@ -669,7 +677,7 @@


X return (status);
X }
X

- /* Install the new processor object in the parent NTE */
+ /* Install the new processor object in the parent Node */
X
X status = acpi_ns_attach_object (processor_nTE, obj_desc,
X (u8) ACPI_TYPE_PROCESSOR);


@@ -700,7 +708,7 @@
X

X /* Second arg is the PBlock Address */
X
- obj_desc->processor.pblk_address = (ACPI_IO_ADDRESS) arg->value.integer;
+ obj_desc->processor.address = (ACPI_IO_ADDRESS) arg->value.integer;
X
X /* Move to next arg and check existence */
X

@@ -712,7 +720,7 @@
X

X /* Third arg is the PBlock Length */
X
- obj_desc->processor.pblk_length = (u8) arg->value.integer;
+ obj_desc->processor.length = (u8) arg->value.integer;


X
X return (AE_OK);
X }

@@ -724,7 +732,7 @@
X *
X * PARAMETERS: Op - Op containing the Power_resource definition
X * and args
- * Power_res_nTE - NTE for the containing NTE
+ * Power_res_nTE - Node for the containing Node
X *


X * RETURN: Status
X *

@@ -734,12 +742,12 @@
X
X ACPI_STATUS
X acpi_aml_exec_create_power_resource (


- ACPI_GENERIC_OP *op,
+ ACPI_PARSE_OBJECT *op,

X ACPI_HANDLE power_res_nTE)


X {
X ACPI_STATUS status;
- ACPI_GENERIC_OP *arg;

- ACPI_OBJECT_INTERNAL *obj_desc;
+ ACPI_PARSE_OBJECT *arg;

+ ACPI_OPERAND_OBJECT *obj_desc;
X
X

X obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_POWER);
@@ -748,7 +756,7 @@


X return (status);
X }
X

- /* Install the new power resource object in the parent NTE */
+ /* Install the new power resource object in the parent Node */
X
X status = acpi_ns_attach_object (power_res_nTE, obj_desc,
X (u8) ACPI_TYPE_POWER);
@@ -789,11 +797,14 @@
X *
X * FUNCTION: Acpi_aml_exec_create_method
X *
- * PARAMETERS: Interpreter_mode - Current running mode (load1/Load2/Exec)
+ * PARAMETERS: Aml_ptr - First byte of the method's AML
+ * Aml_length - AML byte count for this method
+ * Method_flags - AML method flag byte
+ * Method - Method Node
X *


X * RETURN: Status
X *

- * DESCRIPTION: Create a new mutex object
+ * DESCRIPTION: Create a new method object
X *
X ****************************************************************************/
X
@@ -804,7 +815,7 @@
X u32 method_flags,
X ACPI_HANDLE method)
X {


- ACPI_OBJECT_INTERNAL *obj_desc;
+ ACPI_OPERAND_OBJECT *obj_desc;

X ACPI_STATUS status;
X
X

@@ -830,9 +841,8 @@
X METHOD_FLAGS_ARG_COUNT);
X
X /*
- * Get the concurrency count
- * If required, a semaphore will be created for this method when it is
- * parsed.
+ * Get the concurrency count. If required, a semaphore will be
+ * created for this method when it is parsed.
X *
X * TBD: [Future] for APCI 2.0, there will be a Sync_level value, not
X * just a flag
@@ -842,27 +852,16 @@
X if (method_flags & METHOD_FLAGS_SERIALIZED) {
X obj_desc->method.concurrency = 1;
X }
+
X else {
X obj_desc->method.concurrency = INFINITE_CONCURRENCY;
X }
X
- /* Mark the Method as not parsed yet */
-


- obj_desc->method.parser_op = NULL;

-
- /*
- * Another +1 gets added when Acpi_psx_execute is called,
- * no need for: Obj_desc->Method.Pcode++;
- */
-
- obj_desc->method.acpi_table = NULL; /* TBD: [Restructure] was (u8 *) Pcode_addr; */
- obj_desc->method.table_length = 0; /* TBD: [Restructure] needed? (u32) (Walk_state->aml_end - Pcode_addr); */
-
- /* Attach the new object to the method NTE */
+ /* Attach the new object to the method Node */
X
X status = acpi_ns_attach_object (method, obj_desc, (u8) ACPI_TYPE_METHOD);


X if (ACPI_FAILURE (status)) {
- acpi_cm_free (obj_desc);
+ acpi_cm_delete_object_desc (obj_desc);

X }
X
X return (status);

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/interpreter/amdump.c linux/drivers/acpi/interpreter/amdump.c
--- v2.4.0-test8/linux/drivers/acpi/interpreter/amdump.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/interpreter/amdump.c Fri Sep 15 14:30:30 2000
@@ -0,0 +1,41 @@
+/******************************************************************************
+ *
+ * Module Name: amdump - Interpreter debug output routines
+ * $Revision: 90 $


+ *
+ *****************************************************************************/
+
+/*

+ * Copyright (C) 2000 R. Byron Moore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "acpi.h"

+#include "acinterp.h"
+#include "amlcode.h"
+#include "acnamesp.h"
+#include "actables.h"
+
+#define _COMPONENT INTERPRETER
+ MODULE_NAME ("amdump")
+
+
+/*
+ * The following routines are used for debug output only
+ */
+
+
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/interpreter/amdyadic.c linux/drivers/acpi/interpreter/amdyadic.c
--- v2.4.0-test8/linux/drivers/acpi/interpreter/amdyadic.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/interpreter/amdyadic.c Fri Sep 15 14:30:30 2000


@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *

X * Module Name: amdyadic - ACPI AML (p-code) execution for dyadic operators
+ * $Revision: 63 $


X *
X *****************************************************************************/
X

@@ -25,16 +25,16 @@


X
X
X #include "acpi.h"

-#include "parser.h"
-#include "namesp.h"
-#include "interp.h"
-#include "events.h"
+#include "acparser.h"
+#include "acnamesp.h"
+#include "acinterp.h"


+#include "acevents.h"
X #include "amlcode.h"

-#include "dispatch.h"
+#include "acdispat.h"
X
X
X #define _COMPONENT INTERPRETER
- MODULE_NAME ("amdyadic");
+ MODULE_NAME ("amdyadic")
X
X
X /*****************************************************************************
@@ -57,15 +57,15 @@
X u16 opcode,
X ACPI_WALK_STATE *walk_state)
X {
- ACPI_OBJECT_INTERNAL *obj_desc = NULL;
- ACPI_OBJECT_INTERNAL *val_desc = NULL;
- ACPI_NAMED_OBJECT *entry;
+ ACPI_OPERAND_OBJECT *obj_desc = NULL;
+ ACPI_OPERAND_OBJECT *val_desc = NULL;


+ ACPI_NAMESPACE_NODE *node;
X ACPI_STATUS status = AE_OK;
X
X

X /* Resolve all operands */
X
- status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS);
+ status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);
X /* Get the operands */
X
X status |= acpi_ds_obj_stack_pop_object (&val_desc, walk_state);
@@ -73,8 +73,6 @@
X if (ACPI_FAILURE (status)) {
X /* Invalid parameters on object stack */
X
- acpi_aml_append_operand_diag (_THIS_MODULE, __LINE__, opcode,
- WALK_OPERANDS, 2);


X goto cleanup;
X }
X

@@ -88,15 +86,15 @@
X
X case AML_NOTIFY_OP:
X
- /* The Obj_desc is actually an NTE */
+ /* The Obj_desc is actually an Node */
X
- entry = (ACPI_NAMED_OBJECT*) obj_desc;
+ node = (ACPI_NAMESPACE_NODE *) obj_desc;
X obj_desc = NULL;
X
X /* Object must be a device or thermal zone */
X
- if (entry && val_desc) {
- switch (entry->type)
+ if (node && val_desc) {


+ switch (node->type)
X {
X case ACPI_TYPE_DEVICE:

X case ACPI_TYPE_THERMAL:


@@ -108,7 +106,7 @@
X

X /* Dispatch the notify to the appropriate handler */
X
- acpi_ev_notify_dispatch (entry, val_desc->number.value);
+ acpi_ev_notify_dispatch (node, val_desc->number.value);


X break;
X
X default:

@@ -118,6 +116,8 @@


X break;
X
X default:

+
+ REPORT_ERROR ("Acpi_aml_exec_dyadic1: Unknown dyadic opcode");
X status = AE_AML_BAD_OPCODE;
X }


X
@@ -153,23 +153,23 @@

X acpi_aml_exec_dyadic2_r (
X u16 opcode,
X ACPI_WALK_STATE *walk_state,
- ACPI_OBJECT_INTERNAL **return_desc)
+ ACPI_OPERAND_OBJECT **return_desc)
X {
- ACPI_OBJECT_INTERNAL *obj_desc = NULL;
- ACPI_OBJECT_INTERNAL *obj_desc2 = NULL;
- ACPI_OBJECT_INTERNAL *res_desc = NULL;
- ACPI_OBJECT_INTERNAL *res_desc2 = NULL;
- ACPI_OBJECT_INTERNAL *ret_desc = NULL;
- ACPI_OBJECT_INTERNAL *ret_desc2 = NULL;
+ ACPI_OPERAND_OBJECT *obj_desc = NULL;
+ ACPI_OPERAND_OBJECT *obj_desc2 = NULL;
+ ACPI_OPERAND_OBJECT *res_desc = NULL;
+ ACPI_OPERAND_OBJECT *res_desc2 = NULL;
+ ACPI_OPERAND_OBJECT *ret_desc = NULL;
+ ACPI_OPERAND_OBJECT *ret_desc2 = NULL;


X ACPI_STATUS status = AE_OK;

X u32 remainder;
- s32 num_operands = 3;
- char *new_buf;
+ u32 num_operands = 3;
+ NATIVE_CHAR *new_buf;
X
X
X /* Resolve all operands */
X
- status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS);
+ status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);
X /* Get all operands */
X
X if (AML_DIVIDE_OP == opcode) {
@@ -180,10 +180,7 @@
X status |= acpi_ds_obj_stack_pop_object (&res_desc, walk_state);
X status |= acpi_ds_obj_stack_pop_object (&obj_desc2, walk_state);
X status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);


- if (status != AE_OK) {

- acpi_aml_append_operand_diag (_THIS_MODULE, __LINE__, opcode,
- &(walk_state->operands [walk_state->num_operands -1]),
- num_operands);
+ if (ACPI_FAILURE (status)) {
X goto cleanup;
X }
X
@@ -368,9 +365,9 @@


X goto cleanup;
X }
X

- STRCPY (new_buf, (char *) obj_desc->string.pointer);
+ STRCPY (new_buf, obj_desc->string.pointer);
X STRCPY (new_buf + obj_desc->string.length,
- (char *) obj_desc2->string.pointer);
+ obj_desc2->string.pointer);
X
X /* Point the return object to the new string */
X
@@ -391,16 +388,8 @@
X new_buf = acpi_cm_allocate (obj_desc->buffer.length +
X obj_desc2->buffer.length);
X if (!new_buf) {
- /* Only bail out if the buffer is small */
-
- /* TBD: [Investigate] what is the point of this code? */
-
- if (obj_desc->buffer.length + obj_desc2->buffer.length < 1024) {
- REPORT_ERROR
- ("Aml_exec_dyadic2_r/Concat_op: Buffer allocation failure");
- return (AE_NO_MEMORY);
- }
-
+ REPORT_ERROR
+ ("Aml_exec_dyadic2_r/Concat_op: Buffer allocation failure");
X status = AE_NO_MEMORY;
X goto cleanup;
X }
@@ -423,6 +412,7 @@
X
X default:
X
+ REPORT_ERROR ("Acpi_aml_exec_dyadic2_r: Unknown dyadic opcode");
X status = AE_AML_BAD_OPCODE;
X goto cleanup;
X }
@@ -434,12 +424,13 @@
X * descriptor (Res_desc).
X */
X
- if ((status = acpi_aml_exec_store (ret_desc, res_desc)) != AE_OK) {
+ status = acpi_aml_exec_store (ret_desc, res_desc, walk_state);
+ if (ACPI_FAILURE (status)) {
X goto cleanup;
X }
X
X if (AML_DIVIDE_OP == opcode) {
- status = acpi_aml_exec_store (ret_desc2, res_desc2);
+ status = acpi_aml_exec_store (ret_desc2, res_desc2, walk_state);
X
X /*
X * Since the remainder is not returned, remove a reference to
@@ -499,26 +490,24 @@
X acpi_aml_exec_dyadic2_s (
X u16 opcode,
X ACPI_WALK_STATE *walk_state,
- ACPI_OBJECT_INTERNAL **return_desc)
+ ACPI_OPERAND_OBJECT **return_desc)
X {
- ACPI_OBJECT_INTERNAL *obj_desc;
- ACPI_OBJECT_INTERNAL *time_desc;
- ACPI_OBJECT_INTERNAL *ret_desc = NULL;
+ ACPI_OPERAND_OBJECT *obj_desc;
+ ACPI_OPERAND_OBJECT *time_desc;
+ ACPI_OPERAND_OBJECT *ret_desc = NULL;
X ACPI_STATUS status;
X
X
X /* Resolve all operands */
X
- status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS);
+ status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);
X /* Get all operands */
X
X status |= acpi_ds_obj_stack_pop_object (&time_desc, walk_state);
X status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);


- if (status != AE_OK) {
+ if (ACPI_FAILURE (status)) {

X /* Invalid parameters on object stack */
X
- acpi_aml_append_operand_diag (_THIS_MODULE, __LINE__, opcode,
- WALK_OPERANDS, 2);


X goto cleanup;
X }
X

@@ -559,6 +548,7 @@
X
X default:
X
+ REPORT_ERROR ("Acpi_aml_exec_dyadic2_s: Unknown dyadic synchronization opcode");
X status = AE_AML_BAD_OPCODE;
X goto cleanup;
X }
@@ -619,27 +609,25 @@
X acpi_aml_exec_dyadic2 (
X u16 opcode,
X ACPI_WALK_STATE *walk_state,
- ACPI_OBJECT_INTERNAL **return_desc)
+ ACPI_OPERAND_OBJECT **return_desc)
X {
- ACPI_OBJECT_INTERNAL *obj_desc;
- ACPI_OBJECT_INTERNAL *obj_desc2;
- ACPI_OBJECT_INTERNAL *ret_desc = NULL;
+ ACPI_OPERAND_OBJECT *obj_desc;
+ ACPI_OPERAND_OBJECT *obj_desc2;
+ ACPI_OPERAND_OBJECT *ret_desc = NULL;
X ACPI_STATUS status;
X u8 lboolean;
X
X
X /* Resolve all operands */
X
- status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS);
+ status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);
X /* Get all operands */
X
X status |= acpi_ds_obj_stack_pop_object (&obj_desc2, walk_state);
X status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);


- if (status != AE_OK) {
+ if (ACPI_FAILURE (status)) {

X /* Invalid parameters on object stack */
X
- acpi_aml_append_operand_diag (_THIS_MODULE, __LINE__, opcode,
- WALK_OPERANDS, 2);


X goto cleanup;
X }
X

@@ -707,6 +695,7 @@
X
X default:
X
+ REPORT_ERROR ("Acpi_aml_exec_dyadic2: Unknown dyadic opcode");
X status = AE_AML_BAD_OPCODE;
X goto cleanup;
X break;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/interpreter/amfield.c linux/drivers/acpi/interpreter/amfield.c
--- v2.4.0-test8/linux/drivers/acpi/interpreter/amfield.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/interpreter/amfield.c Fri Sep 15 14:30:30 2000


@@ -1,6 +1,7 @@
X /******************************************************************************
X *

X * Module Name: amfield - ACPI AML (p-code) execution - field manipulation
+ * $Revision: 70 $


X *
X *****************************************************************************/
X

@@ -24,16 +25,16 @@


X
X
X #include "acpi.h"

-#include "dispatch.h"
-#include "interp.h"
+#include "acdispat.h"


+#include "acinterp.h"
X #include "amlcode.h"

-#include "namesp.h"
-#include "hardware.h"
-#include "events.h"
+#include "acnamesp.h"
+#include "achware.h"
+#include "acevents.h"

X
X
X #define _COMPONENT INTERPRETER
- MODULE_NAME ("amfield");
+ MODULE_NAME ("amfield")
X
X
X /*******************************************************************************
@@ -67,12 +68,12 @@
X
X ACPI_STATUS
X acpi_aml_setup_field (


- ACPI_OBJECT_INTERNAL *obj_desc,
- ACPI_OBJECT_INTERNAL *rgn_desc,
- s32 field_bit_width)

+ ACPI_OPERAND_OBJECT *obj_desc,
+ ACPI_OPERAND_OBJECT *rgn_desc,
+ u32 field_bit_width)

X {
X ACPI_STATUS status = AE_OK;

- s32 field_byte_width;
+ u32 field_byte_width;
X

X
X /* Parameter validation */

@@ -87,6 +88,8 @@
X
X
X /*
+ * TBD: [Future] Acpi 2.0 supports Qword fields
+ *
X * Init and validate Field width
X * Possible values are 1, 2, 4
X */
@@ -105,7 +108,7 @@
X * If the address and length have not been previously evaluated,
X * evaluate them and save the results.
X */
- if (!(rgn_desc->region.region_flags & REGION_AGRUMENT_DATA_VALID)) {
+ if (!(rgn_desc->region.flags & AOPOBJ_DATA_VALID)) {
X
X status = acpi_ds_get_region_arguments (rgn_desc);
X if (ACPI_FAILURE (status)) {
@@ -113,12 +116,6 @@
X }
X }
X
-
- /*
- * If (offset rounded up to next multiple of field width)
- * exceeds region length, indicate an error.
- */
-
X if (rgn_desc->region.length <
X (obj_desc->field.offset & ~((u32) field_byte_width - 1)) +
X field_byte_width)
@@ -152,12 +149,12 @@
X
X ACPI_STATUS
X acpi_aml_access_named_field (
- s32 mode,
+ u32 mode,
X ACPI_HANDLE named_field,
X void *buffer,
X u32 buffer_length)
X {
- ACPI_OBJECT_INTERNAL *obj_desc = NULL;
+ ACPI_OPERAND_OBJECT *obj_desc = NULL;


X ACPI_STATUS status = AE_OK;

X u8 locked = FALSE;
X u32 bit_granularity = 0;
@@ -167,6 +164,11 @@
X u32 byte_field_length;
X
X
+ /* Basic data checking */
+ if ((!named_field) || (ACPI_READ == mode && !buffer)) {
+ return (AE_AML_INTERNAL);
+ }
+
X /* Get the attached field object */
X
X obj_desc = acpi_ns_get_attached_object (named_field);
@@ -256,72 +258,6 @@
X
X acpi_aml_release_global_lock (locked);
X

- return (status);
-}
-

-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_aml_set_named_field_value
- *
- * PARAMETERS: Named_field - Handle for field to be set
- * Buffer - Bytes to be stored
- * Buffer_length - Number of bytes to be stored
- *
- * RETURN: Status
- *
- * DESCRIPTION: Store the given value into the field
- *
- ******************************************************************************/


-
-ACPI_STATUS
-acpi_aml_set_named_field_value (
- ACPI_HANDLE named_field,
- void *buffer,

- u32 buffer_length)
-{
- ACPI_STATUS status;
-
-
- if (!named_field) {
- return (AE_AML_INTERNAL);
- }
-
- status = acpi_aml_access_named_field (ACPI_WRITE, named_field, buffer,
- buffer_length);


- return (status);
-}
-

-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_aml_get_named_field_value
- *
- * PARAMETERS: Named_field - Handle for field to be read
- * *Buffer - Where to store value read from field
- * Buffer_length - Max length to read
- *
- * RETURN: Status
- *
- * DESCRIPTION: Retrieve the value of the given field
- *
- ******************************************************************************/


-
-ACPI_STATUS
-acpi_aml_get_named_field_value (
- ACPI_HANDLE named_field,
- void *buffer,

- u32 buffer_length)
-{
- ACPI_STATUS status;
-
-
- if ((!named_field) || (!buffer)) {
- return (AE_AML_INTERNAL);
- }
-
- status = acpi_aml_access_named_field (ACPI_READ, named_field, buffer,
- buffer_length);
X return (status);
X }
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/interpreter/amfldio.c linux/drivers/acpi/interpreter/amfldio.c
--- v2.4.0-test8/linux/drivers/acpi/interpreter/amfldio.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/interpreter/amfldio.c Fri Sep 15 14:30:30 2000


@@ -1,6 +1,7 @@
X /******************************************************************************
X *

X * Module Name: amfldio - Aml Field I/O
+ * $Revision: 26 $


X *
X *****************************************************************************/
X

@@ -24,15 +25,15 @@


X
X
X #include "acpi.h"

-#include "interp.h"


+#include "acinterp.h"
X #include "amlcode.h"

-#include "namesp.h"
-#include "hardware.h"
-#include "events.h"
+#include "acnamesp.h"
+#include "achware.h"
+#include "acevents.h"

X
X
X #define _COMPONENT INTERPRETER
- MODULE_NAME ("amfldio");
+ MODULE_NAME ("amfldio")
X
X
X /*******************************************************************************
@@ -51,16 +52,16 @@
X
X ACPI_STATUS
X acpi_aml_read_field_data (
- ACPI_OBJECT_INTERNAL *obj_desc,
+ ACPI_OPERAND_OBJECT *obj_desc,
X u32 field_byte_offset,
X u32 field_bit_width,
X u32 *value)
X {
X ACPI_STATUS status;
- ACPI_OBJECT_INTERNAL *rgn_desc = NULL;
+ ACPI_OPERAND_OBJECT *rgn_desc = NULL;
X u32 address;
X u32 local_value = 0;
- s32 field_byte_width;
+ u32 field_byte_width;
X
X
X /* Obj_desc is validated by callers */
@@ -72,7 +73,7 @@
X
X field_byte_width = DIV_8 (field_bit_width);
X status = acpi_aml_setup_field (obj_desc, rgn_desc, field_bit_width);
- if (AE_OK != status) {
+ if (ACPI_FAILURE (status)) {


X return (status);
X }
X

@@ -84,17 +85,17 @@
X
X
X /*
- * Round offset down to next multiple of
- * field width, add region base address and offset within the field
+ * Set offset to next multiple of field width,
+ * add region base address and offset within the field
X */
-
X address = rgn_desc->region.address +
- (obj_desc->field.offset & ~((u32) field_byte_width - 1)) +
+ (obj_desc->field.offset * field_byte_width) +
X field_byte_offset;
X
X
X
X
+
X /* Invoke the appropriate Address_space/Op_region handler */
X
X status = acpi_ev_address_space_dispatch (rgn_desc, ADDRESS_SPACE_READ,
@@ -122,7 +123,7 @@
X
X ACPI_STATUS
X acpi_aml_read_field (
- ACPI_OBJECT_INTERNAL *obj_desc,
+ ACPI_OPERAND_OBJECT *obj_desc,
X void *buffer,
X u32 buffer_length,
X u32 byte_length,
@@ -236,6 +237,7 @@
X * field datum
X */
X
+
X if (obj_desc->field.bit_offset != 0) {
X merged_datum =
X (previous_raw_datum >> obj_desc->field.bit_offset) |
@@ -247,10 +249,27 @@
X }
X
X /*
+ * Prepare the merged datum for storing into the caller's
+ * buffer. It is possible to have a 32-bit buffer
+ * (Byte_granularity == 4), but a Obj_desc->Field.Length
+ * of 8 or 16, meaning that the upper bytes of merged data
+ * are undesired. This section fixes that.
+ */
+ switch (obj_desc->field.length)
+ {
+ case 8:
+ merged_datum &= 0x000000FF;
+ break;
+
+ case 16:
+ merged_datum &= 0x0000FFFF;


+ break;
+ }
+
+ /*

X * Now store the datum in the caller's buffer, according to
X * the data type
X */
-
X switch (byte_granularity)
X {
X case 1:
@@ -266,7 +285,6 @@
X break;
X }
X
-
X /*
X * Save the most recent datum since it contains bits of
X * the *next* field datum
@@ -302,15 +320,15 @@
X
X ACPI_STATUS
X acpi_aml_write_field_data (
- ACPI_OBJECT_INTERNAL *obj_desc,
+ ACPI_OPERAND_OBJECT *obj_desc,
X u32 field_byte_offset,
X u32 field_bit_width,
X u32 value)


X {
X ACPI_STATUS status = AE_OK;

- ACPI_OBJECT_INTERNAL *rgn_desc = NULL;
+ ACPI_OPERAND_OBJECT *rgn_desc = NULL;
X u32 address;
- s32 field_byte_width;
+ u32 field_byte_width;
X
X
X /* Obj_desc is validated by callers */
@@ -321,21 +339,21 @@
X
X field_byte_width = DIV_8 (field_bit_width);
X status = acpi_aml_setup_field (obj_desc, rgn_desc, field_bit_width);
- if (AE_OK != status) {
+ if (ACPI_FAILURE (status)) {
X return (status);
X }
X
X
X /*
- * Round offset down to next multiple of
- * field width, add region base address and offset within the field
+ * Set offset to next multiple of field width,
+ * add region base address and offset within the field
X */
-
X address = rgn_desc->region.address +
- (obj_desc->field.offset & ~((u32) field_byte_width - 1)) +
+ (obj_desc->field.offset * field_byte_width) +
X field_byte_offset;
X
X
+
X /* Invoke the appropriate Address_space/Op_region handler */
X
X status = acpi_ev_address_space_dispatch (rgn_desc, ADDRESS_SPACE_WRITE,
@@ -363,7 +381,7 @@
X
X ACPI_STATUS
X acpi_aml_write_field_data_with_update_rule (
- ACPI_OBJECT_INTERNAL *obj_desc,
+ ACPI_OPERAND_OBJECT *obj_desc,
X u32 mask,
X u32 field_value,
X u32 this_field_byte_offset,
@@ -426,7 +444,7 @@
X bit_granularity, merged_value);


X }
X
- return status;

+ return (status);
X }
X
X

@@ -446,7 +464,7 @@
X
X ACPI_STATUS
X acpi_aml_write_field (
- ACPI_OBJECT_INTERNAL *obj_desc,
+ ACPI_OPERAND_OBJECT *obj_desc,
X void *buffer,
X u32 buffer_length,
X u32 byte_length,
@@ -638,7 +656,8 @@
X field_value = (previous_raw_datum >>
X (bit_granularity - obj_desc->field.bit_offset)) & mask;
X
- status = acpi_aml_write_field_data_with_update_rule (obj_desc, mask, field_value, this_field_byte_offset + 1,
+ status = acpi_aml_write_field_data_with_update_rule (obj_desc, mask, field_value,
+ this_field_byte_offset + byte_granularity,
X bit_granularity);
X if (ACPI_FAILURE (status)) {
X goto cleanup;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/interpreter/ammisc.c linux/drivers/acpi/interpreter/ammisc.c
--- v2.4.0-test8/linux/drivers/acpi/interpreter/ammisc.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/interpreter/ammisc.c Fri Sep 15 14:30:30 2000
@@ -2,6 +2,7 @@
X /******************************************************************************
X *
X * Module Name: ammisc - ACPI AML (p-code) execution - specific opcodes
+ * $Revision: 67 $


X *
X *****************************************************************************/
X

@@ -25,14 +26,14 @@
X
X
X #include "acpi.h"

-#include "parser.h"
-#include "interp.h"
+#include "acparser.h"
+#include "acinterp.h"


X #include "amlcode.h"
-#include "dispatch.h"

+#include "acdispat.h"
X
X
X #define _COMPONENT INTERPRETER
- MODULE_NAME ("ammisc");
+ MODULE_NAME ("ammisc")
X
X
X /*******************************************************************************
@@ -58,25 +59,23 @@
X acpi_aml_exec_fatal (
X ACPI_WALK_STATE *walk_state)
X {
- ACPI_OBJECT_INTERNAL *type_desc;
- ACPI_OBJECT_INTERNAL *code_desc;
- ACPI_OBJECT_INTERNAL *arg_desc;
+ ACPI_OPERAND_OBJECT *type_desc;
+ ACPI_OPERAND_OBJECT *code_desc;
+ ACPI_OPERAND_OBJECT *arg_desc;
X ACPI_STATUS status;
X
X
X /* Resolve operands */
X
- status = acpi_aml_resolve_operands (AML_FATAL_OP, WALK_OPERANDS);
+ status = acpi_aml_resolve_operands (AML_FATAL_OP, WALK_OPERANDS, walk_state);
X /* Get operands */
X
X status |= acpi_ds_obj_stack_pop_object (&arg_desc, walk_state);
X status |= acpi_ds_obj_stack_pop_object (&code_desc, walk_state);
X status |= acpi_ds_obj_stack_pop_object (&type_desc, walk_state);


- if (status != AE_OK) {

- /* invalid parameters on object stack */
+ if (ACPI_FAILURE (status)) {
+ /* Invalid parameters on object stack */
X
- acpi_aml_append_operand_diag (_THIS_MODULE, __LINE__,
- (u16) AML_FATAL_OP, WALK_OPERANDS, 3);
X goto cleanup;
X }
X
@@ -130,30 +129,28 @@
X ACPI_STATUS
X acpi_aml_exec_index (
X ACPI_WALK_STATE *walk_state,
- ACPI_OBJECT_INTERNAL **return_desc)
+ ACPI_OPERAND_OBJECT **return_desc)
X {
- ACPI_OBJECT_INTERNAL *obj_desc;
- ACPI_OBJECT_INTERNAL *idx_desc;
- ACPI_OBJECT_INTERNAL *res_desc;
- ACPI_OBJECT_INTERNAL *ret_desc = NULL;
- ACPI_OBJECT_INTERNAL *tmp_desc;
+ ACPI_OPERAND_OBJECT *obj_desc;
+ ACPI_OPERAND_OBJECT *idx_desc;
+ ACPI_OPERAND_OBJECT *res_desc;
+ ACPI_OPERAND_OBJECT *ret_desc = NULL;
+ ACPI_OPERAND_OBJECT *tmp_desc;
X ACPI_STATUS status;
X
X
X /* Resolve operands */
X /* First operand can be either a package or a buffer */
X
- status = acpi_aml_resolve_operands (AML_INDEX_OP, WALK_OPERANDS);
+ status = acpi_aml_resolve_operands (AML_INDEX_OP, WALK_OPERANDS, walk_state);
X /* Get all operands */
X
X status |= acpi_ds_obj_stack_pop_object (&res_desc, walk_state);
X status |= acpi_ds_obj_stack_pop_object (&idx_desc, walk_state);
X status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);


- if (status != AE_OK) {
+ if (ACPI_FAILURE (status)) {

X /* Invalid parameters on object stack */
X
- acpi_aml_append_operand_diag (_THIS_MODULE, __LINE__,
- (u16) AML_INDEX_OP, WALK_OPERANDS, 3);
X goto cleanup;
X }
X
@@ -202,7 +199,7 @@
X ret_desc->reference.target_type = tmp_desc->common.type;
X ret_desc->reference.object = tmp_desc;
X
- status = acpi_aml_exec_store (ret_desc, res_desc);
+ status = acpi_aml_exec_store (ret_desc, res_desc, walk_state);
X ret_desc->reference.object = NULL;
X }
X
@@ -228,7 +225,7 @@
X ret_desc->reference.object = obj_desc;
X ret_desc->reference.offset = idx_desc->number.value;
X
- status = acpi_aml_exec_store (ret_desc, res_desc);
+ status = acpi_aml_exec_store (ret_desc, res_desc, walk_state);
X }
X
X
@@ -282,15 +279,15 @@
X ACPI_STATUS
X acpi_aml_exec_match (
X ACPI_WALK_STATE *walk_state,
- ACPI_OBJECT_INTERNAL **return_desc)
+ ACPI_OPERAND_OBJECT **return_desc)
X {
- ACPI_OBJECT_INTERNAL *pkg_desc;
- ACPI_OBJECT_INTERNAL *op1_desc;
- ACPI_OBJECT_INTERNAL *V1_desc;
- ACPI_OBJECT_INTERNAL *op2_desc;
- ACPI_OBJECT_INTERNAL *V2_desc;
- ACPI_OBJECT_INTERNAL *start_desc;
- ACPI_OBJECT_INTERNAL *ret_desc = NULL;
+ ACPI_OPERAND_OBJECT *pkg_desc;
+ ACPI_OPERAND_OBJECT *op1_desc;
+ ACPI_OPERAND_OBJECT *V1_desc;
+ ACPI_OPERAND_OBJECT *op2_desc;
+ ACPI_OPERAND_OBJECT *V2_desc;
+ ACPI_OPERAND_OBJECT *start_desc;
+ ACPI_OPERAND_OBJECT *ret_desc = NULL;
X ACPI_STATUS status;
X u32 index;
X u32 match_value = (u32) -1;
@@ -298,7 +295,7 @@
X
X /* Resolve all operands */
X
- status = acpi_aml_resolve_operands (AML_MATCH_OP, WALK_OPERANDS);
+ status = acpi_aml_resolve_operands (AML_MATCH_OP, WALK_OPERANDS, walk_state);
X /* Get all operands */
X
X status |= acpi_ds_obj_stack_pop_object (&start_desc, walk_state);
@@ -308,11 +305,9 @@
X status |= acpi_ds_obj_stack_pop_object (&op1_desc, walk_state);
X status |= acpi_ds_obj_stack_pop_object (&pkg_desc, walk_state);


X
- if (status != AE_OK) {
+ if (ACPI_FAILURE (status)) {

X /* Invalid parameters on object stack */
X
- acpi_aml_append_operand_diag (_THIS_MODULE, __LINE__,
- (u16) AML_MATCH_OP, WALK_OPERANDS, 6);
X goto cleanup;
X }
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/interpreter/ammonad.c linux/drivers/acpi/interpreter/ammonad.c
--- v2.4.0-test8/linux/drivers/acpi/interpreter/ammonad.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/interpreter/ammonad.c Fri Sep 15 14:30:30 2000
@@ -2,6 +2,7 @@
X /******************************************************************************
X *
X * Module Name: ammonad - ACPI AML (p-code) execution for monadic operators
+ * $Revision: 79 $


X *
X *****************************************************************************/
X

@@ -25,15 +26,15 @@


X
X
X #include "acpi.h"

-#include "parser.h"
-#include "dispatch.h"


-#include "interp.h"
+#include "acparser.h"
+#include "acdispat.h"

+#include "acinterp.h"
X #include "amlcode.h"
-#include "namesp.h"
+#include "acnamesp.h"

X
X
X #define _COMPONENT INTERPRETER
- MODULE_NAME ("ammonad");
+ MODULE_NAME ("ammonad")
X
X
X /*******************************************************************************
@@ -52,8 +53,9 @@
X
X ACPI_STATUS
X acpi_aml_get_object_reference (
- ACPI_OBJECT_INTERNAL *obj_desc,
- ACPI_OBJECT_INTERNAL **ret_desc)
+ ACPI_OPERAND_OBJECT *obj_desc,
+ ACPI_OPERAND_OBJECT **ret_desc,
+ ACPI_WALK_STATE *walk_state)


X {
X ACPI_STATUS status = AE_OK;

X
@@ -74,14 +76,14 @@
X case AML_LOCAL_OP:
X
X *ret_desc = (void *) acpi_ds_method_data_get_nte (MTH_TYPE_LOCAL,
- (obj_desc->reference.offset));
+ (obj_desc->reference.offset), walk_state);
X break;
X
X
X case AML_ARG_OP:
X
X *ret_desc = (void *) acpi_ds_method_data_get_nte (MTH_TYPE_ARG,
- (obj_desc->reference.offset));
+ (obj_desc->reference.offset), walk_state);
X break;
X
X
@@ -95,7 +97,7 @@
X }
X
X else if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
- /* Must be a named object; Just return the NTE */
+ /* Must be a named object; Just return the Node */
X
X *ret_desc = obj_desc;
X }
@@ -130,19 +132,17 @@
X u16 opcode,
X ACPI_WALK_STATE *walk_state)
X {


- ACPI_OBJECT_INTERNAL *obj_desc;
+ ACPI_OPERAND_OBJECT *obj_desc;

X ACPI_STATUS status;
X
X
X /* Resolve all operands */
X
- status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS);
+ status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);
X /* Get all operands */
X
X status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);


- if (status != AE_OK) {

- acpi_aml_append_operand_diag (_THIS_MODULE, __LINE__,
- opcode, WALK_OPERANDS, 1);
+ if (ACPI_FAILURE (status)) {
X goto cleanup;
X }
X

@@ -196,6 +196,7 @@
X

X default:
X
+ REPORT_ERROR ("Acpi_aml_exec_monadic1: Unknown monadic opcode");
X status = AE_AML_BAD_OPCODE;
X break;
X
@@ -229,30 +230,28 @@
X acpi_aml_exec_monadic2_r (
X u16 opcode,
X ACPI_WALK_STATE *walk_state,
- ACPI_OBJECT_INTERNAL **return_desc)
+ ACPI_OPERAND_OBJECT **return_desc)
X {
- ACPI_OBJECT_INTERNAL *obj_desc;
- ACPI_OBJECT_INTERNAL *res_desc;
- ACPI_OBJECT_INTERNAL *ret_desc = NULL;
- ACPI_OBJECT_INTERNAL *ret_desc2 = NULL;
+ ACPI_OPERAND_OBJECT *obj_desc;
+ ACPI_OPERAND_OBJECT *res_desc;
+ ACPI_OPERAND_OBJECT *ret_desc = NULL;
+ ACPI_OPERAND_OBJECT *ret_desc2 = NULL;
X u32 res_val;
X ACPI_STATUS status;
- s32 d0;
- s32 d1;
- s32 d2;
- s32 d3;
+ u32 d0;
+ u32 d1;
+ u32 d2;
+ u32 d3;
X
X
X /* Resolve all operands */
X
- status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS);
+ status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);
X /* Get all operands */
X
X status |= acpi_ds_obj_stack_pop_object (&res_desc, walk_state);


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 030'
echo 'File patch-2.4.0-test9 is continued in part 031'
echo "031" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part031

#!/bin/sh -x
# this is part 031 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 031; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

X status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);
- if (status != AE_OK) {
- acpi_aml_append_operand_diag (_THIS_MODULE, __LINE__,

- opcode, WALK_OPERANDS, 2);


+ if (ACPI_FAILURE (status)) {
X goto cleanup;
X }
X

@@ -264,8 +263,8 @@
X case AML_BIT_NOT_OP:
X case AML_FIND_SET_LEFT_BIT_OP:
X case AML_FIND_SET_RIGHT_BIT_OP:
- case AML_FROM_BCDOP:
- case AML_TO_BCDOP:
+ case AML_FROM_BCD_OP:
+ case AML_TO_BCD_OP:
X case AML_COND_REF_OF_OP:
X
X ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_NUMBER);
@@ -293,7 +292,13 @@
X case AML_FIND_SET_LEFT_BIT_OP:
X
X ret_desc->number.value = obj_desc->number.value;
- for (res_val = 0; ret_desc->number.value && res_val < 33; ++res_val) {
+
+ /*
+ * Acpi x1.94 spec, Chapter 16 describes Integer as a 32-bit
+ * little endian unsigned value, so this boundry condition
+ * is valid.
+ */
+ for (res_val = 0; ret_desc->number.value && res_val < 32; ++res_val) {
X ret_desc->number.value >>= 1;
X }
X
@@ -306,22 +311,29 @@
X case AML_FIND_SET_RIGHT_BIT_OP:
X
X ret_desc->number.value = obj_desc->number.value;
- for (res_val = 0; ret_desc->number.value && res_val < 33; ++res_val) {
+
+ /*
+ * Acpi x1.94 spec, Chapter 16 describes Integer as a 32-bit
+ * little endian unsigned value, so this boundry condition
+ * is valid.
+ */
+ for (res_val = 0; ret_desc->number.value && res_val < 32; ++res_val) {
X ret_desc->number.value <<= 1;
X }
X
+ /* Since returns must be 1-based, subtract from 33 */
X ret_desc->number.value = res_val == 0 ? 0 : 33 - res_val;
X break;
X
X
X /* Def_from_bDC := From_bCDOp BCDValue Result */
X
- case AML_FROM_BCDOP:
+ case AML_FROM_BCD_OP:
X
- d0 = (s32) (obj_desc->number.value & 15);
- d1 = (s32) (obj_desc->number.value >> 4 & 15);
- d2 = (s32) (obj_desc->number.value >> 8 & 15);
- d3 = (s32) (obj_desc->number.value >> 12 & 15);
+ d0 = (u32) (obj_desc->number.value & 15);
+ d1 = (u32) (obj_desc->number.value >> 4 & 15);
+ d2 = (u32) (obj_desc->number.value >> 8 & 15);
+ d3 = (u32) (obj_desc->number.value >> 12 & 15);
X
X if (d0 > 9 || d1 > 9 || d2 > 9 || d3 > 9) {
X status = AE_AML_NUMERIC_OVERFLOW;
@@ -334,7 +346,7 @@
X
X /* Def_to_bDC := To_bCDOp Operand Result */
X
- case AML_TO_BCDOP:
+ case AML_TO_BCD_OP:
X
X
X if (obj_desc->number.value > 9999) {
@@ -361,7 +373,7 @@
X * (There are really two return values)
X */
X
- if ((ACPI_NAMED_OBJECT*) obj_desc == acpi_gbl_root_object) {
+ if ((ACPI_NAMESPACE_NODE *) obj_desc == acpi_gbl_root_node) {
X /*
X * This means that the object does not exist in the namespace,
X * return FALSE
@@ -380,12 +392,12 @@
X
X /* Get the object reference and store it */
X
- status = acpi_aml_get_object_reference (obj_desc, &ret_desc2);
+ status = acpi_aml_get_object_reference (obj_desc, &ret_desc2, walk_state);
X if (ACPI_FAILURE (status)) {


X goto cleanup;
X }
X

- status = acpi_aml_exec_store (ret_desc2, res_desc);
+ status = acpi_aml_exec_store (ret_desc2, res_desc, walk_state);
X
X /* The object exists in the namespace, return TRUE */
X
@@ -406,7 +418,7 @@
X * since the object itself may have been stored.
X */
X
- status = acpi_aml_exec_store (obj_desc, res_desc);
+ status = acpi_aml_exec_store (obj_desc, res_desc, walk_state);
X if (ACPI_FAILURE (status)) {
X /* On failure, just delete the Obj_desc */
X
@@ -454,12 +466,13 @@
X
X default:
X
+ REPORT_ERROR ("Acpi_aml_exec_monadic2_r: Unknown monadic opcode");
X status = AE_AML_BAD_OPCODE;


X goto cleanup;
X }
X
X

- status = acpi_aml_exec_store (ret_desc, res_desc);
+ status = acpi_aml_exec_store (ret_desc, res_desc, walk_state);
X
X

X cleanup:
@@ -502,25 +515,32 @@
X acpi_aml_exec_monadic2 (


X u16 opcode,
X ACPI_WALK_STATE *walk_state,
- ACPI_OBJECT_INTERNAL **return_desc)
+ ACPI_OPERAND_OBJECT **return_desc)
X {
- ACPI_OBJECT_INTERNAL *obj_desc;

- ACPI_OBJECT_INTERNAL *tmp_desc;


- ACPI_OBJECT_INTERNAL *ret_desc = NULL;
+ ACPI_OPERAND_OBJECT *obj_desc;

+ ACPI_OPERAND_OBJECT *tmp_desc;


+ ACPI_OPERAND_OBJECT *ret_desc = NULL;

+ ACPI_STATUS resolve_status;
X ACPI_STATUS status;
X u32 type;
X u32 value;
X
X
- /* Resolve all operands */
+ /* Attempt to resolve the operands */


X
- status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS);

- /* Get all operands */
+ resolve_status = acpi_aml_resolve_operands (opcode, WALK_OPERANDS, walk_state);
+ /* Always get all operands */
X
- status |= acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);


- if (status != AE_OK) {
- acpi_aml_append_operand_diag (_THIS_MODULE, __LINE__,
- opcode, WALK_OPERANDS, 1);

+ status = acpi_ds_obj_stack_pop_object (&obj_desc, walk_state);
+
+
+ /* Now we can check the status codes */
+
+ if (ACPI_FAILURE (resolve_status)) {
+ goto cleanup;
+ }


+
+ if (ACPI_FAILURE (status)) {

X goto cleanup;
X }
X

@@ -553,7 +573,7 @@
X

X /*
X * Since we are expecting an Reference on the top of the stack, it
- * can be either an NTE or an internal object.
+ * can be either an Node or an internal object.
X *
X * TBD: [Future] This may be the prototype code for all cases where
X * an Reference is expected!! 10/99
@@ -586,10 +606,8 @@
X * (This deletes the original Ret_desc)
X */
X
- status = acpi_aml_resolve_operands (AML_LNOT_OP, &ret_desc);


- if (status != AE_OK) {
- acpi_aml_append_operand_diag (_THIS_MODULE, __LINE__,
- opcode, WALK_OPERANDS, 1);

+ status = acpi_aml_resolve_operands (AML_LNOT_OP, &ret_desc, walk_state);


+ if (ACPI_FAILURE (status)) {
X goto cleanup;
X }
X

@@ -604,7 +622,7 @@
X
X /* Store the result back in the original descriptor */
X
- status = acpi_aml_exec_store (ret_desc, obj_desc);
+ status = acpi_aml_exec_store (ret_desc, obj_desc, walk_state);
X
X /* Objdesc was just deleted (because it is an Reference) */
X
@@ -662,19 +680,20 @@
X case AML_LOCAL_OP:
X
X type = acpi_ds_method_data_get_type (MTH_TYPE_LOCAL,


- (obj_desc->reference.offset));
+ (obj_desc->reference.offset), walk_state);
X break;
X
X
X case AML_ARG_OP:
X

X type = acpi_ds_method_data_get_type (MTH_TYPE_ARG,


- (obj_desc->reference.offset));
+ (obj_desc->reference.offset), walk_state);
X break;
X
X

X default:
X
+ REPORT_ERROR ("Acpi_aml_exec_monadic2/Type_op:internal error: Unknown Reference subtype");
X status = AE_AML_INTERNAL;
X goto cleanup;
X }
@@ -682,8 +701,7 @@


X
X else {
X /*

- * Since we passed Acpi_aml_resolve_operands("l") and it's not a
- * Reference, it must be a direct name pointer.
+ * It's not a Reference, so it must be a direct name pointer.
X */
X type = acpi_ns_get_type ((ACPI_HANDLE) obj_desc);
X }
@@ -764,7 +782,7 @@
X
X case AML_REF_OF_OP:
X
- status = acpi_aml_get_object_reference (obj_desc, &ret_desc);
+ status = acpi_aml_get_object_reference (obj_desc, &ret_desc, walk_state);
X if (ACPI_FAILURE (status)) {
X goto cleanup;
X }
@@ -789,7 +807,7 @@
X case AML_LOCAL_OP:
X
X acpi_ds_method_data_get_value (MTH_TYPE_LOCAL,
- (obj_desc->reference.offset), &tmp_desc);
+ (obj_desc->reference.offset), walk_state, &tmp_desc);
X
X /*
X * Delete our reference to the input object and
@@ -803,7 +821,7 @@
X case AML_ARG_OP:
X
X acpi_ds_method_data_get_value (MTH_TYPE_ARG,
- (obj_desc->reference.offset), &tmp_desc);
+ (obj_desc->reference.offset), walk_state, &tmp_desc);
X
X /*
X * Delete our reference to the input object and
@@ -824,9 +842,9 @@
X /* Obj_desc may have changed from the code above */
X
X if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
- /* Get the actual object from the NTE (This is the dereference) */
+ /* Get the actual object from the Node (This is the dereference) */
X
- ret_desc = ((ACPI_NAMED_OBJECT*) obj_desc)->object;
+ ret_desc = ((ACPI_NAMESPACE_NODE *) obj_desc)->object;
X
X /* Returning a pointer to the object, add another reference! */
X
@@ -928,6 +946,7 @@
X
X default:
X
+ REPORT_ERROR ("Acpi_aml_exec_monadic2: Internal error, unknown monadic opcode");
X status = AE_AML_BAD_OPCODE;
X goto cleanup;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/interpreter/amnames.c linux/drivers/acpi/interpreter/amnames.c
--- v2.4.0-test8/linux/drivers/acpi/interpreter/amnames.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/interpreter/amnames.c Fri Sep 15 14:30:30 2000


@@ -2,6 +2,7 @@
X /******************************************************************************
X *

X * Module Name: amnames - interpreter/scanner name load/execute


+ * $Revision: 70 $
X *
X *****************************************************************************/
X

@@ -25,12 +26,12 @@


X
X
X #include "acpi.h"
-#include "interp.h"
+#include "acinterp.h"
X #include "amlcode.h"
-#include "namesp.h"

+#include "acnamesp.h"


X
X #define _COMPONENT INTERPRETER

- MODULE_NAME ("amnames");
+ MODULE_NAME ("amnames")
X
X
X /* AML Package Length encodings */
@@ -57,13 +58,13 @@


X *
X ******************************************************************************/
X

-char *
+NATIVE_CHAR *
X acpi_aml_allocate_name_string (
X u32 prefix_count,
X u32 num_name_segs)
X {
- char *temp_ptr;
- char *name_string;
+ NATIVE_CHAR *temp_ptr;
+ NATIVE_CHAR *name_string;
X u32 size_needed;


X
X
@@ -87,7 +88,7 @@

X * This buffer must be deleted by the caller!
X */
X
- name_string = acpi_cm_allocate ((ACPI_SIZE) size_needed);
+ name_string = acpi_cm_allocate (size_needed);
X if (!name_string) {
X REPORT_ERROR ("Aml_allocate_name_string: name allocation failure");
X return (NULL);
@@ -133,52 +134,6 @@
X return (name_string);
X }
X
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_aml_decode_package_length
- *
- * PARAMETERS: Last_pkg_len - latest value decoded by Do_pkg_length() for
- * most recently examined package or field
- *
- * RETURN: Number of bytes contained in package length encoding
- *
- * DESCRIPTION: Decodes the Package Length. Upper 2 bits are are used to
- * tell if type 1, 2, 3, or 4.
- * 0x3F = Max 1 byte encoding,
- * 0xFFF = Max 2 byte encoding,
- * 0xFFFFF = Max 3 Byte encoding,
- * 0xFFFFFFFFF = Max 4 Byte encoding.


- *
- ******************************************************************************/
-

-u32
-acpi_aml_decode_package_length (
- u32 last_pkg_len)
-{

- u32 num_bytes = 0;
-
-
- if (last_pkg_len < ACPI_AML_PACKAGE_TYPE1) {
- num_bytes = 1;
- }
-
- else if (last_pkg_len < ACPI_AML_PACKAGE_TYPE2) {
- num_bytes = 2;
- }
-
- else if (last_pkg_len < ACPI_AML_PACKAGE_TYPE3) {
- num_bytes = 3;
- }
-
- else if (last_pkg_len < ACPI_AML_PACKAGE_TYPE4) {
- num_bytes = 4;
- }
-
- return (num_bytes);
-}
-
-
X /*******************************************************************************
X *
X * FUNCTION: Acpi_aml_exec_name_segment
@@ -194,12 +149,12 @@
X ACPI_STATUS
X acpi_aml_exec_name_segment (
X u8 **in_aml_address,
- char *name_string)
+ NATIVE_CHAR *name_string)
X {
X u8 *aml_address = *in_aml_address;


X ACPI_STATUS status = AE_OK;

- s32 index;
- char char_buf[5];
+ u32 index;
+ NATIVE_CHAR char_buf[5];
X
X
X /*
@@ -271,15 +226,16 @@
X acpi_aml_get_name_string (
X OBJECT_TYPE_INTERNAL data_type,
X u8 *in_aml_address,
- char **out_name_string,
+ NATIVE_CHAR **out_name_string,
X u32 *out_name_length)


X {
X ACPI_STATUS status = AE_OK;

X u8 *aml_address = in_aml_address;
- char *name_string = NULL;
- s32 num_segments;
- s32 prefix_count = 0;
+ NATIVE_CHAR *name_string = NULL;
+ u32 num_segments;
+ u32 prefix_count = 0;
X u8 prefix = 0;
+ u8 has_prefix = FALSE;
X
X
X if (INTERNAL_TYPE_DEF_FIELD == data_type ||
@@ -313,7 +269,8 @@
X * Remember that we have a Root_prefix --
X * see comment in Acpi_aml_allocate_name_string()
X */
- prefix_count = -1;
+ prefix_count = (u32) -1;
+ has_prefix = TRUE;
X break;
X
X
@@ -327,7 +284,7 @@
X ++prefix_count;
X
X } while (*aml_address == AML_PARENT_PREFIX);
-
+ has_prefix = TRUE;
X break;
X
X
@@ -351,9 +308,8 @@
X break;
X }
X
- /* Ensure Prefix_count != 0 to remember processing a prefix */
-
- prefix_count += 2;
+ /* Indicate that we processed a prefix */
+ has_prefix = TRUE;
X
X status = acpi_aml_exec_name_segment (&aml_address, name_string);
X if (ACPI_SUCCESS (status)) {
@@ -375,9 +331,8 @@
X break;
X }
X
- /* Ensure Prefix_count != 0 to remember processing a prefix */
-
- prefix_count += 2;
+ /* Indicate that we processed a prefix */
+ has_prefix = TRUE;
X
X while (num_segments &&
X (status = acpi_aml_exec_name_segment (&aml_address, name_string)) == AE_OK)
@@ -422,7 +377,7 @@
X }
X
X
- if (AE_CTRL_PENDING == status && prefix_count != 0) {
+ if (AE_CTRL_PENDING == status && has_prefix) {
X /* Ran out of segments after processing a prefix */
X
X REPORT_ERROR ("Ran out of segments after processing a prefix");
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/interpreter/amprep.c linux/drivers/acpi/interpreter/amprep.c
--- v2.4.0-test8/linux/drivers/acpi/interpreter/amprep.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/interpreter/amprep.c Fri Sep 15 14:30:30 2000


@@ -2,6 +2,7 @@
X /******************************************************************************
X *

X * Module Name: amprep - ACPI AML (p-code) execution - field prep utilities


+ * $Revision: 67 $
X *
X *****************************************************************************/
X
@@ -25,14 +26,14 @@
X
X
X #include "acpi.h"

-#include "interp.h"
+#include "acinterp.h"
X #include "amlcode.h"
-#include "namesp.h"

-#include "parser.h"
+#include "acnamesp.h"
+#include "acparser.h"


X
X
X #define _COMPONENT INTERPRETER

- MODULE_NAME ("amprep");
+ MODULE_NAME ("amprep")
X
X
X /*******************************************************************************
@@ -55,25 +56,25 @@
X switch (access)
X {
X case ACCESS_ANY_ACC:
- return 8;
+ return (8);
X break;
X
X case ACCESS_BYTE_ACC:
- return 8;
+ return (8);
X break;
X
X case ACCESS_WORD_ACC:
- return 16;
+ return (16);
X break;
X
X case ACCESS_DWORD_ACC:
- return 32;
+ return (32);


X break;
X
X default:

X /* Invalid field access type */
X
- return 0;
+ return (0);
X }
X }
X
@@ -98,7 +99,7 @@
X
X ACPI_STATUS
X acpi_aml_prep_common_field_object (


- ACPI_OBJECT_INTERNAL *obj_desc,
+ ACPI_OPERAND_OBJECT *obj_desc,

X u8 field_flags,
X u8 field_attribute,
X u32 field_position,
@@ -150,7 +151,7 @@
X *
X * FUNCTION: Acpi_aml_prep_def_field_value
X *
- * PARAMETERS: This_entry - Owning NTE
+ * PARAMETERS: Node - Owning Node
X * Region - Region in which field is being defined
X * Field_flags - Access, Lock_rule, or Update_rule.
X * The format of a Field_flag is described
@@ -160,22 +161,22 @@
X *


X * RETURN: Status
X *

- * DESCRIPTION: Construct an ACPI_OBJECT_INTERNAL of type Def_field and
- * connect it to the parent NTE.
+ * DESCRIPTION: Construct an ACPI_OPERAND_OBJECT of type Def_field and
+ * connect it to the parent Node.
X *
X ******************************************************************************/
X
X ACPI_STATUS
X acpi_aml_prep_def_field_value (
- ACPI_NAMED_OBJECT *this_entry,
+ ACPI_NAMESPACE_NODE *node,
X ACPI_HANDLE region,
X u8 field_flags,
X u8 field_attribute,
X u32 field_position,
X u32 field_length)
X {
- ACPI_OBJECT_INTERNAL *obj_desc;
- s32 type;
+ ACPI_OPERAND_OBJECT *obj_desc;
+ u32 type;


X ACPI_STATUS status;
X
X

@@ -220,11 +221,11 @@
X /* Debug info */
X
X /*
- * Store the constructed descriptor (Obj_desc) into the nte whose
- * handle is on TOS, preserving the current type of that nte.
+ * Store the constructed descriptor (Obj_desc) into the Named_obj whose
+ * handle is on TOS, preserving the current type of that Named_obj.
X */
- status = acpi_ns_attach_object ((ACPI_HANDLE) this_entry, obj_desc,
- (u8) acpi_ns_get_type ((ACPI_HANDLE) this_entry));


+ status = acpi_ns_attach_object ((ACPI_HANDLE) node, obj_desc,

+ (u8) acpi_ns_get_type ((ACPI_HANDLE) node));
X
X return (status);
X }
@@ -234,7 +235,7 @@
X *
X * FUNCTION: Acpi_aml_prep_bank_field_value
X *
- * PARAMETERS: This_entry - Owning NTE
+ * PARAMETERS: Node - Owning Node
X * Region - Region in which field is being defined
X * Bank_reg - Bank selection register
X * Bank_val - Value to store in selection register
@@ -244,14 +245,14 @@
X *


X * RETURN: Status
X *

- * DESCRIPTION: Construct an ACPI_OBJECT_INTERNAL of type Bank_field and
- * connect it to the parent NTE.
+ * DESCRIPTION: Construct an ACPI_OPERAND_OBJECT of type Bank_field and
+ * connect it to the parent Node.
X *
X ******************************************************************************/
X
X ACPI_STATUS
X acpi_aml_prep_bank_field_value (
- ACPI_NAMED_OBJECT *this_entry,
+ ACPI_NAMESPACE_NODE *node,
X ACPI_HANDLE region,
X ACPI_HANDLE bank_reg,
X u32 bank_val,
@@ -260,8 +261,8 @@
X u32 field_position,
X u32 field_length)
X {
- ACPI_OBJECT_INTERNAL *obj_desc;
- s32 type;
+ ACPI_OPERAND_OBJECT *obj_desc;
+ u32 type;


X ACPI_STATUS status;
X
X

@@ -308,11 +309,11 @@
X /* Debug info */
X
X /*
- * Store the constructed descriptor (Obj_desc) into the nte whose
- * handle is on TOS, preserving the current type of that nte.
+ * Store the constructed descriptor (Obj_desc) into the Named_obj whose
+ * handle is on TOS, preserving the current type of that Named_obj.
X */
- status = acpi_ns_attach_object ((ACPI_HANDLE) this_entry, obj_desc,
- (u8) acpi_ns_get_type ((ACPI_HANDLE) this_entry));


+ status = acpi_ns_attach_object ((ACPI_HANDLE) node, obj_desc,

+ (u8) acpi_ns_get_type ((ACPI_HANDLE) node));
X
X return (status);
X }
@@ -322,7 +323,7 @@
X *
X * FUNCTION: Acpi_aml_prep_index_field_value
X *
- * PARAMETERS: This_entry - Owning NTE
+ * PARAMETERS: Node - Owning Node
X * Index_reg - Index register
X * Data_reg - Data register
X * Field_flags - Access, Lock_rule, or Update_rule
@@ -331,14 +332,14 @@
X *


X * RETURN: Status
X *

- * DESCRIPTION: Construct an ACPI_OBJECT_INTERNAL of type Index_field and
- * connect it to the parent NTE.
+ * DESCRIPTION: Construct an ACPI_OPERAND_OBJECT of type Index_field and
+ * connect it to the parent Node.
X *
X ******************************************************************************/
X
X ACPI_STATUS
X acpi_aml_prep_index_field_value (
- ACPI_NAMED_OBJECT *this_entry,
+ ACPI_NAMESPACE_NODE *node,
X ACPI_HANDLE index_reg,
X ACPI_HANDLE data_reg,
X u8 field_flags,
@@ -346,7 +347,7 @@
X u32 field_position,
X u32 field_length)


X {
- ACPI_OBJECT_INTERNAL *obj_desc;
+ ACPI_OPERAND_OBJECT *obj_desc;
X ACPI_STATUS status;
X
X

@@ -381,11 +382,11 @@
X /* Debug info */
X
X /*
- * Store the constructed descriptor (Obj_desc) into the nte whose
- * handle is on TOS, preserving the current type of that nte.
+ * Store the constructed descriptor (Obj_desc) into the Named_obj whose
+ * handle is on TOS, preserving the current type of that Named_obj.
X */
- status = acpi_ns_attach_object ((ACPI_HANDLE) this_entry, obj_desc,
- (u8) acpi_ns_get_type ((ACPI_HANDLE) this_entry));


+ status = acpi_ns_attach_object ((ACPI_HANDLE) node, obj_desc,

+ (u8) acpi_ns_get_type ((ACPI_HANDLE) node));
X
X return (status);
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/interpreter/amregion.c linux/drivers/acpi/interpreter/amregion.c
--- v2.4.0-test8/linux/drivers/acpi/interpreter/amregion.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/interpreter/amregion.c Fri Sep 15 14:30:30 2000
@@ -1,6 +1,8 @@
+
X /******************************************************************************
X *
X * Module Name: amregion - ACPI default Op_region (address space) handlers
+ * $Revision: 35 $


X *
X *****************************************************************************/
X

@@ -24,15 +26,15 @@


X
X
X #include "acpi.h"

-#include "interp.h"
+#include "acinterp.h"
X #include "amlcode.h"
-#include "namesp.h"
-#include "hardware.h"
-#include "events.h"
+#include "acnamesp.h"
+#include "achware.h"
+#include "acevents.h"
X
X
X #define _COMPONENT INTERPRETER

- MODULE_NAME ("amregion");
+ MODULE_NAME ("amregion")
X
X
X /*******************************************************************************
@@ -43,7 +45,9 @@
X * Address - Where in the space to read or write
X * Bit_width - Field width in bits (8, 16, or 32)
X * Value - Pointer to in or out value
- * Context - Context pointer
+ * Handler_context - Pointer to Handler's context
+ * Region_context - Pointer to context specific to the
+ * accessed region


X *
X * RETURN: Status
X *

@@ -57,11 +61,12 @@
X u32 address, /* TBD: [Future] Should this be A POINTER for 64-bit support? */


X u32 bit_width,
X u32 *value,
- void *context)
+ void *handler_context,
+ void *region_context)

X {
X ACPI_STATUS status = AE_OK;

X void *logical_addr_ptr = NULL;
- MEM_HANDLER_CONTEXT *mem_info = context;
+ MEM_HANDLER_CONTEXT *mem_info = region_context;
X u32 length;
X
X
@@ -93,8 +98,8 @@
X * 2) Address beyond the current mapping?
X */
X
- if (((char *) address < mem_info->mapped_physical_address) ||
- (((char *) address + length) >
+ if (((u8 *) address < mem_info->mapped_physical_address) ||
+ (((u8 *) address + length) >
X (mem_info->mapped_physical_address + mem_info->mapped_length)))
X {
X /*
@@ -119,7 +124,7 @@


X return (status);
X }
X

- mem_info->mapped_physical_address = (char *) address;
+ mem_info->mapped_physical_address = (u8 *) address;
X mem_info->mapped_length = SYSMEM_REGION_WINDOW_SIZE;
X }
X
@@ -130,7 +135,7 @@
X */
X
X logical_addr_ptr = mem_info->mapped_logical_address +
- ((char *) address - mem_info->mapped_physical_address);
+ ((u8 *) address - mem_info->mapped_physical_address);
X
X /* Perform the memory read or write */
X
@@ -194,7 +199,9 @@
X * Address - Where in the space to read or write
X * Bit_width - Field width in bits (8, 16, or 32)
X * Value - Pointer to in or out value
- * Context - Context pointer
+ * Handler_context - Pointer to Handler's context
+ * Region_context - Pointer to context specific to the
+ * accessed region


X *
X * RETURN: Status
X *

@@ -208,7 +215,8 @@


X u32 address,
X u32 bit_width,
X u32 *value,
- void *context)
+ void *handler_context,
+ void *region_context)

X {
X ACPI_STATUS status = AE_OK;
X

@@ -283,7 +291,9 @@
X * Address - Where in the space to read or write
X * Bit_width - Field width in bits (8, 16, or 32)
X * Value - Pointer to in or out value
- * Context - Context pointer
+ * Handler_context - Pointer to Handler's context
+ * Region_context - Pointer to context specific to the
+ * accessed region


X *
X * RETURN: Status
X *

@@ -297,7 +307,8 @@


X u32 address,
X u32 bit_width,
X u32 *value,
- void *context)
+ void *handler_context,
+ void *region_context)

X {
X ACPI_STATUS status = AE_OK;

X u32 pci_bus;


@@ -321,7 +332,7 @@
X *

X */
X
- PCIcontext = (PCI_HANDLER_CONTEXT *) context;
+ PCIcontext = (PCI_HANDLER_CONTEXT *) region_context;
X
X pci_bus = LOWORD(PCIcontext->seg) << 16;
X pci_bus |= LOWORD(PCIcontext->bus);
@@ -365,7 +376,6 @@
X
X
X case ADDRESS_SPACE_WRITE:
-
X
X switch (bit_width)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/interpreter/amresnte.c linux/drivers/acpi/interpreter/amresnte.c
--- v2.4.0-test8/linux/drivers/acpi/interpreter/amresnte.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/interpreter/amresnte.c Fri Sep 15 14:30:30 2000


@@ -2,6 +2,7 @@
X /******************************************************************************
X *

X * Module Name: amresnte - AML Interpreter object resolution
+ * $Revision: 21 $


X *
X *****************************************************************************/
X

@@ -26,32 +27,33 @@


X
X #include "acpi.h"
X #include "amlcode.h"

-#include "parser.h"
-#include "dispatch.h"
-#include "interp.h"

-#include "namesp.h"
-#include "tables.h"
-#include "events.h"
+#include "acparser.h"


+#include "acdispat.h"
+#include "acinterp.h"
+#include "acnamesp.h"

+#include "actables.h"


+#include "acevents.h"
X
X
X #define _COMPONENT INTERPRETER

- MODULE_NAME ("amresnte");
+ MODULE_NAME ("amresnte")
X
X
X /*******************************************************************************
X *
- * FUNCTION: Acpi_aml_resolve_entry_to_value
+ * FUNCTION: Acpi_aml_resolve_node_to_value
X *
X * PARAMETERS: Stack_ptr - Pointer to a location on a stack that contains
- * a ptr to an NTE
+ * a pointer to an Node


X *
X * RETURN: Status
X *

- * DESCRIPTION: Resolve a ACPI_NAMED_OBJECT(nte, A.K.A. a "direct name pointer")
+ * DESCRIPTION: Resolve a ACPI_NAMESPACE_NODE (Node,
+ * A.K.A. a "direct name pointer")
X *
- * Note: for some of the data types, the pointer attached to the NTE can be
- * either a pointer to an actual internal object or a pointer into the AML
- * stream itself. These types are currently:
+ * Note: for some of the data types, the pointer attached to the Node
+ * can be either a pointer to an actual internal object or a pointer into the
+ * AML stream itself. These types are currently:
X *
X * ACPI_TYPE_NUMBER
X * ACPI_TYPE_STRING
@@ -62,13 +64,13 @@


X ******************************************************************************/
X
X ACPI_STATUS

-acpi_aml_resolve_entry_to_value (
- ACPI_NAMED_OBJECT **stack_ptr)

+acpi_aml_resolve_node_to_value (
+ ACPI_NAMESPACE_NODE **stack_ptr)

X {
X ACPI_STATUS status = AE_OK;

- ACPI_OBJECT_INTERNAL *val_desc = NULL;


- ACPI_OBJECT_INTERNAL *obj_desc = NULL;

- ACPI_NAMED_OBJECT *stack_entry;


+ ACPI_OPERAND_OBJECT *val_desc = NULL;
+ ACPI_OPERAND_OBJECT *obj_desc = NULL;

+ ACPI_NAMESPACE_NODE *node;
X u8 *aml_pointer = NULL;
X OBJECT_TYPE_INTERNAL entry_type;
X u8 locked;
@@ -78,20 +80,20 @@
X OBJECT_TYPE_INTERNAL object_type;
X
X
- stack_entry = *stack_ptr;
+ node = *stack_ptr;
X
X
X /*
X * The stack pointer is a "Direct name ptr", and points to a
- * a ACPI_NAMED_OBJECT(nte). Get the pointer that is attached to
- * the nte.
+ * a ACPI_NAMESPACE_NODE (Node). Get the pointer that is attached to
+ * the Node.
X */
X
- val_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) stack_entry);
- entry_type = acpi_ns_get_type ((ACPI_HANDLE) stack_entry);
+ val_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) node);
+ entry_type = acpi_ns_get_type ((ACPI_HANDLE) node);
X
X /*
- * The Val_desc attached to the NTE can be either:
+ * The Val_desc attached to the Node can be either:
X * 1) An internal ACPI object
X * 2) A pointer into the AML stream (into one of the ACPI system tables)
X */
@@ -105,7 +107,25 @@
X
X
X /*
- * Action is based on the type of the NTE, which indicates the type
+ * Several Entry_types do not require further processing, so
+ * we will return immediately
+ */
+ /* Devices rarely have an attached object, return the Node
+ * and Method locals and arguments have a pseudo-Node
+ */
+ if (entry_type == ACPI_TYPE_DEVICE ||
+ entry_type == INTERNAL_TYPE_METHOD_ARGUMENT ||
+ entry_type == INTERNAL_TYPE_METHOD_LOCAL_VAR)
+ {


+ return (AE_OK);
+ }
+

+ if (!val_desc) {
+ return (AE_AML_NO_OPERAND);
+ }
+
+ /*
+ * Action is based on the type of the Node, which indicates the type
X * of the attached object or pointer
X */
X switch (entry_type)
@@ -113,15 +133,6 @@
X
X case ACPI_TYPE_PACKAGE:
X
- /*
- * Val_desc should point to either an ACPI_OBJECT_INTERNAL of
- * type Package, or an initialization in the AML stream.
- */
- if (!val_desc) {
- return (AE_AML_NO_OPERAND);
- }
-
-
X if (attached_aml_pointer) {
X /*
X * This means that the package initialization is not parsed
@@ -132,7 +143,7 @@
X
X /* Val_desc is an internal object in all cases by the time we get here */
X
- if (!val_desc || (ACPI_TYPE_PACKAGE != val_desc->common.type)) {
+ if (ACPI_TYPE_PACKAGE != val_desc->common.type) {
X return (AE_AML_OPERAND_TYPE);
X }
X
@@ -145,10 +156,6 @@


X
X case ACPI_TYPE_BUFFER:
X

- if (!val_desc) {
- return (AE_AML_NO_OPERAND);
- }
-
X if (attached_aml_pointer) {
X /*
X * This means that the buffer initialization is not parsed
@@ -159,7 +166,7 @@
X
X /* Val_desc is an internal object in all cases by the time we get here */
X
- if (!val_desc || (ACPI_TYPE_BUFFER != val_desc->common.type)) {
+ if (ACPI_TYPE_BUFFER != val_desc->common.type) {
X return (AE_AML_OPERAND_TYPE);
X }
X
@@ -183,8 +190,8 @@
X
X /* Init the internal object */
X
- obj_desc->string.pointer = (char *) aml_pointer;
- obj_desc->string.length = STRLEN (aml_pointer);
+ obj_desc->string.pointer = (NATIVE_CHAR *) aml_pointer;
+ obj_desc->string.length = STRLEN (obj_desc->string.pointer);
X }
X
X else {
@@ -203,11 +210,6 @@
X
X case ACPI_TYPE_NUMBER:
X
- if (!val_desc) {
- return (AE_AML_NO_OPERAND);
- }
-
-
X /*
X * An ACPI_TYPE_NUMBER can be either an object or an AML pointer
X */
@@ -279,7 +281,7 @@
X
X else {
X /*
- * The NTE has an attached internal object, make sure that it's a
+ * The Node has an attached internal object, make sure that it's a
X * number
X */
X
@@ -337,18 +339,21 @@
X
X obj_desc->buffer.length = val_desc->field.length;
X
- status = acpi_aml_get_named_field_value ((ACPI_HANDLE) stack_entry,
- obj_desc->buffer.pointer, obj_desc->buffer.length);
+ status = acpi_aml_access_named_field (ACPI_READ,
+ (ACPI_HANDLE) node,
+ obj_desc->buffer.pointer,
+ obj_desc->buffer.length);
X

- if (AE_OK != status) {
+ if (ACPI_FAILURE (status)) {
X return (status);
X }
X }

X else {
- status = acpi_aml_get_named_field_value ((ACPI_HANDLE) stack_entry,
+ status = acpi_aml_access_named_field (ACPI_READ,
+ (ACPI_HANDLE) node,
X &temp_val, sizeof (temp_val));
X

- if (AE_OK != status) {
+ if (ACPI_FAILURE (status)) {
X return (status);
X }
X

@@ -361,10 +366,6 @@
X
X case INTERNAL_TYPE_BANK_FIELD:
X
- if (!val_desc) {
- return (AE_AML_NO_OPERAND);
- }
-
X if (attached_aml_pointer) {
X return (AE_AML_OPERAND_TYPE);
X }
@@ -376,30 +377,30 @@
X
X /* Get the global lock if needed */
X
- obj_desc = (ACPI_OBJECT_INTERNAL *) *stack_ptr;
+ obj_desc = (ACPI_OPERAND_OBJECT *) *stack_ptr;
X locked = acpi_aml_acquire_global_lock (obj_desc->field_unit.lock_rule);
- {
X
- /* Set Index value to select proper Data register */
- /* perform the update */
+ /* Set Index value to select proper Data register */
+ /* perform the update */
+
+ status = acpi_aml_access_named_field (ACPI_WRITE,
+ val_desc->bank_field.bank_select,
+ &val_desc->bank_field.value,
+ sizeof (val_desc->bank_field.value));
X
- status = acpi_aml_set_named_field_value (val_desc->bank_field.bank_select,
- &val_desc->bank_field.value,
- sizeof (val_desc->bank_field.value));
- }
X acpi_aml_release_global_lock (locked);
X
X

- if (AE_OK != status) {
+ if (ACPI_FAILURE (status)) {
X return (status);
X }
X

X /* Read Data value */
X
- status = acpi_aml_get_named_field_value (
+ status = acpi_aml_access_named_field (ACPI_READ,
X (ACPI_HANDLE) val_desc->bank_field.container,
X &temp_val, sizeof (temp_val));


- if (AE_OK != status) {
+ if (ACPI_FAILURE (status)) {
X return (status);
X }
X

@@ -414,10 +415,6 @@
X
X case INTERNAL_TYPE_INDEX_FIELD:
X
- if (!val_desc) {
- return (AE_AML_NO_OPERAND);
- }
-
X if (attached_aml_pointer) {
X return (AE_AML_OPERAND_TYPE);
X }
@@ -430,25 +427,27 @@
X /* Set Index value to select proper Data register */
X /* Get the global lock if needed */
X
- obj_desc = (ACPI_OBJECT_INTERNAL *) *stack_ptr;
+ obj_desc = (ACPI_OPERAND_OBJECT *) *stack_ptr;
X locked = acpi_aml_acquire_global_lock (obj_desc->field_unit.lock_rule);
- {
- /* Perform the update */
X
- status = acpi_aml_set_named_field_value (val_desc->index_field.index,
- &val_desc->index_field.value,
- sizeof (val_desc->index_field.value));
- }
+ /* Perform the update */
+ status = acpi_aml_access_named_field (ACPI_WRITE,
+ val_desc->index_field.index,
+ &val_desc->index_field.value,
+ sizeof (val_desc->index_field.value));
+
X acpi_aml_release_global_lock (locked);
X

- if (AE_OK != status) {
+ if (ACPI_FAILURE (status)) {
X return (status);
X }
X

X /* Read Data value */
X
- status = acpi_aml_get_named_field_value (val_desc->index_field.data, &temp_val, sizeof (temp_val));


- if (AE_OK != status) {

+ status = acpi_aml_access_named_field (ACPI_READ,
+ val_desc->index_field.data,
+ &temp_val, sizeof (temp_val));


+ if (ACPI_FAILURE (status)) {
X return (status);
X }
X

@@ -463,10 +462,6 @@
X
X case ACPI_TYPE_FIELD_UNIT:
X
- if (!val_desc) {
- return (AE_AML_NO_OPERAND);
- }
-
X if (attached_aml_pointer) {
X return (AE_AML_OPERAND_TYPE);
X }
@@ -481,7 +476,8 @@
X return (AE_NO_MEMORY);
X }
X
- if ((status = acpi_aml_get_field_unit_value (val_desc, obj_desc)) != AE_OK) {
+ status = acpi_aml_get_field_unit_value (val_desc, obj_desc);
+ if (ACPI_FAILURE (status)) {
X acpi_cm_remove_reference (obj_desc);
X return (status);
X }
@@ -490,7 +486,7 @@
X
X
X /*
- * For these objects, just return the object attached to the NTE
+ * For these objects, just return the object attached to the Node
X */
X
X case ACPI_TYPE_MUTEX:
@@ -502,32 +498,11 @@
X case ACPI_TYPE_REGION:
X
X
- /* There must be an object attached to this NTE */
-
- if (!val_desc) {


- return (AE_AML_INTERNAL);
- }
-

X /* Return an additional reference to the object */
X
X obj_desc = val_desc;
X acpi_cm_add_reference (obj_desc);
X break;
-
-
- /* Devices rarely have an attached object, return the NTE */
-
- case ACPI_TYPE_DEVICE:
-
-
- /* Method locals and arguments have a pseudo-NTE, just return it */
-
- case INTERNAL_TYPE_METHOD_ARGUMENT:
- case INTERNAL_TYPE_METHOD_LOCAL_VAR:
-
- return (AE_OK);
- break;
-
X
X /* TYPE_Any is untyped, and thus there is no object associated with it */
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/interpreter/amresolv.c linux/drivers/acpi/interpreter/amresolv.c
--- v2.4.0-test8/linux/drivers/acpi/interpreter/amresolv.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/interpreter/amresolv.c Fri Sep 15 14:30:30 2000


@@ -2,6 +2,7 @@
X /******************************************************************************
X *

X * Module Name: amresolv - AML Interpreter object resolution
+ * $Revision: 74 $


X *
X *****************************************************************************/
X

@@ -26,16 +27,16 @@


X
X #include "acpi.h"
X #include "amlcode.h"

-#include "parser.h"
-#include "dispatch.h"
-#include "interp.h"

-#include "namesp.h"
-#include "tables.h"
-#include "events.h"
+#include "acparser.h"


+#include "acdispat.h"
+#include "acinterp.h"
+#include "acnamesp.h"

+#include "actables.h"


+#include "acevents.h"
X
X
X #define _COMPONENT INTERPRETER

- MODULE_NAME ("amresolv");
+ MODULE_NAME ("amresolv")
X
X
X /*******************************************************************************
@@ -55,8 +56,8 @@
X
X ACPI_STATUS
X acpi_aml_get_field_unit_value (


- ACPI_OBJECT_INTERNAL *field_desc,
- ACPI_OBJECT_INTERNAL *result_desc)

+ ACPI_OPERAND_OBJECT *field_desc,
+ ACPI_OPERAND_OBJECT *result_desc)

X {
X ACPI_STATUS status = AE_OK;

X u32 mask;
@@ -143,7 +144,7 @@
X * FUNCTION: Acpi_aml_resolve_to_value
X *
X * PARAMETERS: **Stack_ptr - Points to entry on Obj_stack, which can
- * be either an (ACPI_OBJECT_INTERNAL *)
+ * be either an (ACPI_OPERAND_OBJECT *)
X * or an ACPI_HANDLE.


X *
X * RETURN: Status

@@ -154,7 +155,8 @@
X
X ACPI_STATUS
X acpi_aml_resolve_to_value (
- ACPI_OBJECT_INTERNAL **stack_ptr)
+ ACPI_OPERAND_OBJECT **stack_ptr,


+ ACPI_WALK_STATE *walk_state)
X {
X ACPI_STATUS status = AE_OK;
X

@@ -166,13 +168,13 @@
X
X /*
X * The entity pointed to by the Stack_ptr can be either
- * 1) A valid ACPI_OBJECT_INTERNAL, or
- * 2) A ACPI_NAMED_OBJECT(nte)
+ * 1) A valid ACPI_OPERAND_OBJECT, or
+ * 2) A ACPI_NAMESPACE_NODE (Named_obj)
X */
X
X if (VALID_DESCRIPTOR_TYPE (*stack_ptr, ACPI_DESC_TYPE_INTERNAL)) {
X
- status = acpi_aml_resolve_object_to_value (stack_ptr);
+ status = acpi_aml_resolve_object_to_value (stack_ptr, walk_state);


X if (ACPI_FAILURE (status)) {
X return (status);
X }

@@ -184,7 +186,7 @@
X */
X
X if (VALID_DESCRIPTOR_TYPE (*stack_ptr, ACPI_DESC_TYPE_NAMED)) {
- status = acpi_aml_resolve_entry_to_value ((ACPI_NAMED_OBJECT**) stack_ptr);
+ status = acpi_aml_resolve_node_to_value ((ACPI_NAMESPACE_NODE **) stack_ptr);
X }
X
X
@@ -208,19 +210,20 @@
X
X ACPI_STATUS
X acpi_aml_resolve_object_to_value (
- ACPI_OBJECT_INTERNAL **stack_ptr)
+ ACPI_OPERAND_OBJECT **stack_ptr,
+ ACPI_WALK_STATE *walk_state)
X {
- ACPI_OBJECT_INTERNAL *stack_desc;
+ ACPI_OPERAND_OBJECT *stack_desc;


X ACPI_STATUS status = AE_OK;

X ACPI_HANDLE temp_handle = NULL;


- ACPI_OBJECT_INTERNAL *obj_desc = NULL;
+ ACPI_OPERAND_OBJECT *obj_desc = NULL;

X u32 index = 0;
X u16 opcode;
X
X
X stack_desc = *stack_ptr;
X
- /* This is an ACPI_OBJECT_INTERNAL */
+ /* This is an ACPI_OPERAND_OBJECT */
X
X switch (stack_desc->common.type)


X {
@@ -236,7 +239,7 @@

X
X /*
X * Convert indirect name ptr to a direct name ptr.
- * Then, Acpi_aml_resolve_entry_to_value can be used to get the value
+ * Then, Acpi_aml_resolve_node_to_value can be used to get the value
X */
X
X temp_handle = stack_desc->reference.object;
@@ -256,24 +259,26 @@
X
X index = stack_desc->reference.offset;
X
- /* Delete the Reference Object */
-
- acpi_cm_remove_reference (stack_desc);
-
X /*
X * Get the local from the method's state info
- * Note: this increments the object reference count
+ * Note: this increments the local's object reference count
X */
X
X status = acpi_ds_method_data_get_value (MTH_TYPE_LOCAL, index,
- stack_ptr);
+ walk_state, &obj_desc);


X if (ACPI_FAILURE (status)) {
X return (status);
X }
X

- stack_desc = *stack_ptr;
+ /*
+ * Now we can delete the original Reference Object and
+ * replace it with the resolve value
+ */
+
+ acpi_cm_remove_reference (stack_desc);
+ *stack_ptr = obj_desc;
X
- if (ACPI_TYPE_NUMBER == stack_desc->common.type) {
+ if (ACPI_TYPE_NUMBER == obj_desc->common.type) {
X /* Value is a Number */
X
X }
@@ -285,9 +290,6 @@
X
X index = stack_desc->reference.offset;
X
- /* Delete the Reference Object*/
-
- acpi_cm_remove_reference (stack_desc);
X
X /*
X * Get the argument from the method's state info
@@ -295,14 +297,20 @@
X */
X
X status = acpi_ds_method_data_get_value (MTH_TYPE_ARG, index,
- stack_ptr);
+ walk_state, &obj_desc);


X if (ACPI_FAILURE (status)) {
X return (status);
X }
X

- stack_desc = *stack_ptr;
+ /*
+ * Now we can delete the original Reference Object and
+ * replace it with the resolve value
+ */
+
+ acpi_cm_remove_reference (stack_desc);
+ *stack_ptr = obj_desc;
X
- if (ACPI_TYPE_NUMBER == stack_desc->common.type) {
+ if (ACPI_TYPE_NUMBER == obj_desc->common.type) {
X /* Value is a Number */
X
X }
@@ -392,7 +400,7 @@
X } /* switch (Opcode) */
X
X

- if (AE_OK != status) {
+ if (ACPI_FAILURE (status)) {
X return (status);
X }
X

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/interpreter/amresop.c linux/drivers/acpi/interpreter/amresop.c
--- v2.4.0-test8/linux/drivers/acpi/interpreter/amresop.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/interpreter/amresop.c Fri Sep 15 14:30:30 2000


@@ -2,6 +2,7 @@
X /******************************************************************************
X *

X * Module Name: amresop - AML Interpreter operand/object resolution
+ * $Revision: 15 $


X *
X *****************************************************************************/
X

@@ -26,16 +27,16 @@


X
X #include "acpi.h"
X #include "amlcode.h"

-#include "parser.h"
-#include "dispatch.h"
-#include "interp.h"

-#include "namesp.h"
-#include "tables.h"
-#include "events.h"
+#include "acparser.h"


+#include "acdispat.h"
+#include "acinterp.h"
+#include "acnamesp.h"

+#include "actables.h"


+#include "acevents.h"
X
X
X #define _COMPONENT INTERPRETER

- MODULE_NAME ("amresop");
+ MODULE_NAME ("amresop")
X
X
X /*******************************************************************************
@@ -60,19 +61,20 @@
X ACPI_STATUS
X acpi_aml_resolve_operands (
X u16 opcode,
- ACPI_OBJECT_INTERNAL **stack_ptr)
+ ACPI_OPERAND_OBJECT **stack_ptr,
+ ACPI_WALK_STATE *walk_state)


X {
- ACPI_OBJECT_INTERNAL *obj_desc;
+ ACPI_OPERAND_OBJECT *obj_desc;

X ACPI_STATUS status = AE_OK;
X u8 object_type;
X ACPI_HANDLE temp_handle;
X u32 arg_types;


- ACPI_OP_INFO *op_info;
+ ACPI_OPCODE_INFO *op_info;

X u32 this_arg_type;


X
X
X op_info = acpi_ps_get_opcode_info (opcode);
- if (!op_info) {
+ if (ACPI_GET_OP_TYPE (op_info) != ACPI_OP_TYPE_OPCODE) {

X return (AE_AML_BAD_OPCODE);
X }
X
@@ -105,9 +107,9 @@
X /* Decode the descriptor type */
X
X if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) {
- /* NTE */
+ /* Node */
X
- object_type = ((ACPI_NAMED_OBJECT*) obj_desc)->type;
+ object_type = ((ACPI_NAMESPACE_NODE *) obj_desc)->type;
X }
X
X else if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_INTERNAL)) {
@@ -128,7 +130,7 @@
X */
X

X op_info = acpi_ps_get_opcode_info (opcode);
- if (!op_info) {
+ if (ACPI_GET_OP_TYPE (op_info) != ACPI_OP_TYPE_OPCODE) {

X return (AE_AML_BAD_OPCODE);
X }
X
@@ -205,7 +207,8 @@
X
X /* Need an operand of type ACPI_TYPE_NUMBER */
X
- if ((status = acpi_aml_resolve_to_value (stack_ptr)) != AE_OK) {
+ status = acpi_aml_resolve_to_value (stack_ptr, walk_state);


+ if (ACPI_FAILURE (status)) {
X goto cleanup;
X }
X

@@ -220,7 +223,8 @@
X
X /* Need an operand of type ACPI_TYPE_STRING or ACPI_TYPE_BUFFER */
X
- if ((status = acpi_aml_resolve_to_value (stack_ptr)) != AE_OK) {
+ status = acpi_aml_resolve_to_value (stack_ptr, walk_state);


+ if (ACPI_FAILURE (status)) {
X goto cleanup;
X }
X

@@ -237,7 +241,8 @@
X

X /* Need an operand of type ACPI_TYPE_BUFFER */
X
- if ((status = acpi_aml_resolve_to_value(stack_ptr)) != AE_OK) {
+ status = acpi_aml_resolve_to_value (stack_ptr, walk_state);


+ if (ACPI_FAILURE (status)) {
X goto cleanup;
X }
X

@@ -252,7 +257,8 @@
X
X /* Need an operand of type ACPI_TYPE_MUTEX */
X
- if ((status = acpi_aml_resolve_to_value(stack_ptr)) != AE_OK) {
+ status = acpi_aml_resolve_to_value (stack_ptr, walk_state);


+ if (ACPI_FAILURE (status)) {
X goto cleanup;
X }
X

@@ -267,7 +273,8 @@
X
X /* Need an operand of type ACPI_TYPE_EVENT */
X
- if ((status = acpi_aml_resolve_to_value(stack_ptr)) != AE_OK) {
+ status = acpi_aml_resolve_to_value (stack_ptr, walk_state);


+ if (ACPI_FAILURE (status)) {
X goto cleanup;
X }
X

@@ -282,7 +289,8 @@
X
X /* Need an operand of type ACPI_TYPE_REGION */
X
- if ((status = acpi_aml_resolve_to_value(stack_ptr)) != AE_OK) {
+ status = acpi_aml_resolve_to_value (stack_ptr, walk_state);


+ if (ACPI_FAILURE (status)) {
X goto cleanup;
X }
X

@@ -308,7 +316,8 @@
X
X /* Need an operand of type ACPI_TYPE_PACKAGE */
X
- if ((status = acpi_aml_resolve_to_value (stack_ptr)) != AE_OK) {
+ status = acpi_aml_resolve_to_value (stack_ptr, walk_state);


+ if (ACPI_FAILURE (status)) {
X goto cleanup;
X }
X

@@ -337,7 +346,8 @@
X
X /* All others must be resolved */
X
- if ((status = acpi_aml_resolve_to_value (stack_ptr)) != AE_OK) {
+ status = acpi_aml_resolve_to_value (stack_ptr, walk_state);


+ if (ACPI_FAILURE (status)) {
X goto cleanup;
X }
X

@@ -352,15 +362,16 @@
X *
X * The ACPI specification allows Size_of to return the size of
X * a Buffer, String or Package. However, the MS ACPI.SYS AML
- * Interpreter also allows an NTE reference to return without
+ * Interpreter also allows an Node reference to return without
X * error with a size of 4.
X */
X
- if ((status = acpi_aml_resolve_to_value (stack_ptr)) != AE_OK) {
+ status = acpi_aml_resolve_to_value (stack_ptr, walk_state);


+ if (ACPI_FAILURE (status)) {
X goto cleanup;
X }
X

- /* Need a buffer, string, package or NTE reference */
+ /* Need a buffer, string, package or Node reference */
X
X if (((*stack_ptr)->common.type != ACPI_TYPE_BUFFER) &&
X ((*stack_ptr)->common.type != ACPI_TYPE_STRING) &&
@@ -372,10 +383,10 @@
X }
X
X /*
- * If this is a reference, only allow a reference to an NTE.
+ * If this is a reference, only allow a reference to an Node.
X */
X if ((*stack_ptr)->common.type == INTERNAL_TYPE_REFERENCE) {
- if (!(*stack_ptr)->reference.nte) {
+ if (!(*stack_ptr)->reference.node) {
X status = AE_AML_OPERAND_TYPE;
X goto cleanup;
X }
@@ -386,7 +397,8 @@
X
X case ARGI_COMPLEXOBJ:
X
- if ((status = acpi_aml_resolve_to_value (stack_ptr)) != AE_OK) {
+ status = acpi_aml_resolve_to_value (stack_ptr, walk_state);


+ if (ACPI_FAILURE (status)) {
X goto cleanup;
X }
X

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/interpreter/amstore.c linux/drivers/acpi/interpreter/amstore.c
--- v2.4.0-test8/linux/drivers/acpi/interpreter/amstore.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/interpreter/amstore.c Fri Sep 15 14:30:30 2000


@@ -2,6 +2,7 @@
X /******************************************************************************
X *

X * Module Name: amstore - AML Interpreter object store support
+ * $Revision: 116 $


X *
X *****************************************************************************/
X

@@ -25,16 +26,16 @@


X
X
X #include "acpi.h"
-#include "parser.h"
-#include "dispatch.h"
-#include "interp.h"
+#include "acparser.h"
+#include "acdispat.h"
+#include "acinterp.h"
X #include "amlcode.h"
-#include "namesp.h"

-#include "tables.h"
+#include "acnamesp.h"
+#include "actables.h"


X
X
X #define _COMPONENT INTERPRETER

- MODULE_NAME ("amstore");
+ MODULE_NAME ("amstore")
X
X
X /*******************************************************************************
@@ -43,7 +44,7 @@
X *
X * PARAMETERS: *Val_desc - Value to be stored
X * *Dest_desc - Where to store it 0 Must be (ACPI_HANDLE)
- * or an ACPI_OBJECT_INTERNAL of type
+ * or an ACPI_OPERAND_OBJECT of type
X * Reference; if the latter the descriptor
X * will be either reused or deleted.
X *
@@ -58,13 +59,14 @@
X
X ACPI_STATUS
X acpi_aml_exec_store (


- ACPI_OBJECT_INTERNAL *val_desc,
- ACPI_OBJECT_INTERNAL *dest_desc)

+ ACPI_OPERAND_OBJECT *val_desc,
+ ACPI_OPERAND_OBJECT *dest_desc,

+ ACPI_WALK_STATE *walk_state)
X {
X ACPI_STATUS status = AE_OK;

- ACPI_OBJECT_INTERNAL *delete_dest_desc = NULL;
- ACPI_OBJECT_INTERNAL *tmp_desc;


- ACPI_NAMED_OBJECT *entry = NULL;

+ ACPI_OPERAND_OBJECT *delete_dest_desc = NULL;
+ ACPI_OPERAND_OBJECT *tmp_desc;


+ ACPI_NAMESPACE_NODE *node = NULL;

X u8 value = 0;
X u32 length;
X u32 i;
@@ -81,7 +83,7 @@
X if (VALID_DESCRIPTOR_TYPE (dest_desc, ACPI_DESC_TYPE_NAMED)) {
X /* Dest is an ACPI_HANDLE, create a new object */
X
- entry = (ACPI_NAMED_OBJECT*) dest_desc;
+ node = (ACPI_NAMESPACE_NODE *) dest_desc;
X dest_desc = acpi_cm_create_internal_object (INTERNAL_TYPE_REFERENCE);
X if (!dest_desc) {
X /* Allocation failure */
@@ -92,7 +94,7 @@
X /* Build a new Reference wrapper around the handle */
X
X dest_desc->reference.op_code = AML_NAME_OP;
- dest_desc->reference.object = entry;
+ dest_desc->reference.object = node;
X }
X
X
@@ -115,7 +117,8 @@
X * Storing into a Name
X */
X delete_dest_desc = dest_desc;
- status = acpi_aml_store_object_to_nte (val_desc, dest_desc->reference.object);
+ status = acpi_aml_store_object_to_node (val_desc, dest_desc->reference.object,
+ walk_state);
X
X break; /* Case Name_op */
X
@@ -182,7 +185,7 @@
X */
X if (ACPI_TYPE_PACKAGE == tmp_desc->common.type) {
X status = acpi_aml_build_copy_internal_package_object (
- val_desc, tmp_desc);
+ val_desc, tmp_desc, walk_state);
X if (ACPI_FAILURE (status)) {
X acpi_cm_remove_reference (tmp_desc);
X tmp_desc = NULL;
@@ -206,7 +209,8 @@
X * convert the contents of the source (Val_desc) and copy into
X * the destination (Tmp_desc)
X */
- status = acpi_aml_store_object_to_object(val_desc, tmp_desc);
+ status = acpi_aml_store_object_to_object (val_desc, tmp_desc,
+ walk_state);
X if (ACPI_FAILURE (status)) {
X /*
X * An error occurrered when copying the internal object
@@ -299,7 +303,7 @@
X /*
X * If we had an error, break out of this case statement.
X */
- if(AE_OK != status) {
+ if (ACPI_FAILURE (status)) {
X break;
X }
X
@@ -315,7 +319,7 @@
X case AML_ONES_OP:
X
X /*
- * Storing to a constant is a no-op -- see spec sec 15.2.3.3.1.
+ * Storing to a constant is a no-op -- see ACPI Specification
X * Delete the result descriptor.
X */
X
@@ -326,7 +330,7 @@
X case AML_LOCAL_OP:
X
X status = acpi_ds_method_data_set_value (MTH_TYPE_LOCAL,
- (dest_desc->reference.offset), val_desc);
+ (dest_desc->reference.offset), val_desc, walk_state);
X delete_dest_desc = dest_desc;
X break;
X
@@ -334,7 +338,7 @@
X case AML_ARG_OP:
X
X status = acpi_ds_method_data_set_value (MTH_TYPE_ARG,
- (dest_desc->reference.offset), val_desc);
+ (dest_desc->reference.offset), val_desc, walk_state);
X delete_dest_desc = dest_desc;
X break;
X
@@ -343,7 +347,7 @@
X
X /*
X * Storing to the Debug object causes the value stored to be
- * displayed and otherwise has no effect -- see sec. 15.2.3.3.3.
+ * displayed and otherwise has no effect -- see ACPI Specification
X */
X
X delete_dest_desc = dest_desc;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/interpreter/amstoren.c linux/drivers/acpi/interpreter/amstoren.c
--- v2.4.0-test8/linux/drivers/acpi/interpreter/amstoren.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/interpreter/amstoren.c Fri Sep 15 14:30:30 2000
@@ -1,7 +1,9 @@
X
X /******************************************************************************
X *
- * Module Name: amstoren - AML Interpreter object store support, store to NTE
+ * Module Name: amstoren - AML Interpreter object store support,
+ * Store to Node (namespace object)
+ * $Revision: 21 $


X *
X *****************************************************************************/
X

@@ -25,24 +27,24 @@


X
X
X #include "acpi.h"
-#include "parser.h"
-#include "dispatch.h"
-#include "interp.h"
+#include "acparser.h"
+#include "acdispat.h"
+#include "acinterp.h"
X #include "amlcode.h"
-#include "namesp.h"

-#include "tables.h"
+#include "acnamesp.h"
+#include "actables.h"


X
X
X #define _COMPONENT INTERPRETER

- MODULE_NAME ("amstoren");
+ MODULE_NAME ("amstoren")
X
X
X /*******************************************************************************
X *
- * FUNCTION: Acpi_aml_store_object_to_nte
+ * FUNCTION: Acpi_aml_store_object_to_node
X *
X * PARAMETERS: *Val_desc - Value to be stored
- * *Entry - Named object to recieve the value
+ * *Node - Named object to recieve the value


X *
X * RETURN: Status
X *

@@ -65,9 +67,10 @@


X ******************************************************************************/
X
X ACPI_STATUS

-acpi_aml_store_object_to_nte (
- ACPI_OBJECT_INTERNAL *val_desc,
- ACPI_NAMED_OBJECT *entry)

+acpi_aml_store_object_to_node (
+ ACPI_OPERAND_OBJECT *val_desc,
+ ACPI_NAMESPACE_NODE *node,

+ ACPI_WALK_STATE *walk_state)
X {
X ACPI_STATUS status = AE_OK;

X u8 *buffer = NULL;
@@ -76,16 +79,16 @@
X u32 new_value;


X u8 locked = FALSE;

X u8 *location=NULL;
- ACPI_OBJECT_INTERNAL *dest_desc;
+ ACPI_OPERAND_OBJECT *dest_desc;
X OBJECT_TYPE_INTERNAL destination_type = ACPI_TYPE_ANY;
X
X
X /*
X * Assuming the parameters are valid!!!
X */
- ACPI_ASSERT((entry) && (val_desc));
+ ACPI_ASSERT((node) && (val_desc));
X
- destination_type = acpi_ns_get_type (entry);
+ destination_type = acpi_ns_get_type (node);
X
X /*
X * First ensure we have a value that can be stored in the target
@@ -120,8 +123,8 @@
X /*
X * Initially not a number, convert
X */
- status = acpi_aml_resolve_to_value (&val_desc);
- if ((status == AE_OK) &&
+ status = acpi_aml_resolve_to_value (&val_desc, walk_state);
+ if (ACPI_SUCCESS (status) &&
X (val_desc->common.type != ACPI_TYPE_NUMBER))
X {
X /*
@@ -151,8 +154,8 @@
X /*
X * Initially not a valid type, convert
X */
- status = acpi_aml_resolve_to_value (&val_desc);
- if ((status == AE_OK) &&
+ status = acpi_aml_resolve_to_value (&val_desc, walk_state);
+ if (ACPI_SUCCESS (status) &&
X (val_desc->common.type != ACPI_TYPE_NUMBER) &&
X (val_desc->common.type != ACPI_TYPE_BUFFER) &&
X (val_desc->common.type != ACPI_TYPE_STRING))
@@ -184,7 +187,7 @@
X * Val_desc reference count is incremented by Attach_object.
X */
X
- status = acpi_ns_attach_object (entry, val_desc, val_desc->common.type);
+ status = acpi_ns_attach_object (node, val_desc, val_desc->common.type);
X
X goto clean_up_and_bail_out;
X break;


@@ -192,24 +195,24 @@
X

X /* Exit now if failure above */


X
- if (status != AE_OK) {
+ if (ACPI_FAILURE (status)) {

X goto clean_up_and_bail_out;
X }
X
X /*
- * Get descriptor for object attached to NTE
+ * Get descriptor for object attached to Node
X */
- dest_desc = acpi_ns_get_attached_object (entry);
+ dest_desc = acpi_ns_get_attached_object (node);
X if (!dest_desc) {
X /*
- * There is no existing object attached to this NTE


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 031'
echo 'File patch-2.4.0-test9 is continued in part 032'
echo "032" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part032

#!/bin/sh -x
# this is part 032 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 032; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ * There is no existing object attached to this Node
X */
X status = AE_AML_INTERNAL;


X goto clean_up_and_bail_out;
X }
X
X /*

- * Make sure the destination Object is the same as the NTE
+ * Make sure the destination Object is the same as the Node
X */
X if (dest_desc->common.type != (u8) destination_type) {
X status = AE_AML_INTERNAL;
@@ -237,15 +240,17 @@
X * Perform the update (Set Bank Select)
X */
X
- status = acpi_aml_set_named_field_value (dest_desc->bank_field.bank_select,
- &dest_desc->bank_field.value,
- sizeof (dest_desc->bank_field.value));


- if (status == AE_OK) {

+ status = acpi_aml_access_named_field (ACPI_WRITE,

+ dest_desc->bank_field.bank_select,
+ &dest_desc->bank_field.value,
+ sizeof (dest_desc->bank_field.value));
+ if (ACPI_SUCCESS (status)) {
X /* Set bank select successful, set data value */
X
- status = acpi_aml_set_named_field_value (dest_desc->bank_field.bank_select,


- &val_desc->bank_field.value,
- sizeof (val_desc->bank_field.value));

+ status = acpi_aml_access_named_field (ACPI_WRITE,

+ dest_desc->bank_field.bank_select,


+ &val_desc->bank_field.value,
+ sizeof (val_desc->bank_field.value));
X }

X
X break;
@@ -280,7 +285,9 @@
X break;
X }
X
- status = acpi_aml_set_named_field_value (entry, buffer, length);


+ status = acpi_aml_access_named_field (ACPI_WRITE,

+ node, buffer, length);
+
X break; /* Global Lock released below */
X
X
@@ -405,16 +412,18 @@
X * perform the update (Set index)
X */
X
- status = acpi_aml_set_named_field_value (dest_desc->index_field.index,
- &dest_desc->index_field.value,
- sizeof (dest_desc->index_field.value));


+ status = acpi_aml_access_named_field (ACPI_WRITE,

+ dest_desc->index_field.index,
+ &dest_desc->index_field.value,
+ sizeof (dest_desc->index_field.value));
X

- if (AE_OK == status) {

+ if (ACPI_SUCCESS (status)) {
X /* set index successful, next set Data value */
X
- status = acpi_aml_set_named_field_value (dest_desc->index_field.data,
- &val_desc->number.value,
- sizeof (val_desc->number.value));


+ status = acpi_aml_access_named_field (ACPI_WRITE,

+ dest_desc->index_field.data,
+ &val_desc->number.value,
+ sizeof (val_desc->number.value));
X }
X break;
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/interpreter/amstorob.c linux/drivers/acpi/interpreter/amstorob.c
--- v2.4.0-test8/linux/drivers/acpi/interpreter/amstorob.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/interpreter/amstorob.c Fri Sep 15 14:30:30 2000


@@ -2,6 +2,7 @@
X /******************************************************************************
X *

X * Module Name: amstorob - AML Interpreter object store support, store to object
+ * $Revision: 16 $


X *
X *****************************************************************************/
X
@@ -25,16 +26,16 @@
X
X
X #include "acpi.h"
-#include "parser.h"
-#include "dispatch.h"
-#include "interp.h"
+#include "acparser.h"
+#include "acdispat.h"
+#include "acinterp.h"
X #include "amlcode.h"
-#include "namesp.h"
-#include "tables.h"
+#include "acnamesp.h"
+#include "actables.h"
X
X
X #define _COMPONENT INTERPRETER

- MODULE_NAME ("amstorob");
+ MODULE_NAME ("amstorob")
X
X
X /*******************************************************************************
@@ -65,8 +66,9 @@
X
X ACPI_STATUS
X acpi_aml_store_object_to_object (


- ACPI_OBJECT_INTERNAL *val_desc,
- ACPI_OBJECT_INTERNAL *dest_desc)
+ ACPI_OPERAND_OBJECT *val_desc,
+ ACPI_OPERAND_OBJECT *dest_desc,
+ ACPI_WALK_STATE *walk_state)
X {
X ACPI_STATUS status = AE_OK;

X u8 *buffer = NULL;

@@ -99,8 +101,8 @@


X /*
X * Initially not a number, convert
X */
- status = acpi_aml_resolve_to_value (&val_desc);
- if ((status == AE_OK) &&
+ status = acpi_aml_resolve_to_value (&val_desc, walk_state);
+ if (ACPI_SUCCESS (status) &&
X (val_desc->common.type != ACPI_TYPE_NUMBER))
X {
X /*

@@ -129,8 +131,8 @@


X /*
X * Initially not a valid type, convert
X */
- status = acpi_aml_resolve_to_value (&val_desc);
- if ((status == AE_OK) &&
+ status = acpi_aml_resolve_to_value (&val_desc, walk_state);
+ if (ACPI_SUCCESS (status) &&
X (val_desc->common.type != ACPI_TYPE_NUMBER) &&
X (val_desc->common.type != ACPI_TYPE_BUFFER) &&
X (val_desc->common.type != ACPI_TYPE_STRING))

@@ -155,7 +157,7 @@
X

X /* Exit now if failure above */
X
- if (status != AE_OK) {
+ if (ACPI_FAILURE (status)) {
X goto clean_up_and_bail_out;
X }
X

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/interpreter/amsystem.c linux/drivers/acpi/interpreter/amsystem.c
--- v2.4.0-test8/linux/drivers/acpi/interpreter/amsystem.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/interpreter/amsystem.c Fri Sep 15 14:30:30 2000


@@ -2,6 +2,7 @@
X /******************************************************************************
X *

X * Module Name: amsystem - Interface to OS services
+ * $Revision: 51 $


X *
X *****************************************************************************/
X

@@ -25,13 +26,13 @@


X
X
X #include "acpi.h"
-#include "interp.h"

-#include "namesp.h"
-#include "hardware.h"
-#include "events.h"

+#include "acinterp.h"


+#include "acnamesp.h"
+#include "achware.h"
+#include "acevents.h"
X

X #define _COMPONENT INTERPRETER
- MODULE_NAME ("amsystem");
+ MODULE_NAME ("amsystem")
X
X
X /*******************************************************************************
@@ -181,8 +182,8 @@
X
X ACPI_STATUS
X acpi_aml_system_acquire_mutex (
- ACPI_OBJECT_INTERNAL *time_desc,
- ACPI_OBJECT_INTERNAL *obj_desc)
+ ACPI_OPERAND_OBJECT *time_desc,
+ ACPI_OPERAND_OBJECT *obj_desc)


X {
X ACPI_STATUS status = AE_OK;
X

@@ -223,7 +224,7 @@
X
X ACPI_STATUS
X acpi_aml_system_release_mutex (
- ACPI_OBJECT_INTERNAL *obj_desc)
+ ACPI_OPERAND_OBJECT *obj_desc)


X {
X ACPI_STATUS status = AE_OK;
X

@@ -260,7 +261,7 @@
X
X ACPI_STATUS
X acpi_aml_system_signal_event (
- ACPI_OBJECT_INTERNAL *obj_desc)
+ ACPI_OPERAND_OBJECT *obj_desc)


X {
X ACPI_STATUS status = AE_OK;
X

@@ -290,8 +291,8 @@
X
X ACPI_STATUS
X acpi_aml_system_wait_event (
- ACPI_OBJECT_INTERNAL *time_desc,
- ACPI_OBJECT_INTERNAL *obj_desc)
+ ACPI_OPERAND_OBJECT *time_desc,
+ ACPI_OPERAND_OBJECT *obj_desc)


X {
X ACPI_STATUS status = AE_OK;
X

@@ -321,7 +322,7 @@
X
X ACPI_STATUS
X acpi_aml_system_reset_event (
- ACPI_OBJECT_INTERNAL *obj_desc)
+ ACPI_OPERAND_OBJECT *obj_desc)


X {
X ACPI_STATUS status = AE_OK;

X void *temp_semaphore;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/interpreter/amutils.c linux/drivers/acpi/interpreter/amutils.c
--- v2.4.0-test8/linux/drivers/acpi/interpreter/amutils.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/interpreter/amutils.c Fri Sep 15 14:30:30 2000


@@ -2,6 +2,7 @@
X /******************************************************************************
X *

X * Module Name: amutils - interpreter/scanner utilities
+ * $Revision: 53 $


X *
X *****************************************************************************/
X

@@ -25,21 +26,21 @@


X
X
X #include "acpi.h"
-#include "parser.h"

-#include "interp.h"
+#include "acparser.h"


+#include "acinterp.h"
X #include "amlcode.h"
-#include "namesp.h"

-#include "events.h"
+#include "acnamesp.h"
+#include "acevents.h"


X
X #define _COMPONENT INTERPRETER

- MODULE_NAME ("amutils");
+ MODULE_NAME ("amutils")
X
X
X typedef struct internal_search_st
X {
- ACPI_OBJECT_INTERNAL *dest_obj;
+ ACPI_OPERAND_OBJECT *dest_obj;
X u32 index;
- ACPI_OBJECT_INTERNAL *source_obj;
+ ACPI_OPERAND_OBJECT *source_obj;
X
X } INTERNAL_PKG_SEARCH_INFO;
X
@@ -49,7 +50,7 @@
X INTERNAL_PKG_SEARCH_INFO copy_level[MAX_PACKAGE_DEPTH];
X
X
-static char hex[] =
+static NATIVE_CHAR hex[] =
X {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
X
X
@@ -121,41 +122,10 @@
X if ((type > ACPI_TYPE_MAX && type < INTERNAL_TYPE_BEGIN) ||


X (type > INTERNAL_TYPE_MAX))
X {
- return FALSE;

+ return (FALSE);
X }
X

- return TRUE;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_aml_append_operand_diag
- *
- * PARAMETERS: *File_name - Name of source file
- * Line_num - Line Number in file
- * Op_code - Op_code being executed
- * Num_operands - Number of operands Prep_stack tried to check
- *
- * DESCRIPTION: Print diagnostic information about operands.
- * This function is intended to be called after Prep_stack
- * has returned S_ERROR.


- *
- ******************************************************************************/
-

-void
-acpi_aml_append_operand_diag (
- char *file_name,
- s32 line_num,


- u16 op_code,
- ACPI_OBJECT_INTERNAL **operands,

- s32 num_operands)
-{
-
- /*
- * This function outputs debug information only
- */
-


+ return (TRUE);
X }
X
X

@@ -178,7 +148,7 @@
X acpi_aml_buf_seq (void)
X {
X
- return ++acpi_gbl_buf_seq;
+ return (++acpi_gbl_buf_seq);
X }
X
X
@@ -270,12 +240,12 @@


X *
X ******************************************************************************/
X

-s32
+u32
X acpi_aml_digits_needed (
- s32 val,
- s32 base)
+ u32 val,
+ u32 base)
X {
- s32 num_digits = 0;
+ u32 num_digits = 0;
X
X
X if (base < 1) {
@@ -309,13 +279,13 @@
X union
X {
X u32 value;
- char bytes[4];
+ u8 bytes[4];
X } out;
X
X union
X {
X u32 value;
- char bytes[4];
+ u8 bytes[4];
X } in;
X
X
@@ -326,7 +296,7 @@
X out.bytes[2] = in.bytes[1];
X out.bytes[3] = in.bytes[0];
X
- return out.value;
+ return (out.value);
X }
X
X
@@ -344,7 +314,7 @@
X ACPI_STATUS
X acpi_aml_eisa_id_to_string (
X u32 numeric_id,
- char *out_string)
+ NATIVE_CHAR *out_string)
X {
X u32 id;
X
@@ -361,7 +331,7 @@
X out_string[6] = hex[id & 0xf];
X out_string[7] = 0;


X
- return AE_OK;
+ return (AE_OK);
X }
X
X

@@ -381,16 +351,17 @@
X
X ACPI_STATUS
X acpi_aml_build_copy_internal_package_object (


- ACPI_OBJECT_INTERNAL *source_obj,
- ACPI_OBJECT_INTERNAL *dest_obj)

+ ACPI_OPERAND_OBJECT *source_obj,
+ ACPI_OPERAND_OBJECT *dest_obj,

+ ACPI_WALK_STATE *walk_state)
X {
X u32 current_depth = 0;


X ACPI_STATUS status = AE_OK;

X u32 length = 0;
X u32 this_index;


X u32 object_space = 0;

- ACPI_OBJECT_INTERNAL *this_dest_obj;
- ACPI_OBJECT_INTERNAL *this_source_obj;
+ ACPI_OPERAND_OBJECT *this_dest_obj;
+ ACPI_OPERAND_OBJECT *this_source_obj;
X INTERNAL_PKG_SEARCH_INFO *level_ptr;
X
X
@@ -429,8 +400,8 @@
X

X while (1) {
X this_index = level_ptr->index;

- this_dest_obj = (ACPI_OBJECT_INTERNAL *) level_ptr->dest_obj->package.elements[this_index];
- this_source_obj = (ACPI_OBJECT_INTERNAL *) level_ptr->source_obj->package.elements[this_index];
+ this_dest_obj = (ACPI_OPERAND_OBJECT *) level_ptr->dest_obj->package.elements[this_index];
+ this_source_obj = (ACPI_OPERAND_OBJECT *) level_ptr->source_obj->package.elements[this_index];
X
X if (IS_THIS_OBJECT_TYPE (this_source_obj, ACPI_TYPE_PACKAGE)) {
X /*
@@ -458,7 +429,7 @@
X * update the buffer length counter
X */
X object_space = this_dest_obj->package.count *
- sizeof (ACPI_OBJECT_INTERNAL);
+ sizeof (ACPI_OPERAND_OBJECT);
X length += object_space;
X current_depth++;
X level_ptr = &copy_level[current_depth];
@@ -474,9 +445,9 @@
X this_source_obj->common.type);
X level_ptr->dest_obj->package.elements[this_index] = this_dest_obj;
X
- status = acpi_aml_store_object_to_object(this_source_obj, this_dest_obj);
+ status = acpi_aml_store_object_to_object(this_source_obj, this_dest_obj, walk_state);


X
- if (status != AE_OK) {
+ if (ACPI_FAILURE (status)) {

X /*
X * Failure get out
X */
@@ -511,12 +482,6 @@


X }
X } /* else object is NOT a package */
X } /* while (1) */
-

-
- /*
- * We'll never get here, but the compiler whines about return value


- */
- return (AE_OK);
X }

X
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/interpreter/amxface.c linux/drivers/acpi/interpreter/amxface.c
--- v2.4.0-test8/linux/drivers/acpi/interpreter/amxface.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/interpreter/amxface.c Fri Sep 15 14:30:30 2000
@@ -1,7 +1,8 @@


X
X /******************************************************************************
X *

- * Module Name: ixface - External interpreter interfaces
+ * Module Name: amxface - External interpreter interfaces
+ * $Revision: 22 $


X *
X *****************************************************************************/
X

@@ -25,11 +26,11 @@


X
X
X #include "acpi.h"
-#include "interp.h"
+#include "acinterp.h"
X

X
X #define _COMPONENT INTERPRETER

- MODULE_NAME ("amxface");
+ MODULE_NAME ("amxface")
X
X
X /*
@@ -48,8 +49,8 @@
X
X #define DEFINE_AML_GLOBALS


X #include "amlcode.h"
-#include "parser.h"

-#include "namesp.h"
+#include "acparser.h"
+#include "acnamesp.h"
X
X
X /*******************************************************************************
@@ -70,9 +71,9 @@
X
X ACPI_STATUS
X acpi_aml_execute_method (
- ACPI_NAMED_OBJECT *method_entry,
- ACPI_OBJECT_INTERNAL **params,
- ACPI_OBJECT_INTERNAL **return_obj_desc)


+ ACPI_NAMESPACE_NODE *method_node,
+ ACPI_OPERAND_OBJECT **params,
+ ACPI_OPERAND_OBJECT **return_obj_desc)

X {
X ACPI_STATUS status;
X

@@ -84,7 +85,7 @@
X
X acpi_aml_enter_interpreter ();
X
- status = acpi_psx_execute (method_entry, params, return_obj_desc);
+ status = acpi_psx_execute (method_node, params, return_obj_desc);
X
X acpi_aml_exit_interpreter ();
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/namespace/Makefile linux/drivers/acpi/namespace/Makefile
--- v2.4.0-test8/linux/drivers/acpi/namespace/Makefile Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/namespace/Makefile Fri Sep 15 18:21:44 2000

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/namespace/nsaccess.c linux/drivers/acpi/namespace/nsaccess.c
--- v2.4.0-test8/linux/drivers/acpi/namespace/nsaccess.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/namespace/nsaccess.c Fri Sep 15 14:30:30 2000


@@ -1,9 +1,9 @@
-
-/******************************************************************************
+/*******************************************************************************

X *
X * Module Name: nsaccess - Top-level functions for accessing ACPI namespace
+ * $Revision: 108 $


X *
- *****************************************************************************/
+ ******************************************************************************/

X
X /*
X * Copyright (C) 2000 R. Byron Moore
@@ -26,59 +26,16 @@


X
X #include "acpi.h"
X #include "amlcode.h"

-#include "interp.h"
-#include "namesp.h"
-#include "dispatch.h"
+#include "acinterp.h"
+#include "acnamesp.h"
+#include "acdispat.h"
X
X
X #define _COMPONENT NAMESPACE
- MODULE_NAME ("nsaccess");
+ MODULE_NAME ("nsaccess")
X
X
-/****************************************************************************
- *
- * FUNCTION: Acpi_ns_root_create_scope
- *
- * PARAMETERS: Entry - NTE for which a scope will be created
- *
- * RETURN: Status
- *
- * DESCRIPTION: Create a scope table for the given name table entry
- *
- * MUTEX: Expects namespace to be locked
- *
- ***************************************************************************/
-
-ACPI_STATUS
-acpi_ns_root_create_scope (


- ACPI_NAMED_OBJECT *entry)
-{
-

- /* Allocate a scope table */
-
- if (entry->child_table) {
- return (AE_EXIST);
- }
-
- entry->child_table = acpi_ns_allocate_name_table (NS_TABLE_SIZE);
- if (!entry->child_table) {
- /* root name table allocation failure */
-
- REPORT_ERROR ("Root name table allocation failure");


- return (AE_NO_MEMORY);
- }
-

- /*
- * Init the scope first entry -- since it is the exemplar of
- * the scope (Some fields are duplicated to new entries!)
- */
- acpi_ns_initialize_table (entry->child_table, NULL, entry);
- return (AE_OK);
-
-}
-
-
-/****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_ns_root_initialize
X *
@@ -86,40 +43,41 @@


X *
X * RETURN: Status
X *

- * DESCRIPTION: Allocate and initialize the root name table
+ * DESCRIPTION: Allocate and initialize the default root named objects
X *
X * MUTEX: Locks namespace for entire execution
X *
- ***************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS
X acpi_ns_root_initialize (void)


X {
X ACPI_STATUS status = AE_OK;

X PREDEFINED_NAMES *init_val = NULL;
- ACPI_NAMED_OBJECT *new_entry;
- ACPI_OBJECT_INTERNAL *obj_desc;
+ ACPI_NAMESPACE_NODE *new_node;


+ ACPI_OPERAND_OBJECT *obj_desc;
X
X

X acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
X
X /*
- * Root is initially NULL, so a non-NULL value indicates
+ * The global root ptr is initially NULL, so a non-NULL value indicates
X * that Acpi_ns_root_initialize() has already been called; just return.
X */
X
- if (acpi_gbl_root_object->child_table) {
+ if (acpi_gbl_root_node) {
X status = AE_OK;
X goto unlock_and_exit;
X }
X
X
- /* Create the root scope */
+ /*
+ * Tell the rest of the subsystem that the root is initialized
+ * (This is OK because the namespace is locked)
+ */
+
+ acpi_gbl_root_node = &acpi_gbl_root_node_struct;
X
- status = acpi_ns_root_create_scope (acpi_gbl_root_object);
- if (ACPI_FAILURE (status)) {


- goto unlock_and_exit;
- }
X

X /* Enter the pre-defined names in the name table */
X
@@ -127,25 +85,25 @@
X status = acpi_ns_lookup (NULL, init_val->name,
X (OBJECT_TYPE_INTERNAL) init_val->type,
X IMODE_LOAD_PASS2, NS_NO_UPSEARCH,
- NULL, &new_entry);
+ NULL, &new_node);
+
+ if (ACPI_FAILURE (status) ||
+ (!new_node))
X
X /*
- * if name entered successfully
- * && its entry in Pre_defined_names[] specifies an
- * initial value
+ * Name entered successfully.
+ * If entry in Pre_defined_names[] specifies an
+ * initial value, create the initial value.
X */
X
- if ((status == AE_OK) &&
- new_entry && init_val->val)
- {
+ if (init_val->val) {
X /*
X * Entry requests an initial value, allocate a
X * descriptor for it.
X */
X
- obj_desc =
- acpi_cm_create_internal_object (
- (OBJECT_TYPE_INTERNAL) init_val->type);


+ obj_desc = acpi_cm_create_internal_object (

+ (OBJECT_TYPE_INTERNAL) init_val->type);
X

X if (!obj_desc) {
X status = AE_NO_MEMORY;

@@ -164,23 +122,22 @@
X case ACPI_TYPE_NUMBER:
X
X obj_desc->number.value =
- (u32) STRTOUL (init_val->val, NULL, 10);
+ (u32) STRTOUL (init_val->val, NULL, 10);
X break;
X
X
X case ACPI_TYPE_STRING:
X
X obj_desc->string.length =
- (u16) STRLEN (init_val->val);
+ (u16) STRLEN (init_val->val);
X
X /*
X * Allocate a buffer for the string. All
X * String.Pointers must be allocated buffers!
X * (makes deletion simpler)
X */
- obj_desc->string.pointer =
- acpi_cm_allocate ((ACPI_SIZE)
- (obj_desc->string.length + 1));
+ obj_desc->string.pointer = acpi_cm_allocate (
+ (obj_desc->string.length + 1));
X
X if (!obj_desc->string.pointer) {
X REPORT_ERROR ("Initial value string"
@@ -191,24 +148,22 @@


X goto unlock_and_exit;
X }
X

- STRCPY ((char *) obj_desc->string.pointer,
- init_val->val);
+ STRCPY (obj_desc->string.pointer, init_val->val);
X break;
X
X
X case ACPI_TYPE_MUTEX:
X
X obj_desc->mutex.sync_level =
- (u16) STRTOUL (init_val->val, NULL, 10);
+ (u16) STRTOUL (init_val->val, NULL, 10);
X
X if (STRCMP (init_val->name, "_GL_") == 0) {
X /*
X * Create a counting semaphore for the
X * global lock


X */
- status =

- acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT,
- 1, &obj_desc->mutex.semaphore);
+ status = acpi_os_create_semaphore (ACPI_NO_UNIT_LIMIT,
+ 1, &obj_desc->mutex.semaphore);
X
X if (ACPI_FAILURE (status)) {
X goto unlock_and_exit;
@@ -218,8 +173,7 @@
X * global lock, save it
X */
X
- acpi_gbl_global_lock_semaphore =
- obj_desc->mutex.semaphore;
+ acpi_gbl_global_lock_semaphore = obj_desc->mutex.semaphore;
X }
X
X else {
@@ -232,11 +186,6 @@
X goto unlock_and_exit;
X }
X }
-
- /* TBD: [Restructure] These fields may be obsolete */
-
- obj_desc->mutex.lock_count = 0;
- obj_desc->mutex.thread_id = 0;
X break;
X
X
@@ -247,9 +196,9 @@
X continue;
X }
X
- /* Store pointer to value descriptor in nte */
+ /* Store pointer to value descriptor in the Node */
X
- acpi_ns_attach_object (new_entry, obj_desc,
+ acpi_ns_attach_object (new_node, obj_desc,
X obj_desc->common.type);
X }
X }
@@ -261,16 +210,19 @@


X }
X
X
-/****************************************************************************
+/*******************************************************************************

X *
X * FUNCTION: Acpi_ns_lookup
X *
- * PARAMETERS: Prefix_scope - Search scope if name is not fully qualified
+ * PARAMETERS: Prefix_node - Search scope if name is not fully qualified
X * Pathname - Search pathname, in internal format
X * (as represented in the AML stream)
X * Type - Type associated with name
X * Interpreter_mode - IMODE_LOAD_PASS2 => add name if not found
- * Ret_entry - Where the new entry (NTE) is placed
+ * Flags - Flags describing the search restrictions
+ * Walk_state - Current state of the walk
+ * Return_node - Where the Node is placed (if found
+ * or created successfully)


X *
X * RETURN: Status
X *

@@ -279,55 +231,42 @@
X *
X * MUTEX: Assumes namespace is locked.
X *
- ***************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS
X acpi_ns_lookup (
X ACPI_GENERIC_STATE *scope_info,
- char *pathname,
+ NATIVE_CHAR *pathname,
X OBJECT_TYPE_INTERNAL type,
X OPERATING_MODE interpreter_mode,
X u32 flags,
X ACPI_WALK_STATE *walk_state,
- ACPI_NAMED_OBJECT **ret_entry)
+ ACPI_NAMESPACE_NODE **return_node)
X {
X ACPI_STATUS status;
- ACPI_NAME_TABLE *prefix_scope;
- ACPI_NAME_TABLE *table_to_search = NULL;
- ACPI_NAME_TABLE *scope_to_push = NULL;
- ACPI_NAMED_OBJECT *this_entry = NULL;
+ ACPI_NAMESPACE_NODE *prefix_node;
+ ACPI_NAMESPACE_NODE *current_node = NULL;
+ ACPI_NAMESPACE_NODE *scope_to_push = NULL;
+ ACPI_NAMESPACE_NODE *this_node = NULL;
X u32 num_segments;
X ACPI_NAME simple_name;
X u8 null_name_path = FALSE;
X OBJECT_TYPE_INTERNAL type_to_check_for;
X OBJECT_TYPE_INTERNAL this_search_type;
X
- if (!ret_entry) {
+ if (!return_node) {


X return (AE_BAD_PARAMETER);
X }
X
X

X acpi_gbl_ns_lookup_count++;
X
- *ret_entry = ENTRY_NOT_FOUND;
- if (!acpi_gbl_root_object->child_table) {
- /*
- * If the name space has not been initialized:
- * - In Pass1 of Load mode, we need to initialize it
- * before trying to define a name.
- * - In Exec mode, there are no names to be found.
- */
+ *return_node = ENTRY_NOT_FOUND;
X
- if (IMODE_LOAD_PASS1 == interpreter_mode) {
- if ((status = acpi_ns_root_initialize ()) != AE_OK) {


- return (status);
- }
- }

- else {
- return (AE_NOT_FOUND);
- }
- }
X
+ if (!acpi_gbl_root_node) {
+ return (AE_NO_NAMESPACE);
+ }
X
X /*
X * Get the prefix scope.
@@ -335,12 +274,12 @@
X */
X
X if ((!scope_info) ||
- (!scope_info->scope.name_table))
+ (!scope_info->scope.node))
X {
- prefix_scope = acpi_gbl_root_object->child_table;
+ prefix_node = acpi_gbl_root_node;
X }
X else {
- prefix_scope = scope_info->scope.name_table;
+ prefix_node = scope_info->scope.node;
X }
X
X
@@ -369,6 +308,8 @@
X }
X
X
+ /* TBD: [Restructure] - Move the pathname stuff into a new procedure */
+
X /* Examine the name pointer */
X
X if (!pathname) {
@@ -376,7 +317,7 @@
X
X null_name_path = TRUE;
X num_segments = 0;
- this_entry = acpi_gbl_root_object;
+ this_node = acpi_gbl_root_node;
X
X }
X
@@ -403,14 +344,16 @@
X if (*pathname == AML_ROOT_PREFIX) {
X /* Pathname is fully qualified, look in root name table */
X
- table_to_search = acpi_gbl_root_object->child_table;
+ current_node = acpi_gbl_root_node;
+
X /* point to segment part */
+
X pathname++;
X
X /* Direct reference to root, "\" */
X
X if (!(*pathname)) {
- this_entry = acpi_gbl_root_object;
+ this_node = acpi_gbl_root_node;
X goto check_for_new_scope_and_exit;
X }
X }
@@ -418,7 +361,7 @@
X else {
X /* Pathname is relative to current scope, start there */
X
- table_to_search = prefix_scope;
+ current_node = prefix_node;
X
X /*
X * Handle up-prefix (carat). More than one prefix
@@ -426,23 +369,22 @@
X */
X
X while (*pathname == AML_PARENT_PREFIX) {
-
X /* Point to segment part or next Parent_prefix */
X
X pathname++;
X
X /* Backup to the parent's scope */
X
- table_to_search = table_to_search->parent_table;
- if (!table_to_search) {
+ this_node = acpi_ns_get_parent_object (current_node);
+ if (!this_node) {
X /* Current scope has no parent scope */
X
- REPORT_ERROR ("Ns_lookup: Too many parent"
- "prefixes or scope has no parent");
-
+ REPORT_ERROR ("Too many parent prefixes (^) - reached root");
X
X return (AE_NOT_FOUND);
X }
+
+ current_node = this_node;
X }
X }
X
@@ -454,14 +396,18 @@
X
X if (*pathname == AML_DUAL_NAME_PREFIX) {
X num_segments = 2;
+
X /* point to first segment */
+
X pathname++;
X
X }
X
X else if (*pathname == AML_MULTI_NAME_PREFIX_OP) {
- num_segments = (s32)* (u8 *) ++pathname;
+ num_segments = (u32)* (u8 *) ++pathname;
+
X /* point to first segment */
+
X pathname++;
X
X }
@@ -484,32 +430,32 @@
X */
X
X
- while (num_segments-- && table_to_search) {
+ while (num_segments-- && current_node) {
X /*
- * Search for the current segment in the table where
- * it should be.
- * Type is significant only at the last (topmost) level.
+ * Search for the current name segment under the current
+ * named object. The Type is significant only at the last (topmost)
+ * level. (We don't care about the types along the path, only
+ * the type of the final target object.)
X */
X this_search_type = ACPI_TYPE_ANY;
X if (!num_segments) {
X this_search_type = type;
X }
X
+ /* Pluck and ACPI name from the front of the pathname */
+
X MOVE_UNALIGNED32_TO_32 (&simple_name, pathname);
+
+ /* Try to find the ACPI name */
+
X status = acpi_ns_search_and_enter (simple_name, walk_state,
- table_to_search, interpreter_mode,
+ current_node, interpreter_mode,
X this_search_type, flags,
- &this_entry);
+ &this_node);


X
- if (status != AE_OK) {
+ if (ACPI_FAILURE (status)) {

X if (status == AE_NOT_FOUND) {
- /* Name not in ACPI namespace */
-
- if (IMODE_LOAD_PASS1 == interpreter_mode ||
- IMODE_LOAD_PASS2 == interpreter_mode)
- {
- REPORT_ERROR ("Name table overflow");
- }
+ /* Name not found in ACPI namespace */
X
X }
X
@@ -518,92 +464,54 @@
X
X
X /*
- * If 1) last segment (Num_segments == 0)
+ * If 1) This is the last segment (Num_segments == 0)
X * 2) and looking for a specific type
X * (Not checking for TYPE_ANY)
X * 3) which is not a local type (TYPE_DEF_ANY)
X * 4) which is not a local type (TYPE_SCOPE)
X * 5) which is not a local type (TYPE_INDEX_FIELD_DEFN)
- * 6) and type of entry is known (not TYPE_ANY)
- * 7) and entry does not match request
+ * 6) and type of object is known (not TYPE_ANY)
+ * 7) and object does not match request
X *
X * Then we have a type mismatch. Just warn and ignore it.
X */
- if ((num_segments == 0) &&
- (type_to_check_for != ACPI_TYPE_ANY) &&
- (type_to_check_for != INTERNAL_TYPE_DEF_ANY) &&
- (type_to_check_for != INTERNAL_TYPE_SCOPE) &&
- (type_to_check_for != INTERNAL_TYPE_INDEX_FIELD_DEFN) &&
- (this_entry->type != ACPI_TYPE_ANY) &&
- (this_entry->type != type_to_check_for))
+ if ((num_segments == 0) &&
+ (type_to_check_for != ACPI_TYPE_ANY) &&
+ (type_to_check_for != INTERNAL_TYPE_DEF_ANY) &&
+ (type_to_check_for != INTERNAL_TYPE_SCOPE) &&
+ (type_to_check_for != INTERNAL_TYPE_INDEX_FIELD_DEFN) &&
+ (this_node->type != ACPI_TYPE_ANY) &&
+ (this_node->type != type_to_check_for))
X {
- /* Complain about type mismatch */
+ /* Complain about a type mismatch */
X
X REPORT_WARNING ("Type mismatch");
X }
X
X /*
- * If last segment and not looking for a specific type, but type of
- * found entry is known, use that type to see if it opens a scope.
+ * If this is the last name segment and we are not looking for a
+ * specific type, but the type of found object is known, use that type
+ * to see if it opens a scope.
X */
X
X if ((0 == num_segments) && (ACPI_TYPE_ANY == type)) {
- type = this_entry->type;
+ type = this_node->type;
X }
X
X if ((num_segments || acpi_ns_opens_scope (type)) &&
- (this_entry->child_table == NULL))
+ (this_node->child == NULL))
X {
X /*
X * More segments or the type implies enclosed scope,
X * and the next scope has not been allocated.
X */
X
- if ((IMODE_LOAD_PASS1 == interpreter_mode) ||
- (IMODE_LOAD_PASS2 == interpreter_mode))
- {
- /*
- * First or second pass load mode
- * ==> locate the next scope
- */
-
- this_entry->child_table =
- acpi_ns_allocate_name_table (NS_TABLE_SIZE);
-
- if (!this_entry->child_table) {


- return (AE_NO_MEMORY);
- }
- }

-
- /* Now complain if there is no next scope */
-
- if (this_entry->child_table == NULL) {
- if (IMODE_LOAD_PASS1 == interpreter_mode ||
- IMODE_LOAD_PASS2 == interpreter_mode)
- {
- REPORT_ERROR ("Name Table allocation failure");
- return (AE_NOT_FOUND);
- }
-
- return (AE_NOT_FOUND);
- }
-
-
- /* Scope table initialization */
-
- if (IMODE_LOAD_PASS1 == interpreter_mode ||
- IMODE_LOAD_PASS2 == interpreter_mode)
- {
- /* Initialize the new table */
-
- acpi_ns_initialize_table (this_entry->child_table,
- table_to_search,
- this_entry);
- }
X }
X
- table_to_search = this_entry->child_table;
+ current_node = this_node;
+
X /* point to next name segment */
+
X pathname += ACPI_NAME_SIZE;
X }
X
@@ -629,7 +537,7 @@
X scope_to_push = NULL;
X }
X else {
- scope_to_push = this_entry->child_table;
+ scope_to_push = this_node;
X }
X
X status = acpi_ds_scope_stack_push (scope_to_push, type,
@@ -641,7 +549,7 @@
X }
X }
X
- *ret_entry = this_entry;
+ *return_node = this_node;
X return (AE_OK);
X }
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/namespace/nsalloc.c linux/drivers/acpi/namespace/nsalloc.c
--- v2.4.0-test8/linux/drivers/acpi/namespace/nsalloc.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/namespace/nsalloc.c Fri Sep 15 14:30:30 2000


@@ -1,9 +1,9 @@
-
-/******************************************************************************
+/*******************************************************************************

X *
X * Module Name: nsalloc - Namespace allocation and deletion utilities


+ * $Revision: 41 $

X *
- *****************************************************************************/
+ ******************************************************************************/

X
X /*
X * Copyright (C) 2000 R. Byron Moore
@@ -25,46 +25,303 @@


X
X
X #include "acpi.h"

-#include "namesp.h"
-#include "interp.h"
+#include "acnamesp.h"
+#include "acinterp.h"

X
X
X #define _COMPONENT NAMESPACE
- MODULE_NAME ("nsalloc");
+ MODULE_NAME ("nsalloc")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_ns_create_node


+ *
+ * PARAMETERS:

+ *
+ * RETURN: None
+ *
+ * DESCRIPTION:
+ *
+ ******************************************************************************/


+
+ACPI_NAMESPACE_NODE *
+acpi_ns_create_node (
+ u32 acpi_name)

+{


+ ACPI_NAMESPACE_NODE *node;
+
+

+ node = acpi_cm_callocate (sizeof (ACPI_NAMESPACE_NODE));
+ if (!node) {


+ return (NULL);
+ }
+

+ INCREMENT_NAME_TABLE_METRICS (sizeof (ACPI_NAMESPACE_NODE));
+
+ node->data_type = ACPI_DESC_TYPE_NAMED;
+ node->name = acpi_name;
+ node->reference_count = 1;
+
+ return (node);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_ns_delete_node


+ *
+ * PARAMETERS:

+ *
+ * RETURN: None
+ *
+ * DESCRIPTION:


+ *
+ ******************************************************************************/
+
+void

+acpi_ns_delete_node (
+ ACPI_NAMESPACE_NODE *node)
+{
+ ACPI_NAMESPACE_NODE *parent_node;
+ ACPI_NAMESPACE_NODE *prev_node;
+ ACPI_NAMESPACE_NODE *next_node;
+
+
+ parent_node = acpi_ns_get_parent_object (node);
+
+ prev_node = NULL;
+ next_node = parent_node->child;
+
+ while (next_node != node) {
+ prev_node = next_node;
+ next_node = prev_node->peer;
+ }
+
+ if (prev_node) {
+ prev_node->peer = next_node->peer;
+ if (next_node->flags & ANOBJ_END_OF_PEER_LIST) {
+ prev_node->flags |= ANOBJ_END_OF_PEER_LIST;
+ }
+ }
+ else {
+ parent_node->child = next_node->peer;
+ }
+
+
+ DECREMENT_NAME_TABLE_METRICS (sizeof (ACPI_NAMESPACE_NODE));
+
+ /*
+ * Detach an object if there is one
+ */
+
+ if (node->object) {
+ acpi_ns_detach_object (node);
+ }
+
+ acpi_cm_free (node);
+
+


+ return;
+}
+
+

+/*******************************************************************************
+ *
+ * FUNCTION: Acpi_ns_install_node
+ *
+ * PARAMETERS: Walk_state - Current state of the walk
+ * Parent_node - The parent of the new Node
+ * Node - The new Node to install
+ * Type - ACPI object type of the new Node
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Initialize a new entry within a namespace table.
+ *
+ ******************************************************************************/


+
+void
+acpi_ns_install_node (
+ ACPI_WALK_STATE *walk_state,
+ ACPI_NAMESPACE_NODE *parent_node, /* Parent */
+ ACPI_NAMESPACE_NODE *node, /* New Child*/
+ OBJECT_TYPE_INTERNAL type)
+{

+ u16 owner_id = TABLE_ID_DSDT;
+ ACPI_NAMESPACE_NODE *child_node;
+
+
+ /*
+ * Get the owner ID from the Walk state
+ * The owner ID is used to track table deletion and
+ * deletion of objects created by methods
+ */
+ if (walk_state) {
+ owner_id = walk_state->owner_id;
+ }
+
+
+ /* link the new entry into the parent and existing children */
+
+ /* TBD: Could be first, last, or alphabetic */
+
+ child_node = parent_node->child;
+ if (!child_node) {
+ parent_node->child = node;
+ }
+
+ else {
+ while (!(child_node->flags & ANOBJ_END_OF_PEER_LIST)) {
+ child_node = child_node->peer;
+ }
+
+ child_node->peer = node;
+
+ /* Clear end-of-list flag */
+
+ child_node->flags &= ~ANOBJ_END_OF_PEER_LIST;
+ }
+
+ /* Init the new entry */
+
+ node->owner_id = owner_id;
+ node->flags |= ANOBJ_END_OF_PEER_LIST;
+ node->peer = parent_node;
+
+
+ /*
+ * If adding a name with unknown type, or having to
+ * add the region in order to define fields in it, we
+ * have a forward reference.
+ */
+
+ if ((ACPI_TYPE_ANY == type) ||
+ (INTERNAL_TYPE_DEF_FIELD_DEFN == type) ||
+ (INTERNAL_TYPE_BANK_FIELD_DEFN == type))
+ {
+ /*
+ * We don't want to abort here, however!
+ * We will fill in the actual type when the
+ * real definition is found later.
+ */
+
+ }
+
+ /*
+ * The Def_field_defn and Bank_field_defn cases are actually
+ * looking up the Region in which the field will be defined
+ */
+
+ if ((INTERNAL_TYPE_DEF_FIELD_DEFN == type) ||
+ (INTERNAL_TYPE_BANK_FIELD_DEFN == type))
+ {
+ type = ACPI_TYPE_REGION;
+ }
+
+ /*
+ * Scope, Def_any, and Index_field_defn are bogus "types" which do
+ * not actually have anything to do with the type of the name
+ * being looked up. Save any other value of Type as the type of
+ * the entry.
+ */
+
+ if ((type != INTERNAL_TYPE_SCOPE) &&
+ (type != INTERNAL_TYPE_DEF_ANY) &&
+ (type != INTERNAL_TYPE_INDEX_FIELD_DEFN))
+ {
+ node->type = (u8) type;
+ }
+
+ /*
+ * Increment the reference count(s) of all parents up to
+ * the root!
+ */
+
+ while ((node = acpi_ns_get_parent_object (node)) != NULL) {
+ node->reference_count++;
+ }
+
+ return;
+}
X
X
-/****************************************************************************
+/*******************************************************************************
X *
- * FUNCTION: Acpi_ns_allocate_name_table
+ * FUNCTION: Acpi_ns_delete_children
X *
- * PARAMETERS: Nte_count - Count of NTEs to allocate
+ * PARAMETERS: Parent_node - Delete this objects children
X *
- * RETURN: The address of the first nte in the array, or NULL
+ * RETURN: None.
X *
- * DESCRIPTION: Allocate an array of nte, including prepended link space
- * Array is set to all zeros via Acpi_os_callcate().
+ * DESCRIPTION: Delete all children of the parent object. Deletes a
+ * "scope".
X *


- ***************************************************************************/
+ ******************************************************************************/
X

-ACPI_NAME_TABLE *
-acpi_ns_allocate_name_table (
- u32 num_entries)

+void
+acpi_ns_delete_children (
+ ACPI_NAMESPACE_NODE *parent_node)
X {
- ACPI_NAME_TABLE *name_table = NULL;
- ACPI_SIZE alloc_size;
+ ACPI_NAMESPACE_NODE *child_node;
+ ACPI_NAMESPACE_NODE *next_node;


+ u8 flags;
+
+

+ if (!parent_node) {
+ return;
+ }
+
+ /* If no children, all done! */
+
+ child_node = parent_node->child;
+ if (!child_node) {
+ return;
+ }
+
+ /*
+ * Deallocate all children at this level
+ */
+ do
+ {
+ /* Get the things we need */
+
+ next_node = child_node->peer;
+ flags = child_node->flags;
+
+ /* Grandchildren should have all been deleted already */
+
X
+ /* Now we can free this child object */
X
- alloc_size = sizeof (ACPI_NAME_TABLE) + ((num_entries - 1) *
- sizeof (ACPI_NAMED_OBJECT));
+ DECREMENT_NAME_TABLE_METRICS (sizeof (ACPI_NAMESPACE_NODE));
X
- name_table = acpi_cm_callocate (alloc_size);
+ /*
+ * Detach an object if there is one
+ */
+
+ if (child_node->object) {
+ acpi_ns_detach_object (child_node);
+ }
+
+ acpi_cm_free (child_node);
+
+ /* And move on to the next child in the list */
+
+ child_node = next_node;
X
+ } while (!(flags & ANOBJ_END_OF_PEER_LIST));
X
- return (name_table);
+
+ /* Clear the parent's child pointer */
+
+ parent_node->child = NULL;
+
+ return;


X }
X
X
-/****************************************************************************
+/*******************************************************************************

X *
X * FUNCTION: Acpi_ns_delete_namespace_subtree
X *
@@ -72,22 +329,27 @@
X *
X * RETURN: None.
X *
- * DESCRIPTION: Delete a subtree of the namespace. This includes all objects stored
- * within the subtree. Scope tables are deleted also
+ * DESCRIPTION: Delete a subtree of the namespace. This includes all objects
+ * stored within the subtree. Scope tables are deleted also
X *
- ***************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS
X acpi_ns_delete_namespace_subtree (
- ACPI_NAMED_OBJECT *parent_entry)
+ ACPI_NAMESPACE_NODE *parent_node)
X {
- ACPI_NAMED_OBJECT *child_entry;
+ ACPI_NAMESPACE_NODE *child_node;
+ ACPI_OPERAND_OBJECT *obj_desc;
X u32 level;
- ACPI_OBJECT_INTERNAL *obj_desc;
X
X
- child_entry = 0;
- level = 1;
+ if (!parent_node) {


+ return (AE_OK);
+ }
+
+

+ child_node = 0;
+ level = 1;
X
X /*
X * Traverse the tree of objects until we bubble back up
@@ -100,53 +362,32 @@
X * Null returned if not found
X */
X
- child_entry = acpi_ns_get_next_object (ACPI_TYPE_ANY,
- parent_entry,
- child_entry);
-
- if (child_entry) {
+ child_node = acpi_ns_get_next_object (ACPI_TYPE_ANY, parent_node,
+ child_node);
+ if (child_node) {
X /*
X * Found an object - delete the object within
X * the Value field
X */
X
- obj_desc = acpi_ns_get_attached_object (child_entry);
+ obj_desc = acpi_ns_get_attached_object (child_node);
X if (obj_desc) {
- acpi_ns_detach_object (child_entry);
+ acpi_ns_detach_object (child_node);
X acpi_cm_remove_reference (obj_desc);
X }
X
X
- /*
- * Clear the NTE in case this scope is reused
- * (e.g., a control method scope)
- */
-
- child_entry->type = ACPI_TYPE_ANY;
- child_entry->name = 0;
-
X /* Check if this object has any children */
X
- if (acpi_ns_get_next_object (ACPI_TYPE_ANY, child_entry, 0)) {
+ if (acpi_ns_get_next_object (ACPI_TYPE_ANY, child_node, 0)) {
X /*
X * There is at least one child of this object,
X * visit the object
X */
X
X level++;
- parent_entry = child_entry;
- child_entry = 0;
- }
-
- else {
- /*
- * There may be a name table even if there are
- * no children
- */
-
- acpi_ns_delete_name_table (child_entry->child_table);
- child_entry->child_table = NULL;
-
+ parent_node = child_node;
+ child_node = 0;
X }
X }
X
@@ -158,26 +399,18 @@
X level--;
X
X /*
- * Delete the scope (Name Table) associated with
- * the parent object
+ * Now delete all of the children of this parent
+ * all at the same time.
X */
- /* Don't delete the top level scope, this allows
- * the dynamic deletion of objects created underneath
- * control methods!
- */
-
- if (level != 0) {
- acpi_ns_delete_name_table (parent_entry->child_table);
- parent_entry->child_table = NULL;
- }
+ acpi_ns_delete_children (parent_node);
X
X /* New "last child" is this parent object */
X
- child_entry = parent_entry;
+ child_node = parent_node;
X
X /* Now we can move up the tree to the grandparent */
X
- parent_entry = acpi_ns_get_parent_entry (parent_entry);
+ parent_node = acpi_ns_get_parent_object (parent_node);
X }
X }
X
@@ -186,70 +419,55 @@


X }
X
X
-/****************************************************************************
+/*******************************************************************************

X *
X * FUNCTION: Acpi_ns_remove_reference
X *
- * PARAMETERS: Entry - NTE whose reference count is to be decremented
+ * PARAMETERS: Node - Named object whose reference count is to be
+ * decremented
X *
X * RETURN: None.
X *
- * DESCRIPTION: Remove an NTE reference. Decrements the reference count of
- * all parent NTEs up to the root. Any NTE along the way that
- * reaches zero references is freed.
+ * DESCRIPTION: Remove a Node reference. Decrements the reference count
+ * of all parent Nodes up to the root. Any object along
+ * the way that reaches zero references is freed.
X *


- ***************************************************************************/
+ ******************************************************************************/
X

X void
X acpi_ns_remove_reference (
- ACPI_NAMED_OBJECT *entry)
+ ACPI_NAMESPACE_NODE *node)
X {
- ACPI_NAMED_OBJECT *this_entry;
-
-
- /* There may be a name table even if there are no children */
-
- acpi_ns_delete_name_table (entry->child_table);
- entry->child_table = NULL;
+ ACPI_NAMESPACE_NODE *next_node;
X
X
X /*
- * Decrement the reference count(s) of all parents up to the root,
- * And delete anything with zero remaining references.
+ * Decrement the reference count(s) of this object and all
+ * objects up to the root, Delete anything with zero remaining references.
X */
- this_entry = entry;
- while (this_entry) {
- /* Decrement the reference */
+ next_node = node;
+ while (next_node) {
+ /* Decrement the reference count on this object*/
X
- this_entry->reference_count--;
+ next_node->reference_count--;
X
- /* Delete entry if no more references */
-
- if (!this_entry->reference_count) {
- /* Delete the scope if present */
-
- if (this_entry->child_table) {
- acpi_ns_delete_name_table (this_entry->child_table);
- this_entry->child_table = NULL;
- }
-
- /*
- * Mark the entry free
- * (This doesn't deallocate anything)
- */
+ /* Delete the object if no more references */
X
- acpi_ns_free_table_entry (this_entry);
+ if (!next_node->reference_count) {
+ /* Delete all children and delete the object */
X
+ acpi_ns_delete_children (next_node);
+ acpi_ns_delete_node (next_node);
X }
X
X /* Move up to parent */
X
- this_entry = acpi_ns_get_parent_entry (this_entry);
+ next_node = acpi_ns_get_parent_object (next_node);
X }


X }
X
X
-/****************************************************************************
+/*******************************************************************************

X *
X * FUNCTION: Acpi_ns_delete_namespace_by_owner
X *
@@ -261,21 +479,21 @@
X * specific ID. Used to delete entire ACPI tables. All
X * reference counts are updated.
X *
- ***************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS
X acpi_ns_delete_namespace_by_owner (
X u16 owner_id)
X {
- ACPI_NAMED_OBJECT *child_entry;
+ ACPI_NAMESPACE_NODE *child_node;
X u32 level;
- ACPI_OBJECT_INTERNAL *obj_desc;
- ACPI_NAMED_OBJECT *parent_entry;
+ ACPI_OPERAND_OBJECT *obj_desc;
+ ACPI_NAMESPACE_NODE *parent_node;
X
X
- parent_entry = acpi_gbl_root_object;
- child_entry = 0;
- level = 1;
+ parent_node = acpi_gbl_root_node;
+ child_node = 0;
+ level = 1;
X
X /*
X * Traverse the tree of objects until we bubble back up
@@ -288,124 +506,65 @@
X * Null returned if not found
X */
X
- child_entry = acpi_ns_get_next_object (ACPI_TYPE_ANY,
- parent_entry,
- child_entry);
+ child_node = acpi_ns_get_next_object (ACPI_TYPE_ANY, parent_node,
+ child_node);
X
- if (child_entry) {
- if (child_entry->owner_id == owner_id) {
+ if (child_node) {
+ if (child_node->owner_id == owner_id) {
X /*
X * Found an object - delete the object within
X * the Value field
X */
X
- obj_desc = acpi_ns_get_attached_object (child_entry);
+ obj_desc = acpi_ns_get_attached_object (child_node);
X if (obj_desc) {
- acpi_ns_detach_object (child_entry);
+ acpi_ns_detach_object (child_node);
X acpi_cm_remove_reference (obj_desc);
X }
X }
X
X /* Check if this object has any children */
X
- if (acpi_ns_get_next_object (ACPI_TYPE_ANY, child_entry, 0)) {
+ if (acpi_ns_get_next_object (ACPI_TYPE_ANY, child_node, 0)) {
X /*
X * There is at least one child of this object,
X * visit the object
X */
X
X level++;
- parent_entry = child_entry;
- child_entry = 0;
+ parent_node = child_node;
+ child_node = 0;
X }
X
- else if (child_entry->owner_id == owner_id) {
- acpi_ns_remove_reference (child_entry);
+ else if (child_node->owner_id == owner_id) {
+ acpi_ns_remove_reference (child_node);
X }
X }


X
X else {
X /*

- * No more children in this object.
- * We will move up to the grandparent.
+ * No more children in this object. Move up to grandparent.
X */
X level--;
X
- /*
- * Delete the scope (Name Table) associated with
- * the parent object
- */
- /* Don't delete the top level scope, this allows
- * the dynamic deletion of objects created underneath
- * control methods!
- */
-
-
X if (level != 0) {
- if (parent_entry->owner_id == owner_id) {
- acpi_ns_remove_reference (parent_entry);
+ if (parent_node->owner_id == owner_id) {
+ acpi_ns_remove_reference (parent_node);
X }
X }
X
-
X /* New "last child" is this parent object */
X
- child_entry = parent_entry;
+ child_node = parent_node;
X
X /* Now we can move up the tree to the grandparent */
X
- parent_entry = acpi_ns_get_parent_entry (parent_entry);
+ parent_node = acpi_ns_get_parent_object (parent_node);
X }
X }


X
X
X return (AE_OK);

-}
-
-
-/****************************************************************************
- *
- * FUNCTION: Acpi_ns_delete_name_table
- *
- * PARAMETERS: Scope - A handle to the scope to be deleted
- *
- * RETURN: None.
- *
- * DESCRIPTION: Delete a namespace Name Table with zero or
- * more appendages. The table and all appendages are deleted.
- *
- ***************************************************************************/


-
-void
-acpi_ns_delete_name_table (
- ACPI_NAME_TABLE *name_table)
-{

- ACPI_NAME_TABLE *this_table;
- ACPI_NAME_TABLE *next_table;
-
-
- if (!name_table) {
- return;
- }
-
- this_table = name_table;
-
-
- /*
- * Deallocate the name table and all appendages
- */
- do
- {
- next_table = this_table->next_table;
-
- /* Now we can free the table */
-
- acpi_cm_free (this_table);
- this_table = next_table;
-
- } while (this_table);
-
- return;
X }
X
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/namespace/nsdump.c linux/drivers/acpi/namespace/nsdump.c
--- v2.4.0-test8/linux/drivers/acpi/namespace/nsdump.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/namespace/nsdump.c Fri Sep 15 14:30:30 2000
@@ -0,0 +1,36 @@
+/******************************************************************************
+ *
+ * Module Name: nsdump - table dumping routines for debug
+ * $Revision: 78 $


+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 R. Byron Moore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "acpi.h"

+#include "acinterp.h"
+#include "acnamesp.h"
+#include "actables.h"
+

+
+#define _COMPONENT NAMESPACE
+ MODULE_NAME ("nsdump")
+
+
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/namespace/nseval.c linux/drivers/acpi/namespace/nseval.c
--- v2.4.0-test8/linux/drivers/acpi/namespace/nseval.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/namespace/nseval.c Fri Sep 15 14:30:30 2000
@@ -1,10 +1,10 @@
-
-/******************************************************************************
+/*******************************************************************************
X *
X * Module Name: nseval - Object evaluation interfaces -- includes control
X * method lookup and execution.
+ * $Revision: 76 $


X *
- *****************************************************************************/
+ ******************************************************************************/

X
X /*
X * Copyright (C) 2000 R. Byron Moore
@@ -27,20 +27,20 @@


X
X #include "acpi.h"
X #include "amlcode.h"
-#include "parser.h"

-#include "interp.h"
-#include "namesp.h"


+#include "acparser.h"
+#include "acinterp.h"
+#include "acnamesp.h"

X
X
X #define _COMPONENT NAMESPACE
- MODULE_NAME ("nseval");
+ MODULE_NAME ("nseval")
X
X
-/****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_ns_evaluate_relative
X *
- * PARAMETERS: Rel_obj_entry - NTE of the relative containing object
+ * PARAMETERS: Handle - The relative containing object
X * *Pathname - Name of method to execute, If NULL, the
X * handle is the object to execute
X * **Params - List of parameters to pass to the method,


@@ -56,19 +56,19 @@
X *

X * MUTEX: Locks Namespace
X *
- ****************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS
X acpi_ns_evaluate_relative (
- ACPI_NAMED_OBJECT *handle,


- char *pathname,
- ACPI_OBJECT_INTERNAL **params,
- ACPI_OBJECT_INTERNAL **return_object)

+ ACPI_NAMESPACE_NODE *handle,
+ NATIVE_CHAR *pathname,
+ ACPI_OPERAND_OBJECT **params,
+ ACPI_OPERAND_OBJECT **return_object)
X {
- ACPI_NAMED_OBJECT *rel_obj_entry;
+ ACPI_NAMESPACE_NODE *prefix_node;
X ACPI_STATUS status;
- ACPI_NAMED_OBJECT *obj_entry = NULL;
- char *internal_path = NULL;
+ ACPI_NAMESPACE_NODE *node = NULL;
+ NATIVE_CHAR *internal_path = NULL;
X ACPI_GENERIC_STATE scope_info;
X
X
@@ -86,12 +86,12 @@


X return (status);
X }
X

- /* Get the prefix handle and NTE */
+ /* Get the prefix handle and Node */


X
X acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
X

- rel_obj_entry = acpi_ns_convert_handle_to_entry (handle);
- if (!rel_obj_entry) {
+ prefix_node = acpi_ns_convert_handle_to_entry (handle);
+ if (!prefix_node) {
X acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
X status = AE_BAD_PARAMETER;
X goto cleanup;
@@ -99,15 +99,14 @@
X
X /* Lookup the name in the namespace */
X
- scope_info.scope.name_table = rel_obj_entry->child_table;
+ scope_info.scope.node = prefix_node->child;
X status = acpi_ns_lookup (&scope_info, internal_path, ACPI_TYPE_ANY,
- IMODE_EXECUTE,
- NS_NO_UPSEARCH, NULL,
- &obj_entry);
+ IMODE_EXECUTE, NS_NO_UPSEARCH, NULL,
+ &node);
X
X acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);


X
- if (status != AE_OK) {
+ if (ACPI_FAILURE (status)) {

X goto cleanup;
X }
X
@@ -116,7 +115,7 @@
X * to evaluate it.
X */
X
- status = acpi_ns_evaluate_by_handle (obj_entry, params, return_object);
+ status = acpi_ns_evaluate_by_handle (node, params, return_object);
X
X cleanup:
X
@@ -128,7 +127,7 @@


X }
X
X
-/****************************************************************************
+/*******************************************************************************

X *
X * FUNCTION: Acpi_ns_evaluate_by_name
X *
@@ -146,26 +145,24 @@
X *
X * MUTEX: Locks Namespace


X *
- ****************************************************************************/
+ ******************************************************************************/

SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 032'
echo 'File patch-2.4.0-test9 is continued in part 033'
echo "033" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part033

#!/bin/sh -x
# this is part 033 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 033; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

X
X ACPI_STATUS
X acpi_ns_evaluate_by_name (


- char *pathname,
- ACPI_OBJECT_INTERNAL **params,
- ACPI_OBJECT_INTERNAL **return_object)

+ NATIVE_CHAR *pathname,
+ ACPI_OPERAND_OBJECT **params,
+ ACPI_OPERAND_OBJECT **return_object)
X {

X ACPI_STATUS status;
- ACPI_NAMED_OBJECT *obj_entry = NULL;
- char *internal_path = NULL;
+ ACPI_NAMESPACE_NODE *node = NULL;
+ NATIVE_CHAR *internal_path = NULL;
X

X
X /* Build an internal name string for the method */
X
- if (pathname[0] != '\\' || pathname[1] != '/') {
- status = acpi_ns_internalize_name (pathname, &internal_path);
- if (ACPI_FAILURE (status)) {
- return (status);
- }
+ status = acpi_ns_internalize_name (pathname, &internal_path);


+ if (ACPI_FAILURE (status)) {
+ return (status);

X }
X
X acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);

@@ -173,13 +170,12 @@


X /* Lookup the name in the namespace */
X

X status = acpi_ns_lookup (NULL, internal_path, ACPI_TYPE_ANY,


- IMODE_EXECUTE,
- NS_NO_UPSEARCH, NULL,
- &obj_entry);
+ IMODE_EXECUTE, NS_NO_UPSEARCH, NULL,
+ &node);
X
X acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
X
- if (status != AE_OK) {
+ if (ACPI_FAILURE (status)) {
X goto cleanup;
X }
X

@@ -188,7 +184,7 @@


X * to evaluate it.
X */
X
- status = acpi_ns_evaluate_by_handle (obj_entry, params, return_object);
+ status = acpi_ns_evaluate_by_handle (node, params, return_object);
X
X

X cleanup:
@@ -203,16 +199,16 @@


X }
X
X
-/****************************************************************************
+/*******************************************************************************
X *

X * FUNCTION: Acpi_ns_evaluate_by_handle
X *
- * PARAMETERS: Obj_entry - NTE of method to execute
- * *Return_object - Where to put method's return value (if
- * any). If NULL, no value is returned.
+ * PARAMETERS: Handle - Method Node to execute


X * **Params - List of parameters to pass to the method,

X * terminated by NULL. Params itself may be
X * NULL if no parameters are being passed.
+ * *Return_object - Where to put method's return value (if
+ * any). If NULL, no value is returned.


X *
X * RETURN: Status
X *

@@ -220,22 +216,22 @@


X *
X * MUTEX: Locks Namespace
X *
- ****************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS

X acpi_ns_evaluate_by_handle (
- ACPI_NAMED_OBJECT *handle,


- ACPI_OBJECT_INTERNAL **params,
- ACPI_OBJECT_INTERNAL **return_object)
+ ACPI_NAMESPACE_NODE *handle,

+ ACPI_OPERAND_OBJECT **params,
+ ACPI_OPERAND_OBJECT **return_object)
X {

- ACPI_NAMED_OBJECT *obj_entry;
+ ACPI_NAMESPACE_NODE *node;
X ACPI_STATUS status;
- ACPI_OBJECT_INTERNAL *local_return_object;
+ ACPI_OPERAND_OBJECT *local_return_object;
X
X
X /* Check if namespace has been initialized */
X
- if (!acpi_gbl_root_object->child_table) {
+ if (!acpi_gbl_root_node) {
X return (AE_NO_NAMESPACE);
X }
X
@@ -251,12 +247,12 @@
X *return_object = NULL;


X }
X
- /* Get the prefix handle and NTE */
+ /* Get the prefix handle and Node */
X
X acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
X

- obj_entry = acpi_ns_convert_handle_to_entry (handle);
- if (!obj_entry) {
+ node = acpi_ns_convert_handle_to_entry (handle);
+ if (!node) {
X status = AE_BAD_PARAMETER;
X goto unlock_and_exit;
X }
@@ -271,14 +267,11 @@
X * In both cases, the namespace is unlocked by the
X * Acpi_ns* procedure
X */
-
- if (acpi_ns_get_type (obj_entry) == ACPI_TYPE_METHOD) {
+ if (acpi_ns_get_type (node) == ACPI_TYPE_METHOD) {
X /*
X * Case 1) We have an actual control method to execute
X */
-
- status = acpi_ns_execute_control_method (obj_entry,
- params,
+ status = acpi_ns_execute_control_method (node, params,
X &local_return_object);
X }
X
@@ -287,9 +280,7 @@
X * Case 2) Object is NOT a method, just return its
X * current value
X */
-
- status = acpi_ns_get_object_value (obj_entry,
- &local_return_object);
+ status = acpi_ns_get_object_value (node, &local_return_object);
X }
X
X
@@ -297,7 +288,6 @@
X * Check if there is a return value on the stack that must
X * be dealt with
X */
-
X if (status == AE_CTRL_RETURN_VALUE) {
X /*
X * If the Method returned a value and the caller
@@ -305,13 +295,11 @@
X * the returned value to the object descriptor provided
X * by the caller.
X */
-
X if (return_object) {
X /*
X * Valid return object, copy the pointer to
X * the returned object
X */
-
X *return_object = local_return_object;
X }
X
@@ -327,7 +315,6 @@
X * Namespace was unlocked by the handling Acpi_ns* function,
X * so we just return
X */
-


X return (status);
X
X

@@ -338,14 +325,16 @@


X }
X
X
-/****************************************************************************
+/*******************************************************************************
X *

X * FUNCTION: Acpi_ns_execute_control_method
X *
- * PARAMETERS: Method_entry - The Nte of the object/method
+ * PARAMETERS: Method_node - The object/method


X * **Params - List of parameters to pass to the method,

X * terminated by NULL. Params itself may be
X * NULL if no parameters are being passed.
+ * **Return_obj_desc - List of result objects to be returned
+ * from the method.


X *
X * RETURN: Status
X *

@@ -353,36 +342,31 @@


X *
X * MUTEX: Assumes namespace is locked

X *
- ****************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS

X acpi_ns_execute_control_method (


- ACPI_NAMED_OBJECT *method_entry,
- ACPI_OBJECT_INTERNAL **params,
- ACPI_OBJECT_INTERNAL **return_obj_desc)
+ ACPI_NAMESPACE_NODE *method_node,
+ ACPI_OPERAND_OBJECT **params,
+ ACPI_OPERAND_OBJECT **return_obj_desc)
X {
X ACPI_STATUS status;

- ACPI_OBJECT_INTERNAL *obj_desc;


+ ACPI_OPERAND_OBJECT *obj_desc;
X
X

X /* Verify that there is a method associated with this object */
X
- obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) method_entry);
+ obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) method_node);
X if (!obj_desc) {
X return (AE_ERROR);
X }
X
- /*
- * Valid method, Set the current scope to that of the Method,
- * and execute it.
- */
-
X
X /*
X * Unlock the namespace before execution. This allows namespace access
X * via the external Acpi* interfaces while a method is being executed.
X * However, any namespace deletion must acquire both the namespace and
- * interpter locks to ensure that no thread is using the portion of the
+ * interpreter locks to ensure that no thread is using the portion of the
X * namespace that is being deleted.
X */
X
@@ -391,17 +375,17 @@
X /*
X * Excecute the method via the interpreter
X */
- status = acpi_aml_execute_method (method_entry, params, return_obj_desc);
+ status = acpi_aml_execute_method (method_node, params, return_obj_desc);
X
X return (status);


X }
X
X
-/****************************************************************************
+/*******************************************************************************
X *

X * FUNCTION: Acpi_ns_get_object_value
X *
- * PARAMETERS: Object_entry - The Nte of the object
+ * PARAMETERS: Node - The object


X *
X * RETURN: Status
X *

@@ -409,30 +393,29 @@


X *
X * MUTEX: Assumes namespace is locked

X *
- ****************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS

X acpi_ns_get_object_value (
- ACPI_NAMED_OBJECT *object_entry,
- ACPI_OBJECT_INTERNAL **return_obj_desc)
+ ACPI_NAMESPACE_NODE *node,
+ ACPI_OPERAND_OBJECT **return_obj_desc)
X {
X ACPI_STATUS status = AE_OK;
- ACPI_OBJECT_INTERNAL *obj_desc;
- ACPI_OBJECT_INTERNAL *val_desc;
+ ACPI_OPERAND_OBJECT *obj_desc;
+ ACPI_OPERAND_OBJECT *val_desc;
X
X
X /*
X * We take the value from certain objects directly
X */
X
- if ((object_entry->type == ACPI_TYPE_PROCESSOR) ||
- (object_entry->type == ACPI_TYPE_POWER))
+ if ((node->type == ACPI_TYPE_PROCESSOR) ||
+ (node->type == ACPI_TYPE_POWER))
X {
-
X /*
X * Create a Reference object to contain the object
X */
- obj_desc = acpi_cm_create_internal_object (object_entry->type);
+ obj_desc = acpi_cm_create_internal_object (node->type);
X if (!obj_desc) {
X status = AE_NO_MEMORY;
X goto unlock_and_exit;
@@ -442,7 +425,7 @@
X * Get the attached object
X */
X
- val_desc = acpi_ns_get_attached_object (object_entry);
+ val_desc = acpi_ns_get_attached_object (node);
X if (!val_desc) {
X status = AE_NULL_OBJECT;
X goto unlock_and_exit;
@@ -452,10 +435,25 @@
X * Just copy from the original to the return object
X */
X
- MEMCPY (&obj_desc->common.first_non_common_byte,
- &val_desc->common.first_non_common_byte,
- (sizeof(ACPI_OBJECT_COMMON) -
- sizeof(obj_desc->common.first_non_common_byte)));
+ switch (node->type)
+ {
+ case ACPI_TYPE_PROCESSOR:
+ obj_desc->processor.proc_id = val_desc->processor.proc_id;
+ obj_desc->processor.address = val_desc->processor.address;
+ obj_desc->processor.sys_handler = val_desc->processor.sys_handler;
+ obj_desc->processor.drv_handler = val_desc->processor.drv_handler;
+ obj_desc->processor.addr_handler = val_desc->processor.addr_handler;
+
+ break;
+
+ case ACPI_TYPE_POWER:
+ obj_desc->power_resource.system_level = val_desc->power_resource.system_level;
+ obj_desc->power_resource.resource_order = val_desc->power_resource.resource_order;
+ obj_desc->power_resource.sys_handler = val_desc->power_resource.sys_handler;
+ obj_desc->power_resource.drv_handler = val_desc->power_resource.drv_handler;
+
+ break;
+ }
X }
X
X
@@ -475,15 +473,19 @@
X /* Construct a descriptor pointing to the name */
X
X obj_desc->reference.op_code = (u8) AML_NAME_OP;
- obj_desc->reference.object = (void *) object_entry;
+ obj_desc->reference.object = (void *) node;
X
X /*
X * Use Acpi_aml_resolve_to_value() to get the associated value.
X * The call to Acpi_aml_resolve_to_value causes
X * Obj_desc (allocated above) to always be deleted.
+ *
+ * NOTE: we can get away with passing in NULL for a walk state
+ * because Obj_desc is guaranteed to not be a reference to either
+ * a method local or a method argument
X */
X
- status = acpi_aml_resolve_to_value (&obj_desc);
+ status = acpi_aml_resolve_to_value (&obj_desc, NULL);
X }
X
X /*
@@ -491,7 +493,7 @@
X * placed in Obj_desc.
X */
X
- if (status == AE_OK) {
+ if (ACPI_SUCCESS (status)) {
X status = AE_CTRL_RETURN_VALUE;
X
X *return_obj_desc = obj_desc;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/namespace/nsload.c linux/drivers/acpi/namespace/nsload.c
--- v2.4.0-test8/linux/drivers/acpi/namespace/nsload.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/namespace/nsload.c Fri Sep 15 14:30:30 2000
@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *
X * Module Name: nsload - namespace loading/expanding/contracting procedures
+ * $Revision: 28 $


X *
X *****************************************************************************/
X

@@ -25,16 +25,16 @@


X
X
X #include "acpi.h"
-#include "interp.h"
-#include "namesp.h"

+#include "acinterp.h"
+#include "acnamesp.h"


X #include "amlcode.h"
-#include "parser.h"

-#include "dispatch.h"
-#include "debugger.h"
+#include "acparser.h"
+#include "acdispat.h"
+#include "acdebug.h"


X
X
X #define _COMPONENT NAMESPACE

- MODULE_NAME ("nsload");
+ MODULE_NAME ("nsload")
X
X
X /*******************************************************************************
@@ -42,7 +42,7 @@
X * FUNCTION: Acpi_ns_parse_table
X *
X * PARAMETERS: Table_desc - An ACPI table descriptor for table to parse
- * Scope - Where to enter the table into the namespace
+ * Start_node - Where to enter the table into the namespace


X *
X * RETURN: Status
X *

@@ -53,50 +53,85 @@
X ACPI_STATUS
X acpi_ns_parse_table (
X ACPI_TABLE_DESC *table_desc,
- ACPI_NAME_TABLE *scope)
+ ACPI_NAMESPACE_NODE *start_node)


X {
X ACPI_STATUS status;
X

X
- /* Create the root object */
+ /*
+ * AML Parse, pass 1
+ *
+ * In this pass, we load most of the namespace. Control methods
+ * are not parsed until later. A parse tree is not created. Instead,
+ * each Parser Op subtree is deleted when it is finished. This saves
+ * a great deal of memory, and allows a small cache of parse objects
+ * to service the entire parse. The second pass of the parse then
+ * performs another complete parse of the AML..
+ */
+


+ /* Create and init a Root Node */

X
X acpi_gbl_parsed_namespace_root = acpi_ps_alloc_op (AML_SCOPE_OP);
X if (!acpi_gbl_parsed_namespace_root) {


X return (AE_NO_MEMORY);
X }
X

- /* Initialize the root object */
+ ((ACPI_PARSE2_OBJECT *) acpi_gbl_parsed_namespace_root)->name = ACPI_ROOT_NAME;
X
- ((ACPI_NAMED_OP *) acpi_gbl_parsed_namespace_root)->name = ACPI_ROOT_NAME;
X
X /* Pass 1: Parse everything except control method bodies */
X
X status = acpi_ps_parse_aml (acpi_gbl_parsed_namespace_root,
X table_desc->aml_pointer,
- table_desc->aml_length, 0);
+ table_desc->aml_length,
+ ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE,
+ NULL, NULL, NULL,
+ acpi_ds_load1_begin_op,
+ acpi_ds_load1_end_op);


X
X if (ACPI_FAILURE (status)) {

X return (status);
X }
X
-

-#ifndef PARSER_ONLY
- status = acpi_ps_walk_parsed_aml (acpi_ps_get_child (acpi_gbl_parsed_namespace_root),
- acpi_gbl_parsed_namespace_root, NULL,
- scope, NULL, NULL,
- table_desc->table_id,
- acpi_ds_load2_begin_op,
- acpi_ds_load2_end_op);
+ acpi_ps_delete_parse_tree (acpi_gbl_parsed_namespace_root);
X
X
X /*
- * Now that the internal namespace has been constructed, we can delete the
- * parsed namespace, since it is no longer needed
+ * AML Parse, pass 2
+ *
+ * In this pass, we resolve forward references and other things
+ * that could not be completed during the first pass.
+ * Another complete parse of the AML is performed, but the
+ * overhead of this is compensated for by the fact that the
+ * parse objects are all cached.
X */
X

+ /* Create and init a Root Node */
+

+ acpi_gbl_parsed_namespace_root = acpi_ps_alloc_op (AML_SCOPE_OP);
+ if (!acpi_gbl_parsed_namespace_root) {


+ return (AE_NO_MEMORY);
+ }
+

+ ((ACPI_PARSE2_OBJECT *) acpi_gbl_parsed_namespace_root)->name = ACPI_ROOT_NAME;
+
+
+ /* Pass 2: Resolve forward references */
+
+ status = acpi_ps_parse_aml (acpi_gbl_parsed_namespace_root,
+ table_desc->aml_pointer,
+ table_desc->aml_length,
+ ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE,
+ NULL, NULL, NULL,
+ acpi_ds_load2_begin_op,
+ acpi_ds_load2_end_op);


+
+ if (ACPI_FAILURE (status)) {

+ return (status);
+ }
+

X acpi_ps_delete_parse_tree (acpi_gbl_parsed_namespace_root);
X acpi_gbl_parsed_namespace_root = NULL;
-#endif


X
X
X return (status);

@@ -120,7 +155,7 @@
X ACPI_STATUS
X acpi_ns_load_table (
X ACPI_TABLE_DESC *table_desc,


- ACPI_NAMED_OBJECT *entry)
+ ACPI_NAMESPACE_NODE *node)
X {

X ACPI_STATUS status;
X
@@ -146,7 +181,7 @@
X */
X
X acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
- status = acpi_ns_parse_table (table_desc, entry->child_table);
+ status = acpi_ns_parse_table (table_desc, node->child);
X acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);


X
X if (ACPI_FAILURE (status)) {

@@ -160,7 +195,7 @@
X * parse trees.
X */
X
- status = acpi_ds_initialize_objects (table_desc, entry);
+ status = acpi_ds_initialize_objects (table_desc, node);


X
X return (status);
X }

@@ -222,7 +257,7 @@
X
X /* Now load the single DSDT */
X
- status = acpi_ns_load_table (table_desc, acpi_gbl_root_object);
+ status = acpi_ns_load_table (table_desc, acpi_gbl_root_node);
X if (ACPI_SUCCESS (status)) {
X table_desc->loaded_into_namespace = TRUE;
X }
@@ -247,7 +282,7 @@
X
X if (!table_desc->loaded_into_namespace) {
X status = acpi_ns_load_table (table_desc,
- acpi_gbl_root_object);
+ acpi_gbl_root_node);
X if (ACPI_FAILURE (status)) {
X break;
X }
@@ -276,7 +311,7 @@
X
X if (!table_desc->loaded_into_namespace) {
X status = acpi_ns_load_table (table_desc,
- acpi_gbl_root_object);
+ acpi_gbl_root_node);
X if (ACPI_FAILURE (status)) {
X break;
X }
@@ -306,52 +341,6 @@


X
X /******************************************************************************
X *

- * FUNCTION: Acpi_ns_free_table_entry
- *
- * PARAMETERS: Entry - The entry to be deleted
- *
- * RETURNS None
- *
- * DESCRIPTION: Free an entry in a namespace table. Delete any objects contained
- * in the entry, unlink the entry, then mark it unused.


- *
- ******************************************************************************/
-
-void

-acpi_ns_free_table_entry (


- ACPI_NAMED_OBJECT *entry)
-{
-

- if (!entry) {
- return;
- }
-
- /*
- * Need to delete
- * 1) The scope, if any
- * 2) An attached object, if any
- */
-
- if (entry->child_table) {
- acpi_cm_free (entry->child_table);


- entry->child_table = NULL;

- }
-
- if (entry->object) {
- acpi_ns_detach_object (entry->object);
- entry->object = NULL;
- }
-
- /* Mark the entry unallocated */
-
- entry->name = 0;
-


- return;
-}
-
-

-/******************************************************************************
- *
X * FUNCTION: Acpi_ns_delete_subtree
X *
X * PARAMETERS: Start_handle - Handle in namespace where search begins
@@ -394,15 +383,6 @@
X child_handle,
X &next_child_handle);
X
- /*
- * Regardless of the success or failure of the
- * previous operation, we are done with the previous
- * object (if there was one), and any children it
- * may have had. So we can now safely delete it (and
- * its scope, if any)
- */
-
- acpi_ns_free_table_entry (child_handle);
X child_handle = next_child_handle;
X
X
@@ -432,6 +412,11 @@
X * the object's parent
X */
X level--;
+
+ /* Delete all children now */
+
+ acpi_ns_delete_children (child_handle);
+
X child_handle = parent_handle;
X acpi_get_parent (parent_handle, &parent_handle);
X }


@@ -439,7 +424,7 @@
X

X /* Now delete the starting object, and we are done */
X
- acpi_ns_free_table_entry ((ACPI_NAMED_OBJECT*) child_handle);
+ acpi_ns_delete_node (child_handle);


X
X
X return (AE_OK);

@@ -469,7 +454,7 @@


X
X /* Parameter validation */

X
- if (!acpi_gbl_root_object->child_table) {
+ if (!acpi_gbl_root_node) {
X return (AE_NO_NAMESPACE);
X }
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/namespace/nsnames.c linux/drivers/acpi/namespace/nsnames.c
--- v2.4.0-test8/linux/drivers/acpi/namespace/nsnames.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/namespace/nsnames.c Fri Sep 15 14:30:30 2000


@@ -1,9 +1,9 @@
-
-/******************************************************************************
+/*******************************************************************************
X *

X * Module Name: nsnames - Name manipulation and search
+ * $Revision: 48 $


X *
- *****************************************************************************/
+ ******************************************************************************/
X
X /*
X * Copyright (C) 2000 R. Byron Moore

@@ -26,42 +26,40 @@


X
X #include "acpi.h"
X #include "amlcode.h"
-#include "interp.h"
-#include "namesp.h"

+#include "acinterp.h"
+#include "acnamesp.h"
X
X
X #define _COMPONENT NAMESPACE

- MODULE_NAME ("nsnames");
+ MODULE_NAME ("nsnames")


X
X
-/****************************************************************************
+/*******************************************************************************
X *

- * FUNCTION: Acpi_ns_name_of_scope
+ * FUNCTION: Acpi_ns_get_table_pathname
X *
- * PARAMETERS: Scope - Scope whose name is needed
+ * PARAMETERS: Node - Scope whose name is needed
X *
X * RETURN: Pointer to storage containing the fully qualified name of
X * the scope, in Label format (all segments strung together
X * with no separators)
X *
- * DESCRIPTION: Used via Acpi_ns_name_of_current_scope() and Acpi_ns_last_fQN()
- * for label generation in the interpreter, and for debug
- * printing in Acpi_ns_search_table().


- *
- ***************************************************************************/
-

-char *
-acpi_ns_name_of_scope (
- ACPI_NAME_TABLE *scope)

+ * DESCRIPTION: Used for debug printing in Acpi_ns_search_table().


+ *
+ ******************************************************************************/
+

+NATIVE_CHAR *
+acpi_ns_get_table_pathname (
+ ACPI_NAMESPACE_NODE *node)
X {
- char *name_buffer;
- ACPI_SIZE size;
+ NATIVE_CHAR *name_buffer;
+ u32 size;
X ACPI_NAME name;
- ACPI_NAMED_OBJECT *entry_to_search;
- ACPI_NAMED_OBJECT *parent_entry;
+ ACPI_NAMESPACE_NODE *child_node;
+ ACPI_NAMESPACE_NODE *parent_node;
X
X
- if (!acpi_gbl_root_object->child_table || !scope) {
+ if (!acpi_gbl_root_node || !node) {
X /*
X * If the name space has not been initialized,
X * this function should not have been called.
@@ -69,26 +67,26 @@
X return (NULL);
X }
X
- entry_to_search = scope->entries;
+ child_node = node->child;
X
X
- /* Calculate required buffer size based on depth below root NT */
+ /* Calculate required buffer size based on depth below root */
X
X size = 1;
- parent_entry = entry_to_search;
- while (parent_entry) {


- parent_entry = acpi_ns_get_parent_entry (parent_entry);

- if (parent_entry) {
+ parent_node = child_node;
+ while (parent_node) {


+ parent_node = acpi_ns_get_parent_object (parent_node);

+ if (parent_node) {
X size += ACPI_NAME_SIZE;
X }
X }
X
X
- /* Allocate the buffer */
+ /* Allocate a buffer to be returned to caller */
X
X name_buffer = acpi_cm_callocate (size + 1);
X if (!name_buffer) {
- REPORT_ERROR ("Ns_name_of_scope: allocation failure");
+ REPORT_ERROR ("Ns_get_table_pathname: allocation failure");
X return (NULL);
X }
X
@@ -97,15 +95,15 @@
X
X name_buffer[size] = '\0';
X while ((size > ACPI_NAME_SIZE) &&
- acpi_ns_get_parent_entry (entry_to_search))
+ acpi_ns_get_parent_object (child_node))
X {
X size -= ACPI_NAME_SIZE;
- name = acpi_ns_find_parent_name (entry_to_search);
+ name = acpi_ns_find_parent_name (child_node);
X
X /* Put the name into the buffer */
X
X MOVE_UNALIGNED32_TO_32 ((name_buffer + size), &name);
- entry_to_search = acpi_ns_get_parent_entry (entry_to_search);
+ child_node = acpi_ns_get_parent_object (child_node);
X }
X
X name_buffer[--size] = AML_ROOT_PREFIX;
@@ -115,69 +113,39 @@
X }
X
X
-/****************************************************************************
- *
- * FUNCTION: Acpi_ns_name_of_current_scope
- *
- * PARAMETERS: none
- *
- * RETURN: pointer to storage containing the name of the current scope


- *
- ***************************************************************************/
-

-char *
-acpi_ns_name_of_current_scope (
- ACPI_WALK_STATE *walk_state)
-{
- char *scope_name;
-
-
- if (walk_state && walk_state->scope_info) {
- scope_name =
- acpi_ns_name_of_scope (walk_state->scope_info->scope.name_table);
-
- return (scope_name);
- }
-
- REPORT_ERROR ("Current scope pointer is invalid");
-
- return (NULL);


-}
-
-
-/****************************************************************************
+/*******************************************************************************
X *

X * FUNCTION: Acpi_ns_handle_to_pathname
X *
- * PARAMETERS: Target_handle - Handle of nte whose name is to be found
+ * PARAMETERS: Target_handle - Handle of named object whose name is
+ * to be found
X * Buf_size - Size of the buffer provided
X * User_buffer - Where the pathname is returned
X *
- * RETURN: Status, Buffer is filled with pathname if status == AE_OK
+ * RETURN: Status, Buffer is filled with pathname if status is AE_OK
X *
X * DESCRIPTION: Build and return a full namespace pathname


X *
X * MUTEX: Locks Namespace
X *

- ***************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS

X acpi_ns_handle_to_pathname (
X ACPI_HANDLE target_handle,
X u32 *buf_size,
- char *user_buffer)
+ NATIVE_CHAR *user_buffer)


X {
X ACPI_STATUS status = AE_OK;

- ACPI_NAMED_OBJECT *entry_to_search = NULL;
- ACPI_NAMED_OBJECT *temp = NULL;
- ACPI_SIZE path_length = 0;
- ACPI_SIZE size;
+ ACPI_NAMESPACE_NODE *node;
+ ACPI_NAMESPACE_NODE *next_node;
+ u32 path_length;
+ u32 size;
X u32 user_buf_size;
X ACPI_NAME name;
- u8 namespace_was_locked;
X
X
- if (!acpi_gbl_root_object->child_table || !target_handle) {
+ if (!acpi_gbl_root_node || !target_handle) {
X /*
X * If the name space has not been initialized,
X * this function should not have been called.
@@ -186,13 +154,8 @@
X return (AE_NO_NAMESPACE);
X }
X
- namespace_was_locked = acpi_gbl_acpi_mutex_info[ACPI_MTX_NAMESPACE].locked;
- if (!namespace_was_locked) {
- acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
- }
-
- entry_to_search = acpi_ns_convert_handle_to_entry (target_handle);
- if (!entry_to_search) {
+ node = acpi_ns_convert_handle_to_entry (target_handle);
+ if (!node) {


X return (AE_BAD_PARAMETER);
X }
X

@@ -200,9 +163,9 @@
X * Compute length of pathname as 5 * number of name segments.
X * Go back up the parent tree to the root
X */
- for (size = 0, temp = entry_to_search;
- acpi_ns_get_parent_entry (temp);
- temp = acpi_ns_get_parent_entry (temp))
+ for (size = 0, next_node = node;
+ acpi_ns_get_parent_object (next_node);
+ next_node = acpi_ns_get_parent_object (next_node))
X {
X size += PATH_SEGMENT_LENGTH;


X }
@@ -217,7 +180,7 @@
X

X if (path_length > user_buf_size) {
X status = AE_BUFFER_OVERFLOW;
- goto unlock_and_exit;
+ goto exit;
X }
X
X /* Store null terminator */
@@ -228,19 +191,19 @@
X /* Put the original ACPI name at the end of the path */
X
X MOVE_UNALIGNED32_TO_32 ((user_buffer + size),
- &entry_to_search->name);
+ &node->name);
X
X user_buffer[--size] = PATH_SEPARATOR;
X
X /* Build name backwards, putting "." between segments */
X
- while ((size > ACPI_NAME_SIZE) && entry_to_search) {
+ while ((size > ACPI_NAME_SIZE) && node) {
X size -= ACPI_NAME_SIZE;
- name = acpi_ns_find_parent_name (entry_to_search);
+ name = acpi_ns_find_parent_name (node);
X MOVE_UNALIGNED32_TO_32 ((user_buffer + size), &name);
X
X user_buffer[--size] = PATH_SEPARATOR;
- entry_to_search = acpi_ns_get_parent_entry (entry_to_search);


+ node = acpi_ns_get_parent_object (node);

X }
X
X /*
@@ -250,254 +213,8 @@
X
X user_buffer[size] = '\\';
X
-
-unlock_and_exit:
-
- if (!namespace_was_locked) {
- acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
- }
-
+exit:
X return (status);
-}
-
-
-/****************************************************************************
- *
- * FUNCTION: Acpi_ns_pattern_match
- *
- * PARAMETERS: Obj_entry - A namespace entry
- * Search_for - Wildcard pattern string
- *
- * DESCRIPTION: Matches a namespace name against a wildcard pattern. Only
- * a very simple pattern - 4 chars, either a valid char or a "?"
- * to match any.


- *
- ***************************************************************************/
-

-u8
-acpi_ns_pattern_match (
- ACPI_NAMED_OBJECT *obj_entry,
- char *search_for)

-{
- s32 i;
-
-
- for (i = 0; i < ACPI_NAME_SIZE; i++) {
- if (search_for[i] != '?' &&
- search_for[i] != ((char *) &obj_entry->name)[i])
- {
- /* No match */
-
- return FALSE;
- }
- }
-
- /* name matches pattern */
-


- return TRUE;
-}
-
-

-/****************************************************************************
- *
- * FUNCTION: Acpi_ns_name_compare
- *
- * PARAMETERS: Obj_handle - A namespace entry
- * Level - Current nesting level
- * Context - A FIND_CONTEXT structure
- *
- * DESCRIPTION: A User_function called by Acpi_ns_walk_namespace(). It performs
- * a pattern match for Acpi_ns_low_find_names(), and updates the list
- * and count as required.


- *
- ***************************************************************************/
-
-ACPI_STATUS

-acpi_ns_name_compare (


- ACPI_HANDLE obj_handle,
- u32 level,
- void *context,
- void **return_value)

-{
- FIND_CONTEXT *find = context;
-
-
- /* Match, yes or no? */
-
- if (acpi_ns_pattern_match ((ACPI_NAMED_OBJECT*) obj_handle,
- find->search_for))
- {
- /* Name matches pattern */
-
- if (find->list) {
- find->list[*(find->count)] = obj_handle;
- }
-
- ++*(find->count);
- }
-
- /* Don't terminate the walk */
- return AE_OK;


-}
-
-
-/****************************************************************************
- *

- * FUNCTION: Acpi_ns_low_find_names
- *
- * PARAMETERS: *This_entry - Table to be searched
- * *Search_for - Pattern to be found.
- * 4 bytes, ? matches any character.
- * *Count - Output count of matches found.
- * Outermost caller should preset to 0
- * List[] - Output array of handles. If
- * null, only the count is obtained.
- * Max_depth - Maximum depth of search. Use
- * INT_MAX for an effectively
- * unlimited depth.
- *
- * DESCRIPTION: Low-level find name.
- * Traverse the name space finding names which match a search
- * pattern, and return an array of handles in List[].


- *
- ***************************************************************************/
-
-void

-acpi_ns_low_find_names (
- ACPI_NAMED_OBJECT *this_entry,
- char *search_for,
- s32 *count,
- ACPI_HANDLE list[],
- s32 max_depth)

-{
- FIND_CONTEXT find;
-
-
- if (0 == max_depth || !this_entry || !search_for || !count) {
- /*
- * Zero requested depth, nothing to search,
- * nothing to search for, or count pointer bad
- */
-
- return;
- }
-
- /* Init the context structure used by compare routine */
-
- find.list = list;
- find.count = count;
- find.search_for = search_for;
-
- /* Walk the namespace and find all matches */
-
- acpi_ns_walk_namespace (ACPI_TYPE_ANY, (ACPI_HANDLE) this_entry,
- max_depth, NS_WALK_NO_UNLOCK,
- acpi_ns_name_compare, &find, NULL);
-
- if (list) {
- /* null-terminate the output array */
-
- list[*count] = (ACPI_HANDLE) 0;
- }
-


- return;
-}
-
-

-/****************************************************************************
- *
- * FUNCTION: Acpi_ns_find_names
-
- *
- * PARAMETERS: *Search_for - pattern to be found.
- * 4 bytes, ? matches any character.
- * If NULL, "????" will be used.
- * Start_handle - Root of subtree to be searched, or
- * NS_ALL to search the entire namespace
- * Max_depth - Maximum depth of search. Use INT_MAX
- * for an effectively unlimited depth.
- *
- * DESCRIPTION: Traverse the name space finding names which match a search
- * pattern, and return an array of handles. The end of the
- * array is marked by the value (ACPI_HANDLE)0. A return value
- * of (ACPI_HANDLE *)0 indicates that no matching names were
- * found or that space for the list could not be allocated.
- * if Start_handle is NS_ALL (null) search from the root,
- * else it is a handle whose children are to be searched.


- *
- ***************************************************************************/
-

-ACPI_HANDLE *
-acpi_ns_find_names (
- char *search_for,

- ACPI_HANDLE start_handle,
- s32 max_depth)
-{
- ACPI_HANDLE *list = NULL;
- s32 count;
-
-


- if (!acpi_gbl_root_object->child_table) {
- /*

- * If the name space has not been initialized,
- * there surely are no matching names.
- */
- return (NULL);
- }
-
- if (NS_ALL == start_handle) {
- /* base is root */
-
- start_handle = acpi_gbl_root_object;
- }
-
- else if (((ACPI_NAMED_OBJECT *) start_handle)->child_table) {
- /* base has children to search */
-
- start_handle =
- ((ACPI_NAMED_OBJECT *) start_handle)->child_table->entries;


- }
-
- else {
- /*

- * If base is not the root and has no children,
- * there is nothing to search.
- */
- return (NULL);
- }
-
- if (!search_for) {
- /* Search name not specified */
-
- search_for = "????";
- }
-
-
- /* Pass 1. Get required buffer size, don't try to build list */
-
- count = 0;
- acpi_ns_low_find_names (start_handle, search_for, &count,
- NULL, max_depth);
-
- if (0 == count) {
- return (NULL);
- }
-
- /* Allow for trailing null */
- count++;
-
- list = acpi_cm_callocate (count * sizeof(ACPI_HANDLE));
- if (!list) {
- REPORT_ERROR ("Ns_find_names: allocation failure");
- return (NULL);
- }
-
- /* Pass 2. Fill buffer */
-
- count = 0;
- acpi_ns_low_find_names (start_handle, search_for, &count, list, max_depth);
-
- return (list);
X }
X
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/namespace/nsobject.c linux/drivers/acpi/namespace/nsobject.c
--- v2.4.0-test8/linux/drivers/acpi/namespace/nsobject.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/namespace/nsobject.c Fri Sep 15 14:30:30 2000


@@ -1,10 +1,10 @@
-
-/******************************************************************************
+/*******************************************************************************
X *

X * Module Name: nsobject - Utilities for objects attached to namespace
- * table entries
+ * table entries
+ * $Revision: 44 $


X *
- *****************************************************************************/
+ ******************************************************************************/
X
X /*
X * Copyright (C) 2000 R. Byron Moore
@@ -27,20 +27,20 @@
X
X #include "acpi.h"
X #include "amlcode.h"

-#include "namesp.h"
-#include "interp.h"
-#include "tables.h"
+#include "acnamesp.h"
+#include "acinterp.h"
+#include "actables.h"
X
X
X #define _COMPONENT NAMESPACE
- MODULE_NAME ("nsobject");
+ MODULE_NAME ("nsobject")


X
X
-/****************************************************************************
+/*******************************************************************************
X *

X * FUNCTION: Acpi_ns_attach_object
X *
- * PARAMETERS: Handle - Handle of nte
+ * PARAMETERS: Node - Parent Node
X * Object - Object to be attached
X * Type - Type of object, or ACPI_TYPE_ANY if not
X * known
@@ -51,17 +51,16 @@


X *
X * MUTEX: Assumes namespace is locked

X *
- ***************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS

X acpi_ns_attach_object (
- ACPI_HANDLE handle,
- ACPI_HANDLE object,


+ ACPI_NAMESPACE_NODE *node,
+ ACPI_OPERAND_OBJECT *object,

X OBJECT_TYPE_INTERNAL type)
X {
- ACPI_NAMED_OBJECT *this_entry = (ACPI_NAMED_OBJECT*) handle;
- ACPI_OBJECT_INTERNAL *obj_desc;
- ACPI_OBJECT_INTERNAL *previous_obj_desc;
+ ACPI_OPERAND_OBJECT *obj_desc;
+ ACPI_OPERAND_OBJECT *previous_obj_desc;
X OBJECT_TYPE_INTERNAL obj_type = ACPI_TYPE_ANY;
X u8 flags;
X u16 opcode;
@@ -71,17 +70,17 @@
X * Parameter validation
X */
X
- if (!acpi_gbl_root_object->child_table) {
+ if (!acpi_gbl_root_node) {
X /* Name space not initialized */
X
X REPORT_ERROR ("Ns_attach_object: Name space not initialized");
X return (AE_NO_NAMESPACE);
X }
X
- if (!handle) {
+ if (!node) {
X /* Invalid handle */
X
- REPORT_ERROR ("Ns_attach_object: Null name handle");
+ REPORT_ERROR ("Ns_attach_object: Null Named_obj handle");


X return (AE_BAD_PARAMETER);
X }
X

@@ -93,7 +92,7 @@


X return (AE_BAD_PARAMETER);
X }
X

- if (!VALID_DESCRIPTOR_TYPE (handle, ACPI_DESC_TYPE_NAMED)) {
+ if (!VALID_DESCRIPTOR_TYPE (node, ACPI_DESC_TYPE_NAMED)) {
X /* Not a name handle */
X
X REPORT_ERROR ("Ns_attach_object: Invalid handle");
@@ -102,15 +101,15 @@
X
X /* Check if this object is already attached */
X
- if (this_entry->object == object) {
+ if (node->object == object) {


X return (AE_OK);
X }
X

X
- /* Get the current flags field of the NTE */
+ /* Get the current flags field of the Node */
X
- flags = this_entry->flags;
- flags &= ~NTE_AML_ATTACHMENT;
+ flags = node->flags;
+ flags &= ~ANOBJ_AML_ATTACHMENT;
X
X
X /* If null object, we will just install it */
@@ -121,27 +120,27 @@
X }
X
X /*
- * If the object is an NTE with an attached object,
+ * If the object is an Node with an attached object,
X * we will use that (attached) object
X */
X
X else if (VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_NAMED) &&
- ((ACPI_NAMED_OBJECT*) object)->object)
+ ((ACPI_NAMESPACE_NODE *) object)->object)
X {
X /*
X * Value passed is a name handle and that name has a
X * non-null value. Use that name's value and type.
X */
X
- obj_desc = ((ACPI_NAMED_OBJECT*) object)->object;
- obj_type = ((ACPI_NAMED_OBJECT*) object)->type;
+ obj_desc = ((ACPI_NAMESPACE_NODE *) object)->object;
+ obj_type = ((ACPI_NAMESPACE_NODE *) object)->type;
X
X /*
X * Copy appropriate flags
X */
X
- if (((ACPI_NAMED_OBJECT*) object)->flags & NTE_AML_ATTACHMENT) {
- flags |= NTE_AML_ATTACHMENT;
+ if (((ACPI_NAMESPACE_NODE *) object)->flags & ANOBJ_AML_ATTACHMENT) {
+ flags |= ANOBJ_AML_ATTACHMENT;
X }
X }
X
@@ -152,7 +151,7 @@
X */
X
X else {
- obj_desc = (ACPI_OBJECT_INTERNAL *) object;
+ obj_desc = (ACPI_OPERAND_OBJECT *) object;
X
X
X /* If a valid type (non-ANY) was given, just use it */
@@ -173,10 +172,10 @@
X else if (acpi_tb_system_table_pointer (object)) {
X /*
X * Object points into the AML stream.
- * Set a flag bit in the NTE to indicate this
+ * Set a flag bit in the Node to indicate this
X */
X
- flags |= NTE_AML_ATTACHMENT;
+ flags |= ANOBJ_AML_ATTACHMENT;
X
X /*
X * The next byte (perhaps the next two bytes)
@@ -263,13 +262,13 @@
X
X /* Save the existing object (if any) for deletion later */
X
- previous_obj_desc = this_entry->object;
+ previous_obj_desc = node->object;
X
X /* Install the object and set the type, flags */
X
- this_entry->object = obj_desc;
- this_entry->type = (u8) obj_type;
- this_entry->flags = flags;
+ node->object = obj_desc;
+ node->type = (u8) obj_type;
+ node->flags |= flags;
X
X
X /*
@@ -277,86 +276,12 @@
X */
X
X if (previous_obj_desc) {
- /* One for the attach to the NTE */
- acpi_cm_remove_reference (previous_obj_desc);
- /* Now delete */
- acpi_cm_remove_reference (previous_obj_desc);
- }
+ /* One for the attach to the Node */
X
- return (AE_OK);


-}
-
-
-/****************************************************************************
- *

- * FUNCTION: Acpi_ns_attach_method
- *
- * PARAMETERS: Handle - Handle of nte to be set
- * Offset - Value to be set
- * Length - Length associated with value
- *
- * DESCRIPTION: Record the given offset and p-code length of the method
- * whose handle is passed
- *
- * MUTEX: Assumes namespace is locked


- *
- ***************************************************************************/
-
-ACPI_STATUS

-acpi_ns_attach_method (
- ACPI_HANDLE handle,


- u8 *pcode_addr,
- u32 pcode_length)

-{
- ACPI_OBJECT_INTERNAL *obj_desc;
- ACPI_OBJECT_INTERNAL *previous_obj_desc;
- ACPI_NAMED_OBJECT *this_entry = (ACPI_NAMED_OBJECT*) handle;
-
-
- /* Parameter validation */
-
- if (!acpi_gbl_root_object->child_table) {
- /* Name space uninitialized */
-
- REPORT_ERROR ("Ns_attach_method: name space uninitialized");
- return (AE_NO_NAMESPACE);
- }
-
- if (!handle) {
- /* Null name handle */
-
- REPORT_ERROR ("Ns_attach_method: null name handle");
- return (AE_BAD_PARAMETER);
- }
-
-
- /* Allocate a method descriptor */
-
- obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_METHOD);
- if (!obj_desc) {
- /* Method allocation failure */
-
- REPORT_ERROR ("Ns_attach_method: allocation failure");


- return (AE_NO_MEMORY);
- }
-

- /* Init the method info */
-
- obj_desc->method.pcode = pcode_addr;
- obj_desc->method.pcode_length = pcode_length;
-
- /* Update reference count and install */
-
- acpi_cm_add_reference (obj_desc);
-
- previous_obj_desc = this_entry->object;
- this_entry->object = obj_desc;
+ acpi_cm_remove_reference (previous_obj_desc);
X
+ /* Now delete */
X
- /*
- * Delete an existing object. Don't try to re-use in case it is shared
- */
- if (previous_obj_desc) {
X acpi_cm_remove_reference (previous_obj_desc);
X }
X
@@ -364,11 +289,11 @@


X }
X
X
-/****************************************************************************
+/*******************************************************************************
X *

X * FUNCTION: Acpi_ns_detach_object
X *
- * PARAMETERS: Object - An object whose Value will be deleted
+ * PARAMETERS: Node - An object whose Value will be deleted


X *
X * RETURN: None.
X *

@@ -376,24 +301,23 @@
X * Value is an allocated object, it is freed. Otherwise, the
X * field is simply cleared.


X *
- ***************************************************************************/
+ ******************************************************************************/
X
X void

X acpi_ns_detach_object (
- ACPI_HANDLE object)
+ ACPI_NAMESPACE_NODE *node)
X {
- ACPI_NAMED_OBJECT *entry = object;
- ACPI_OBJECT_INTERNAL *obj_desc;


+ ACPI_OPERAND_OBJECT *obj_desc;
X
X

- obj_desc = entry->object;

+ obj_desc = node->object;
X if (!obj_desc) {

X return;
X }
X
X /* Clear the entry in all cases */
X
- entry->object = NULL;
+ node->object = NULL;
X
X /* Found a valid value */
X
@@ -412,16 +336,16 @@


X }
X
X
-/****************************************************************************
+/*******************************************************************************
X *

X * FUNCTION: Acpi_ns_get_attached_object
X *
- * PARAMETERS: Handle - Handle of nte to be examined
+ * PARAMETERS: Handle - Parent Node to be examined
X *
- * RETURN: Current value of the object field from nte whose handle is
- * passed
+ * RETURN: Current value of the object field from the Node whose
+ * handle is passed


X *
- ***************************************************************************/
+ ******************************************************************************/
X

X void *
X acpi_ns_get_attached_object (
@@ -435,122 +359,7 @@
X return (NULL);
X }
X
- return (((ACPI_NAMED_OBJECT*) handle)->object);


-}
-
-
-/****************************************************************************
- *

- * FUNCTION: Acpi_ns_compare_object
- *
- * PARAMETERS: Obj_handle - A namespace entry
- * Level - Current nesting level
- * Obj_desc - The value to be compared
- *
- * DESCRIPTION: A User_function called by Acpi_ns_walk_namespace(). It performs
- * a comparison for Acpi_ns_find_attached_object(). The comparison is against
- * the value in the value field of the Obj_handle (an NTE).
- * If a match is found, the handle is returned, which aborts
- * Acpi_ns_walk_namespace.


- *
- ***************************************************************************/
-
-ACPI_STATUS

-acpi_ns_compare_object (


- ACPI_HANDLE obj_handle,
- u32 level,

- void *obj_desc,


- void **return_value)
-{
-

- if (((ACPI_NAMED_OBJECT*) obj_handle)->object == obj_desc) {
- if (return_value) {
- *return_value = obj_handle;
- }
-
- /* Stop the walk */
- return AE_CTRL_TERMINATE;
- }
-
- /* Not found, continue the walk */
- return AE_OK;


-}
-
-
-/****************************************************************************
- *

- * FUNCTION: Acpi_ns_find_attached_object
- *
- * PARAMETERS: *Obj_desc - Value to be found in ptr_val field.
- * Start_handle - Root of subtree to be searched, or
- * NS_ALL to search the entire namespace
- * Max_depth - Maximum depth of search. Use INT_MAX
- * for an effectively unlimited depth.
- *
- * DESCRIPTION: Traverse the name space until finding a name whose Value field
- * matches the Obj_desc parameter, and return a handle to that
- * name, or (ACPI_HANDLE)0 if none exists.
- * if Start_handle is NS_ALL (null) search from the root,
- * else it is a handle whose children are to be searched.


- *
- ***************************************************************************/
-

-ACPI_HANDLE
-acpi_ns_find_attached_object (
- ACPI_OBJECT_INTERNAL *obj_desc,
- ACPI_HANDLE start_handle,
- s32 max_depth)
-{
- ACPI_HANDLE ret_object;


- ACPI_STATUS status;
-
-

- /* Parameter validation */
-
- if (!obj_desc) {
- return (NULL);
- }
-
- if (0 == max_depth) {
- return (NULL);
- }
-


- if (!acpi_gbl_root_object->child_table) {
- /*

- * If the name space has not been initialized,
- * there surely are no matching values.
- */
- return (NULL);
- }
-
- if (NS_ALL == start_handle) {
- start_handle = acpi_gbl_root_object;


- }
-
- else {
- /*

- * If base is not the root and has no children,
- * there is nothing to search.
- */
- return (NULL);


- }
-
-
- /*

- * Walk namespace until a match is found.
- * Either the matching object is returned, or NULL in case
- * of no match.
- */
- status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, start_handle,
- max_depth, NS_WALK_NO_UNLOCK,
- acpi_ns_compare_object,
- obj_desc, &ret_object);
-
- if (ACPI_FAILURE (status)) {
- ret_object = NULL;
- }
-
- return (ret_object);
+ return (((ACPI_NAMESPACE_NODE *) handle)->object);
X }
X
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/namespace/nssearch.c linux/drivers/acpi/namespace/nssearch.c
--- v2.4.0-test8/linux/drivers/acpi/namespace/nssearch.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/namespace/nssearch.c Fri Sep 15 14:30:30 2000


@@ -1,9 +1,9 @@
-
-/******************************************************************************
+/*******************************************************************************
X *

X * Module Name: nssearch - Namespace search
+ * $Revision: 57 $


X *
- *****************************************************************************/
+ ******************************************************************************/
X
X /*
X * Copyright (C) 2000 R. Byron Moore

@@ -26,192 +26,132 @@


X
X #include "acpi.h"
X #include "amlcode.h"
-#include "interp.h"
-#include "namesp.h"

+#include "acinterp.h"
+#include "acnamesp.h"
X
X
X #define _COMPONENT NAMESPACE

- MODULE_NAME ("nssearch");
+ MODULE_NAME ("nssearch")


X
X
-/****************************************************************************
+/*******************************************************************************
X *

- * FUNCTION: Acpi_ns_search_one_scope
+ * FUNCTION: Acpi_ns_search_node
X *
- * PARAMETERS: *Entry_name - Ascii ACPI name to search for
- * *Name_table - Starting table where search will begin
+ * PARAMETERS: *Target_name - Ascii ACPI name to search for
+ * *Node - Starting table where search will begin
X * Type - Object type to match
- * **Ret_entry - Where the matched NTE is returned
- * *Ret_info - Where info about the search is returned
+ * **Return_node - Where the matched Named obj is returned
X *
- * RETURN: Status and return information via NS_SEARCH_DATA
+ * RETURN: Status
X *
X * DESCRIPTION: Search a single namespace table. Performs a simple search,
X * does not add entries or search parents.


X *
- ***************************************************************************/
+ *

+ * Named object lists are built (and subsequently dumped) in the
+ * order in which the names are encountered during the namespace load;
+ *
+ * All namespace searching is linear in this implementation, but
+ * could be easily modified to support any improved search
+ * algorithm. However, the linear search was chosen for simplicity
+ * and because the trees are small and the other interpreter
+ * execution overhead is relatively high.
+ *


+ ******************************************************************************/
X
X ACPI_STATUS

-acpi_ns_search_one_scope (
- u32 entry_name,
- ACPI_NAME_TABLE *name_table,

+acpi_ns_search_node (
+ u32 target_name,
+ ACPI_NAMESPACE_NODE *node,
X OBJECT_TYPE_INTERNAL type,


- ACPI_NAMED_OBJECT **ret_entry,
- NS_SEARCH_DATA *ret_info)

+ ACPI_NAMESPACE_NODE **return_node)
X {
- u32 position;
- ACPI_NAME_TABLE *this_table;
- ACPI_NAME_TABLE *previous_table = name_table;
- ACPI_NAMED_OBJECT *entries;
- u8 table_full = TRUE;
- ACPI_NAME_TABLE *table_with_empty_slots = NULL;
- u32 empty_slot_position = 0;


+ ACPI_NAMESPACE_NODE *next_node;
X
X
X

- /*
- * Name tables are built (and subsequently dumped) in the
- * order in which the names are encountered during the namespace load;
- *
- * All namespace searching will be linear; If a table overflows an
- * additional segment will be allocated and added (chained).
- *
- * Start linear search at top of table
- */
- position = 0;
- this_table = name_table;
- entries = this_table->entries;
-
-
- /* Init return data */
-
- if (ret_info) {
- ret_info->name_table = this_table;
- }
-
X
X /*
- * Search entire name table, including all linked appendages
+ * Search for name in this table, which is to say that we must search
+ * for the name among the children of this object
X */
X
- while (this_table) {
- /*
- * Search for name in table, starting at Position. Stop
- * searching upon examining all entries in the table.
- *
- */
+ next_node = node->child;
+ while (next_node) {
+ /* Check for match against the name */
X
- entries = this_table->entries;
- while (position < NS_TABLE_SIZE) {
- /* Check for a valid entry */
-
- if (!entries[position].name) {
- if (table_full) {
- /*
- * There is room in the table for more
- * entries, if necessary
- */
-
- table_full = FALSE;
- table_with_empty_slots = this_table;
- empty_slot_position = position;
- }
- }
-
- /* Search for name in table */
+ if (next_node->name == target_name) {
+ /*
+ * Found matching entry. Capture type if
+ * appropriate before returning the entry.
+ */
X
- else if (entries[position].name == entry_name) {
- /*
- * Found matching entry. Capture type if
- * appropriate before returning the entry.
- */
-
- /*
- * The Def_field_defn and Bank_field_defn cases
- * are actually looking up the Region in which
- * the field will be defined
- */
-
- if ((INTERNAL_TYPE_DEF_FIELD_DEFN == type) ||
- (INTERNAL_TYPE_BANK_FIELD_DEFN == type))
- {
- type = ACPI_TYPE_REGION;
- }
-
- /*
- * Scope, Def_any, and Index_field_defn are bogus
- * "types" which do not actually have anything
- * to do with the type of the name being looked
- * up. For any other value of Type, if the type
- * stored in the entry is Any (i.e. unknown),
- * save the actual type.
- */
-
- if (type != INTERNAL_TYPE_SCOPE &&
- type != INTERNAL_TYPE_DEF_ANY &&
- type != INTERNAL_TYPE_INDEX_FIELD_DEFN &&
- entries[position].type == ACPI_TYPE_ANY)
- {
- entries[position].type = (u8) type;
- }


+ /*
+ * The Def_field_defn and Bank_field_defn cases

+ * are actually looking up the Region in which
+ * the field will be defined
+ */
X
- *ret_entry = &entries[position];
- return (AE_OK);


+ if ((INTERNAL_TYPE_DEF_FIELD_DEFN == type) ||
+ (INTERNAL_TYPE_BANK_FIELD_DEFN == type))
+ {
+ type = ACPI_TYPE_REGION;

X }
X

+ /*
+ * Scope, Def_any, and Index_field_defn are bogus

+ * "types" which do not actually have anything
+ * to do with the type of the name being looked
+ * up. For any other value of Type, if the type
+ * stored in the entry is Any (i.e. unknown),
+ * save the actual type.
+ */
X
- /* Didn't match name, move on to the next entry */
+ if (type != INTERNAL_TYPE_SCOPE &&
+ type != INTERNAL_TYPE_DEF_ANY &&
+ type != INTERNAL_TYPE_INDEX_FIELD_DEFN &&
+ next_node->type == ACPI_TYPE_ANY)
+ {
+ next_node->type = (u8) type;
+ }
X
- position++;
+ *return_node = next_node;


+ return (AE_OK);
X }
X
X

X /*
- * Just examined last slot in this table, move on
- * to next appendate.
- * All appendages, even to the root NT, contain
- * NS_TABLE_SIZE entries.
+ * The last entry in the list points back to the parent,
+ * so a flag is used to indicate the end-of-list
X */


+ if (next_node->flags & ANOBJ_END_OF_PEER_LIST) {

+ /* Searched entire list, we are done */
+
+ break;
+ }
X
- previous_table = this_table;
- this_table = this_table->next_table;
+ /* Didn't match name, move on to the next peer object */
X
- position = 0;
+ next_node = next_node->peer;
X }
X
X
X /* Searched entire table, not found */
X
X
- if (ret_info) {
- /*
- * Save info on if/where a slot is available
- * (name was not found)
- */
-
- ret_info->table_full = table_full;
- if (table_full) {
- ret_info->name_table = previous_table;
- }
-
- else {
- ret_info->position = empty_slot_position;
- ret_info->name_table = table_with_empty_slots;
- }
- }
-
X return (AE_NOT_FOUND);


X }
X
X
-/****************************************************************************
+/*******************************************************************************
X *

X * FUNCTION: Acpi_ns_search_parent_tree
X *
- * PARAMETERS: *Entry_name - Ascii ACPI name to search for
- * *Name_table - Starting table where search will begin
+ * PARAMETERS: *Target_name - Ascii ACPI name to search for
+ * *Node - Starting table where search will begin
X * Type - Object type to match
- * **Ret_entry - Where the matched NTE is returned
+ * **Return_node - Where the matched Named Obj is returned


X *
X * RETURN: Status
X *

@@ -227,274 +167,79 @@
X * indicates that the name is not found" (From ACPI Specification,
X * section 5.3)
X *
- ***************************************************************************/
-


+ ******************************************************************************/
X
X ACPI_STATUS

X acpi_ns_search_parent_tree (


- u32 entry_name,
- ACPI_NAME_TABLE *name_table,

+ u32 target_name,


+ ACPI_NAMESPACE_NODE *node,
X OBJECT_TYPE_INTERNAL type,

- ACPI_NAMED_OBJECT **ret_entry)
+ ACPI_NAMESPACE_NODE **return_node)
X {
X ACPI_STATUS status;

- ACPI_NAMED_OBJECT *parent_entry;
- ACPI_NAMED_OBJECT *entries;


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 033'
echo 'File patch-2.4.0-test9 is continued in part 034'
echo "034" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part034

#!/bin/sh -x
# this is part 034 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 034; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ ACPI_NAMESPACE_NODE *parent_node;
X
X

- entries = name_table->entries;
+ parent_node = acpi_ns_get_parent_object (node);
X
X /*
- * If no parent or type is "local", we won't be searching the
- * parent tree.
+ * If there is no parent (at the root) or type is "local", we won't be
+ * searching the parent tree.
X */
-
- if (!acpi_ns_local (type) &&
- name_table->parent_entry)
+ if ((acpi_ns_local (type)) ||
+ (!parent_node))
X {
- parent_entry = name_table->parent_entry;
- /*
- * Search parents until found or we have backed up to
- * the root
- */
-
- while (parent_entry) {
- /* Search parent scope */
- /* TBD: [Investigate] Why ACPI_TYPE_ANY? */
-
- status = acpi_ns_search_one_scope (entry_name,
- parent_entry->child_table,
- ACPI_TYPE_ANY,
- ret_entry, NULL);


X
- if (status == AE_OK) {

- return (status);
- }
-
- /*
- * Not found here, go up another level
- * (until we reach the root)
- */
-


- parent_entry = acpi_ns_get_parent_entry (parent_entry);
- }

-
- /* Not found in parent tree */
- }


-
-
- return (AE_NOT_FOUND);

-}
-
-
-/****************************************************************************
- *

- * FUNCTION: Acpi_ns_create_and_link_new_table
- *
- * PARAMETERS: *Name_table - The table that is to be "extended" by
- * the creation of an appendage table.
- *
- * RETURN: Status
- *
- * DESCRIPTION: Allocate a new namespace table, initialize it, and link it
- * into the parent table.
- *
- * NOTE: We are in the first or second pass load mode, want to
- * add a new table entry, and the current table is full.


- *
- ***************************************************************************/
-
-ACPI_STATUS

-acpi_ns_create_and_link_new_table (
- ACPI_NAME_TABLE *name_table)
-{
- ACPI_NAME_TABLE *new_table;
- ACPI_NAMED_OBJECT *parent_entry;
- ACPI_STATUS status = AE_OK;
-
-
- /* Sanity check on the data structure */
-
- if (name_table->next_table) {
- /* We should never get here (an appendage already allocated) */
-
- return (AE_AML_INTERNAL);


- }
-
-
- /*

- * We can use the parent entries from the current table
- * Since the parent information remains the same.
- */
- parent_entry = name_table->parent_entry;
-
-
- /* Allocate and chain an appendage to the filled table */
-
- new_table = acpi_ns_allocate_name_table (NS_TABLE_SIZE);
- if (!new_table) {
- REPORT_ERROR ("Name Table appendage allocation failure");
- return (AE_NO_MEMORY);
- }
X
- /*
- * Allocation successful. Init the new table.
- */
- name_table->next_table = new_table;
- acpi_ns_initialize_table (new_table, parent_entry->child_table,
- parent_entry);
-
- return (status);


-}
-
-
-/****************************************************************************
- *

- * FUNCTION: Acpi_ns_initialize_table
- *
- * PARAMETERS: New_table - The new table to be initialized
- * Parent_table - The parent (owner) scope
- * Parent_entry - The NTE for the parent
- *
- * RETURN: None
- *
- * DESCRIPTION: Initialize a new namespace table. Simple, but called
- * from several places -- code should be kept in one place.


- *
- ***************************************************************************/
-
-void

-acpi_ns_initialize_table (
- ACPI_NAME_TABLE *new_table,

- ACPI_NAME_TABLE *parent_table,
- ACPI_NAMED_OBJECT *parent_entry)
-{
- u8 i;
-
-
- new_table->parent_entry = parent_entry;
- new_table->parent_table = parent_table;
-
-
- /* Init each named object entry in the table */
-
- for (i = 0; i < NS_TABLE_SIZE; i++) {
- new_table->entries[i].this_index = i;
- new_table->entries[i].data_type = ACPI_DESC_TYPE_NAMED;


+ return (AE_NOT_FOUND);
X }
X

-}
-
-
-/****************************************************************************
- *

- * FUNCTION: Acpi_ns_initialize_entry
- *
- * PARAMETERS: Name_table - The containing table for the new NTE
- * Position - Position (index) of the new NTE in the table
- * Entry_name - ACPI name of the new entry
- * Type - ACPI object type of the new entry
- * Previous_entry - Link back to the previous entry (can span
- * multiple tables)
- *
- * RETURN: None
- *
- * DESCRIPTION: Initialize a new entry within a namespace table.


- *
- ***************************************************************************/
-
-void

-acpi_ns_initialize_entry (
- ACPI_WALK_STATE *walk_state,
- ACPI_NAME_TABLE *name_table,
- u32 position,
- u32 entry_name,
- OBJECT_TYPE_INTERNAL type)
-{
- ACPI_NAMED_OBJECT *new_entry;
- u16 owner_id = TABLE_ID_DSDT;
- ACPI_NAMED_OBJECT *entries;
X
+ /* Search the parent tree */
X
X /*
- * Get the owner ID from the Walk state
- * The owner ID is used to track table deletion and
- * deletion of objects created by methods
+ * Search parents until found the target or we have backed up to
+ * the root
X */
- if (walk_state) {
- owner_id = walk_state->owner_id;
- }
-
- /* The new entry is given by two parameters */
-
- entries = name_table->entries;
- new_entry = &entries[position];
-
- /* Init the new entry */
X
- new_entry->data_type = ACPI_DESC_TYPE_NAMED;
- new_entry->name = entry_name;
- new_entry->owner_id = owner_id;
- new_entry->reference_count = 1;
+ while (parent_node) {
+ /* Search parent scope */
+ /* TBD: [Investigate] Why ACPI_TYPE_ANY? */
X
+ status = acpi_ns_search_node (target_name, parent_node,
+ ACPI_TYPE_ANY, return_node);
X
- /*
- * If adding a name with unknown type, or having to
- * add the region in order to define fields in it, we
- * have a forward reference.
- */
+ if (ACPI_SUCCESS (status)) {
+ return (status);
+ }
X
- if ((ACPI_TYPE_ANY == type) ||
- (INTERNAL_TYPE_DEF_FIELD_DEFN == type) ||


- (INTERNAL_TYPE_BANK_FIELD_DEFN == type))
- {

X /*
- * We don't want to abort here, however!
- * We will fill in the actual type when the
- * real definition is found later.
+ * Not found here, go up another level
+ * (until we reach the root)
X */
X

+ parent_node = acpi_ns_get_parent_object (parent_node);

X }
X
- /*
- * The Def_field_defn and Bank_field_defn cases are actually
- * looking up the Region in which the field will be defined


- */
-
- if ((INTERNAL_TYPE_DEF_FIELD_DEFN == type) ||
- (INTERNAL_TYPE_BANK_FIELD_DEFN == type))
- {
- type = ACPI_TYPE_REGION;
- }

X
- /*
- * Scope, Def_any, and Index_field_defn are bogus "types" which do
- * not actually have anything to do with the type of the name
- * being looked up. Save any other value of Type as the type of
- * the entry.
- */
+ /* Not found in parent tree */
X
- if ((type != INTERNAL_TYPE_SCOPE) &&
- (type != INTERNAL_TYPE_DEF_ANY) &&
- (type != INTERNAL_TYPE_INDEX_FIELD_DEFN))
- {
- new_entry->type = (u8) type;
- }
-
- return;
+ return (AE_NOT_FOUND);


X }
X
X
-/****************************************************************************
+/*******************************************************************************
X *

X * FUNCTION: Acpi_ns_search_and_enter
X *
- * PARAMETERS: Entry_name - Ascii ACPI name to search for (4 chars)


- * *Name_table - Starting table where search will begin

- * Interpreter_mode - Add names only in MODE_Load_pass_x. Otherwise,
- * search only.
+ * PARAMETERS: Target_name - Ascii ACPI name to search for (4 chars)


+ * Walk_state - Current state of the walk

+ * *Node - Starting table where search will begin

+ * Interpreter_mode - Add names only in MODE_Load_pass_x.
+ * Otherwise,search only.


X * Type - Object type to match
- * **Ret_entry - Where the matched NTE is returned

+ * Flags - Flags describing the search restrictions

+ * **Return_node - Where the Node is returned


X *
X * RETURN: Status
X *

@@ -506,51 +251,48 @@
X * In IMODE_EXECUTE, search only.
X * In other modes, search and add if not found.


X *
- ***************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS

X acpi_ns_search_and_enter (
- u32 entry_name,
+ u32 target_name,
X ACPI_WALK_STATE *walk_state,
- ACPI_NAME_TABLE *name_table,
+ ACPI_NAMESPACE_NODE *node,
X OPERATING_MODE interpreter_mode,
X OBJECT_TYPE_INTERNAL type,
X u32 flags,


- ACPI_NAMED_OBJECT **ret_entry)
+ ACPI_NAMESPACE_NODE **return_node)
X {

- u32 position; /* position in table */
X ACPI_STATUS status;
- NS_SEARCH_DATA search_info;
- ACPI_NAMED_OBJECT *entry;
- ACPI_NAMED_OBJECT *entries;
+ ACPI_NAMESPACE_NODE *new_node;
X

X
X /* Parameter validation */
X

- if (!name_table || !entry_name || !ret_entry) {
- REPORT_ERROR ("Ns_search_and_enter: bad parameter");
+ if (!node || !target_name || !return_node) {
+ REPORT_ERROR ("Ns_search_and_enter: bad (null)parameter");


X return (AE_BAD_PARAMETER);
X }
X

X
X /* Name must consist of printable characters */
X
- if (!acpi_cm_valid_acpi_name (entry_name)) {
+ if (!acpi_cm_valid_acpi_name (target_name)) {
+ REPORT_ERROR ("Ns_search_and_enter: Bad character in ACPI Name");
X return (AE_BAD_CHARACTER);
X }
X
X
X /* Try to find the name in the table specified by the caller */
X
- *ret_entry = ENTRY_NOT_FOUND;
- status = acpi_ns_search_one_scope (entry_name, name_table,
- type, ret_entry, &search_info);
+ *return_node = ENTRY_NOT_FOUND;
+ status = acpi_ns_search_node (target_name, node,
+ type, return_node);
X if (status != AE_NOT_FOUND) {
X /*
X * Either found it or there was an error
X * -- finished either way


X */
-
X return (status);
X }
X

@@ -573,10 +315,9 @@
X * to ACPI specification
X */
X
- status = acpi_ns_search_parent_tree (entry_name, name_table,
- type, ret_entry);
-


- if (status == AE_OK) {

+ status = acpi_ns_search_parent_tree (target_name, node,
+ type, return_node);
+ if (ACPI_SUCCESS (status)) {


X return (status);
X }
X }

@@ -585,61 +326,22 @@
X /*
X * In execute mode, just search, never add names. Exit now.
X */
-
X if (interpreter_mode == IMODE_EXECUTE) {


X return (AE_NOT_FOUND);
X }
X
X

- /*
- * Extract the pertinent info from the search result struct.
- * Name_table and position might now point to an appendage
- */
- name_table = search_info.name_table;
- position = search_info.position;
+ /* Create the new named object */
X
-
- /*
- * This block handles the case where the existing table is full.
- * we must allocate a new table before we can initialize a new entry
- */
-
- if (search_info.table_full) {
- status = acpi_ns_create_and_link_new_table (name_table);


- if (status != AE_OK) {

- return (status);
- }
-
- /* Point to the first slot in the new table */
-
- name_table = name_table->next_table;
- position = 0;
+ new_node = acpi_ns_create_node (target_name);
+ if (!new_node) {


+ return (AE_NO_MEMORY);
X }
X

+ /* Install the new object into the parent's list of children */
X
- /*
- * There is room in the table (or we have just allocated a new one.)
- * Initialize the new entry
- */
-
- acpi_ns_initialize_entry (walk_state, name_table, position,
- entry_name, type);
-
-
- entries = name_table->entries;


- *ret_entry = &entries[position];

- entry = &entries[position];
-
- /*
- * Increment the reference count(s) of all parents up to
- * the root!
- */
-
- while (acpi_ns_get_parent_entry (entry)) {


- entry = acpi_ns_get_parent_entry (entry);

- entry->reference_count++;
- }
-
+ acpi_ns_install_node (walk_state, node, new_node, type);
+ *return_node = new_node;
X
X return (AE_OK);
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/namespace/nsutils.c linux/drivers/acpi/namespace/nsutils.c
--- v2.4.0-test8/linux/drivers/acpi/namespace/nsutils.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/namespace/nsutils.c Fri Sep 15 14:30:30 2000
@@ -1,8 +1,8 @@


-
X /******************************************************************************
X *

X * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing
- * parents and siblings and Scope manipulation
+ * parents and siblings and Scope manipulation
+ * $Revision: 69 $


X *
X *****************************************************************************/
X

@@ -26,13 +26,13 @@


X
X
X #include "acpi.h"

-#include "namesp.h"
-#include "interp.h"
+#include "acnamesp.h"
+#include "acinterp.h"

X #include "amlcode.h"
-#include "tables.h"
+#include "actables.h"


X
X #define _COMPONENT NAMESPACE

- MODULE_NAME ("nsutils");
+ MODULE_NAME ("nsutils")
X
X
X /****************************************************************************


@@ -49,7 +49,7 @@
X

X u8
X acpi_ns_valid_root_prefix (
- char prefix)
+ NATIVE_CHAR prefix)
X {
X
X return ((u8) (prefix == '\\'));
@@ -70,7 +70,7 @@
X
X u8
X acpi_ns_valid_path_separator (
- char sep)
+ NATIVE_CHAR sep)
X {
X
X return ((u8) (sep == '.'));
@@ -81,9 +81,9 @@
X *
X * FUNCTION: Acpi_ns_get_type


X *
- * PARAMETERS: Handle - Handle of nte to be examined
+ * PARAMETERS: Handle - Parent Node to be examined
X *

- * RETURN: Type field from nte whose handle is passed
+ * RETURN: Type field from Node whose handle is passed
X *
X ***************************************************************************/
X
@@ -93,13 +93,11 @@
X {
X
X if (!handle) {
- /* Handle invalid */
-
X REPORT_WARNING ("Ns_get_type: Null handle");
X return (ACPI_TYPE_ANY);
X }
X
- return (((ACPI_NAMED_OBJECT*) handle)->type);
+ return (((ACPI_NAMESPACE_NODE *) handle)->type);
X }
X
X
@@ -114,19 +112,19 @@


X *
X ***************************************************************************/
X

-s32
+u32
X acpi_ns_local (
X OBJECT_TYPE_INTERNAL type)
X {
X
X if (!acpi_cm_valid_object_type (type)) {
- /* type code out of range */
+ /* Type code out of range */
X
X REPORT_WARNING ("Ns_local: Invalid Object Type");
X return (NSP_NORMAL);
X }
X
- return ((s32) acpi_gbl_ns_properties[type] & NSP_LOCAL);
+ return ((u32) acpi_gbl_ns_properties[type] & NSP_LOCAL);
X }
X
X
@@ -147,12 +145,12 @@
X
X ACPI_STATUS
X acpi_ns_internalize_name (
- char *external_name,
- char **converted_name)
+ NATIVE_CHAR *external_name,
+ NATIVE_CHAR **converted_name)
X {
- char *result = NULL;
- char *internal_name;
- ACPI_SIZE num_segments;
+ NATIVE_CHAR *result = NULL;
+ NATIVE_CHAR *internal_name;
+ u32 num_segments;
X u8 fully_qualified = FALSE;
X u32 i;
X
@@ -235,7 +233,7 @@
X }
X
X else {
- /* Convert char to uppercase and save it */
+ /* Convert s8 to uppercase and save it */
X
X result[i] = (char) TOUPPER (*external_name);
X external_name++;
@@ -273,166 +271,17 @@
X
X /****************************************************************************
X *
- * FUNCTION: Acpi_ns_externalize_name
- *
- * PARAMETERS: *Internal_name - Internal representation of name
- * **Converted_name - Where to return the resulting
- * external representation of name
- *
- * RETURN: Status
- *
- * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30)
- * to its external form (e.g. "\_PR_.CPU0")


- *
- ****************************************************************************/
-

-ACPI_STATUS
-acpi_ns_externalize_name (
- u32 internal_name_length,
- char *internal_name,
- u32 *converted_name_length,
- char **converted_name)

-{
- u32 prefix_length = 0;
- u32 names_index = 0;
- u32 names_count = 0;
- u32 i = 0;
- u32 j = 0;
-
- if (internal_name_length < 0 ||
- !internal_name ||
- !converted_name_length ||
- !converted_name)
- {


- return (AE_BAD_PARAMETER);
- }
-

- /*
- * Check for a prefix (one '\' | one or more '^').
- */
- switch (internal_name[0])
- {
- case '\\':
- prefix_length = 1;
- break;
-
- case '^':
- for (i = 0; i < internal_name_length; i++) {
- if (internal_name[i] != '^') {
- prefix_length = i + 1;
- }
- }
-
- if (i == internal_name_length) {
- prefix_length = i;
- }
-
- break;
- }
-
- /*
- * Check for object names. Note that there could be 0-255 of these
- * 4-byte elements.
- */
- if (prefix_length < internal_name_length) {
- switch (internal_name[prefix_length])
- {
-
- /* <count> 4-byte names */
-
- case AML_MULTI_NAME_PREFIX_OP:
- names_index = prefix_length + 2;
- names_count = (u32) internal_name[prefix_length + 1];
- break;
-
-
- /* two 4-byte names */
-
- case AML_DUAL_NAME_PREFIX:
- names_index = prefix_length + 1;
- names_count = 2;
- break;
-
-
- /* Null_name */
-
- case 0:
- names_index = 0;
- names_count = 0;
- break;
-
-
- /* one 4-byte name */
-
- default:
- names_index = prefix_length;
- names_count = 1;
- break;


- }
- }
-
- /*

- * Calculate the length of Converted_name, which equals the length
- * of the prefix, length of all object names, length of any required
- * punctuation ('.') between object names, plus the NULL terminator.
- */
- *converted_name_length = prefix_length + (4 * names_count) +
- ((names_count > 0) ? (names_count - 1) : 0) + 1;
-
- /*
- * Check to see if we're still in bounds. If not, there's a problem
- * with Internal_name (invalid format).
- */
- if (*converted_name_length > internal_name_length) {
- REPORT_ERROR ("Ns_externalize_name: Invalid internal name.\n");
- return (AE_BAD_PATHNAME);
- }
-
- /*
- * Build Converted_name...
- */
-
- (*converted_name) = acpi_cm_callocate (*converted_name_length);
- if (!(*converted_name)) {


- return (AE_NO_MEMORY);
- }
-

- j = 0;
-
- for (i = 0; i < prefix_length; i++) {
- (*converted_name)[j++] = internal_name[i];
- }
-
- if (names_count > 0) {
- for (i = 0; i < names_count; i++) {
- if (i > 0) {
- (*converted_name)[j++] = '.';
- }
-
- (*converted_name)[j++] = internal_name[names_index++];
- (*converted_name)[j++] = internal_name[names_index++];
- (*converted_name)[j++] = internal_name[names_index++];
- (*converted_name)[j++] = internal_name[names_index++];
- }
- }
-


- return (AE_OK);
-}
-
-
-/****************************************************************************
- *

X * FUNCTION: Acpi_ns_convert_handle_to_entry
X *
- * PARAMETERS: Handle - Handle to be converted to an NTE
+ * PARAMETERS: Handle - Handle to be converted to an Node
X *
X * RETURN: A Name table entry pointer
X *
- * DESCRIPTION: Convert a namespace handle to a real NTE
+ * DESCRIPTION: Convert a namespace handle to a real Node


X *
X ****************************************************************************/
X

-ACPI_NAMED_OBJECT*
+ACPI_NAMESPACE_NODE *
X acpi_ns_convert_handle_to_entry (
X ACPI_HANDLE handle)
X {
@@ -444,21 +293,21 @@
X */
X
X if (!handle) {


- return NULL;
+ return (NULL);
X }
X

X if (handle == ACPI_ROOT_OBJECT) {
- return acpi_gbl_root_object;
+ return (acpi_gbl_root_node);
X }
X
X
X /* We can at least attempt to verify the handle */
X
X if (!VALID_DESCRIPTOR_TYPE (handle, ACPI_DESC_TYPE_NAMED)) {
- return NULL;
+ return (NULL);
X }
X
- return (ACPI_NAMED_OBJECT*) handle;
+ return ((ACPI_NAMESPACE_NODE *) handle);
X }
X
X
@@ -466,16 +315,17 @@
X *
X * FUNCTION: Acpi_ns_convert_entry_to_handle
X *
- * PARAMETERS: Nte - NTE to be converted to a Handle
+ * PARAMETERS: Node - Node to be converted to a Handle
X *
X * RETURN: An USER ACPI_HANDLE
X *
- * DESCRIPTION: Convert a real NTE to a namespace handle
+ * DESCRIPTION: Convert a real Node to a namespace handle


X *
X ****************************************************************************/
X

X ACPI_HANDLE
-acpi_ns_convert_entry_to_handle(ACPI_NAMED_OBJECT*nte)
+acpi_ns_convert_entry_to_handle (
+ ACPI_NAMESPACE_NODE *node)
X {
X
X
@@ -485,21 +335,21 @@
X * and keep all pointers within this subsystem!
X */
X
- return (ACPI_HANDLE) nte;
+ return ((ACPI_HANDLE) node);
X
X
X /* ---------------------------------------------------
X
- if (!Nte) {
- return NULL;
+ if (!Node) {
+ return (NULL);
X }
X
- if (Nte == Acpi_gbl_Root_object) {
- return ACPI_ROOT_OBJECT;
+ if (Node == Acpi_gbl_Root_node) {
+ return (ACPI_ROOT_OBJECT);
X }
X
X
- return (ACPI_HANDLE) Nte;
+ return ((ACPI_HANDLE) Node);
X ------------------------------------------------------*/
X }
X
@@ -519,11 +369,11 @@
X void
X acpi_ns_terminate (void)
X {
- ACPI_OBJECT_INTERNAL *obj_desc;
- ACPI_NAMED_OBJECT *entry;
+ ACPI_OPERAND_OBJECT *obj_desc;
+ ACPI_NAMESPACE_NODE *this_node;
X
X
- entry = acpi_gbl_root_object;
+ this_node = acpi_gbl_root_node;
X
X /*
X * 1) Free the entire namespace -- all objects, tables, and stacks
@@ -533,22 +383,19 @@
X * (additional table descriptors)
X */
X
- acpi_ns_delete_namespace_subtree (entry);
+ acpi_ns_delete_namespace_subtree (this_node);
X
X /* Detach any object(s) attached to the root */
X
- obj_desc = acpi_ns_get_attached_object (entry);
+ obj_desc = acpi_ns_get_attached_object (this_node);
X if (obj_desc) {
- acpi_ns_detach_object (entry);
+ acpi_ns_detach_object (this_node);


X acpi_cm_remove_reference (obj_desc);
X }
X

- acpi_ns_delete_name_table (entry->child_table);


- entry->child_table = NULL;

+ acpi_ns_delete_children (this_node);
X
X
- REPORT_SUCCESS ("Entire namespace and objects deleted");
-
X /*
X * 2) Now we can delete the ACPI tables
X */
@@ -570,7 +417,7 @@
X *
X ***************************************************************************/
X
-s32
+u32
X acpi_ns_opens_scope (
X OBJECT_TYPE_INTERNAL type)
X {
@@ -582,47 +429,46 @@
X return (NSP_NORMAL);
X }
X
- return (((s32) acpi_gbl_ns_properties[type]) & NSP_NEWSCOPE);
+ return (((u32) acpi_gbl_ns_properties[type]) & NSP_NEWSCOPE);
X }
X
X
X /****************************************************************************
X *
- * FUNCTION: Acpi_ns_get_named_object
+ * FUNCTION: Acpi_ns_get_node
X *
X * PARAMETERS: *Pathname - Name to be found, in external (ASL) format. The
X * \ (backslash) and ^ (carat) prefixes, and the
X * . (period) to separate segments are supported.
- * In_scope - Root of subtree to be searched, or NS_ALL for the
+ * Start_node - Root of subtree to be searched, or NS_ALL for the
X * root of the name space. If Name is fully
- * qualified (first char is '\'), the passed value
+ * qualified (first s8 is '\'), the passed value
X * of Scope will not be accessed.
- * Out_nte - Where the Nte is returned
+ * Return_node - Where the Node is returned
X *
X * DESCRIPTION: Look up a name relative to a given scope and return the
- * corresponding NTE. NOTE: Scope can be null.
+ * corresponding Node. NOTE: Scope can be null.
X *
X * MUTEX: Locks namespace


X *
X ***************************************************************************/
X
X ACPI_STATUS

-acpi_ns_get_named_object (
- char *pathname,


- ACPI_NAME_TABLE *in_scope,
- ACPI_NAMED_OBJECT **out_nte)

+acpi_ns_get_node (
+ NATIVE_CHAR *pathname,

+ ACPI_NAMESPACE_NODE *start_node,
+ ACPI_NAMESPACE_NODE **return_node)
X {
X ACPI_GENERIC_STATE scope_info;


X ACPI_STATUS status;
- ACPI_NAMED_OBJECT *obj_entry = NULL;
- char *internal_path = NULL;

+ NATIVE_CHAR *internal_path = NULL;
X
X

- scope_info.scope.name_table = in_scope;
+ scope_info.scope.node = start_node;
X
X /* Ensure that the namespace has been initialized */


X
- if (!acpi_gbl_root_object->child_table) {
+ if (!acpi_gbl_root_node) {
X return (AE_NO_NAMESPACE);
X }
X

@@ -643,13 +489,13 @@
X
X /* NS_ALL means start from the root */
X
- if (NS_ALL == scope_info.scope.name_table) {
- scope_info.scope.name_table = acpi_gbl_root_object->child_table;
+ if (NS_ALL == scope_info.scope.node) {
+ scope_info.scope.node = acpi_gbl_root_node;
X }
X
X else {
- scope_info.scope.name_table = in_scope;
- if (!scope_info.scope.name_table) {
+ scope_info.scope.node = start_node;
+ if (!scope_info.scope.node) {


X status = AE_BAD_PARAMETER;
X goto unlock_and_exit;
X }

@@ -660,12 +506,8 @@
X status = acpi_ns_lookup (&scope_info, internal_path,
X ACPI_TYPE_ANY, IMODE_EXECUTE,
X NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE,
- NULL, &obj_entry);
-
+ NULL, return_node);
X
- /* Return what was wanted - the NTE that matches the name */
-
- *out_nte = obj_entry;
X
X
X unlock_and_exit:
@@ -684,11 +526,11 @@
X *
X * FUNCTION: Acpi_ns_find_parent_name
X *
- * PARAMETERS: *Child_entry - nte whose name is to be found
+ * PARAMETERS: *Child_node - Named Obj whose name is to be found
X *
X * RETURN: The ACPI name
X *
- * DESCRIPTION: Search for the given nte in its parent scope and return the
+ * DESCRIPTION: Search for the given obj in its parent scope and return the
X * name segment, or "????" if the parent name can't be found
X * (which "should not happen").
X *
@@ -696,18 +538,18 @@
X
X ACPI_NAME
X acpi_ns_find_parent_name (
- ACPI_NAMED_OBJECT *child_entry)
+ ACPI_NAMESPACE_NODE *child_node)
X {
- ACPI_NAMED_OBJECT *parent_entry;


+ ACPI_NAMESPACE_NODE *parent_node;
X
X

- if (child_entry) {
- /* Valid entry. Get the parent Nte */
+ if (child_node) {
+ /* Valid entry. Get the parent Node */
X
- parent_entry = acpi_ns_get_parent_entry (child_entry);
- if (parent_entry) {
- if (parent_entry->name) {
- return (parent_entry->name);
+ parent_node = acpi_ns_get_parent_object (child_node);
+ if (parent_node) {
+ if (parent_node->name) {
+ return (parent_node->name);
X }
X }
X
@@ -717,92 +559,12 @@
X return (ACPI_UNKNOWN_NAME);


X }
X
-/****************************************************************************
- *

- * FUNCTION: Acpi_ns_exist_downstream_sibling
- *
- * PARAMETERS: *This_entry - pointer to first nte to examine
- *
- * RETURN: TRUE if sibling is found, FALSE otherwise
- *
- * DESCRIPTION: Searches remainder of scope being processed to determine
- * whether there is a downstream sibling to the current
- * object. This function is used to determine what type of
- * line drawing character to use when displaying namespace
- * trees.


- *
- ***************************************************************************/
-
-u8

-acpi_ns_exist_downstream_sibling (
- ACPI_NAMED_OBJECT *this_entry)
-{
-

- if (!this_entry) {


- return FALSE;
- }
-

- if (this_entry->name) {


- return TRUE;
- }
-
-

-/* TBD: what did this really do?
- if (This_entry->Next_entry) {
- return TRUE;
- }
-*/


- return FALSE;
-}
-
-

-/****************************************************************************
- *
- * FUNCTION: Acpi_ns_get_owner_table


- *
- * PARAMETERS:

- *
- * RETURN:

- *
- * DESCRIPTION:

- *
- ***************************************************************************/
-
-

-ACPI_NAME_TABLE *
-acpi_ns_get_owner_table (
- ACPI_NAMED_OBJECT *this_entry)
-{
-
- /*
- * Given an entry in the Name_table->Entries field of a name table,
- * we can create a pointer to the beginning of the table as follows:
- *
- * 1) Starting with the the pointer to the entry,
- * 2) Subtract the entry index * size of each entry to get a
- * pointer to Entries[0]
- * 3) Subtract the size of NAME_TABLE structure to get a pointer
- * to the start.
- *
- * This saves having to put a pointer in every entry that points
- * back to the beginning of the table and/or a pointer back to
- * the parent.
- */
-
- return (ACPI_NAME_TABLE *) ((char *) this_entry -
- (this_entry->this_index *
- sizeof (ACPI_NAMED_OBJECT)) -
- (sizeof (ACPI_NAME_TABLE) -
- sizeof (ACPI_NAMED_OBJECT)));
-
-}
-
X
X /****************************************************************************
X *
- * FUNCTION: Acpi_ns_get_parent_entry
+ * FUNCTION: Acpi_ns_get_parent_object
X *
- * PARAMETERS: This_entry - Current table entry
+ * PARAMETERS: Node - Current table entry
X *
X * RETURN: Parent entry of the given entry
X *
@@ -811,76 +573,58 @@
X ***************************************************************************/
X
X

-ACPI_NAMED_OBJECT *
-acpi_ns_get_parent_entry (
- ACPI_NAMED_OBJECT *this_entry)

+ACPI_NAMESPACE_NODE *
+acpi_ns_get_parent_object (
+ ACPI_NAMESPACE_NODE *node)
X {
- ACPI_NAME_TABLE *name_table;
X
X
- name_table = acpi_ns_get_owner_table (this_entry);
-
X /*
- * Now that we have a pointer to the name table, we can just pluck
- * the parent
+ * Walk to the end of this peer list.
+ * The last entry is marked with a flag and the peer
+ * pointer is really a pointer back to the parent.
+ * This saves putting a parent back pointer in each and
+ * every named object!
X */
X
- return (name_table->parent_entry);
+ while (!(node->flags & ANOBJ_END_OF_PEER_LIST)) {
+ node = node->peer;
+ }
+
+
+ return (node->peer);
X }
X
X
X /****************************************************************************
X *
- * FUNCTION: Acpi_ns_get_next_valid_entry
+ * FUNCTION: Acpi_ns_get_next_valid_object
X *
- * PARAMETERS: This_entry - Current table entry
+ * PARAMETERS: Node - Current table entry
X *
X * RETURN: Next valid object in the table. NULL if no more valid
X * objects
X *
X * DESCRIPTION: Find the next valid object within a name table.
+ * Useful for implementing NULL-end-of-list loops.


X *
X ***************************************************************************/
X
X

-ACPI_NAMED_OBJECT *
-acpi_ns_get_next_valid_entry (
- ACPI_NAMED_OBJECT *this_entry)

+ACPI_NAMESPACE_NODE *
+acpi_ns_get_next_valid_object (
+ ACPI_NAMESPACE_NODE *node)
X {
- ACPI_NAME_TABLE *name_table;
- u32 index;
-
-
- index = this_entry->this_index + 1;
- name_table = acpi_ns_get_owner_table (this_entry);
-
-
- while (name_table) {
- if (index >= NS_TABLE_SIZE) {
- /* We are at the end of this table */
X
- name_table = name_table->next_table;
- index = 0;
- continue;
- }
-
-
- /* Is this a valid (occupied) slot? */
-
- if (name_table->entries[index].name) {
- /* Found a valid entry, all done */
+ /* If we are at the end of this peer list, return NULL */
X
- return (&name_table->entries[index]);
- }
-
- /* Go to the next slot */
-
- index++;
+ if (node->flags & ANOBJ_END_OF_PEER_LIST) {
+ return NULL;
X }
X
- /* No more valid entries in this name table */
+ /* Otherwise just return the next peer */
X
- return NULL;
+ return (node->peer);
X }
X
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/namespace/nswalk.c linux/drivers/acpi/namespace/nswalk.c
--- v2.4.0-test8/linux/drivers/acpi/namespace/nswalk.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/namespace/nswalk.c Fri Sep 15 14:30:30 2000


@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *

X * Module Name: nswalk - Functions for walking the APCI namespace
+ * $Revision: 17 $


X *
X *****************************************************************************/
X

@@ -25,90 +25,85 @@


X
X
X #include "acpi.h"
-#include "interp.h"
-#include "namesp.h"
+#include "acinterp.h"
+#include "acnamesp.h"
X

X
X #define _COMPONENT NAMESPACE

- MODULE_NAME ("nswalk");
+ MODULE_NAME ("nswalk")
X
X
X /****************************************************************************
X *
X * FUNCTION: Acpi_get_next_object
X *
- * PARAMETERS: Type - Type of object to be searched for
- * Parent - Parent object whose children we are getting
- * Last_child - Previous child that was found.
- * The NEXT child will be returned
- * Ret_handle - Where handle to the next object is placed
- *
- * RETURN: Status
- *
- * DESCRIPTION: Return the next peer object within the namespace. If Handle is
- * valid, Scope is ignored. Otherwise, the first object within
- * Scope is returned.
+ * PARAMETERS: Type - Type of object to be searched for
+ * Parent - Parent object whose children we are
+ * getting
+ * Last_child - Previous child that was found.
+ * The NEXT child will be returned
+ *
+ * RETURN: ACPI_NAMESPACE_NODE - Pointer to the NEXT child or NULL if
+ * none is found.
+ *
+ * DESCRIPTION: Return the next peer object within the namespace. If Handle
+ * is valid, Scope is ignored. Otherwise, the first object
+ * within Scope is returned.
X *
- ******************************************************************************/
+ ****************************************************************************/
X
-ACPI_NAMED_OBJECT*
+ACPI_NAMESPACE_NODE *
X acpi_ns_get_next_object (
X OBJECT_TYPE_INTERNAL type,
- ACPI_NAMED_OBJECT *parent,
- ACPI_NAMED_OBJECT *child)
+ ACPI_NAMESPACE_NODE *parent_node,
+ ACPI_NAMESPACE_NODE *child_node)
X {
- ACPI_NAMED_OBJECT *this_entry = NULL;
+ ACPI_NAMESPACE_NODE *next_node = NULL;
X
X
- if (!child) {
+ if (!child_node) {
X
X /* It's really the parent's _scope_ that we want */
X
- if (parent->child_table) {
- this_entry = parent->child_table->entries;
+ if (parent_node->child) {


+ next_node = parent_node->child;

X }
X }
X
X else {

X /* Start search at the NEXT object */
X
- this_entry = acpi_ns_get_next_valid_entry (child);
+ next_node = acpi_ns_get_next_valid_object (child_node);
X }
X
X
X /* If any type is OK, we are done */
X
X if (type == ACPI_TYPE_ANY) {
- /* Make sure this is valid entry first */
-
- if ((!this_entry) ||
- (!this_entry->name))
- {
- return NULL;
- }
+ /* Next_node is NULL if we are at the end-of-list */
X
- return (this_entry);
+ return (next_node);
X }
X
X
X /* Must search for the object -- but within this scope only */
X
- while (this_entry) {
+ while (next_node) {
X /* If type matches, we are done */
X
- if (this_entry->type == type) {
- return (this_entry);
+ if (next_node->type == type) {
+ return (next_node);
X }
X
X /* Otherwise, move on to the next object */
X
- this_entry = acpi_ns_get_next_valid_entry (this_entry);
+ next_node = acpi_ns_get_next_valid_object (next_node);
X }
X
X
X /* Not found */
X

- return NULL;
+ return (NULL);
X }
X

X
@@ -117,7 +112,7 @@
X * FUNCTION: Acpi_ns_walk_namespace
X *
X * PARAMETERS: Type - ACPI_OBJECT_TYPE to search for
- * Start_object - Handle in namespace where search begins
+ * Start_node - Handle in namespace where search begins
X * Max_depth - Depth to which search is to reach
X * Unlock_before_callback- Whether to unlock the NS before invoking
X * the callback routine
@@ -145,7 +140,7 @@
X ACPI_STATUS
X acpi_ns_walk_namespace (
X OBJECT_TYPE_INTERNAL type,
- ACPI_HANDLE start_object,
+ ACPI_HANDLE start_node,
X u32 max_depth,
X u8 unlock_before_callback,
X WALK_CALLBACK user_function,
@@ -153,25 +148,25 @@
X void **return_value)
X {
X ACPI_STATUS status;
- ACPI_NAMED_OBJECT *child_entry;


- ACPI_NAMED_OBJECT *parent_entry;
+ ACPI_NAMESPACE_NODE *child_node;
+ ACPI_NAMESPACE_NODE *parent_node;

X OBJECT_TYPE_INTERNAL child_type;
X u32 level;
X
X
- /* Special case for the namespace root object */
+ /* Special case for the namespace Root Node */
X
- if (start_object == ACPI_ROOT_OBJECT) {
- start_object = acpi_gbl_root_object;
+ if (start_node == ACPI_ROOT_OBJECT) {
+ start_node = acpi_gbl_root_node;
X }
X
X
X /* Null child means "get first object" */
X
- parent_entry = start_object;
- child_entry = 0;
- child_type = ACPI_TYPE_ANY;
- level = 1;
+ parent_node = start_node;
+ child_node = 0;
+ child_type = ACPI_TYPE_ANY;
+ level = 1;
X
X /*
X * Traverse the tree of objects until we bubble back up to where we
@@ -186,18 +181,18 @@
X */
X
X status = AE_OK;


- child_entry = acpi_ns_get_next_object (ACPI_TYPE_ANY,
- parent_entry,
- child_entry);
+ child_node = acpi_ns_get_next_object (ACPI_TYPE_ANY,

+ parent_node,


+ child_node);
X
- if (child_entry) {

+ if (child_node) {
X /*

X * Found an object, Get the type if we are not
X * searching for ANY
X */
X
X if (type != ACPI_TYPE_ANY) {
- child_type = child_entry->type;
+ child_type = child_node->type;
X }
X
X if (child_type == type) {
@@ -210,7 +205,7 @@


X acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
X }
X

- status = user_function (child_entry, level,
+ status = user_function (child_node, level,
X context, return_value);
X
X if (unlock_before_callback) {
@@ -247,15 +242,15 @@
X
X if ((level < max_depth) && (status != AE_CTRL_DEPTH)) {
X if (acpi_ns_get_next_object (ACPI_TYPE_ANY,
- child_entry, 0))
+ child_node, 0))
X {
X /*


X * There is at least one child of this

X * object, visit the object


X */
X level++;
- parent_entry = child_entry;
- child_entry = 0;

+ parent_node = child_node;


+ child_node = 0;
X }
X }
X }

@@ -267,8 +262,8 @@
X * the object's parent.
X */
X level--;
- child_entry = parent_entry;


- parent_entry = acpi_ns_get_parent_entry (parent_entry);

+ child_node = parent_node;


+ parent_node = acpi_ns_get_parent_object (parent_node);

X }
X }
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/namespace/nsxfname.c linux/drivers/acpi/namespace/nsxfname.c
--- v2.4.0-test8/linux/drivers/acpi/namespace/nsxfname.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/namespace/nsxfname.c Fri Sep 15 14:30:30 2000
@@ -2,6 +2,7 @@
X *
X * Module Name: nsxfname - Public interfaces to the ACPI subsystem
X * ACPI Namespace oriented interfaces
+ * $Revision: 64 $


X *
X *****************************************************************************/
X

@@ -25,16 +26,16 @@


X
X
X #include "acpi.h"
-#include "interp.h"
-#include "namesp.h"
+#include "acinterp.h"
+#include "acnamesp.h"
X #include "amlcode.h"
-#include "parser.h"
-#include "dispatch.h"

-#include "events.h"
+#include "acparser.h"
+#include "acdispat.h"
+#include "acevents.h"


X
X
X #define _COMPONENT NAMESPACE

- MODULE_NAME ("nsxfname");
+ MODULE_NAME ("nsxfname")
X
X
X /******************************************************************************
@@ -64,21 +65,6 @@
X }
X
X
- /* Init the hardware */
-
- /*
- * TBD: [Restructure] Should this should be moved elsewhere,
- * like Acpi_enable! ??
- */
-
- /* we need to be able to call this interface repeatedly! */
- /* Does H/W require init before loading the namespace? */
-
- status = acpi_cm_hardware_initialize ();


- if (ACPI_FAILURE (status)) {
- return (status);
- }

-
X /*
X * Load the namespace. The DSDT is required,
X * but the SSDT and PSDT tables are optional.
@@ -131,24 +117,24 @@
X ACPI_HANDLE *ret_handle)
X {
X ACPI_STATUS status;
- ACPI_NAMED_OBJECT *this_entry;
- ACPI_NAME_TABLE *scope = NULL;
+ ACPI_NAMESPACE_NODE *node;
+ ACPI_NAMESPACE_NODE *prefix_node = NULL;
X
X
X if (!ret_handle || !pathname) {
- return AE_BAD_PARAMETER;
+ return (AE_BAD_PARAMETER);
X }
X
X if (parent) {
X acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
X
- this_entry = acpi_ns_convert_handle_to_entry (parent);
- if (!this_entry) {
+ node = acpi_ns_convert_handle_to_entry (parent);
+ if (!node) {
X acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
- return AE_BAD_PARAMETER;
+ return (AE_BAD_PARAMETER);
X }
X
- scope = this_entry->child_table;
+ prefix_node = node->child;


X acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
X }
X

@@ -156,17 +142,20 @@
X /* TBD: [Investigate] Check for both forward and backslash?? */
X
X if (STRCMP (pathname, NS_ROOT_PATH) == 0) {
- *ret_handle = acpi_ns_convert_entry_to_handle (acpi_gbl_root_object);
- return AE_OK;
+ *ret_handle = acpi_ns_convert_entry_to_handle (acpi_gbl_root_node);


+ return (AE_OK);
X }
X

X /*
- * Find the Nte and convert to the user format
+ * Find the Node and convert to the user format
X */
- this_entry = NULL;
- status = acpi_ns_get_named_object (pathname, scope, &this_entry);
+ node = NULL;
+ status = acpi_ns_get_node (pathname, prefix_node, &node);
X
- *ret_handle = acpi_ns_convert_entry_to_handle (this_entry);
+ *ret_handle = NULL;
+ if(ACPI_SUCCESS(status)) {
+ *ret_handle = acpi_ns_convert_entry_to_handle (node);
+ }


X
X return (status);
X }

@@ -195,13 +184,13 @@
X ACPI_BUFFER *ret_path_ptr)
X {
X ACPI_STATUS status;
- ACPI_NAMED_OBJECT *obj_entry;


+ ACPI_NAMESPACE_NODE *node;
X
X

X /* Buffer pointer must be valid always */
X
X if (!ret_path_ptr || (name_type > ACPI_NAME_TYPE_MAX)) {
- return AE_BAD_PARAMETER;
+ return (AE_BAD_PARAMETER);
X }
X
X /* Allow length to be zero and ignore the pointer */
@@ -209,7 +198,7 @@
X if ((ret_path_ptr->length) &&
X (!ret_path_ptr->pointer))
X {
- return AE_BAD_PARAMETER;
+ return (AE_BAD_PARAMETER);
X }
X
X if (name_type == ACPI_FULL_PATHNAME) {
@@ -217,17 +206,17 @@
X
X status = acpi_ns_handle_to_pathname (handle, &ret_path_ptr->length,
X ret_path_ptr->pointer);
- return status;


+ return (status);
X }
X

X /*
X * Wants the single segment ACPI name.
- * Validate handle and convert to an NTE
+ * Validate handle and convert to an Node


X */
X
X acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);

- obj_entry = acpi_ns_convert_handle_to_entry (handle);
- if (!obj_entry) {
+ node = acpi_ns_convert_handle_to_entry (handle);
+ if (!node) {
X status = AE_BAD_PARAMETER;
X goto unlock_and_exit;
X }

@@ -240,18 +229,18 @@
X goto unlock_and_exit;
X }
X
- /* Just copy the ACPI name from the NTE and zero terminate it */
+ /* Just copy the ACPI name from the Node and zero terminate it */
X
- STRNCPY (ret_path_ptr->pointer, (char *) &obj_entry->name,
+ STRNCPY (ret_path_ptr->pointer, (NATIVE_CHAR *) &node->name,
X ACPI_NAME_SIZE);
- ((char *) ret_path_ptr->pointer) [ACPI_NAME_SIZE] = 0;
+ ((NATIVE_CHAR *) ret_path_ptr->pointer) [ACPI_NAME_SIZE] = 0;


X status = AE_OK;
X

X
X unlock_and_exit:
X
X acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
- return status;


+ return (status);
X }
X
X

@@ -279,27 +268,27 @@
X ACPI_STATUS status;
X u32 device_status = 0;
X u32 address = 0;
- ACPI_NAMED_OBJECT *device_entry;
+ ACPI_NAMESPACE_NODE *device_node;
X

X
X /* Parameter validation */
X

X if (!device || !info) {


- return AE_BAD_PARAMETER;
+ return (AE_BAD_PARAMETER);

X }
X
X acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);

X
- device_entry = acpi_ns_convert_handle_to_entry (device);
- if (!device_entry) {
+ device_node = acpi_ns_convert_handle_to_entry (device);
+ if (!device_node) {
X acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
- return AE_BAD_PARAMETER;
+ return (AE_BAD_PARAMETER);
X }
X
- info->type = device_entry->type;
- info->name = device_entry->name;
- info->parent =
- acpi_ns_convert_entry_to_handle (acpi_ns_get_parent_entry (device_entry));
+ info->type = device_node->type;
+ info->name = device_node->name;
+ info->parent = acpi_ns_convert_entry_to_handle (
+ acpi_ns_get_parent_object (device_node));


X
X acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
X

@@ -307,17 +296,17 @@
X * If not a device, we are all done.
X */
X if (info->type != ACPI_TYPE_DEVICE) {
- return AE_OK;


+ return (AE_OK);
X }
X
X

X /* Get extra info for ACPI devices */
X
- info->valid = 0;
+ info->valid = 0;
X
X /* Execute the _HID method and save the result */
X
- status = acpi_cm_execute_HID (device_entry, &hid);
+ status = acpi_cm_execute_HID (device_node, &hid);
X if (ACPI_SUCCESS (status)) {
X if (hid.type == STRING_PTR_DEVICE_ID) {
X STRCPY (info->hardware_id, hid.data.string_ptr);
@@ -331,7 +320,7 @@
X
X /* Execute the _UID method and save the result */
X
- status = acpi_cm_execute_UID (device_entry, &uid);
+ status = acpi_cm_execute_UID (device_node, &uid);
X if (ACPI_SUCCESS (status)) {
X if (hid.type == STRING_PTR_DEVICE_ID) {
X STRCPY (info->unique_id, uid.data.string_ptr);
@@ -348,7 +337,7 @@
X * _STA is not always present
X */
X
- status = acpi_cm_execute_STA (device_entry, &device_status);
+ status = acpi_cm_execute_STA (device_node, &device_status);
X if (ACPI_SUCCESS (status)) {
X info->current_status = device_status;
X info->valid |= ACPI_VALID_STA;
@@ -360,13 +349,13 @@
X */
X
X status = acpi_cm_evaluate_numeric_object (METHOD_NAME__ADR,
- device_entry, &address);
+ device_node, &address);
X
X if (ACPI_SUCCESS (status)) {
X info->address = address;
X info->valid |= ACPI_VALID_ADR;


X }
X
- return AE_OK;

+ return (AE_OK);
X }
X

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/namespace/nsxfobj.c linux/drivers/acpi/namespace/nsxfobj.c
--- v2.4.0-test8/linux/drivers/acpi/namespace/nsxfobj.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/namespace/nsxfobj.c Fri Sep 15 14:30:30 2000


@@ -1,10 +1,10 @@
-
-/******************************************************************************
+/*******************************************************************************
X *

X * Module Name: nsxfobj - Public interfaces to the ACPI subsystem
X * ACPI Object oriented interfaces
+ * $Revision: 65 $


X *
- *****************************************************************************/
+ ******************************************************************************/
X
X /*
X * Copyright (C) 2000 R. Byron Moore

@@ -26,15 +26,15 @@


X
X
X #include "acpi.h"
-#include "interp.h"
-#include "namesp.h"
+#include "acinterp.h"
+#include "acnamesp.h"
X

X
X #define _COMPONENT NAMESPACE

- MODULE_NAME ("nsxfobj");
+ MODULE_NAME ("nsxfobj")


X
X
-/****************************************************************************
+/*******************************************************************************
X *

X * FUNCTION: Acpi_evaluate_object
X *
@@ -54,7 +54,7 @@
X * parameters if necessary. One of "Handle" or "Pathname" must
X * be valid (non-null)


X *
- ****************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS

X acpi_evaluate_object (
@@ -64,9 +64,9 @@
X ACPI_BUFFER *return_buffer)
X {
X ACPI_STATUS status;
- ACPI_OBJECT_INTERNAL **param_ptr = NULL;
- ACPI_OBJECT_INTERNAL *return_obj = NULL;
- ACPI_OBJECT_INTERNAL *object_ptr = NULL;
+ ACPI_OPERAND_OBJECT **param_ptr = NULL;
+ ACPI_OPERAND_OBJECT *return_obj = NULL;
+ ACPI_OPERAND_OBJECT *object_ptr = NULL;
X u32 buffer_space_needed;
X u32 user_buffer_length;
X u32 count;
@@ -85,12 +85,11 @@
X /*
X * Allocate a new parameter block for the internal objects
X * Add 1 to count to allow for null terminated internal list
- * TBD: [Restructure] merge into single allocation!
X */
X
X count = param_objects->count;
X param_length = (count + 1) * sizeof (void *);
- object_length = count * sizeof (ACPI_OBJECT_INTERNAL);
+ object_length = count * sizeof (ACPI_OPERAND_OBJECT);
X
X param_ptr = acpi_cm_callocate (param_length + /* Parameter List part */
X object_length); /* Actual objects */
@@ -98,7 +97,7 @@


X return (AE_NO_MEMORY);
X }
X

- object_ptr = (ACPI_OBJECT_INTERNAL *) ((u8 *) param_ptr +
+ object_ptr = (ACPI_OPERAND_OBJECT *) ((u8 *) param_ptr +
X param_length);
X
X /*
@@ -169,18 +168,15 @@
X * The null pathname case means the handle is for
X * the actual object to be evaluated
X */
- status = acpi_ns_evaluate_by_handle (handle,
- param_ptr,
- &return_obj);
+ status = acpi_ns_evaluate_by_handle (handle, param_ptr, &return_obj);


X }
X
X else {
X /*

X * Both a Handle and a relative Pathname
X */
- status = acpi_ns_evaluate_relative (handle, pathname,
- param_ptr,
- &return_obj);
+ status = acpi_ns_evaluate_relative (handle, pathname, param_ptr,
+ &return_obj);
X }
X }
X
@@ -195,11 +191,9 @@
X return_buffer->length = 0;
X
X if (return_obj) {
- if (VALID_DESCRIPTOR_TYPE (return_obj,
- ACPI_DESC_TYPE_NAMED))
- {
+ if (VALID_DESCRIPTOR_TYPE (return_obj, ACPI_DESC_TYPE_NAMED)) {
X /*
- * If we got an NTE as a return object,
+ * If we got an Node as a return object,
X * this means the object we are evaluating
X * has nothing interesting to return (such
X * as a mutex, etc.) We return an error
@@ -210,7 +204,7 @@
X * types at a later date if necessary.
X */
X status = AE_TYPE;
- return_obj = NULL; /* No need to delete an NTE */
+ return_obj = NULL; /* No need to delete an Node */
X }
X
X if (ACPI_SUCCESS (status)) {
@@ -241,9 +235,8 @@
X /*
X * We have enough space for the object, build it


X */
- status =

- acpi_cm_build_external_object (return_obj,
- return_buffer);
+ status = acpi_cm_build_external_object (return_obj,
+ return_buffer);
X return_buffer->length = buffer_space_needed;
X }
X }
@@ -276,7 +269,7 @@


X }
X
X
-/****************************************************************************
+/*******************************************************************************
X *

X * FUNCTION: Acpi_get_next_object
X *
@@ -302,15 +295,15 @@
X ACPI_HANDLE *ret_handle)


X {
X ACPI_STATUS status = AE_OK;

- ACPI_NAMED_OBJECT *entry;
- ACPI_NAMED_OBJECT *parent_entry = NULL;
- ACPI_NAMED_OBJECT *child_entry = NULL;
+ ACPI_NAMESPACE_NODE *node;
+ ACPI_NAMESPACE_NODE *parent_node = NULL;
+ ACPI_NAMESPACE_NODE *child_node = NULL;
X
X
X /* Parameter validation */
X
X if (type > ACPI_TYPE_MAX) {


- return AE_BAD_PARAMETER;
+ return (AE_BAD_PARAMETER);

X }
X
X acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);

@@ -320,8 +313,8 @@
X if (!child) {
X /* Start search at the beginning of the specified scope */
X
- parent_entry = acpi_ns_convert_handle_to_entry (parent);
- if (!parent_entry) {
+ parent_node = acpi_ns_convert_handle_to_entry (parent);
+ if (!parent_node) {


X status = AE_BAD_PARAMETER;
X goto unlock_and_exit;
X }

@@ -332,8 +325,8 @@
X else {
X /* Convert and validate the handle */
X
- child_entry = acpi_ns_convert_handle_to_entry (child);
- if (!child_entry) {
+ child_node = acpi_ns_convert_handle_to_entry (child);
+ if (!child_node) {


X status = AE_BAD_PARAMETER;
X goto unlock_and_exit;
X }

@@ -342,26 +335,26 @@
X
X /* Internal function does the real work */
X
- entry = acpi_ns_get_next_object ((OBJECT_TYPE_INTERNAL) type,
- parent_entry, child_entry);
- if (!entry) {
+ node = acpi_ns_get_next_object ((OBJECT_TYPE_INTERNAL) type,
+ parent_node, child_node);
+ if (!node) {
X status = AE_NOT_FOUND;


X goto unlock_and_exit;
X }
X

X if (ret_handle) {
- *ret_handle = acpi_ns_convert_entry_to_handle (entry);
+ *ret_handle = acpi_ns_convert_entry_to_handle (node);
X }
X
X
X unlock_and_exit:
X
X acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
- return status;


+ return (status);
X }
X
X

-/****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_get_type
X *
@@ -379,44 +372,43 @@
X ACPI_HANDLE handle,
X ACPI_OBJECT_TYPE *ret_type)
X {
- ACPI_NAMED_OBJECT *object;


+ ACPI_NAMESPACE_NODE *node;
X
X

X /* Parameter Validation */
X
X if (!ret_type) {


- return AE_BAD_PARAMETER;
+ return (AE_BAD_PARAMETER);

X }
X
X /*
- * Special case for the predefined Root Object
+ * Special case for the predefined Root Node
X * (return type ANY)
X */
-
X if (handle == ACPI_ROOT_OBJECT) {
X *ret_type = ACPI_TYPE_ANY;
- return AE_OK;


+ return (AE_OK);
X }
X

X acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE);
X
X /* Convert and validate the handle */
X
- object = acpi_ns_convert_handle_to_entry (handle);
- if (!object) {


+ node = acpi_ns_convert_handle_to_entry (handle);
+ if (!node) {

X acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
- return AE_BAD_PARAMETER;
+ return (AE_BAD_PARAMETER);
X }
X
- *ret_type = object->type;
+ *ret_type = node->type;
X
X
X acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
- return AE_OK;


+ return (AE_OK);
X }
X
X

-/****************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_get_parent
X *
@@ -435,7 +427,7 @@
X ACPI_HANDLE handle,
X ACPI_HANDLE *ret_handle)
X {
- ACPI_NAMED_OBJECT *object;
+ ACPI_NAMESPACE_NODE *node;


X ACPI_STATUS status = AE_OK;
X
X

@@ -443,13 +435,13 @@
X
X
X if (!ret_handle) {
- return AE_BAD_PARAMETER;
+ return (AE_BAD_PARAMETER);
X }
X
- /* Special case for the predefined Root Object (no parent) */
+ /* Special case for the predefined Root Node (no parent) */
X
X if (handle == ACPI_ROOT_OBJECT) {
- return AE_NULL_ENTRY;
+ return (AE_NULL_ENTRY);
X }
X
X
@@ -457,8 +449,8 @@
X
X /* Convert and validate the handle */
X
- object = acpi_ns_convert_handle_to_entry (handle);
- if (!object) {


+ node = acpi_ns_convert_handle_to_entry (handle);
+ if (!node) {
X status = AE_BAD_PARAMETER;
X goto unlock_and_exit;
X }

@@ -467,11 +459,11 @@
X /* Get the parent entry */
X
X *ret_handle =
- acpi_ns_convert_entry_to_handle (acpi_ns_get_parent_entry (object));
+ acpi_ns_convert_entry_to_handle (acpi_ns_get_parent_object (node));
X
X /* Return exeption if parent is null */
X
- if (!acpi_ns_get_parent_entry (object)) {
+ if (!acpi_ns_get_parent_object (node)) {
X status = AE_NULL_ENTRY;
X }
X
@@ -479,11 +471,11 @@
X unlock_and_exit:
X
X acpi_cm_release_mutex (ACPI_MTX_NAMESPACE);
- return AE_OK;


+ return (status);
X }
X
X

-/******************************************************************************
+/*******************************************************************************
X *
X * FUNCTION: Acpi_walk_namespace
X *
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/os.c linux/drivers/acpi/os.c
--- v2.4.0-test8/linux/drivers/acpi/os.c Thu Jul 13 09:39:49 2000
+++ linux/drivers/acpi/os.c Fri Sep 22 14:21:17 2000
@@ -24,11 +24,14 @@
X #include <linux/mm.h>
X #include <linux/pci.h>
X #include <linux/acpi.h>
+#include <linux/delay.h>
X #include <asm/io.h>
-#include <asm/delay.h>
X #include "acpi.h"


X #include "driver.h"
X
+#define _COMPONENT OS_DEPENDENT

+ MODULE_NAME ("os")
+
X static int acpi_irq_irq = 0;
X static OSD_HANDLER acpi_irq_handler = NULL;
X static void *acpi_irq_context = NULL;
@@ -61,7 +64,7 @@
X }
X
X s32
-acpi_os_printf(const char *fmt,...)
+acpi_os_printf(const NATIVE_CHAR *fmt,...)
X {
X s32 size;
X va_list args;
@@ -72,11 +75,11 @@
X }
X
X s32
-acpi_os_vprintf(const char *fmt, va_list args)
+acpi_os_vprintf(const NATIVE_CHAR *fmt, va_list args)
X {
X static char buffer[512];
X int size = vsprintf(buffer, fmt, args);
- printk(KERN_DEBUG "ACPI: %s", buffer);
+ printk("%s", buffer);
X return size;
X }
X
@@ -137,7 +140,7 @@
X acpi_irq_context = context;
X if (request_irq(irq,
X acpi_irq,
- SA_INTERRUPT | SA_SHIRQ,
+ SA_SHIRQ,
X "acpi",
X acpi_irq)) {
X printk(KERN_ERR "ACPI: SCI (IRQ%d) allocation failed\n", irq);


@@ -338,7 +341,7 @@
X }

X
X ACPI_STATUS
-acpi_os_breakpoint(char *msg)
+acpi_os_breakpoint(NATIVE_CHAR *msg)
X {
X acpi_os_printf("breakpoint: %s", msg);
X return AE_OK;


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 034'
echo 'File patch-2.4.0-test9 is continued in part 035'
echo "035" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part035

#!/bin/sh -x
# this is part 035 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 035; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

@@ -351,13 +354,13 @@
X }
X
X void
-acpi_os_dbg_assert(void *failure, void *file, u32 line, char *msg)
+acpi_os_dbg_assert(void *failure, void *file, u32 line, NATIVE_CHAR *msg)
X {
X acpi_os_printf("assert: %s", msg);
X }
X
X u32
-acpi_os_get_line(char *buffer)
+acpi_os_get_line(NATIVE_CHAR *buffer)
X {
X return 0;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/parser/Makefile linux/drivers/acpi/parser/Makefile
--- v2.4.0-test8/linux/drivers/acpi/parser/Makefile Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/parser/Makefile Fri Sep 15 18:21:44 2000

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/parser/psargs.c linux/drivers/acpi/parser/psargs.c
--- v2.4.0-test8/linux/drivers/acpi/parser/psargs.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/parser/psargs.c Fri Sep 15 14:30:30 2000
@@ -1,6 +1,7 @@
X /******************************************************************************
X *
X * Module Name: psargs - Parse AML opcode arguments
+ * $Revision: 35 $


X *
X *****************************************************************************/
X

@@ -24,12 +25,26 @@


X
X
X #include "acpi.h"

-#include "parser.h"
+#include "acparser.h"


X #include "amlcode.h"
-#include "namesp.h"

+#include "acnamesp.h"
X
X #define _COMPONENT PARSER
- MODULE_NAME ("psargs");
+ MODULE_NAME ("psargs")
+
+
+u32
+acpi_ps_pkg_length_encoding_size (
+ u32 first_byte)
+{
+
+ /*
+ * Bits 6-7 contain the number of bytes
+ * in the encoded package length (-1)
+ */
+
+ return ((first_byte >> 6) + 1);
+}
X
X
X /*******************************************************************************
@@ -46,14 +61,63 @@
X ******************************************************************************/
X
X u32
+xxx_acpi_ps_get_next_package_length (
+ ACPI_PARSE_STATE *parser_state)
+{
+ u32 encoding_length;
+ u32 package_length = 0;
+ u8 *aml_ptr = parser_state->aml;
+
+
+ encoding_length = acpi_ps_pkg_length_encoding_size ((u32) GET8 (aml_ptr));
+
+
+ switch (encoding_length)
+ {
+ case 1: /* 1-byte encoding (bits 0-5) */
+
+ package_length = ((u32) GET8 (aml_ptr) & 0x3f);
+ break;
+
+
+ case 2: /* 2-byte encoding (next byte + bits 0-3) */
+
+ package_length = ((((u32) GET8 (aml_ptr + 1)) << 4) |
+ (((u32) GET8 (aml_ptr)) & 0x0f));
+ break;
+
+
+ case 3: /* 3-byte encoding (next 2 bytes + bits 0-3) */
+
+ package_length = ((((u32) GET8 (aml_ptr + 2)) << 12) |
+ (((u32) GET8 (aml_ptr + 1)) << 4) |
+ (((u32) GET8 (aml_ptr)) & 0x0f));
+ break;
+
+
+ case 4: /* 4-byte encoding (next 3 bytes + bits 0-3) */
+
+ package_length = ((((u32) GET8 (aml_ptr + 3)) << 20) |
+ (((u32) GET8 (aml_ptr + 2)) << 12) |
+ (((u32) GET8 (aml_ptr + 1)) << 4) |
+ (((u32) GET8 (aml_ptr)) & 0x0f));
+ break;
+ }
+
+ parser_state->aml += encoding_length;
+
+ return (package_length);
+}
+
+u32
X acpi_ps_get_next_package_length (
X ACPI_PARSE_STATE *parser_state)
X {
- s32 encoded_length;
- s32 length = 0;
+ u32 encoded_length;
+ u32 length = 0;
X
X
- encoded_length = (s32) GET8 (parser_state->aml);
+ encoded_length = (u32) GET8 (parser_state->aml);
X parser_state->aml++;
X
X
@@ -137,13 +201,13 @@


X *
X ******************************************************************************/
X

-char *
+NATIVE_CHAR *
X acpi_ps_get_next_namestring (
X ACPI_PARSE_STATE *parser_state)
X {
- char *start = (char *) parser_state->aml;
- char *end = (char *) parser_state->aml;
- s32 length;
+ u8 *start = parser_state->aml;
+ u8 *end = parser_state->aml;
+ u32 length;
X
X
X /* Handle multiple prefix characters */


@@ -181,7 +245,7 @@
X

X /* multiple name segments */
X
- length = (s32) GET8 (end + 1) * 4;
+ length = (u32) GET8 (end + 1) * 4;
X end += 2 + length;
X break;
X
@@ -197,7 +261,7 @@
X
X parser_state->aml = (u8*) end;
X
- return (start);
+ return ((NATIVE_CHAR *) start);
X }
X
X
@@ -228,14 +292,14 @@
X void
X acpi_ps_get_next_namepath (
X ACPI_PARSE_STATE *parser_state,
- ACPI_GENERIC_OP *arg,
+ ACPI_PARSE_OBJECT *arg,
X u32 *arg_count,
X u8 method_call)
X {
- char *path;
- ACPI_GENERIC_OP *name;
- ACPI_GENERIC_OP *op;
- ACPI_GENERIC_OP *count;
+ NATIVE_CHAR *path;
+ ACPI_PARSE_OBJECT *name_op;
+ ACPI_PARSE_OBJECT *op;
+ ACPI_PARSE_OBJECT *count;
X
X
X path = acpi_ps_get_next_namestring (parser_state);
@@ -270,18 +334,18 @@
X
X count = acpi_ps_get_arg (op, 0);
X if (count && count->opcode == AML_BYTE_OP) {
- name = acpi_ps_alloc_op (AML_NAMEPATH_OP);
- if (name) {
+ name_op = acpi_ps_alloc_op (AML_NAMEPATH_OP);
+ if (name_op) {
X /* Change arg into a METHOD CALL and attach the name */
X
X acpi_ps_init_op (arg, AML_METHODCALL_OP);
X
- name->value.name = path;
+ name_op->value.name = path;
X
- /* Point METHODCALL/NAME to the METHOD NTE */
+ /* Point METHODCALL/NAME to the METHOD Node */
X
- name->acpi_named_object = op;
- acpi_ps_append_arg (arg, name);
+ name_op->node = (ACPI_NAMESPACE_NODE *) op;
+ acpi_ps_append_arg (arg, name_op);
X
X *arg_count = count->value.integer &
X METHOD_FLAGS_ARG_COUNT;
@@ -320,15 +384,15 @@
X void
X acpi_ps_get_next_namepath (
X ACPI_PARSE_STATE *parser_state,
- ACPI_GENERIC_OP *arg,
+ ACPI_PARSE_OBJECT *arg,
X u32 *arg_count,
X u8 method_call)
X {
- char *path;
- ACPI_GENERIC_OP *name;
+ NATIVE_CHAR *path;
+ ACPI_PARSE_OBJECT *name_op;
X ACPI_STATUS status;
- ACPI_NAMED_OBJECT *method = NULL;
- ACPI_NAMED_OBJECT *entry;
+ ACPI_NAMESPACE_NODE *method_node = NULL;
+ ACPI_NAMESPACE_NODE *node;


X ACPI_GENERIC_STATE scope_info;
X
X

@@ -346,10 +410,10 @@
X /*
X * Lookup the name in the internal namespace
X */
- scope_info.scope.name_table = NULL;
- entry = parser_state->start_op->acpi_named_object;
- if (entry) {
- scope_info.scope.name_table = entry->child_table;
+ scope_info.scope.node = NULL;
+ node = parser_state->start_node;
+ if (node) {
+ scope_info.scope.node = node;
X }
X
X /*
@@ -361,24 +425,24 @@
X
X status = acpi_ns_lookup (&scope_info, path, ACPI_TYPE_ANY, IMODE_EXECUTE,
X NS_SEARCH_PARENT | NS_DONT_OPEN_SCOPE, NULL,
- &entry);
+ &node);
X if (ACPI_SUCCESS (status)) {
- if (entry->type == ACPI_TYPE_METHOD) {
- method = entry;
- name = acpi_ps_alloc_op (AML_NAMEPATH_OP);
- if (name) {
+ if (node->type == ACPI_TYPE_METHOD) {
+ method_node = node;
+ name_op = acpi_ps_alloc_op (AML_NAMEPATH_OP);
+ if (name_op) {
X /* Change arg into a METHOD CALL and attach name to it */
X
X acpi_ps_init_op (arg, AML_METHODCALL_OP);
X
- name->value.name = path;
+ name_op->value.name = path;
X
- /* Point METHODCALL/NAME to the METHOD NTE */
+ /* Point METHODCALL/NAME to the METHOD Node */
X
- name->acpi_named_object = method;
- acpi_ps_append_arg (arg, name);
+ name_op->node = method_node;
+ acpi_ps_append_arg (arg, name_op);
X
- *arg_count = ((ACPI_OBJECT_INTERNAL *) method->object)->method.param_count;
+ *arg_count = ((ACPI_OPERAND_OBJECT *) method_node->object)->method.param_count;
X }
X
X return;
@@ -424,8 +488,8 @@
X void
X acpi_ps_get_next_simple_arg (
X ACPI_PARSE_STATE *parser_state,
- s32 arg_type,
- ACPI_GENERIC_OP *arg)
+ u32 arg_type,


+ ACPI_PARSE_OBJECT *arg)
X {
X

X
@@ -498,13 +562,13 @@


X *
X ******************************************************************************/
X

-ACPI_GENERIC_OP *
+ACPI_PARSE_OBJECT *
X acpi_ps_get_next_field (
X ACPI_PARSE_STATE *parser_state)
X {
X ACPI_PTRDIFF aml_offset = parser_state->aml -
X parser_state->aml_start;
- ACPI_GENERIC_OP *field;
+ ACPI_PARSE_OBJECT *field;
X u16 opcode;
X u32 name;
X
@@ -598,16 +662,16 @@


X *
X ******************************************************************************/
X

-ACPI_GENERIC_OP *
+ACPI_PARSE_OBJECT *
X acpi_ps_get_next_arg (
X ACPI_PARSE_STATE *parser_state,
- s32 arg_type,
+ u32 arg_type,
X u32 *arg_count)
X {
- ACPI_GENERIC_OP *arg = NULL;
- ACPI_GENERIC_OP *prev = NULL;
- ACPI_GENERIC_OP *field;
- s32 subop;
+ ACPI_PARSE_OBJECT *arg = NULL;
+ ACPI_PARSE_OBJECT *prev = NULL;
+ ACPI_PARSE_OBJECT *field;
+ u32 subop;
X
X
X switch (arg_type)
@@ -675,7 +739,7 @@
X /* fill in bytelist data */
X
X arg->value.size = (parser_state->pkg_end - parser_state->aml);
- acpi_ps_to_bytelist_op (arg)->data = parser_state->aml;
+ ((ACPI_PARSE2_OBJECT *) arg)->data = parser_state->aml;
X }
X
X /* skip to End of byte data */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/parser/psfind.c linux/drivers/acpi/parser/psfind.c
--- v2.4.0-test8/linux/drivers/acpi/parser/psfind.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/parser/psfind.c Fri Sep 15 14:30:30 2000
@@ -0,0 +1,319 @@
+
+/******************************************************************************
+ *
+ * Module Name: psfind - Parse tree search routine


+ * $Revision: 16 $

+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 R. Byron Moore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "acpi.h"

+#include "acparser.h"
+#include "amlcode.h"
+
+#define _COMPONENT PARSER
+ MODULE_NAME ("psfind")


+
+
+/*******************************************************************************
+ *

+ * FUNCTION: Acpi_ps_get_parent
+ *
+ * PARAMETERS: Op - Get the parent of this Op
+ *
+ * RETURN: The Parent op.
+ *
+ * DESCRIPTION: Get op's parent


+ *
+ ******************************************************************************/
+

+ACPI_PARSE_OBJECT*
+acpi_ps_get_parent (
+ ACPI_PARSE_OBJECT *op)
+{
+ ACPI_PARSE_OBJECT *parent = op;
+
+
+ /* Traverse the tree upward (to root if necessary) */
+
+ while (parent) {
+ switch (parent->opcode)
+ {
+ case AML_SCOPE_OP:
+ case AML_PACKAGE_OP:
+ case AML_METHOD_OP:
+ case AML_DEVICE_OP:
+ case AML_POWER_RES_OP:
+ case AML_THERMAL_ZONE_OP:
+
+ return (parent->parent);
+ }
+
+ parent = parent->parent;
+ }
+
+ return (parent);


+}
+
+
+/*******************************************************************************
+ *

+ * FUNCTION: Acpi_ps_find_name
+ *
+ * PARAMETERS: Scope - Scope to search
+ * Name - ACPI name to search for
+ * Opcode - Opcode to search for
+ *
+ * RETURN: Op containing the name
+ *
+ * DESCRIPTION: Find name segment from a list of acpi_ops. Searches a single
+ * scope, no more.


+ *
+ ******************************************************************************/
+

+ACPI_PARSE_OBJECT *
+acpi_ps_find_name (
+ ACPI_PARSE_OBJECT *scope,
+ u32 name,
+ u32 opcode)
+{
+ ACPI_PARSE_OBJECT *op;
+ ACPI_PARSE_OBJECT *field;
+
+
+ /* search scope level for matching name segment */
+
+ op = acpi_ps_get_child (scope);
+
+ while (op) {
+
+ if (acpi_ps_is_field_op (op->opcode)) {
+ /* Field, search named fields */
+
+ field = acpi_ps_get_child (op);
+ while (field) {
+ if (acpi_ps_is_named_op (field->opcode) &&
+ acpi_ps_get_name (field) == name &&
+ (!opcode || field->opcode == opcode))
+ {
+ return (field);
+ }
+
+ field = field->next;
+ }
+ }
+
+ else if (acpi_ps_is_create_field_op (op->opcode)) {
+ if (op->opcode == AML_CREATE_FIELD_OP) {
+ field = acpi_ps_get_arg (op, 3);
+ }
+
+ else {
+ /* Create_xXXField, check name */
+
+ field = acpi_ps_get_arg (op, 2);
+ }
+
+ if ((field) &&
+ (field->value.string) &&
+ (!STRNCMP (field->value.string, (char *) &name, ACPI_NAME_SIZE)))
+ {
+ return (op);
+ }
+ }
+
+ else if ((acpi_ps_is_named_op (op->opcode)) &&
+ (acpi_ps_get_name (op) == name) &&
+ (!opcode || op->opcode == opcode))


+ {
+ break;
+ }
+

+ op = op->next;
+ }
+
+ return (op);


+}
+
+
+/*******************************************************************************
+ *

+ * FUNCTION: Acpi_ps_find
+ *
+ * PARAMETERS: Scope - Where to begin the search
+ * Path - ACPI Path to the named object
+ * Opcode - Opcode associated with the object
+ * Create - if TRUE, create the object if not found.
+ *
+ * RETURN: Op if found, NULL otherwise.
+ *
+ * DESCRIPTION: Find object within scope


+ *
+ ******************************************************************************/
+

+ACPI_PARSE_OBJECT*
+acpi_ps_find (
+ ACPI_PARSE_OBJECT *scope,
+ NATIVE_CHAR *path,
+ u16 opcode,
+ u32 create)

+{
+ u32 seg_count;
+ u32 name;
+ u32 name_op;
+ ACPI_PARSE_OBJECT *op = NULL;
+ u8 unprefixed = TRUE;
+
+
+ if (!scope || !path) {


+ return (NULL);
+ }
+
+

+ acpi_gbl_ps_find_count++;
+
+
+ /* Handle all prefixes in the name path */
+
+ while (acpi_ps_is_prefix_char (GET8 (path))) {
+ switch (GET8 (path))
+ {
+
+ case '\\':
+
+ /* Could just use a global for "root scope" here */
+
+ while (scope->parent) {
+ scope = scope->parent;
+ }
+
+ /* get first object within the scope */
+ /* TBD: [Investigate] OR - set next in root scope to point to the same value as arg */
+
+ /* Scope = Scope->Value.Arg; */
+
+ break;
+
+
+ case '^':
+
+ /* Go up to the next valid scoping Op (method, scope, etc.) */
+
+ if (acpi_ps_get_parent (scope)) {
+ scope = acpi_ps_get_parent (scope);
+ }


+
+ break;
+ }
+

+ unprefixed = FALSE;
+ path++;
+ }
+
+ /* get name segment count */
+
+ switch (GET8 (path))
+ {
+ case '\0':
+ seg_count = 0;
+
+ /* Null name case */
+
+ if (unprefixed) {
+ op = NULL;
+ }
+ else {
+ op = scope;
+ }
+
+
+ return (op);
+ break;
+
+ case AML_DUAL_NAME_PREFIX:
+ seg_count = 2;
+ path++;
+ break;
+
+ case AML_MULTI_NAME_PREFIX_OP:
+ seg_count = GET8 (path + 1);
+ path += 2;


+ break;
+
+ default:

+ seg_count = 1;
+ break;
+ }
+
+ /* match each name segment */
+
+ while (scope && seg_count) {
+ MOVE_UNALIGNED32_TO_32 (&name, path);
+ path += 4;
+ seg_count --;
+
+ if (seg_count) {
+ name_op = 0;
+ }
+ else {
+ name_op = opcode;
+ }
+
+ op = acpi_ps_find_name (scope, name, name_op);
+
+ if (!op) {
+ if (create) {
+ /* Create a new Scope level */
+
+ if (seg_count) {


+ op = acpi_ps_alloc_op (AML_SCOPE_OP);
+ }

+ else {


+ op = acpi_ps_alloc_op (opcode);
+ }

+
+ if (op) {
+ acpi_ps_set_name (op, name);
+ acpi_ps_append_arg (scope, op);
+
+ }
+ }
+
+ else if (unprefixed) {
+ /* Search higher scopes for unprefixed name */
+
+ while (!op && scope->parent) {
+ scope = scope->parent;
+ op = acpi_ps_find_name (scope, name, opcode);


+
+ }
+ }
+
+ }

+
+ unprefixed = FALSE;
+ scope = op;
+ }
+
+ return (op);
+}
+
+
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/parser/psopcode.c linux/drivers/acpi/parser/psopcode.c
--- v2.4.0-test8/linux/drivers/acpi/parser/psopcode.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/parser/psopcode.c Fri Sep 15 14:30:30 2000
@@ -1,6 +1,7 @@
X /******************************************************************************
X *
X * Module Name: psopcode - Parser opcode information table
+ * $Revision: 20 $


X *
X *****************************************************************************/
X

@@ -24,12 +25,32 @@


X
X
X #include "acpi.h"

-#include "parser.h"
+#include "acparser.h"
X #include "amlcode.h"

X
X
X #define _COMPONENT PARSER
- MODULE_NAME ("psopcode");
+ MODULE_NAME ("psopcode")
+
+
+u8 acpi_gbl_aml_short_op_info_index[];
+u8 acpi_gbl_aml_long_op_info_index[];
+
+#define _UNK 0x6B
+/*
+ * Reserved ASCII characters. Do not use any of these for
+ * internal opcodes, since they are used to differentiate
+ * name strings from AML opcodes
+ */
+#define _ASC 0x6C
+#define _NAM 0x6C
+#define _PFX 0x6D
+#define _UNKNOWN_OPCODE 0x02 /* An example unknown opcode */
+
+#define MAX_EXTENDED_OPCODE 0x87
+#define NUM_EXTENDED_OPCODE MAX_EXTENDED_OPCODE + 1
+#define MAX_INTERNAL_OPCODE
+#define NUM_INTERNAL_OPCODE MAX_INTERNAL_OPCODE + 1
X
X
X /*******************************************************************************
@@ -41,27 +62,41 @@
X * RETURN: A pointer to the info about the opcode. NULL if the opcode was
X * not found in the table.
X *
- * DESCRIPTION: Find AML opcode description based on the opcode
+ * DESCRIPTION: Find AML opcode description based on the opcode.
+ * NOTE: This procedure must ALWAYS return a valid pointer!


X *
X ******************************************************************************/
X

-ACPI_OP_INFO *
+ACPI_OPCODE_INFO *
X acpi_ps_get_opcode_info (
X u16 opcode)
X {
- ACPI_OP_INFO *op;
- s32 hash;
+ ACPI_OPCODE_INFO *op_info;
+ u8 upper_opcode;
+ u8 lower_opcode;
+
+
+ /* Split the 16-bit opcode into separate bytes */
+
+ upper_opcode = (u8) (opcode >> 8);
+ lower_opcode = (u8) opcode;
+
+ /* Default is "unknown opcode" */
X
+ op_info = &acpi_gbl_aml_op_info [_UNK];
X
- /* compute hash/index into the Acpi_aml_op_index table */
X
- switch (opcode >> 8)
+ /*
+ * Detect normal 8-bit opcode or extended 16-bit opcode
+ */
+
+ switch (upper_opcode)
X {
X case 0:
X
- /* Simple (8-bit) opcode */
+ /* Simple (8-bit) opcode: 0-255, can't index beyond table */
X
- hash = opcode;
+ op_info = &acpi_gbl_aml_op_info [acpi_gbl_aml_short_op_info_index [lower_opcode]];
X break;
X
X
@@ -69,38 +104,29 @@
X
X /* Extended (16-bit, prefix+opcode) opcode */
X
- hash = (opcode + AML_EXTOP_HASH_OFFSET) & 0xff;
+ if (lower_opcode <= MAX_EXTENDED_OPCODE) {
+ op_info = &acpi_gbl_aml_op_info [acpi_gbl_aml_long_op_info_index [lower_opcode]];
+ }
X break;
X
X
X case AML_LNOT_OP:
X
X /* This case is for the bogus opcodes LNOTEQUAL, LLESSEQUAL, LGREATEREQUAL */
+ /* TBD: [Investigate] remove this case? */
X
- hash = (opcode + AML_LNOT_HASH_OFFSET) & 0xff;
X break;
X
X
X default:
X
- return NULL;
+ break;
X }
X
X
X /* Get the Op info pointer for this opcode */
X
- op = &acpi_gbl_aml_op_info [(s32) acpi_gbl_aml_op_info_index [hash]];
-
-
- /* If the returned opcode matches, we have a valid opcode */
-
- if (op->opcode == opcode) {
- return op;
- }
-
- /* Otherwise, the opcode is an ASCII char or other non-opcode value */
-
- return NULL;
+ return (op_info);
X }
X
X
@@ -117,21 +143,19 @@


X *
X ******************************************************************************/
X

-char *
+NATIVE_CHAR *
X acpi_ps_get_opcode_name (
X u16 opcode)
X {
- ACPI_OP_INFO *op;
+ ACPI_OPCODE_INFO *op;
X
X
X op = acpi_ps_get_opcode_info (opcode);
X
- if (!op) {
- return "*ERROR*";
- }
+ /* Always guaranteed to return a valid pointer */
X
X DEBUG_ONLY_MEMBERS (return op->name);
- return "AE_NOT_CONFIGURED";
+ return ("AE_NOT_CONFIGURED");
X }


X
X
@@ -153,7 +177,7 @@

X * 6-7 (2 bits) = Reserved
X */
X #define AML_NO_ARGS 0
-#define AML_HAS_ARGS OP_INFO_HAS_ARGS
+#define AML_HAS_ARGS ACPI_OP_ARGS_MASK
X
X /*
X * All AML opcodes and the parse-time arguments for each. Used by the AML parser Each list is compressed
@@ -225,7 +249,7 @@
X #define ARGP_IF_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_TERMARG, ARGP_TERMLIST)
X #define ARGP_ELSE_OP ARGP_LIST2 (ARGP_PKGLENGTH, ARGP_TERMLIST)
X #define ARGP_WHILE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_TERMARG, ARGP_TERMLIST)
-#define ARGP_NOOP_CODE ARG_NONE
+#define ARGP_NOOP_OP ARG_NONE
X #define ARGP_RETURN_OP ARGP_LIST1 (ARGP_TERMARG)
X #define ARGP_BREAK_OP ARG_NONE
X #define ARGP_BREAK_POINT_OP ARG_NONE
@@ -242,9 +266,9 @@
X #define ARGP_WAIT_OP ARGP_LIST2 (ARGP_SUPERNAME, ARGP_TERMARG)
X #define ARGP_RESET_OP ARGP_LIST1 (ARGP_SUPERNAME)
X #define ARGP_RELEASE_OP ARGP_LIST1 (ARGP_SUPERNAME)
-#define ARGP_FROM_BCDOP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET)
-#define ARGP_TO_BCDOP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET)
-#define ARGP_UN_LOAD_OP ARGP_LIST1 (ARGP_SUPERNAME)
+#define ARGP_FROM_BCD_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET)
+#define ARGP_TO_BCD_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET)
+#define ARGP_UNLOAD_OP ARGP_LIST1 (ARGP_SUPERNAME)
X #define ARGP_REVISION_OP ARG_NONE
X #define ARGP_DEBUG_OP ARG_NONE
X #define ARGP_FATAL_OP ARGP_LIST3 (ARGP_BYTEDATA, ARGP_DWORDDATA, ARGP_TERMARG)
@@ -340,7 +364,7 @@
X #define ARGI_IF_OP ARGI_INVALID_OPCODE
X #define ARGI_ELSE_OP ARGI_INVALID_OPCODE
X #define ARGI_WHILE_OP ARGI_INVALID_OPCODE
-#define ARGI_NOOP_CODE ARG_NONE
+#define ARGI_NOOP_OP ARG_NONE
X #define ARGI_RETURN_OP ARGI_INVALID_OPCODE
X #define ARGI_BREAK_OP ARG_NONE
X #define ARGI_BREAK_POINT_OP ARG_NONE
@@ -357,9 +381,9 @@
X #define ARGI_WAIT_OP ARGI_LIST2 (ARGI_EVENT, ARGI_NUMBER)
X #define ARGI_RESET_OP ARGI_LIST1 (ARGI_EVENT)
X #define ARGI_RELEASE_OP ARGI_LIST1 (ARGI_MUTEX)
-#define ARGI_FROM_BCDOP ARGI_LIST2 (ARGI_NUMBER, ARGI_TARGETREF)
-#define ARGI_TO_BCDOP ARGI_LIST2 (ARGI_NUMBER, ARGI_TARGETREF)
-#define ARGI_UN_LOAD_OP ARGI_LIST1 (ARGI_DDBHANDLE)
+#define ARGI_FROM_BCD_OP ARGI_LIST2 (ARGI_NUMBER, ARGI_TARGETREF)
+#define ARGI_TO_BCD_OP ARGI_LIST2 (ARGI_NUMBER, ARGI_TARGETREF)
+#define ARGI_UNLOAD_OP ARGI_LIST1 (ARGI_DDBHANDLE)
X #define ARGI_REVISION_OP ARG_NONE
X #define ARGI_DEBUG_OP ARG_NONE
X #define ARGI_FATAL_OP ARGI_LIST3 (ARGI_NUMBER, ARGI_NUMBER, ARGI_NUMBER)
@@ -388,157 +412,156 @@
X */
X
X
-ACPI_OP_INFO acpi_gbl_aml_op_info[] =
+ACPI_OPCODE_INFO acpi_gbl_aml_op_info[] =
X {
-/* Opcode Opcode Type Has Arguments? Child Name Parser Args Interpreter Args */
+/* Index Opcode Type Class Has Arguments? Name Parser Args Interpreter Args */
X
-/* 00 */ OP_INFO_ENTRY (AML_ZERO_OP, OPTYPE_CONSTANT| AML_NO_ARGS| 0, "Zero_op", ARGP_ZERO_OP, ARGI_ZERO_OP),
-/* 01 */ OP_INFO_ENTRY (AML_ONE_OP, OPTYPE_CONSTANT| AML_NO_ARGS| 0, "One_op", ARGP_ONE_OP, ARGI_ONE_OP),
-/* 02 */ OP_INFO_ENTRY (AML_ALIAS_OP, OPTYPE_NAMED_OBJECT| AML_HAS_ARGS| 0, "Alias", ARGP_ALIAS_OP, ARGI_ALIAS_OP),
-/* 03 */ OP_INFO_ENTRY (AML_NAME_OP, OPTYPE_NAMED_OBJECT| AML_HAS_ARGS| 0, "Name", ARGP_NAME_OP, ARGI_NAME_OP),
-/* 04 */ OP_INFO_ENTRY (AML_BYTE_OP, OPTYPE_LITERAL| AML_NO_ARGS| 0, "Byte_const", ARGP_BYTE_OP, ARGI_BYTE_OP),
-/* 05 */ OP_INFO_ENTRY (AML_WORD_OP, OPTYPE_LITERAL| AML_NO_ARGS| 0, "Word_const", ARGP_WORD_OP, ARGI_WORD_OP),
-/* 06 */ OP_INFO_ENTRY (AML_DWORD_OP, OPTYPE_LITERAL| AML_NO_ARGS| 0, "Dword_const", ARGP_DWORD_OP, ARGI_DWORD_OP),
-/* 07 */ OP_INFO_ENTRY (AML_STRING_OP, OPTYPE_LITERAL| AML_NO_ARGS| 0, "String", ARGP_STRING_OP, ARGI_STRING_OP),
-/* 08 */ OP_INFO_ENTRY (AML_SCOPE_OP, OPTYPE_NAMED_OBJECT| AML_HAS_ARGS| 0, "Scope", ARGP_SCOPE_OP, ARGI_SCOPE_OP),
-/* 09 */ OP_INFO_ENTRY (AML_BUFFER_OP, OPTYPE_DATA_TERM| AML_HAS_ARGS| 0, "Buffer", ARGP_BUFFER_OP, ARGI_BUFFER_OP),
-/* 0A */ OP_INFO_ENTRY (AML_PACKAGE_OP, OPTYPE_DATA_TERM| AML_HAS_ARGS| 0, "Package", ARGP_PACKAGE_OP, ARGI_PACKAGE_OP),
-/* 0B */ OP_INFO_ENTRY (AML_METHOD_OP, OPTYPE_NAMED_OBJECT| AML_HAS_ARGS| 0, "Method", ARGP_METHOD_OP, ARGI_METHOD_OP),
-/* 0C */ OP_INFO_ENTRY (AML_LOCAL0, OPTYPE_LOCAL_VARIABLE| AML_NO_ARGS| 0, "Local0", ARGP_LOCAL0, ARGI_LOCAL0),
-/* 0D */ OP_INFO_ENTRY (AML_LOCAL1, OPTYPE_LOCAL_VARIABLE| AML_NO_ARGS| 0, "Local1", ARGP_LOCAL1, ARGI_LOCAL1),
-/* 0E */ OP_INFO_ENTRY (AML_LOCAL2, OPTYPE_LOCAL_VARIABLE| AML_NO_ARGS| 0, "Local2", ARGP_LOCAL2, ARGI_LOCAL2),
-/* 0F */ OP_INFO_ENTRY (AML_LOCAL3, OPTYPE_LOCAL_VARIABLE| AML_NO_ARGS| 0, "Local3", ARGP_LOCAL3, ARGI_LOCAL3),
-/* 10 */ OP_INFO_ENTRY (AML_LOCAL4, OPTYPE_LOCAL_VARIABLE| AML_NO_ARGS| 0, "Local4", ARGP_LOCAL4, ARGI_LOCAL4),
-/* 11 */ OP_INFO_ENTRY (AML_LOCAL5, OPTYPE_LOCAL_VARIABLE| AML_NO_ARGS| 0, "Local5", ARGP_LOCAL5, ARGI_LOCAL5),
-/* 12 */ OP_INFO_ENTRY (AML_LOCAL6, OPTYPE_LOCAL_VARIABLE| AML_NO_ARGS| 0, "Local6", ARGP_LOCAL6, ARGI_LOCAL6),
-/* 13 */ OP_INFO_ENTRY (AML_LOCAL7, OPTYPE_LOCAL_VARIABLE| AML_NO_ARGS| 0, "Local7", ARGP_LOCAL7, ARGI_LOCAL7),
-/* 14 */ OP_INFO_ENTRY (AML_ARG0, OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS| 0, "Arg0", ARGP_ARG0, ARGI_ARG0),
-/* 15 */ OP_INFO_ENTRY (AML_ARG1, OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS| 0, "Arg1", ARGP_ARG1, ARGI_ARG1),
-/* 16 */ OP_INFO_ENTRY (AML_ARG2, OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS| 0, "Arg2", ARGP_ARG2, ARGI_ARG2),
-/* 17 */ OP_INFO_ENTRY (AML_ARG3, OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS| 0, "Arg3", ARGP_ARG3, ARGI_ARG3),
-/* 18 */ OP_INFO_ENTRY (AML_ARG4, OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS| 0, "Arg4", ARGP_ARG4, ARGI_ARG4),
-/* 19 */ OP_INFO_ENTRY (AML_ARG5, OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS| 0, "Arg5", ARGP_ARG5, ARGI_ARG5),
-/* 1_a */ OP_INFO_ENTRY (AML_ARG6, OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS| 0, "Arg6", ARGP_ARG6, ARGI_ARG6),
-/* 1_b */ OP_INFO_ENTRY (AML_STORE_OP, OPTYPE_MONADIC2_r| AML_HAS_ARGS| 0, "Store", ARGP_STORE_OP, ARGI_STORE_OP),
-/* 1_c */ OP_INFO_ENTRY (AML_REF_OF_OP, OPTYPE_MONADIC2| AML_HAS_ARGS| 0, "Ref_of", ARGP_REF_OF_OP, ARGI_REF_OF_OP),
-/* 1_d */ OP_INFO_ENTRY (AML_ADD_OP, OPTYPE_DYADIC2_r| AML_HAS_ARGS| 0, "Add", ARGP_ADD_OP, ARGI_ADD_OP),
-/* 1_e */ OP_INFO_ENTRY (AML_CONCAT_OP, OPTYPE_DYADIC2_r| AML_HAS_ARGS| 0, "Concat", ARGP_CONCAT_OP, ARGI_CONCAT_OP),
-/* 1_f */ OP_INFO_ENTRY (AML_SUBTRACT_OP, OPTYPE_DYADIC2_r| AML_HAS_ARGS| 0, "Subtract", ARGP_SUBTRACT_OP, ARGI_SUBTRACT_OP),
-/* 20 */ OP_INFO_ENTRY (AML_INCREMENT_OP, OPTYPE_MONADIC2| AML_HAS_ARGS| 0, "Increment", ARGP_INCREMENT_OP, ARGI_INCREMENT_OP),
-/* 21 */ OP_INFO_ENTRY (AML_DECREMENT_OP, OPTYPE_MONADIC2| AML_HAS_ARGS| 0, "Decrement", ARGP_DECREMENT_OP, ARGI_DECREMENT_OP),
-/* 22 */ OP_INFO_ENTRY (AML_MULTIPLY_OP, OPTYPE_DYADIC2_r| AML_HAS_ARGS| 0, "Multiply", ARGP_MULTIPLY_OP, ARGI_MULTIPLY_OP),
-/* 23 */ OP_INFO_ENTRY (AML_DIVIDE_OP, OPTYPE_DYADIC2_r| AML_HAS_ARGS| 0, "Divide", ARGP_DIVIDE_OP, ARGI_DIVIDE_OP),
-/* 24 */ OP_INFO_ENTRY (AML_SHIFT_LEFT_OP, OPTYPE_DYADIC2_r| AML_HAS_ARGS| 0, "Shift_left", ARGP_SHIFT_LEFT_OP, ARGI_SHIFT_LEFT_OP),
-/* 25 */ OP_INFO_ENTRY (AML_SHIFT_RIGHT_OP, OPTYPE_DYADIC2_r| AML_HAS_ARGS| 0, "Shift_right", ARGP_SHIFT_RIGHT_OP, ARGI_SHIFT_RIGHT_OP),
-/* 26 */ OP_INFO_ENTRY (AML_BIT_AND_OP, OPTYPE_DYADIC2_r| AML_HAS_ARGS| 0, "And", ARGP_BIT_AND_OP, ARGI_BIT_AND_OP),
-/* 27 */ OP_INFO_ENTRY (AML_BIT_NAND_OP, OPTYPE_DYADIC2_r| AML_HAS_ARGS| 0, "NAnd", ARGP_BIT_NAND_OP, ARGI_BIT_NAND_OP),
-/* 28 */ OP_INFO_ENTRY (AML_BIT_OR_OP, OPTYPE_DYADIC2_r| AML_HAS_ARGS| 0, "Or", ARGP_BIT_OR_OP, ARGI_BIT_OR_OP),
-/* 29 */ OP_INFO_ENTRY (AML_BIT_NOR_OP, OPTYPE_DYADIC2_r| AML_HAS_ARGS| 0, "NOr", ARGP_BIT_NOR_OP, ARGI_BIT_NOR_OP),
-/* 2_a */ OP_INFO_ENTRY (AML_BIT_XOR_OP, OPTYPE_DYADIC2_r| AML_HAS_ARGS| 0, "XOr", ARGP_BIT_XOR_OP, ARGI_BIT_XOR_OP),
-/* 2_b */ OP_INFO_ENTRY (AML_BIT_NOT_OP, OPTYPE_MONADIC2_r| AML_HAS_ARGS| 0, "Not", ARGP_BIT_NOT_OP, ARGI_BIT_NOT_OP),
-/* 2_c */ OP_INFO_ENTRY (AML_FIND_SET_LEFT_BIT_OP, OPTYPE_MONADIC2_r| AML_HAS_ARGS| 0, "Find_set_left_bit", ARGP_FIND_SET_LEFT_BIT_OP, ARGI_FIND_SET_LEFT_BIT_OP),
-/* 2_d */ OP_INFO_ENTRY (AML_FIND_SET_RIGHT_BIT_OP, OPTYPE_MONADIC2_r| AML_HAS_ARGS| 0, "Find_set_right_bit", ARGP_FIND_SET_RIGHT_BIT_OP, ARGI_FIND_SET_RIGHT_BIT_OP),
-/* 2_e */ OP_INFO_ENTRY (AML_DEREF_OF_OP, OPTYPE_MONADIC2| AML_HAS_ARGS| 0, "Deref_of", ARGP_DEREF_OF_OP, ARGI_DEREF_OF_OP),
-/* 2_f */ OP_INFO_ENTRY (AML_NOTIFY_OP, OPTYPE_DYADIC1| AML_HAS_ARGS| 0, "Notify", ARGP_NOTIFY_OP, ARGI_NOTIFY_OP),
-/* 30 */ OP_INFO_ENTRY (AML_SIZE_OF_OP, OPTYPE_MONADIC2| AML_HAS_ARGS| 0, "Size_of", ARGP_SIZE_OF_OP, ARGI_SIZE_OF_OP),
-/* 31 */ OP_INFO_ENTRY (AML_INDEX_OP, OPTYPE_INDEX| AML_HAS_ARGS| 0, "Index", ARGP_INDEX_OP, ARGI_INDEX_OP),
-/* 32 */ OP_INFO_ENTRY (AML_MATCH_OP, OPTYPE_MATCH| AML_HAS_ARGS| 0, "Match", ARGP_MATCH_OP, ARGI_MATCH_OP),
-/* 33 */ OP_INFO_ENTRY (AML_DWORD_FIELD_OP, OPTYPE_CREATE_FIELD| AML_HAS_ARGS| 0, "Create_dWord_field", ARGP_DWORD_FIELD_OP, ARGI_DWORD_FIELD_OP),
-/* 34 */ OP_INFO_ENTRY (AML_WORD_FIELD_OP, OPTYPE_CREATE_FIELD| AML_HAS_ARGS| 0, "Create_word_field", ARGP_WORD_FIELD_OP, ARGI_WORD_FIELD_OP),
-/* 35 */ OP_INFO_ENTRY (AML_BYTE_FIELD_OP, OPTYPE_CREATE_FIELD| AML_HAS_ARGS| 0, "Create_byte_field", ARGP_BYTE_FIELD_OP, ARGI_BYTE_FIELD_OP),
-/* 36 */ OP_INFO_ENTRY (AML_BIT_FIELD_OP, OPTYPE_CREATE_FIELD| AML_HAS_ARGS| 0, "Create_bit_field", ARGP_BIT_FIELD_OP, ARGI_BIT_FIELD_OP),
-/* 37 */ OP_INFO_ENTRY (AML_TYPE_OP, OPTYPE_MONADIC2| AML_HAS_ARGS| 0, "Object_type", ARGP_TYPE_OP, ARGI_TYPE_OP),
-/* 38 */ OP_INFO_ENTRY (AML_LAND_OP, OPTYPE_DYADIC2| AML_HAS_ARGS| 0, "LAnd", ARGP_LAND_OP, ARGI_LAND_OP),
-/* 39 */ OP_INFO_ENTRY (AML_LOR_OP, OPTYPE_DYADIC2| AML_HAS_ARGS| 0, "LOr", ARGP_LOR_OP, ARGI_LOR_OP),
-/* 3_a */ OP_INFO_ENTRY (AML_LNOT_OP, OPTYPE_MONADIC2| AML_HAS_ARGS| 0, "LNot", ARGP_LNOT_OP, ARGI_LNOT_OP),
-/* 3_b */ OP_INFO_ENTRY (AML_LEQUAL_OP, OPTYPE_DYADIC2| AML_HAS_ARGS| 0, "LEqual", ARGP_LEQUAL_OP, ARGI_LEQUAL_OP),
-/* 3_c */ OP_INFO_ENTRY (AML_LGREATER_OP, OPTYPE_DYADIC2| AML_HAS_ARGS| 0, "LGreater", ARGP_LGREATER_OP, ARGI_LGREATER_OP),
-/* 3_d */ OP_INFO_ENTRY (AML_LLESS_OP, OPTYPE_DYADIC2| AML_HAS_ARGS| 0, "LLess", ARGP_LLESS_OP, ARGI_LLESS_OP),
-/* 3_e */ OP_INFO_ENTRY (AML_IF_OP, OPTYPE_CONTROL| AML_HAS_ARGS| 0, "If", ARGP_IF_OP, ARGI_IF_OP),
-/* 3_f */ OP_INFO_ENTRY (AML_ELSE_OP, OPTYPE_CONTROL| AML_HAS_ARGS| 0, "Else", ARGP_ELSE_OP, ARGI_ELSE_OP),
-/* 40 */ OP_INFO_ENTRY (AML_WHILE_OP, OPTYPE_CONTROL| AML_HAS_ARGS| 0, "While", ARGP_WHILE_OP, ARGI_WHILE_OP),
-/* 41 */ OP_INFO_ENTRY (AML_NOOP_CODE, OPTYPE_CONTROL| AML_NO_ARGS| 0, "Noop", ARGP_NOOP_CODE, ARGI_NOOP_CODE),
-/* 42 */ OP_INFO_ENTRY (AML_RETURN_OP, OPTYPE_CONTROL| AML_HAS_ARGS| 0, "Return", ARGP_RETURN_OP, ARGI_RETURN_OP),
-/* 43 */ OP_INFO_ENTRY (AML_BREAK_OP, OPTYPE_CONTROL| AML_NO_ARGS| 0, "Break", ARGP_BREAK_OP, ARGI_BREAK_OP),
-/* 44 */ OP_INFO_ENTRY (AML_BREAK_POINT_OP, OPTYPE_CONTROL| AML_NO_ARGS| 0, "Break_point", ARGP_BREAK_POINT_OP, ARGI_BREAK_POINT_OP),
-/* 45 */ OP_INFO_ENTRY (AML_ONES_OP, OPTYPE_CONSTANT| AML_NO_ARGS| 0, "Ones_op", ARGP_ONES_OP, ARGI_ONES_OP),
+/* 00 */ /* AML_ZERO_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONSTANT| AML_NO_ARGS, "Zero_op", ARGP_ZERO_OP, ARGI_ZERO_OP),
+/* 01 */ /* AML_ONE_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONSTANT| AML_NO_ARGS, "One_op", ARGP_ONE_OP, ARGI_ONE_OP),
+/* 02 */ /* AML_ALIAS_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT| AML_HAS_ARGS, "Alias", ARGP_ALIAS_OP, ARGI_ALIAS_OP),
+/* 03 */ /* AML_NAME_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT| AML_HAS_ARGS, "Name", ARGP_NAME_OP, ARGI_NAME_OP),
+/* 04 */ /* AML_BYTE_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LITERAL| AML_NO_ARGS, "Byte_const", ARGP_BYTE_OP, ARGI_BYTE_OP),
+/* 05 */ /* AML_WORD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LITERAL| AML_NO_ARGS, "Word_const", ARGP_WORD_OP, ARGI_WORD_OP),
+/* 06 */ /* AML_DWORD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LITERAL| AML_NO_ARGS, "Dword_const", ARGP_DWORD_OP, ARGI_DWORD_OP),
+/* 07 */ /* AML_STRING_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LITERAL| AML_NO_ARGS, "String", ARGP_STRING_OP, ARGI_STRING_OP),
+/* 08 */ /* AML_SCOPE_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT| AML_HAS_ARGS, "Scope", ARGP_SCOPE_OP, ARGI_SCOPE_OP),
+/* 09 */ /* AML_BUFFER_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DATA_TERM| AML_HAS_ARGS, "Buffer", ARGP_BUFFER_OP, ARGI_BUFFER_OP),
+/* 0A */ /* AML_PACKAGE_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DATA_TERM| AML_HAS_ARGS, "Package", ARGP_PACKAGE_OP, ARGI_PACKAGE_OP),
+/* 0B */ /* AML_METHOD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT| AML_HAS_ARGS, "Method", ARGP_METHOD_OP, ARGI_METHOD_OP),
+/* 0C */ /* AML_LOCAL0 */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LOCAL_VARIABLE| AML_NO_ARGS, "Local0", ARGP_LOCAL0, ARGI_LOCAL0),
+/* 0D */ /* AML_LOCAL1 */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LOCAL_VARIABLE| AML_NO_ARGS, "Local1", ARGP_LOCAL1, ARGI_LOCAL1),
+/* 0E */ /* AML_LOCAL2 */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LOCAL_VARIABLE| AML_NO_ARGS, "Local2", ARGP_LOCAL2, ARGI_LOCAL2),
+/* 0F */ /* AML_LOCAL3 */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LOCAL_VARIABLE| AML_NO_ARGS, "Local3", ARGP_LOCAL3, ARGI_LOCAL3),
+/* 10 */ /* AML_LOCAL4 */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LOCAL_VARIABLE| AML_NO_ARGS, "Local4", ARGP_LOCAL4, ARGI_LOCAL4),
+/* 11 */ /* AML_LOCAL5 */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LOCAL_VARIABLE| AML_NO_ARGS, "Local5", ARGP_LOCAL5, ARGI_LOCAL5),
+/* 12 */ /* AML_LOCAL6 */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LOCAL_VARIABLE| AML_NO_ARGS, "Local6", ARGP_LOCAL6, ARGI_LOCAL6),
+/* 13 */ /* AML_LOCAL7 */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LOCAL_VARIABLE| AML_NO_ARGS, "Local7", ARGP_LOCAL7, ARGI_LOCAL7),
+/* 14 */ /* AML_ARG0 */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS, "Arg0", ARGP_ARG0, ARGI_ARG0),
+/* 15 */ /* AML_ARG1 */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS, "Arg1", ARGP_ARG1, ARGI_ARG1),
+/* 16 */ /* AML_ARG2 */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS, "Arg2", ARGP_ARG2, ARGI_ARG2),
+/* 17 */ /* AML_ARG3 */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS, "Arg3", ARGP_ARG3, ARGI_ARG3),
+/* 18 */ /* AML_ARG4 */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS, "Arg4", ARGP_ARG4, ARGI_ARG4),
+/* 19 */ /* AML_ARG5 */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS, "Arg5", ARGP_ARG5, ARGI_ARG5),
+/* 1_a */ /* AML_ARG6 */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_METHOD_ARGUMENT| AML_NO_ARGS, "Arg6", ARGP_ARG6, ARGI_ARG6),
+/* 1_b */ /* AML_STORE_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r| AML_HAS_ARGS, "Store", ARGP_STORE_OP, ARGI_STORE_OP),
+/* 1_c */ /* AML_REF_OF_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2| AML_HAS_ARGS, "Ref_of", ARGP_REF_OF_OP, ARGI_REF_OF_OP),
+/* 1_d */ /* AML_ADD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r| AML_HAS_ARGS, "Add", ARGP_ADD_OP, ARGI_ADD_OP),
+/* 1_e */ /* AML_CONCAT_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r| AML_HAS_ARGS, "Concat", ARGP_CONCAT_OP, ARGI_CONCAT_OP),
+/* 1_f */ /* AML_SUBTRACT_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r| AML_HAS_ARGS, "Subtract", ARGP_SUBTRACT_OP, ARGI_SUBTRACT_OP),
+/* 20 */ /* AML_INCREMENT_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2| AML_HAS_ARGS, "Increment", ARGP_INCREMENT_OP, ARGI_INCREMENT_OP),
+/* 21 */ /* AML_DECREMENT_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2| AML_HAS_ARGS, "Decrement", ARGP_DECREMENT_OP, ARGI_DECREMENT_OP),
+/* 22 */ /* AML_MULTIPLY_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r| AML_HAS_ARGS, "Multiply", ARGP_MULTIPLY_OP, ARGI_MULTIPLY_OP),
+/* 23 */ /* AML_DIVIDE_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r| AML_HAS_ARGS, "Divide", ARGP_DIVIDE_OP, ARGI_DIVIDE_OP),
+/* 24 */ /* AML_SHIFT_LEFT_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r| AML_HAS_ARGS, "Shift_left", ARGP_SHIFT_LEFT_OP, ARGI_SHIFT_LEFT_OP),
+/* 25 */ /* AML_SHIFT_RIGHT_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r| AML_HAS_ARGS, "Shift_right", ARGP_SHIFT_RIGHT_OP, ARGI_SHIFT_RIGHT_OP),
+/* 26 */ /* AML_BIT_AND_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r| AML_HAS_ARGS, "And", ARGP_BIT_AND_OP, ARGI_BIT_AND_OP),
+/* 27 */ /* AML_BIT_NAND_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r| AML_HAS_ARGS, "NAnd", ARGP_BIT_NAND_OP, ARGI_BIT_NAND_OP),
+/* 28 */ /* AML_BIT_OR_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r| AML_HAS_ARGS, "Or", ARGP_BIT_OR_OP, ARGI_BIT_OR_OP),
+/* 29 */ /* AML_BIT_NOR_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r| AML_HAS_ARGS, "NOr", ARGP_BIT_NOR_OP, ARGI_BIT_NOR_OP),
+/* 2_a */ /* AML_BIT_XOR_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r| AML_HAS_ARGS, "XOr", ARGP_BIT_XOR_OP, ARGI_BIT_XOR_OP),
+/* 2_b */ /* AML_BIT_NOT_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r| AML_HAS_ARGS, "Not", ARGP_BIT_NOT_OP, ARGI_BIT_NOT_OP),
+/* 2_c */ /* AML_FIND_SET_LEFT_BIT_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r| AML_HAS_ARGS, "Find_set_left_bit", ARGP_FIND_SET_LEFT_BIT_OP, ARGI_FIND_SET_LEFT_BIT_OP),
+/* 2_d */ /* AML_FIND_SET_RIGHT_BIT_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r| AML_HAS_ARGS, "Find_set_right_bit", ARGP_FIND_SET_RIGHT_BIT_OP, ARGI_FIND_SET_RIGHT_BIT_OP),
+/* 2_e */ /* AML_DEREF_OF_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2| AML_HAS_ARGS, "Deref_of", ARGP_DEREF_OF_OP, ARGI_DEREF_OF_OP),
+/* 2_f */ /* AML_NOTIFY_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC1| AML_HAS_ARGS, "Notify", ARGP_NOTIFY_OP, ARGI_NOTIFY_OP),
+/* 30 */ /* AML_SIZE_OF_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2| AML_HAS_ARGS, "Size_of", ARGP_SIZE_OF_OP, ARGI_SIZE_OF_OP),
+/* 31 */ /* AML_INDEX_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_INDEX| AML_HAS_ARGS, "Index", ARGP_INDEX_OP, ARGI_INDEX_OP),
+/* 32 */ /* AML_MATCH_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MATCH| AML_HAS_ARGS, "Match", ARGP_MATCH_OP, ARGI_MATCH_OP),
+/* 33 */ /* AML_DWORD_FIELD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CREATE_FIELD| AML_HAS_ARGS, "Create_dWord_field", ARGP_DWORD_FIELD_OP, ARGI_DWORD_FIELD_OP),
+/* 34 */ /* AML_WORD_FIELD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CREATE_FIELD| AML_HAS_ARGS, "Create_word_field", ARGP_WORD_FIELD_OP, ARGI_WORD_FIELD_OP),
+/* 35 */ /* AML_BYTE_FIELD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CREATE_FIELD| AML_HAS_ARGS, "Create_byte_field", ARGP_BYTE_FIELD_OP, ARGI_BYTE_FIELD_OP),
+/* 36 */ /* AML_BIT_FIELD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CREATE_FIELD| AML_HAS_ARGS, "Create_bit_field", ARGP_BIT_FIELD_OP, ARGI_BIT_FIELD_OP),
+/* 37 */ /* AML_TYPE_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2| AML_HAS_ARGS, "Object_type", ARGP_TYPE_OP, ARGI_TYPE_OP),
+/* 38 */ /* AML_LAND_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2| AML_HAS_ARGS, "LAnd", ARGP_LAND_OP, ARGI_LAND_OP),
+/* 39 */ /* AML_LOR_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2| AML_HAS_ARGS, "LOr", ARGP_LOR_OP, ARGI_LOR_OP),
+/* 3_a */ /* AML_LNOT_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2| AML_HAS_ARGS, "LNot", ARGP_LNOT_OP, ARGI_LNOT_OP),
+/* 3_b */ /* AML_LEQUAL_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2| AML_HAS_ARGS, "LEqual", ARGP_LEQUAL_OP, ARGI_LEQUAL_OP),
+/* 3_c */ /* AML_LGREATER_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2| AML_HAS_ARGS, "LGreater", ARGP_LGREATER_OP, ARGI_LGREATER_OP),
+/* 3_d */ /* AML_LLESS_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2| AML_HAS_ARGS, "LLess", ARGP_LLESS_OP, ARGI_LLESS_OP),
+/* 3_e */ /* AML_IF_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONTROL| AML_HAS_ARGS, "If", ARGP_IF_OP, ARGI_IF_OP),
+/* 3_f */ /* AML_ELSE_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONTROL| AML_HAS_ARGS, "Else", ARGP_ELSE_OP, ARGI_ELSE_OP),
+/* 40 */ /* AML_WHILE_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONTROL| AML_HAS_ARGS, "While", ARGP_WHILE_OP, ARGI_WHILE_OP),
+/* 41 */ /* AML_NOOP_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONTROL| AML_NO_ARGS, "Noop", ARGP_NOOP_OP, ARGI_NOOP_OP),
+/* 42 */ /* AML_RETURN_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONTROL| AML_HAS_ARGS, "Return", ARGP_RETURN_OP, ARGI_RETURN_OP),
+/* 43 */ /* AML_BREAK_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONTROL| AML_NO_ARGS, "Break", ARGP_BREAK_OP, ARGI_BREAK_OP),
+/* 44 */ /* AML_BREAK_POINT_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONTROL| AML_NO_ARGS, "Break_point", ARGP_BREAK_POINT_OP, ARGI_BREAK_POINT_OP),
+/* 45 */ /* AML_ONES_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONSTANT| AML_NO_ARGS, "Ones_op", ARGP_ONES_OP, ARGI_ONES_OP),
X
X /* Prefixed opcodes (Two-byte opcodes with a prefix op) */
X
-/* 46 */ OP_INFO_ENTRY (AML_MUTEX_OP, OPTYPE_NAMED_OBJECT| AML_HAS_ARGS| 0, "Mutex", ARGP_MUTEX_OP, ARGI_MUTEX_OP),
-/* 47 */ OP_INFO_ENTRY (AML_EVENT_OP, OPTYPE_NAMED_OBJECT| AML_NO_ARGS| 0, "Event", ARGP_EVENT_OP, ARGI_EVENT_OP),
-/* 48 */ OP_INFO_ENTRY (AML_COND_REF_OF_OP, OPTYPE_MONADIC2_r| AML_HAS_ARGS| 0, "Cond_ref_of", ARGP_COND_REF_OF_OP, ARGI_COND_REF_OF_OP),
-/* 49 */ OP_INFO_ENTRY (AML_CREATE_FIELD_OP, OPTYPE_CREATE_FIELD| AML_HAS_ARGS| 0, "Create_field", ARGP_CREATE_FIELD_OP, ARGI_CREATE_FIELD_OP),
-/* 4_a */ OP_INFO_ENTRY (AML_LOAD_OP, OPTYPE_RECONFIGURATION| AML_HAS_ARGS| 0, "Load", ARGP_LOAD_OP, ARGI_LOAD_OP),
-/* 4_b */ OP_INFO_ENTRY (AML_STALL_OP, OPTYPE_MONADIC1| AML_HAS_ARGS| 0, "Stall", ARGP_STALL_OP, ARGI_STALL_OP),
-/* 4_c */ OP_INFO_ENTRY (AML_SLEEP_OP, OPTYPE_MONADIC1| AML_HAS_ARGS| 0, "Sleep", ARGP_SLEEP_OP, ARGI_SLEEP_OP),
-/* 4_d */ OP_INFO_ENTRY (AML_ACQUIRE_OP, OPTYPE_DYADIC2_s| AML_HAS_ARGS| 0, "Acquire", ARGP_ACQUIRE_OP, ARGI_ACQUIRE_OP),
-/* 4_e */ OP_INFO_ENTRY (AML_SIGNAL_OP, OPTYPE_MONADIC1| AML_HAS_ARGS| 0, "Signal", ARGP_SIGNAL_OP, ARGI_SIGNAL_OP),
-/* 4_f */ OP_INFO_ENTRY (AML_WAIT_OP, OPTYPE_DYADIC2_s| AML_HAS_ARGS| 0, "Wait", ARGP_WAIT_OP, ARGI_WAIT_OP),
-/* 50 */ OP_INFO_ENTRY (AML_RESET_OP, OPTYPE_MONADIC1| AML_HAS_ARGS| 0, "Reset", ARGP_RESET_OP, ARGI_RESET_OP),
-/* 51 */ OP_INFO_ENTRY (AML_RELEASE_OP, OPTYPE_MONADIC1| AML_HAS_ARGS| 0, "Release", ARGP_RELEASE_OP, ARGI_RELEASE_OP),
-/* 52 */ OP_INFO_ENTRY (AML_FROM_BCDOP, OPTYPE_MONADIC2_r| AML_HAS_ARGS| 0, "From_bCD", ARGP_FROM_BCDOP, ARGI_FROM_BCDOP),
-/* 53 */ OP_INFO_ENTRY (AML_TO_BCDOP, OPTYPE_MONADIC2_r| AML_HAS_ARGS| 0, "To_bCD", ARGP_TO_BCDOP, ARGI_TO_BCDOP),
-/* 54 */ OP_INFO_ENTRY (AML_UN_LOAD_OP, OPTYPE_RECONFIGURATION| AML_HAS_ARGS| 0, "Unload", ARGP_UN_LOAD_OP, ARGI_UN_LOAD_OP),
-/* 55 */ OP_INFO_ENTRY (AML_REVISION_OP, OPTYPE_CONSTANT| AML_NO_ARGS| 0, "Revision", ARGP_REVISION_OP, ARGI_REVISION_OP),
-/* 56 */ OP_INFO_ENTRY (AML_DEBUG_OP, OPTYPE_CONSTANT| AML_NO_ARGS| 0, "Debug", ARGP_DEBUG_OP, ARGI_DEBUG_OP),
-/* 57 */ OP_INFO_ENTRY (AML_FATAL_OP, OPTYPE_FATAL| AML_HAS_ARGS| 0, "Fatal", ARGP_FATAL_OP, ARGI_FATAL_OP),
-/* 58 */ OP_INFO_ENTRY (AML_REGION_OP, OPTYPE_NAMED_OBJECT| AML_HAS_ARGS| 0, "Op_region", ARGP_REGION_OP, ARGI_REGION_OP),
-/* 59 */ OP_INFO_ENTRY (AML_DEF_FIELD_OP, OPTYPE_NAMED_OBJECT| AML_HAS_ARGS| 0, "Field", ARGP_DEF_FIELD_OP, ARGI_DEF_FIELD_OP),
-/* 5_a */ OP_INFO_ENTRY (AML_DEVICE_OP, OPTYPE_NAMED_OBJECT| AML_HAS_ARGS| 0, "Device", ARGP_DEVICE_OP, ARGI_DEVICE_OP),
-/* 5_b */ OP_INFO_ENTRY (AML_PROCESSOR_OP, OPTYPE_NAMED_OBJECT| AML_HAS_ARGS| 0, "Processor", ARGP_PROCESSOR_OP, ARGI_PROCESSOR_OP),
-/* 5_c */ OP_INFO_ENTRY (AML_POWER_RES_OP, OPTYPE_NAMED_OBJECT| AML_HAS_ARGS| 0, "Power_res", ARGP_POWER_RES_OP, ARGI_POWER_RES_OP),
-/* 5_d */ OP_INFO_ENTRY (AML_THERMAL_ZONE_OP, OPTYPE_NAMED_OBJECT| AML_HAS_ARGS| 0, "Thermal_zone", ARGP_THERMAL_ZONE_OP, ARGI_THERMAL_ZONE_OP),
-/* 5_e */ OP_INFO_ENTRY (AML_INDEX_FIELD_OP, OPTYPE_NAMED_OBJECT| AML_HAS_ARGS| 0, "Index_field", ARGP_INDEX_FIELD_OP, ARGI_INDEX_FIELD_OP),
-/* 5_f */ OP_INFO_ENTRY (AML_BANK_FIELD_OP, OPTYPE_NAMED_OBJECT| AML_HAS_ARGS| 0, "Bank_field", ARGP_BANK_FIELD_OP, ARGI_BANK_FIELD_OP),
+/* 46 */ /* AML_MUTEX_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT| AML_HAS_ARGS, "Mutex", ARGP_MUTEX_OP, ARGI_MUTEX_OP),
+/* 47 */ /* AML_EVENT_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT| AML_NO_ARGS, "Event", ARGP_EVENT_OP, ARGI_EVENT_OP),
+/* 48 */ /* AML_COND_REF_OF_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r| AML_HAS_ARGS, "Cond_ref_of", ARGP_COND_REF_OF_OP, ARGI_COND_REF_OF_OP),
+/* 49 */ /* AML_CREATE_FIELD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CREATE_FIELD| AML_HAS_ARGS, "Create_field", ARGP_CREATE_FIELD_OP, ARGI_CREATE_FIELD_OP),
+/* 4_a */ /* AML_LOAD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_RECONFIGURATION| AML_HAS_ARGS, "Load", ARGP_LOAD_OP, ARGI_LOAD_OP),
+/* 4_b */ /* AML_STALL_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC1| AML_HAS_ARGS, "Stall", ARGP_STALL_OP, ARGI_STALL_OP),
+/* 4_c */ /* AML_SLEEP_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC1| AML_HAS_ARGS, "Sleep", ARGP_SLEEP_OP, ARGI_SLEEP_OP),
+/* 4_d */ /* AML_ACQUIRE_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_s| AML_HAS_ARGS, "Acquire", ARGP_ACQUIRE_OP, ARGI_ACQUIRE_OP),
+/* 4_e */ /* AML_SIGNAL_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC1| AML_HAS_ARGS, "Signal", ARGP_SIGNAL_OP, ARGI_SIGNAL_OP),
+/* 4_f */ /* AML_WAIT_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_s| AML_HAS_ARGS, "Wait", ARGP_WAIT_OP, ARGI_WAIT_OP),
+/* 50 */ /* AML_RESET_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC1| AML_HAS_ARGS, "Reset", ARGP_RESET_OP, ARGI_RESET_OP),
+/* 51 */ /* AML_RELEASE_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC1| AML_HAS_ARGS, "Release", ARGP_RELEASE_OP, ARGI_RELEASE_OP),
+/* 52 */ /* AML_FROM_BCD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r| AML_HAS_ARGS, "From_bCD", ARGP_FROM_BCD_OP, ARGI_FROM_BCD_OP),
+/* 53 */ /* AML_TO_BCD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r| AML_HAS_ARGS, "To_bCD", ARGP_TO_BCD_OP, ARGI_TO_BCD_OP),
+/* 54 */ /* AML_UNLOAD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_RECONFIGURATION| AML_HAS_ARGS, "Unload", ARGP_UNLOAD_OP, ARGI_UNLOAD_OP),
+/* 55 */ /* AML_REVISION_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONSTANT| AML_NO_ARGS, "Revision", ARGP_REVISION_OP, ARGI_REVISION_OP),
+/* 56 */ /* AML_DEBUG_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONSTANT| AML_NO_ARGS, "Debug", ARGP_DEBUG_OP, ARGI_DEBUG_OP),
+/* 57 */ /* AML_FATAL_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_FATAL| AML_HAS_ARGS, "Fatal", ARGP_FATAL_OP, ARGI_FATAL_OP),
+/* 58 */ /* AML_REGION_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT| AML_HAS_ARGS, "Op_region", ARGP_REGION_OP, ARGI_REGION_OP),
+/* 59 */ /* AML_DEF_FIELD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT| AML_HAS_ARGS, "Field", ARGP_DEF_FIELD_OP, ARGI_DEF_FIELD_OP),
+/* 5_a */ /* AML_DEVICE_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT| AML_HAS_ARGS, "Device", ARGP_DEVICE_OP, ARGI_DEVICE_OP),
+/* 5_b */ /* AML_PROCESSOR_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT| AML_HAS_ARGS, "Processor", ARGP_PROCESSOR_OP, ARGI_PROCESSOR_OP),
+/* 5_c */ /* AML_POWER_RES_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT| AML_HAS_ARGS, "Power_res", ARGP_POWER_RES_OP, ARGI_POWER_RES_OP),
+/* 5_d */ /* AML_THERMAL_ZONE_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT| AML_HAS_ARGS, "Thermal_zone", ARGP_THERMAL_ZONE_OP, ARGI_THERMAL_ZONE_OP),
+/* 5_e */ /* AML_INDEX_FIELD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT| AML_HAS_ARGS, "Index_field", ARGP_INDEX_FIELD_OP, ARGI_INDEX_FIELD_OP),
+/* 5_f */ /* AML_BANK_FIELD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT| AML_HAS_ARGS, "Bank_field", ARGP_BANK_FIELD_OP, ARGI_BANK_FIELD_OP),
X
X /* Internal opcodes that map to invalid AML opcodes */


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 035'
echo 'File patch-2.4.0-test9 is continued in part 036'
echo "036" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part036

#!/bin/sh -x
# this is part 036 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 036; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

X
-/* 60 */ OP_INFO_ENTRY (AML_LNOTEQUAL_OP, OPTYPE_BOGUS| AML_HAS_ARGS| 0, "LNot_equal", ARGP_LNOTEQUAL_OP, ARGI_LNOTEQUAL_OP),
-/* 61 */ OP_INFO_ENTRY (AML_LLESSEQUAL_OP, OPTYPE_BOGUS| AML_HAS_ARGS| 0, "LLess_equal", ARGP_LLESSEQUAL_OP, ARGI_LLESSEQUAL_OP),
-/* 62 */ OP_INFO_ENTRY (AML_LGREATEREQUAL_OP, OPTYPE_BOGUS| AML_HAS_ARGS| 0, "LGreater_equal", ARGP_LGREATEREQUAL_OP, ARGI_LGREATEREQUAL_OP),
-/* 63 */ OP_INFO_ENTRY (AML_NAMEPATH_OP, OPTYPE_LITERAL| AML_NO_ARGS| 0, "Name_path", ARGP_NAMEPATH_OP, ARGI_NAMEPATH_OP),
-/* 64 */ OP_INFO_ENTRY (AML_METHODCALL_OP, OPTYPE_METHOD_CALL| AML_HAS_ARGS| 0, "Method_call", ARGP_METHODCALL_OP, ARGI_METHODCALL_OP),
-/* 65 */ OP_INFO_ENTRY (AML_BYTELIST_OP, OPTYPE_LITERAL| AML_NO_ARGS| 0, "Byte_list", ARGP_BYTELIST_OP, ARGI_BYTELIST_OP),
-/* 66 */ OP_INFO_ENTRY (AML_RESERVEDFIELD_OP, OPTYPE_BOGUS| AML_NO_ARGS| 0, "Reserved_field", ARGP_RESERVEDFIELD_OP, ARGI_RESERVEDFIELD_OP),
-/* 67 */ OP_INFO_ENTRY (AML_NAMEDFIELD_OP, OPTYPE_BOGUS| AML_NO_ARGS| 0, "Named_field", ARGP_NAMEDFIELD_OP, ARGI_NAMEDFIELD_OP),
-/* 68 */ OP_INFO_ENTRY (AML_ACCESSFIELD_OP, OPTYPE_BOGUS| AML_NO_ARGS| 0, "Access_field", ARGP_ACCESSFIELD_OP, ARGI_ACCESSFIELD_OP),
-/* 69 */ OP_INFO_ENTRY (AML_STATICSTRING_OP, OPTYPE_BOGUS| AML_NO_ARGS| 0, "Static_string", ARGP_STATICSTRING_OP, ARGI_STATICSTRING_OP),
-/* 6_a */ OP_INFO_ENTRY (0, OPTYPE_BOGUS| AML_HAS_ARGS| 0, "UNKNOWN_OP!", ARG_NONE, ARG_NONE),
- OP_INFO_ENTRY (0, 0| AML_HAS_ARGS| 0, NULL, ARG_NONE, ARG_NONE)
+/* 60 */ /* AML_LNOTEQUAL_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_BOGUS| AML_HAS_ARGS, "LNot_equal", ARGP_LNOTEQUAL_OP, ARGI_LNOTEQUAL_OP),
+/* 61 */ /* AML_LLESSEQUAL_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_BOGUS| AML_HAS_ARGS, "LLess_equal", ARGP_LLESSEQUAL_OP, ARGI_LLESSEQUAL_OP),
+/* 62 */ /* AML_LGREATEREQUAL_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_BOGUS| AML_HAS_ARGS, "LGreater_equal", ARGP_LGREATEREQUAL_OP, ARGI_LGREATEREQUAL_OP),
+/* 63 */ /* AML_NAMEPATH_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LITERAL| AML_NO_ARGS, "Name_path", ARGP_NAMEPATH_OP, ARGI_NAMEPATH_OP),
+/* 64 */ /* AML_METHODCALL_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_METHOD_CALL| AML_HAS_ARGS, "Method_call", ARGP_METHODCALL_OP, ARGI_METHODCALL_OP),
+/* 65 */ /* AML_BYTELIST_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LITERAL| AML_NO_ARGS, "Byte_list", ARGP_BYTELIST_OP, ARGI_BYTELIST_OP),
+/* 66 */ /* AML_RESERVEDFIELD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_BOGUS| AML_NO_ARGS, "Reserved_field", ARGP_RESERVEDFIELD_OP, ARGI_RESERVEDFIELD_OP),
+/* 67 */ /* AML_NAMEDFIELD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_BOGUS| AML_NO_ARGS, "Named_field", ARGP_NAMEDFIELD_OP, ARGI_NAMEDFIELD_OP),
+/* 68 */ /* AML_ACCESSFIELD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_BOGUS| AML_NO_ARGS, "Access_field", ARGP_ACCESSFIELD_OP, ARGI_ACCESSFIELD_OP),
+/* 69 */ /* AML_STATICSTRING_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_BOGUS| AML_NO_ARGS, "Static_string", ARGP_STATICSTRING_OP, ARGI_STATICSTRING_OP),
+/* 6_a */ /* AML_RETURN_VALUE_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_RETURN| AML_HAS_ARGS, "[Return Value]", ARG_NONE, ARG_NONE),
+/* 6_b */ /* UNKNOWN OPCODES */ OP_INFO_ENTRY (ACPI_OP_TYPE_UNKNOWN | OPTYPE_BOGUS| AML_HAS_ARGS, "UNKNOWN_OP!", ARG_NONE, ARG_NONE),
+/* 6_c */ /* ASCII CHARACTERS */ OP_INFO_ENTRY (ACPI_OP_TYPE_ASCII | OPTYPE_BOGUS| AML_HAS_ARGS, "ASCII_ONLY!", ARG_NONE, ARG_NONE),
+/* 6_d */ /* PREFIX CHARACTERS */ OP_INFO_ENTRY (ACPI_OP_TYPE_PREFIX | OPTYPE_BOGUS| AML_HAS_ARGS, "PREFIX_ONLY!", ARG_NONE, ARG_NONE),
X };
X
-#define _UNK 0x6A
-#define _UNKNOWN_OPCODE 0x02 /* An example unknown opcode */
-
X /*
X * This table is directly indexed by the opcodes, and returns an
X * index into the table above
X */
X
-u8 acpi_gbl_aml_op_info_index[256] =
+u8 acpi_gbl_aml_short_op_info_index[256] =
X {
X /* 0 1 2 3 4 5 6 7 */
X /* 0x00 */ 0x00, 0x01, _UNK, _UNK, _UNK, _UNK, 0x02, _UNK,
X /* 0x08 */ 0x03, _UNK, 0x04, 0x05, 0x06, 0x07, _UNK, _UNK,
-/* 0x10 */ 0x08, 0x09, 0x0a, _UNK, 0x0b, _UNK, _UNK, 0x46,
-/* 0x18 */ 0x47, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x10 */ 0x08, 0x09, 0x0a, _UNK, 0x0b, _UNK, _UNK, _UNK,
+/* 0x18 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
X /* 0x20 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x28 */ 0x48, 0x49, _UNK, _UNK, _UNK, 0x63, _UNK, _UNK,
-/* 0x30 */ 0x67, 0x66, 0x68, 0x65, 0x69, 0x64, 0x4a, 0x4b,
-/* 0x38 */ 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53,
-/* 0x40 */ 0x54, _UNK, _UNK, _UNK, _UNK, _UNK, 0x55, 0x56,
-/* 0x48 */ 0x57, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x50 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
-/* 0x58 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x28 */ _UNK, _UNK, _UNK, _UNK, _UNK, 0x63, _PFX, _PFX,
+/* 0x30 */ 0x67, 0x66, 0x68, 0x65, 0x69, 0x64, 0x6A, _UNK,
+/* 0x38 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x40 */ _UNK, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
+/* 0x48 */ _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
+/* 0x50 */ _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
+/* 0x58 */ _ASC, _ASC, _ASC, _UNK, _PFX, _UNK, _PFX, _ASC,
X /* 0x60 */ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
X /* 0x68 */ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, _UNK,
X /* 0x70 */ 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22,
X /* 0x78 */ 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
X /* 0x80 */ 0x2b, 0x2c, 0x2d, 0x2e, _UNK, _UNK, 0x2f, 0x30,
X /* 0x88 */ 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, _UNK,
-/* 0x90 */ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x58, 0x59,
-/* 0x98 */ 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, _UNK, _UNK,
+/* 0x90 */ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, _UNK, _UNK,
+/* 0x98 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
X /* 0xA0 */ 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x60, 0x61,
X /* 0xA8 */ 0x62, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
X /* 0xB0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
@@ -552,3 +575,32 @@
X /* 0xF0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
X /* 0xF8 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 0x45,
X };
+
+
+u8 acpi_gbl_aml_long_op_info_index[NUM_EXTENDED_OPCODE] =
+{
+/* 0 1 2 3 4 5 6 7 */
+/* 0x00 */ _UNK, 0x46, 0x47, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x08 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x10 */ _UNK, _UNK, 0x48, 0x49, _UNK, _UNK, _UNK, _UNK,
+/* 0x18 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x20 */ 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51,
+/* 0x28 */ 0x52, 0x53, 0x54, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x30 */ 0x55, 0x56, 0x57, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x38 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x40 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x48 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x50 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x58 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x60 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x68 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x70 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x78 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
+/* 0x80 */ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+};
+
+
+/* 0 1 2 3 4 5 6 7 */
+/* 0x00 */
+
+
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/parser/psparse.c linux/drivers/acpi/parser/psparse.c
--- v2.4.0-test8/linux/drivers/acpi/parser/psparse.c Wed Jul 5 11:23:12 2000
+++ linux/drivers/acpi/parser/psparse.c Fri Sep 15 14:30:30 2000


@@ -1,6 +1,7 @@
X /******************************************************************************
X *

X * Module Name: psparse - Parser top level AML parse routines
+ * $Revision: 51 $


X *
X *****************************************************************************/
X

@@ -33,14 +34,14 @@
X */
X

X #include "acpi.h"
-#include "parser.h"
-#include "dispatch.h"

+#include "acparser.h"
+#include "acdispat.h"


X #include "amlcode.h"
-#include "namesp.h"

-#include "debugger.h"
+#include "acnamesp.h"
+#include "acdebug.h"


X
X #define _COMPONENT PARSER

- MODULE_NAME ("psparse");
+ MODULE_NAME ("psparse")
X
X
X u32 acpi_gbl_depth = 0;
@@ -65,11 +66,11 @@
X ACPI_STATUS
X acpi_ps_delete_completed_op (
X ACPI_WALK_STATE *state,
- ACPI_GENERIC_OP *op)


+ ACPI_PARSE_OBJECT *op)
X {
X

X acpi_ps_free_op (op);


- return AE_OK;
+ return (AE_OK);
X }
X
X

@@ -78,7 +79,7 @@
X *
X * FUNCTION: Acpi_ps_delete_parse_tree
X *
- * PARAMETERS: Root - Root of tree (or subtree) to delete
+ * PARAMETERS: Subtree_root - Root of tree (or subtree) to delete
X *
X * RETURN: None
X *
@@ -88,33 +89,54 @@
X
X void
X acpi_ps_delete_parse_tree (
- ACPI_GENERIC_OP *root)
+ ACPI_PARSE_OBJECT *subtree_root)
X {
- ACPI_GENERIC_OP *op;
- ACPI_WALK_STATE walk_state;
+ ACPI_WALK_STATE *walk_state;
+ ACPI_WALK_LIST walk_list;
X
X
- walk_state.origin = root;
- op = root;
+ if (!subtree_root) {
+ return;
+ }
X
- /* TBD: [Restructure] hack for root case */
+ /* Create and initialize a new walk list */
X
- if (op == acpi_gbl_parsed_namespace_root) {
- op = acpi_ps_get_child (op);
+ walk_list.walk_state = NULL;
+ walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, NULL, NULL, &walk_list);
+ if (!walk_state) {
+ return;
X }
X
- /* Save root until last, so that we know when the tree has been walked */
+ walk_state->parser_state = NULL;
+ walk_state->parse_flags = 0;
+ walk_state->descending_callback = NULL;
+ walk_state->ascending_callback = NULL;
+
X
- walk_state.next_op = op;
- walk_state.next_op_info = NEXT_OP_DOWNWARD;
+ walk_state->origin = subtree_root;
+ walk_state->next_op = subtree_root;
X
- while (walk_state.next_op) {
- acpi_ps_get_next_walk_op (&walk_state, walk_state.next_op,
+
+ /* Head downward in the tree */
+
+ walk_state->next_op_info = NEXT_OP_DOWNWARD;
+
+ /* Visit all nodes in the subtree */
+
+ while (walk_state->next_op) {
+ acpi_ps_get_next_walk_op (walk_state, walk_state->next_op,
X acpi_ps_delete_completed_op);
X }
+
+ /* We are done with this walk */
+
+ acpi_ds_delete_walk_state (walk_state);
+
+ return;
X }
X #endif
X
+
X /*******************************************************************************
X *
X * FUNCTION: Acpi_ps_peek_opcode
@@ -135,12 +157,12 @@
X /* Extended (2-byte) opcode if > 255 */
X
X if (opcode > 0x00FF) {
- return 2;
+ return (2);
X }
X
X /* Otherwise, just a single byte opcode */
X
- return 1;
+ return (1);
X }
X
X
@@ -194,7 +216,7 @@
X
X /* don't convert bare name to a namepath */
X
- return opcode;
+ return (opcode);
X }
X
X
@@ -214,7 +236,7 @@
X ACPI_PARSE_STATE *
X acpi_ps_create_state (
X u8 *aml,
- s32 aml_size)
+ u32 aml_size)
X {
X ACPI_PARSE_STATE *parser_state;
X
@@ -257,88 +279,270 @@
X ACPI_STATUS
X acpi_ps_find_object (
X u16 opcode,
- ACPI_PARSE_STATE *parser_state,
+ ACPI_PARSE_OBJECT *op,
X ACPI_WALK_STATE *walk_state,
- ACPI_GENERIC_OP **op)
+ ACPI_PARSE_OBJECT **out_op)
X {
- char *path;


+ NATIVE_CHAR *path;
X
X

+ /* We are only interested in opcodes that have an associated name */


+
+ if (!acpi_ps_is_named_op (opcode)) {

+ *out_op = op;


+ return (AE_OK);
+ }
+

X /* Find the name in the parse tree */
X
- path = acpi_ps_get_next_namestring (parser_state);


+ path = acpi_ps_get_next_namestring (walk_state->parser_state);

X
- *op = acpi_ps_find (acpi_ps_get_parent_scope (parser_state),
+ *out_op = acpi_ps_find (acpi_ps_get_parent_scope (walk_state->parser_state),
X path, opcode, 1);
X
- if (!(*op)) {
- return AE_NOT_FOUND;
+ if (!(*out_op)) {


+ return (AE_NOT_FOUND);
X }
X

- return AE_OK;
+ return (AE_OK);
X }

+
+#endif


+
+
+/*******************************************************************************
+ *

+ * FUNCTION: Acpi_ps_complete_this_op
+ *
+ * PARAMETERS: Walk_state - Current State
+ * Op - Op to complete
+ *
+ * RETURN: TRUE if Op and subtree was deleted
+ *
+ * DESCRIPTION: Perform any cleanup at the completion of an Op.


+ *
+ ******************************************************************************/
+

+u8
+acpi_ps_complete_this_op (
+ ACPI_WALK_STATE *walk_state,
+ ACPI_PARSE_OBJECT *op)
+{
+#ifndef PARSER_ONLY
+ ACPI_PARSE_OBJECT *prev;
+ ACPI_PARSE_OBJECT *next;
+ ACPI_OPCODE_INFO *op_info;
+ ACPI_OPCODE_INFO *parent_info;
+ u32 opcode_class;
+ ACPI_PARSE_OBJECT *replacement_op = NULL;
+
+
+ op_info = acpi_ps_get_opcode_info (op->opcode);
+ opcode_class = ACPI_GET_OP_CLASS (op_info);
+
+
+ /* Delete this op and the subtree below it if asked to */
+
+ if (((walk_state->parse_flags & ACPI_PARSE_TREE_MASK) == ACPI_PARSE_DELETE_TREE) &&
+ (opcode_class != OPTYPE_CONSTANT) &&
+ (opcode_class != OPTYPE_LITERAL) &&
+ (opcode_class != OPTYPE_LOCAL_VARIABLE) &&
+ (opcode_class != OPTYPE_METHOD_ARGUMENT) &&
+ (opcode_class != OPTYPE_DATA_TERM) &&
+ (op->opcode != AML_NAMEPATH_OP))
+ {
+ /* Make sure that we only delete this subtree */
+
+ if (op->parent) {
+ /*
+ * Check if we need to replace the operator and its subtree
+ * with a return value op
+ */
+
+ parent_info = acpi_ps_get_opcode_info (op->parent->opcode);
+
+ switch (ACPI_GET_OP_CLASS (parent_info))
+ {
+ case OPTYPE_CONTROL: /* IF, ELSE, WHILE only */
+ case OPTYPE_NAMED_OBJECT: /* Scope, method, etc. */


+ break;
+
+ default:

+ replacement_op = acpi_ps_alloc_op (AML_RETURN_VALUE_OP);
+ if (!replacement_op) {
+ return (FALSE);
+ }
+ }
+
+ /* We must unlink this op from the parent tree */
+
+ prev = op->parent->value.arg;
+ if (prev == op) {
+ /* This op is the first in the list */
+
+ if (replacement_op) {
+ replacement_op->parent = op->parent;
+ replacement_op->value.arg = NULL;
+ op->parent->value.arg = replacement_op;
+ replacement_op->next = op->next;
+ }
+ else {
+ op->parent->value.arg = op->next;
+ }
+ }
+
+ /* Search the parent list */
+
+ else while (prev) {
+ /* Traverse all siblings in the parent's argument list */
+
+ next = prev->next;
+ if (next == op) {
+ if (replacement_op) {
+ replacement_op->parent = op->parent;
+ replacement_op->value.arg = NULL;
+ prev->next = replacement_op;
+ replacement_op->next = op->next;
+ next = NULL;
+ }
+ else {
+ prev->next = op->next;
+ next = NULL;
+ }
+ }
+
+ prev = next;
+ }
+
+ }
+
+ /* Now we can actually delete the subtree rooted at op */
+
+ acpi_ps_delete_parse_tree (op);
+


+ return (TRUE);
+ }
+

+ return (FALSE);
+
X #else
+ return (FALSE);
+#endif


+}
+
+
+/*******************************************************************************
+ *

+ * FUNCTION: Acpi_ps_next_parse_state
+ *
+ * PARAMETERS: Parser_state - Current parser state object


+ *
+ * RETURN:

+ *
+ * DESCRIPTION:

+ *
+ ******************************************************************************/
+

X
X ACPI_STATUS
-acpi_ps_find_object (
- u16 opcode,
- ACPI_PARSE_STATE *parser_state,
+acpi_ps_next_parse_state (
X ACPI_WALK_STATE *walk_state,
- ACPI_GENERIC_OP **out_op)
+ ACPI_PARSE_OBJECT *op,
+ ACPI_STATUS callback_status)
X {
- char *path;
- ACPI_GENERIC_OP *op;
- OBJECT_TYPE_INTERNAL data_type;
- ACPI_STATUS status;


- ACPI_NAMED_OBJECT *entry = NULL;

+ ACPI_PARSE_STATE *parser_state = walk_state->parser_state;
+ ACPI_STATUS status = AE_CTRL_PENDING;
X
X
- /*
- * The full parse tree has already been deleted -- therefore, we are parsing
- * a control method. We can lookup the name in the namespace instead of
- * the parse tree!
- */
+ switch (callback_status)
+ {
+ case AE_CTRL_TERMINATE:
X
+ /*
+ * A control method was terminated via a RETURN statement.
+ * The walk of this method is complete.
+ */
X
- path = acpi_ps_get_next_namestring (parser_state);
+ parser_state->aml = parser_state->aml_end;
+ status = AE_CTRL_TERMINATE;
+ break;
X
- /* Map the raw opcode into an internal object type */
X
- data_type = acpi_ds_map_named_opcode_to_data_type (opcode);
+ case AE_CTRL_PENDING:
X
- /*
- * Enter the object into the namespace
- * LOAD_PASS1 means Create if not found
- */
+ /*
+ * Predicate of a WHILE was true and the loop just completed an
+ * execution. Go back to the start of the loop and reevaluate the
+ * predicate.
+ */
+/* Walk_state->Control_state->Common.State =
+ CONTROL_PREDICATE_EXECUTING;*/
X
- status = acpi_ns_lookup (walk_state->scope_info, path, data_type,
- IMODE_LOAD_PASS1,
- NS_NO_UPSEARCH, walk_state, &entry);


- if (ACPI_FAILURE (status)) {
- return (status);
- }

+ /* TBD: How to handle a break within a while. */
+ /* This code attempts it */
X
- /* Create a new op */
+ parser_state->aml = walk_state->aml_last_while;
+ break;
X
- op = acpi_ps_alloc_op (opcode);
- if (!op) {


- return (AE_NO_MEMORY);
- }
X

- /* Initialize */
+ case AE_CTRL_TRUE:
+ /*
+ * Predicate of an IF was true, and we are at the matching ELSE.
+ * Just close out this package
+ *
+ * Parser_state->Aml is modified by the package length procedure
+ */
+ parser_state->aml = (parser_state->aml +
+ acpi_ps_get_next_package_length (parser_state)) -1;
+ break;
+
X
- ((ACPI_NAMED_OP *)op)->name = entry->name;


- op->acpi_named_object = entry;

+ case AE_CTRL_FALSE:
X
+ /*
+ * Either an IF/WHILE Predicate was false or we encountered a BREAK
+ * opcode. In both cases, we do not execute the rest of the
+ * package; We simply close out the parent (finishing the walk of
+ * this branch of the tree) and continue execution at the parent
+ * level.
+ */
X
- acpi_ps_append_arg (acpi_ps_get_parent_scope (parser_state), op);
+ parser_state->aml = parser_state->scope->parse_scope.pkg_end;
X
- *out_op = op;
+ /* In the case of a BREAK, just force a predicate (if any) to FALSE */
X
+ walk_state->control_state->common.value = FALSE;
+ status = AE_CTRL_END;
+ break;


X
- return (AE_OK);
+

+ case AE_CTRL_TRANSFER:
+
+ /*
+ * A method call (invocation) -- transfer control
+ */
+ status = AE_CTRL_TRANSFER;
+ walk_state->prev_op = op;
+ walk_state->method_call_op = op;
+ walk_state->method_call_node = (op->value.arg)->node;
+
+ /* Will return value (if any) be used by the caller? */
+
+ walk_state->return_used = acpi_ds_is_result_used (op);
+ break;
+
+
+ default:
+ status = callback_status;
+ if ((callback_status & AE_CODE_MASK) == AE_CODE_CONTROL) {
+ status = AE_OK;


+ }
+ break;
+ }
+
+

+ return (status);
X }
-#endif
X
X
X /*******************************************************************************
@@ -356,26 +560,27 @@
X
X ACPI_STATUS
X acpi_ps_parse_loop (


- ACPI_PARSE_STATE *parser_state,
- ACPI_WALK_STATE *walk_state,
- u32 parse_flags)

+ ACPI_WALK_STATE *walk_state)


X {
X ACPI_STATUS status = AE_OK;

- ACPI_GENERIC_OP *op = NULL; /* current op */
- ACPI_OP_INFO *op_info;


- ACPI_GENERIC_OP *arg = NULL;

- ACPI_DEFERRED_OP *deferred_op;
+ ACPI_PARSE_OBJECT *op = NULL; /* current op */
+ ACPI_OPCODE_INFO *op_info;


+ ACPI_PARSE_OBJECT *arg = NULL;

+ ACPI_PARSE2_OBJECT *deferred_op;
X u32 arg_count; /* push for fixed or var args */
X u32 arg_types = 0;
X ACPI_PTRDIFF aml_offset;
X u16 opcode;
- ACPI_GENERIC_OP pre_op;
+ ACPI_PARSE_OBJECT pre_op;
+ ACPI_PARSE_STATE *parser_state;
X
X
-#ifndef PARSER_ONLY
- OBJECT_TYPE_INTERNAL data_type;
-#endif
+ parser_state = walk_state->parser_state;
X
+ if (walk_state->prev_op) {
+ op = walk_state->prev_op;
+ arg_types = walk_state->prev_arg_types;
+ }
X
X /*
X * Iterative parsing loop, while there is more aml to process:
@@ -384,9 +589,8 @@
X if (!op) {
X /* Get the next opcode from the AML stream */
X
- aml_offset = parser_state->aml - parser_state->aml_start;
- opcode = acpi_ps_peek_opcode (parser_state);
- op_info = acpi_ps_get_opcode_info (opcode);
+ aml_offset = parser_state->aml - parser_state->aml_start;
+ opcode = acpi_ps_peek_opcode (parser_state);
X
X /*
X * First cut to determine what we have found:
@@ -395,16 +599,19 @@
X * 3) An unknown/invalid opcode
X */
X
- if (op_info) {
+ op_info = acpi_ps_get_opcode_info (opcode);
+ switch (ACPI_GET_OP_TYPE (op_info))
+ {
+ case ACPI_OP_TYPE_OPCODE:
+
X /* Found opcode info, this is a normal opcode */
X
X parser_state->aml += acpi_ps_get_opcode_size (opcode);
X arg_types = op_info->parse_args;
- }
+ break;
X
- else if (acpi_ps_is_prefix_char (opcode) ||
- acpi_ps_is_leading_char (opcode))
- {
+ case ACPI_OP_TYPE_ASCII:
+ case ACPI_OP_TYPE_PREFIX:
X /*
X * Starts with a valid prefix or ASCII char, this is a name
X * string. Convert the bare name string to a namepath.
@@ -412,9 +619,10 @@
X
X opcode = AML_NAMEPATH_OP;
X arg_types = ARGP_NAMESTRING;
- }
+ break;
+
+ case ACPI_OP_TYPE_UNKNOWN:
X
- else {
X /* The opcode is unrecognized. Just skip unknown opcodes */
X
X parser_state->aml += acpi_ps_get_opcode_size (opcode);
@@ -441,9 +649,24 @@
X
X INCREMENT_ARG_LIST (arg_types);
X
- status = acpi_ps_find_object (opcode, parser_state, walk_state, &op);
- if (ACPI_FAILURE (status)) {
- return (AE_NOT_FOUND);
+ if (walk_state->descending_callback != NULL) {
+ /*
+ * Find the object. This will either insert the object into
+ * the namespace or simply look it up
+ */
+ status = walk_state->descending_callback (opcode, NULL, walk_state, &op);
+ if (op == NULL) {
+ continue;
+ }
+ status = acpi_ps_next_parse_state (walk_state, op, status);
+ if (status == AE_CTRL_PENDING) {
+ status = AE_OK;
+ goto close_this_op;
+ }


+
+ if (ACPI_FAILURE (status)) {

+ goto close_this_op;
+ }
X }
X
X acpi_ps_append_arg (op, pre_op.value.arg);
@@ -451,7 +674,7 @@
X
X
X if (op->opcode == AML_REGION_OP) {
- deferred_op = acpi_ps_to_deferred_op (op);
+ deferred_op = acpi_ps_to_extended_op (op);
X if (deferred_op) {
X /*
X * Skip parsing of control method or opregion body,
@@ -464,13 +687,15 @@
X * Body_length is unknown until we parse the body
X */
X
- deferred_op->body = parser_state->aml - 6;
- deferred_op->body_length = 0;
+ deferred_op->data = parser_state->aml - 6;
+ deferred_op->length = 0;
X }
X }
X }
X
X else {
+
+
X /* Not a named opcode, just allocate Op and append to parent */
X
X op = acpi_ps_alloc_op (opcode);
@@ -479,6 +704,23 @@
X }
X
X acpi_ps_append_arg (acpi_ps_get_parent_scope (parser_state), op);
+
+ if ((walk_state->descending_callback != NULL)) {
+ /*
+ * Find the object. This will either insert the object into
+ * the namespace or simply look it up
+ */
+ status = walk_state->descending_callback (opcode, op, walk_state, &op);
+ status = acpi_ps_next_parse_state (walk_state, op, status);
+ if (status == AE_CTRL_PENDING) {
+ status = AE_OK;
+ goto close_this_op;
+ }


+
+ if (ACPI_FAILURE (status)) {

+ goto close_this_op;
+ }
+ }
X }
X
X op->aml_offset = aml_offset;
@@ -532,7 +774,7 @@
X /* For a method, save the length and address of the body */
X
X if (op->opcode == AML_METHOD_OP) {
- deferred_op = acpi_ps_to_deferred_op (op);
+ deferred_op = acpi_ps_to_extended_op (op);
X if (deferred_op) {
X /*
X * Skip parsing of control method or opregion body,
@@ -540,8 +782,8 @@
X * to parse them correctly.
X */
X
- deferred_op->body = parser_state->aml;
- deferred_op->body_length = parser_state->pkg_end -
+ deferred_op->data = parser_state->aml;
+ deferred_op->length = parser_state->pkg_end -
X parser_state->aml;
X
X /*
@@ -549,8 +791,8 @@
X * parsing because the opregion is not a standalone
X * package (We don't know where the end is).
X */
- parser_state->aml = parser_state->pkg_end;
- arg_count = 0;
+ parser_state->aml = parser_state->pkg_end;
+ arg_count = 0;
X }
X }
X
@@ -567,7 +809,7 @@
X }
X
X if (op->opcode == AML_REGION_OP) {
- deferred_op = acpi_ps_to_deferred_op (op);
+ deferred_op = acpi_ps_to_extended_op (op);
X if (deferred_op) {
X /*
X * Skip parsing of control method or opregion body,
@@ -578,46 +820,75 @@
X * know the length.
X */
X
- deferred_op->body_length = parser_state->aml -
- deferred_op->body;
+ deferred_op->length = parser_state->aml -
+ deferred_op->data;
X }
X }
+ }
X
X
-#ifndef PARSER_ONLY


- data_type = acpi_ds_map_named_opcode_to_data_type (op->opcode);

+ /* This op complete, notify the dispatcher */


X
- if (op->opcode == AML_NAME_OP) {
- if (op->value.arg) {

- data_type = acpi_ds_map_opcode_to_data_type (
- (op->value.arg)->opcode, NULL);
- ((ACPI_NAMED_OBJECT*)op->acpi_named_object)->type =
- (u8) data_type;
- }
+ if (walk_state->ascending_callback != NULL) {
+ status = walk_state->ascending_callback (walk_state, op);
+ status = acpi_ps_next_parse_state (walk_state, op, status);
+ if (status == AE_CTRL_PENDING) {
+ status = AE_OK;
+ goto close_this_op;
X }
+ }
X
- /* Pop the scope stack */
X
- if (acpi_ns_opens_scope (data_type)) {
+close_this_op:
X
- acpi_ds_scope_stack_pop (walk_state);
- }
-#endif
+ parser_state->scope->parse_scope.arg_count--;
+
+ /* Close this Op (may result in parse subtree deletion) */
+
+ if (acpi_ps_complete_this_op (walk_state, op)) {


+ op = NULL;
+ }
+

+
+ if (status == AE_CTRL_END) {
+ acpi_ps_pop_scope (parser_state, &op, &arg_types);
+ status = walk_state->ascending_callback (walk_state, op);
+ status = acpi_ps_next_parse_state (walk_state, op, status);
+ acpi_ps_complete_this_op (walk_state, op);
+ op = NULL;
+ status = AE_OK;
X }
X

+ else if (ACPI_FAILURE (status)) {

+ if (op == NULL) {
+ acpi_ps_pop_scope (parser_state, &op, &arg_types);
+ }
+ walk_state->prev_op = op;
+ walk_state->prev_arg_types = arg_types;
X
- parser_state->scope->arg_count--;
+ /*
+ * TEMP:
+ */
X
+ if (status == AE_CTRL_TERMINATE) {
+ status = AE_OK;
X
- /* Delete op if asked to */
+ /* Clean up */
+ do
+ {
+ if (op) {
+ acpi_ps_complete_this_op (walk_state, op);
+ }
X
-#ifndef PARSER_ONLY
- if (parse_flags & PARSE_DELETE_TREE) {
- acpi_ps_delete_parse_tree (op);
+ acpi_ps_pop_scope (parser_state, &op, &arg_types);
+ } while (op);
+ }
+ return (status);
X }
-#endif
X
X
+ /* This scope complete? */
+
X if (acpi_ps_has_completed_scope (parser_state)) {
X acpi_ps_pop_scope (parser_state, &op, &arg_types);
X }
@@ -625,6 +896,7 @@
X else {
X op = NULL;
X }
+
X }
X
X else {
@@ -637,6 +909,54 @@
X } /* while Parser_state->Aml */
X
X
+ /*
+ * Complete the last Op (if not completed), and clear the scope stack.
+ * It is easily possible to end an AML "package" with an unbounded number
+ * of open scopes (such as when several AML blocks are closed with
+ * sequential closing braces). We want to terminate each one cleanly.
+ */
+
+ do
+ {
+ if (op) {
+ if (walk_state->ascending_callback != NULL) {
+ status = walk_state->ascending_callback (walk_state, op);
+ status = acpi_ps_next_parse_state (walk_state, op, status);
+ if (status == AE_CTRL_PENDING) {
+ status = AE_OK;
+ goto close_this_op;
+ }
+
+ if (status == AE_CTRL_TERMINATE) {
+ status = AE_OK;
+
+ /* Clean up */
+ do
+ {
+ if (op) {
+ acpi_ps_complete_this_op (walk_state, op);
+ }
+
+ acpi_ps_pop_scope (parser_state, &op, &arg_types);


+
+ } while (op);
+

+ return (status);
+ }
+
+ else if (ACPI_FAILURE (status)) {
+ acpi_ps_complete_this_op (walk_state, op);


+ return (status);
+ }
+ }

+
+ acpi_ps_complete_this_op (walk_state, op);
+ }
+
+ acpi_ps_pop_scope (parser_state, &op, &arg_types);


+
+ } while (op);
+

X return (status);
X }
X

@@ -658,19 +978,28 @@
X
X ACPI_STATUS
X acpi_ps_parse_aml (
- ACPI_GENERIC_OP *start_scope,
+ ACPI_PARSE_OBJECT *start_scope,
X u8 *aml,
X u32 aml_size,
- u32 parse_flags)
+ u32 parse_flags,


+ ACPI_NAMESPACE_NODE *method_node,
+ ACPI_OPERAND_OBJECT **params,

+ ACPI_OPERAND_OBJECT **caller_return_desc,
+ ACPI_PARSE_DOWNWARDS descending_callback,
+ ACPI_PARSE_UPWARDS ascending_callback)

X {
X ACPI_STATUS status;
X ACPI_PARSE_STATE *parser_state;
X ACPI_WALK_STATE *walk_state;
X ACPI_WALK_LIST walk_list;
- ACPI_NAMED_OBJECT *entry = NULL;
+ ACPI_NAMESPACE_NODE *node = NULL;
+ ACPI_WALK_LIST *prev_walk_list = acpi_gbl_current_walk_list;
+ ACPI_OPERAND_OBJECT *return_desc;
+ ACPI_OPERAND_OBJECT *mth_desc = NULL;
+ ACPI_NAMESPACE_NODE *start_node;
X
X
- /* Initialize parser state and scope */


+ /* Create and initialize a new parser state */

X
X parser_state = acpi_ps_create_state (aml, aml_size);
X if (!parser_state) {
@@ -679,36 +1008,166 @@
X
X acpi_ps_init_scope (parser_state, start_scope);
X
+ if (method_node) {
+ mth_desc = acpi_ns_get_attached_object (method_node);
+ }
X
- /* Initialize a new walk list */
+ /* Create and initialize a new walk list */
X
X walk_list.walk_state = NULL;
X
- walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, NULL, NULL, &walk_list);
+ walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, parser_state->start_op, mth_desc, &walk_list);
X if (!walk_state) {
X status = AE_NO_MEMORY;
X goto cleanup;
X }
X
+ walk_state->method_node = method_node;
+ walk_state->parser_state = parser_state;
+ walk_state->parse_flags = parse_flags;
+ walk_state->descending_callback = descending_callback;
+ walk_state->ascending_callback = ascending_callback;
+
+ /* TBD: [Restructure] TEMP until we pass Walk_state to the interpreter
+ */
+ acpi_gbl_current_walk_list = &walk_list;
+
X
- /* Setup the current scope */
+ if (method_node) {
+ start_node = method_node;


+ parser_state->start_node = method_node;

+ walk_state->walk_type = WALK_METHOD;
X

- entry = parser_state->start_op->acpi_named_object;
- if (entry) {

- /* Push start scope on scope stack and make it current */
+ if (start_node) {
+ /* Push start scope on scope stack and make it current */
+
+ status = acpi_ds_scope_stack_push (start_node, ACPI_TYPE_METHOD, walk_state);
+ if (ACPI_FAILURE (status)) {


+ return (status);
+ }
X

- status = acpi_ds_scope_stack_push (entry->child_table, entry->type,
- walk_state);
- if (ACPI_FAILURE (status)) {
- goto cleanup;
X }
+ /* Init arguments if this is a control method */
+ /* TBD: [Restructure] add walkstate as a param */
X
+ acpi_ds_method_data_init_args (params, MTH_NUM_ARGS, walk_state);
X }
X
+ else {
+ /* Setup the current scope */
X
- /* Create the parse tree */
+ node = parser_state->start_op->node;
+ if (node) {
+ /* Push start scope on scope stack and make it current */
+
+ status = acpi_ds_scope_stack_push (node, node->type,
+ walk_state);
+ if (ACPI_FAILURE (status)) {


+ goto cleanup;
+ }
+
+ }

+ }
X
- status = acpi_ps_parse_loop (parser_state, walk_state, parse_flags);
+
+ status = AE_OK;
+
+ /*
+ * Execute the walk loop as long as there is a valid Walk State. This
+ * handles nested control method invocations without recursion.
+ */
+
+ while (walk_state) {
+ if (ACPI_SUCCESS (status)) {
+ status = acpi_ps_parse_loop (walk_state);
+ }
+
+ if (status == AE_CTRL_TRANSFER) {
+ /*
+ * A method call was detected.
+ * Transfer control to the called control method
+ */
+
+ status = acpi_ds_call_control_method (&walk_list, walk_state, NULL);
+
+ /*
+ * If the transfer to the new method method call worked, a new walk
+ * state was created -- get it
+ */
+
+ walk_state = acpi_ds_get_current_walk_state (&walk_list);
+ continue;
+ }
+
+ else if (status == AE_CTRL_TERMINATE) {


+ status = AE_OK;
+ }
+

+ /* We are done with this walk, move on to the parent if any */
+
+
+ walk_state = acpi_ds_pop_walk_state (&walk_list);
+
+ /* Extract return value before we delete Walk_state */
+
+ return_desc = walk_state->return_desc;
+
+ /* Reset the current scope to the beginning of scope stack */
+
+ acpi_ds_scope_stack_clear (walk_state);
+
+ /*
+ * If we just returned from the execution of a control method,
+ * there's lots of cleanup to do
+ */
+
+ if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) {
+ acpi_ds_terminate_control_method (walk_state);
+ }
+
+ /* Delete this walk state and all linked control states */
+
+ acpi_ps_cleanup_scope (walk_state->parser_state);
+ acpi_cm_free (walk_state->parser_state);
+ acpi_ds_delete_walk_state (walk_state);
+
+ /* Check if we have restarted a preempted walk */
+
+ walk_state = acpi_ds_get_current_walk_state (&walk_list);
+ if (walk_state &&
+ ACPI_SUCCESS (status))
+ {
+ /* There is another walk state, restart it */
+
+ /*
+ * If the method returned value is not used by the parent,
+ * The object is deleted
+ */
+
+ acpi_ds_restart_control_method (walk_state, return_desc);
+ }
+
+ /*
+ * Just completed a 1st-level method, save the final internal return
+ * value (if any)
+ */
+
+ else if (caller_return_desc) {
+ *caller_return_desc = return_desc; /* NULL if no return value */
+ }
+
+ else if (return_desc) {
+ /* Caller doesn't want it, must delete it */
+
+ acpi_cm_remove_reference (return_desc);
+ }
+ }
+
+
+ /* Normal exit */
+
+ acpi_gbl_current_walk_list = prev_walk_list;


+ return (status);
X
X

X cleanup:
@@ -719,6 +1178,7 @@
X acpi_ps_cleanup_scope (parser_state);
X acpi_cm_free (parser_state);
X
+ acpi_gbl_current_walk_list = prev_walk_list;
X
X return (status);
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/parser/psscope.c linux/drivers/acpi/parser/psscope.c
--- v2.4.0-test8/linux/drivers/acpi/parser/psscope.c Wed Jul 5 11:23:13 2000
+++ linux/drivers/acpi/parser/psscope.c Fri Sep 15 14:30:30 2000


@@ -1,6 +1,7 @@
X /******************************************************************************
X *

X * Module Name: psscope - Parser scope stack management routines
+ * $Revision: 18 $


X *
X *****************************************************************************/
X

@@ -24,10 +25,10 @@


X
X
X #include "acpi.h"
-#include "parser.h"
+#include "acparser.h"
X

X #define _COMPONENT PARSER
- MODULE_NAME ("psscope");
+ MODULE_NAME ("psscope")
X
X
X /*******************************************************************************
@@ -42,11 +43,11 @@


X *
X ******************************************************************************/
X
-ACPI_GENERIC_OP *
+ACPI_PARSE_OBJECT *

X acpi_ps_get_parent_scope (
X ACPI_PARSE_STATE *parser_state)
X {
- return parser_state->scope->op;
+ return (parser_state->scope->parse_scope.op);
X }
X
X
@@ -68,8 +69,8 @@
X acpi_ps_has_completed_scope (
X ACPI_PARSE_STATE *parser_state)
X {
- return (u8) ((parser_state->aml >= parser_state->scope->arg_end ||
- !parser_state->scope->arg_count));
+ return ((u8) ((parser_state->aml >= parser_state->scope->parse_scope.arg_end ||
+ !parser_state->scope->parse_scope.arg_count)));
X }
X
X
@@ -78,7 +79,7 @@
X * FUNCTION: Acpi_ps_init_scope
X *
X * PARAMETERS: Parser_state - Current parser state object
- * Root - the root object of this new scope
+ * Root - the Root Node of this new scope


X *
X * RETURN: Status
X *

@@ -89,24 +90,25 @@
X ACPI_STATUS
X acpi_ps_init_scope (
X ACPI_PARSE_STATE *parser_state,
- ACPI_GENERIC_OP *root)
+ ACPI_PARSE_OBJECT *root_op)
X {
- ACPI_PARSE_SCOPE *scope;
+ ACPI_GENERIC_STATE *scope;
X
X
- scope = acpi_cm_callocate (sizeof (ACPI_PARSE_SCOPE));
+ scope = acpi_cm_create_generic_state ();
X if (!scope) {
- return AE_NO_MEMORY;


+ return (AE_NO_MEMORY);
X }
X

- scope->op = root;
- scope->arg_count = ACPI_VAR_ARGS;
- scope->arg_end = parser_state->aml_end;
- scope->pkg_end = parser_state->aml_end;
- parser_state->scope = scope;
- parser_state->start_op = root;
+ scope->parse_scope.op = root_op;
+ scope->parse_scope.arg_count = ACPI_VAR_ARGS;
+ scope->parse_scope.arg_end = parser_state->aml_end;
+ scope->parse_scope.pkg_end = parser_state->aml_end;
X
- return AE_OK;
+ parser_state->scope = scope;
+ parser_state->start_op = root_op;
+


+ return (AE_OK);
X }
X
X

@@ -128,49 +130,39 @@
X ACPI_STATUS
X acpi_ps_push_scope (
X ACPI_PARSE_STATE *parser_state,


- ACPI_GENERIC_OP *op,
+ ACPI_PARSE_OBJECT *op,

X u32 remaining_args,
X u32 arg_count)
X {
- ACPI_PARSE_SCOPE *scope = parser_state->scope_avail;
-
+ ACPI_GENERIC_STATE *scope;
X
- if (scope) {
- /* grabbed scope from available list */
X
- parser_state->scope_avail = scope->parent;
+ scope = acpi_cm_create_generic_state ();
+ if (!scope) {


+ return (AE_NO_MEMORY);
X }
X

- else {
- /* allocate scope from the heap */
X
- scope = (ACPI_PARSE_SCOPE*) acpi_cm_allocate (sizeof (ACPI_PARSE_SCOPE));
- if (!scope) {


- return (AE_NO_MEMORY);
- }
- }

+ scope->parse_scope.op = op;
+ scope->parse_scope.arg_list = remaining_args;
+ scope->parse_scope.arg_count = arg_count;
+ scope->parse_scope.pkg_end = parser_state->pkg_end;
X
- /* Always zero out the scope before init */
+ /* Push onto scope stack */
X
- MEMSET (scope, 0, sizeof (*scope));
+ acpi_cm_push_generic_state (&parser_state->scope, scope);
X
- scope->op = op;
- scope->arg_list = remaining_args;
- scope->arg_count = arg_count;
- scope->pkg_end = parser_state->pkg_end;
- scope->parent = parser_state->scope;
- parser_state->scope = scope;
X
X if (arg_count == ACPI_VAR_ARGS) {
X /* multiple arguments */
X
- scope->arg_end = parser_state->pkg_end;
+ scope->parse_scope.arg_end = parser_state->pkg_end;
X }
X
X else {
X /* single argument */
X
- scope->arg_end = ACPI_MAX_AML;
+ scope->parse_scope.arg_end = ACPI_MAX_AML;


X }
X
X return (AE_OK);

@@ -195,24 +187,28 @@
X void
X acpi_ps_pop_scope (
X ACPI_PARSE_STATE *parser_state,
- ACPI_GENERIC_OP **op,
+ ACPI_PARSE_OBJECT **op,
X u32 *arg_list)
X {
- ACPI_PARSE_SCOPE *scope = parser_state->scope;
+ ACPI_GENERIC_STATE *scope = parser_state->scope;
+
+
+ /*
+ * Only pop the scope if there is in fact a next scope
+ */
+ if (scope->common.next) {
+ scope = acpi_cm_pop_generic_state (&parser_state->scope);
X
X
- if (scope->parent) {
X /* return to parsing previous op */
X
- *op = scope->op;
- *arg_list = scope->arg_list;
- parser_state->pkg_end = scope->pkg_end;
- parser_state->scope = scope->parent;
+ *op = scope->parse_scope.op;
+ *arg_list = scope->parse_scope.arg_list;
+ parser_state->pkg_end = scope->parse_scope.pkg_end;
X
- /* add scope to available list */
+ /* All done with this scope state structure */
X
- scope->parent = parser_state->scope_avail;
- parser_state->scope_avail = scope;
+ acpi_cm_delete_generic_state (scope);
X }
X
X else {
@@ -222,6 +218,7 @@
X *arg_list = 0;
X }
X

+
X return;
X }
X

@@ -243,27 +240,19 @@
X acpi_ps_cleanup_scope (
X ACPI_PARSE_STATE *parser_state)
X {
- ACPI_PARSE_SCOPE *scope;
+ ACPI_GENERIC_STATE *scope;
X
X
X if (!parser_state) {
X return;
X }
X
- /* destroy available list */
-
- while (parser_state->scope_avail) {
- scope = parser_state->scope_avail;
- parser_state->scope_avail = scope->parent;
- acpi_cm_free (scope);
- }
X
- /* destroy scope stack */
+ /* Delete anything on the scope stack */
X
X while (parser_state->scope) {
- scope = parser_state->scope;
- parser_state->scope = scope->parent;
- acpi_cm_free (scope);
+ scope = acpi_cm_pop_generic_state (&parser_state->scope);
+ acpi_cm_delete_generic_state (scope);
X }
X
X return;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/parser/pstree.c linux/drivers/acpi/parser/pstree.c
--- v2.4.0-test8/linux/drivers/acpi/parser/pstree.c Wed Jul 5 11:23:13 2000
+++ linux/drivers/acpi/parser/pstree.c Fri Sep 15 14:30:30 2000


@@ -1,6 +1,7 @@
X /******************************************************************************
X *

X * Module Name: pstree - Parser op tree manipulation/traversal/search
+ * $Revision: 23 $


X *
X *****************************************************************************/
X

@@ -24,11 +25,11 @@


X
X
X #include "acpi.h"
-#include "parser.h"
+#include "acparser.h"
X #include "amlcode.h"
X

X #define _COMPONENT PARSER
- MODULE_NAME ("pstree");
+ MODULE_NAME ("pstree")
X
X
X /*******************************************************************************
@@ -44,30 +45,30 @@


X *
X ******************************************************************************/
X
-ACPI_GENERIC_OP *
+ACPI_PARSE_OBJECT *

X acpi_ps_get_arg (


- ACPI_GENERIC_OP *op,
+ ACPI_PARSE_OBJECT *op,

X u32 argn)


X {
- ACPI_GENERIC_OP *arg = NULL;

- ACPI_OP_INFO *op_info;


+ ACPI_PARSE_OBJECT *arg = NULL;

+ ACPI_OPCODE_INFO *op_info;
X
X
X /* Get the info structure for this opcode */
X

X op_info = acpi_ps_get_opcode_info (op->opcode);
- if (!op_info) {

- /* Invalid opcode */


+ if (ACPI_GET_OP_TYPE (op_info) != ACPI_OP_TYPE_OPCODE) {

+ /* Invalid opcode or ASCII character */
X
- return NULL;


+ return (NULL);
X }
X

X /* Check if this opcode requires argument sub-objects */
X
- if (!(op_info->flags & OP_INFO_HAS_ARGS)) {
+ if (!(ACPI_GET_OP_ARGS (op_info))) {
X /* Has no linked argument objects */
X
- return NULL;
+ return (NULL);
X }
X
X /* Get the requested argument object */
@@ -78,7 +79,7 @@


X arg = arg->next;
X }

X
- return arg;
+ return (arg);
X }
X
X
@@ -97,11 +98,11 @@
X
X void
X acpi_ps_append_arg (
- ACPI_GENERIC_OP *op,
- ACPI_GENERIC_OP *arg)


+ ACPI_PARSE_OBJECT *op,
+ ACPI_PARSE_OBJECT *arg)

X {
- ACPI_GENERIC_OP *prev_arg;
- ACPI_OP_INFO *op_info;
+ ACPI_PARSE_OBJECT *prev_arg;


+ ACPI_OPCODE_INFO *op_info;
X
X

X if (!op) {
@@ -111,7 +112,7 @@
X /* Get the info structure for this opcode */
X

X op_info = acpi_ps_get_opcode_info (op->opcode);

- if (!op_info) {
+ if (ACPI_GET_OP_TYPE (op_info) != ACPI_OP_TYPE_OPCODE) {

X /* Invalid opcode */
X
X return;
@@ -119,7 +120,7 @@
X
X /* Check if this opcode requires argument sub-objects */
X
- if (!(op_info->flags & OP_INFO_HAS_ARGS)) {
+ if (!(ACPI_GET_OP_ARGS (op_info))) {
X /* Has no linked argument objects */
X
X return;
@@ -166,11 +167,11 @@


X *
X ******************************************************************************/
X
-ACPI_GENERIC_OP *
+ACPI_PARSE_OBJECT *

X acpi_ps_get_child (


- ACPI_GENERIC_OP *op)
+ ACPI_PARSE_OBJECT *op)
X {

- ACPI_GENERIC_OP *child = NULL;
+ ACPI_PARSE_OBJECT *child = NULL;
X
X
X switch (op->opcode)
@@ -211,7 +212,7 @@
X
X }
X
- return child;
+ return (child);
X }
X
X
@@ -229,32 +230,32 @@


X *
X ******************************************************************************/
X
-ACPI_GENERIC_OP *
+ACPI_PARSE_OBJECT *

X acpi_ps_get_depth_next (
- ACPI_GENERIC_OP *origin,
- ACPI_GENERIC_OP *op)


+ ACPI_PARSE_OBJECT *origin,
+ ACPI_PARSE_OBJECT *op)

X {
- ACPI_GENERIC_OP *next = NULL;
- ACPI_GENERIC_OP *parent;
- ACPI_GENERIC_OP *arg;
+ ACPI_PARSE_OBJECT *next = NULL;
+ ACPI_PARSE_OBJECT *parent;
+ ACPI_PARSE_OBJECT *arg;
X
X
X if (!op) {
- return NULL;


+ return (NULL);
X }
X

X /* look for an argument or child */
X
X next = acpi_ps_get_arg (op, 0);
X if (next) {
- return next;
+ return (next);
X }
X
X /* look for a sibling */
X
X next = op->next;
X if (next) {
- return next;
+ return (next);
X }
X
X /* look for a sibling of parent */
@@ -270,19 +271,19 @@
X if (arg == origin) {
X /* reached parent of origin, end search */
X
- return NULL;


+ return (NULL);
X }
X

X if (parent->next) {
X /* found sibling of parent */
- return parent->next;
+ return (parent->next);
X }
X
X op = parent;
X parent = parent->parent;
X }
X
- return next;
+ return (next);
X }
X
X
@@ -300,10 +301,10 @@


X *
X ******************************************************************************/
X
-ACPI_GENERIC_OP *
+ACPI_PARSE_OBJECT *

X acpi_ps_fetch_prefix (
- ACPI_GENERIC_OP *scope,
- char **path,
+ ACPI_PARSE_OBJECT *scope,
+ NATIVE_CHAR **path,
X u32 io)
X {
X u32 prefix = io ? GET8 (*path):**path;
@@ -338,7 +339,7 @@
X scope = acpi_ps_get_child (scope);
X }
X
- return scope;
+ return (scope);
X }
X
X
@@ -349,7 +350,7 @@
X * PARAMETERS: Path - A string containing the name segment
X * io - Direction flag
X *
- * RETURN: The 4-char ASCII ACPI Name as a u32
+ * RETURN: The 4-s8 ASCII ACPI Name as a u32
X *
X * DESCRIPTION: Fetch ACPI name segment (dot-delimited)
X *
@@ -357,13 +358,13 @@
X
X u32
X acpi_ps_fetch_name (
- char **path,
+ NATIVE_CHAR **path,
X u32 io)
X {
X u32 name = 0;
- char *nm;
+ NATIVE_CHAR *nm;
X u32 i;
- char ch;
+ NATIVE_CHAR ch;
X
X
X if (io) {
@@ -378,7 +379,7 @@
X *path += 1;
X }
X
- nm = (char*) &name;
+ nm = (NATIVE_CHAR *) &name;
X for (i = 0; i < 4; i++) {
X ch = **path;
X if (ch && ch != '.') {
@@ -393,7 +394,7 @@
X }
X }
X
- return name;
+ return (name);
X }
X
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/parser/psutils.c linux/drivers/acpi/parser/psutils.c
--- v2.4.0-test8/linux/drivers/acpi/parser/psutils.c Wed Jul 5 11:23:13 2000
+++ linux/drivers/acpi/parser/psutils.c Fri Sep 15 14:30:30 2000


@@ -1,6 +1,7 @@
X /******************************************************************************
X *

X * Module Name: psutils - Parser miscellaneous utilities (Parser only)
+ * $Revision: 29 $


X *
X *****************************************************************************/
X

@@ -24,17 +25,18 @@


X
X
X #include "acpi.h"
-#include "parser.h"
+#include "acparser.h"
X #include "amlcode.h"
X

X #define _COMPONENT PARSER
- MODULE_NAME ("psutils");
+ MODULE_NAME ("psutils")
X
X
-#define PARSEOP_GENERIC 1
-#define PARSEOP_NAMED 2
-#define PARSEOP_DEFERRED 3
-#define PARSEOP_BYTELIST 4
+#define PARSEOP_GENERIC 0x01
+#define PARSEOP_NAMED 0x02
+#define PARSEOP_DEFERRED 0x03
+#define PARSEOP_BYTELIST 0x04
+#define PARSEOP_IN_CACHE 0x80
X
X
X /*******************************************************************************
@@ -53,21 +55,19 @@
X
X void
X acpi_ps_init_op (


- ACPI_GENERIC_OP *op,
+ ACPI_PARSE_OBJECT *op,

X u16 opcode)
X {
- ACPI_OP_INFO *aml_op;
+ ACPI_OPCODE_INFO *aml_op;
X
X
X op->data_type = ACPI_DESC_TYPE_PARSER;
X op->opcode = opcode;
X
-
X aml_op = acpi_ps_get_opcode_info (opcode);
- if (aml_op) {
- DEBUG_ONLY_MEMBERS (STRNCPY (op->op_name, aml_op->name,
- sizeof (op->op_name)));
- }
+
+ DEBUG_ONLY_MEMBERS (STRNCPY (op->op_name, aml_op->name,
+ sizeof (op->op_name)));
X }
X
X
@@ -85,11 +85,11 @@


X *
X ******************************************************************************/
X

-ACPI_GENERIC_OP*
+ACPI_PARSE_OBJECT*
X acpi_ps_alloc_op (
X u16 opcode)
X {
- ACPI_GENERIC_OP *op = NULL;


+ ACPI_PARSE_OBJECT *op = NULL;

X u32 size;
X u8 flags;
X
@@ -97,24 +97,27 @@
X /* Allocate the minimum required size object */
X
X if (acpi_ps_is_deferred_op (opcode)) {
- size = sizeof (ACPI_DEFERRED_OP);
+ size = sizeof (ACPI_PARSE2_OBJECT);
X flags = PARSEOP_DEFERRED;
X }
X
X else if (acpi_ps_is_named_op (opcode)) {
- size = sizeof (ACPI_NAMED_OP);
+ size = sizeof (ACPI_PARSE2_OBJECT);
X flags = PARSEOP_NAMED;
X }
X
X else if (acpi_ps_is_bytelist_op (opcode)) {
- size = sizeof (ACPI_BYTELIST_OP);
+ size = sizeof (ACPI_PARSE2_OBJECT);
X flags = PARSEOP_BYTELIST;
X }
X
X else {
- size = sizeof (ACPI_GENERIC_OP);
+ size = sizeof (ACPI_PARSE_OBJECT);
X flags = PARSEOP_GENERIC;
+ }
+
X
+ if (size == sizeof (ACPI_PARSE_OBJECT)) {
X /*
X * The generic op is by far the most common (16 to 1), and therefore
X * the op cache is implemented with this type.
@@ -133,13 +136,44 @@
X op = acpi_gbl_parse_cache;
X acpi_gbl_parse_cache = op->next;
X
+
+ /* Clear the previously used Op */
+
+ MEMSET (op, 0, sizeof (ACPI_PARSE_OBJECT));
+
+ }
+ acpi_cm_release_mutex (ACPI_MTX_CACHES);


+ }
+
+ else {
+ /*

+ * The generic op is by far the most common (16 to 1), and therefore
+ * the op cache is implemented with this type.
+ *
+ * Check if there is an Op already available in the cache
+ */
+
+ acpi_cm_acquire_mutex (ACPI_MTX_CACHES);
+ acpi_gbl_ext_parse_cache_requests++;
+ if (acpi_gbl_ext_parse_cache) {
+ /* Extract an op from the front of the cache list */
+
+ acpi_gbl_ext_parse_cache_depth--;
+ acpi_gbl_ext_parse_cache_hits++;
+
+ op = (ACPI_PARSE_OBJECT *) acpi_gbl_ext_parse_cache;
+ acpi_gbl_ext_parse_cache = (ACPI_PARSE2_OBJECT *) op->next;
+
+
X /* Clear the previously used Op */
X
- MEMSET (op, 0, sizeof (ACPI_GENERIC_OP));
+ MEMSET (op, 0, sizeof (ACPI_PARSE2_OBJECT));
+
X }
X acpi_cm_release_mutex (ACPI_MTX_CACHES);
X }
X
+
X /* Allocate a new Op if necessary */
X
X if (!op) {
@@ -152,7 +186,7 @@
X op->flags = flags;
X }
X
- return op;
+ return (op);
X }
X
X
@@ -171,16 +205,22 @@
X
X void
X acpi_ps_free_op (


- ACPI_GENERIC_OP *op)
+ ACPI_PARSE_OBJECT *op)

X {
X
X
+
X if (op->flags == PARSEOP_GENERIC) {
X /* Is the cache full? */
X
X if (acpi_gbl_parse_cache_depth < MAX_PARSE_CACHE_DEPTH) {
X /* Put a GENERIC_OP back into the cache */
X
+ /* Clear the previously used Op */
+
+ MEMSET (op, 0, sizeof (ACPI_PARSE_OBJECT));
+ op->flags = PARSEOP_IN_CACHE;
+
X acpi_cm_acquire_mutex (ACPI_MTX_CACHES);
X acpi_gbl_parse_cache_depth++;
X
@@ -192,6 +232,29 @@
X }
X }
X
+ else {
+ /* Is the cache full? */
+
+ if (acpi_gbl_ext_parse_cache_depth < MAX_EXTPARSE_CACHE_DEPTH) {
+ /* Put a GENERIC_OP back into the cache */
+
+ /* Clear the previously used Op */
+
+ MEMSET (op, 0, sizeof (ACPI_PARSE2_OBJECT));
+ op->flags = PARSEOP_IN_CACHE;
+
+ acpi_cm_acquire_mutex (ACPI_MTX_CACHES);
+ acpi_gbl_ext_parse_cache_depth++;
+
+ op->next = (ACPI_PARSE_OBJECT *) acpi_gbl_ext_parse_cache;
+ acpi_gbl_ext_parse_cache = (ACPI_PARSE2_OBJECT *) op;
+
+ acpi_cm_release_mutex (ACPI_MTX_CACHES);


+ return;
+ }
+ }
+

+
X /*
X * Not a GENERIC OP, or the cache is full, just free the Op
X */
@@ -216,7 +279,7 @@
X acpi_ps_delete_parse_cache (
X void)
X {
- ACPI_GENERIC_OP *next;
+ ACPI_PARSE_OBJECT *next;


X
X
X /* Traverse the global cache list */

@@ -227,6 +290,18 @@
X next = acpi_gbl_parse_cache->next;
X acpi_cm_free (acpi_gbl_parse_cache);
X acpi_gbl_parse_cache = next;
+ acpi_gbl_parse_cache_depth--;
+ }
+
+ /* Traverse the global cache list */
+
+ while (acpi_gbl_ext_parse_cache) {
+ /* Delete one cached state object */
+
+ next = acpi_gbl_ext_parse_cache->next;
+ acpi_cm_free (acpi_gbl_ext_parse_cache);
+ acpi_gbl_ext_parse_cache = (ACPI_PARSE2_OBJECT *) next;
+ acpi_gbl_ext_parse_cache_depth--;
X }
X
X return;
@@ -253,7 +328,7 @@
X
X u8
X acpi_ps_is_leading_char (
- s32 c)
+ u32 c)
X {
X return ((u8) (c == '_' || (c >= 'A' && c <= 'Z')));
X }
@@ -264,7 +339,7 @@
X */
X u8
X acpi_ps_is_prefix_char (
- s32 c)
+ u32 c)
X {
X return ((u8) (c == '\\' || c == '^'));
X }
@@ -329,7 +404,7 @@
X * TBD: [Restructure] Need a better way than this brute force approach!
X */
X u8
-acpi_ps_is_named_object_op (
+acpi_ps_is_node_op (
X u16 opcode)
X {
X return ((u8)
@@ -433,38 +508,16 @@
X
X
X /*
- * Cast an acpi_op to an acpi_deferred_op if possible
- */
-ACPI_DEFERRED_OP *
-acpi_ps_to_deferred_op (
- ACPI_GENERIC_OP *op)
-{
- return (acpi_ps_is_deferred_op (op->opcode)
- ? ( (ACPI_DEFERRED_OP *) op) : NULL);
-}
-
-
-/*
- * Cast an acpi_op to an acpi_named_op if possible
+ * Cast an acpi_op to an acpi_extended_op if possible
X */
-ACPI_NAMED_OP*
-acpi_ps_to_named_op (
- ACPI_GENERIC_OP *op)
-{
- return (acpi_ps_is_named_op (op->opcode)
- ? ( (ACPI_NAMED_OP *) op) : NULL);
-}
-
X
-/*
- * Cast an acpi_op to an acpi_bytelist_op if possible
- */
-ACPI_BYTELIST_OP*
-acpi_ps_to_bytelist_op (
- ACPI_GENERIC_OP *op)
+/* TBD: This is very inefficient, fix */
+ACPI_PARSE2_OBJECT *
+acpi_ps_to_extended_op (
+ ACPI_PARSE_OBJECT *op)
X {
- return (acpi_ps_is_bytelist_op (op->opcode)
- ? ( (ACPI_BYTELIST_OP*) op) : NULL);
+ return ((acpi_ps_is_deferred_op (op->opcode) || acpi_ps_is_named_op (op->opcode) || acpi_ps_is_bytelist_op (op->opcode))
+ ? ( (ACPI_PARSE2_OBJECT *) op) : NULL);
X }
X
X
@@ -473,9 +526,9 @@
X */
X u32
X acpi_ps_get_name (


- ACPI_GENERIC_OP *op)
+ ACPI_PARSE_OBJECT *op)
X {

- ACPI_NAMED_OP *named = acpi_ps_to_named_op (op);
+ ACPI_PARSE2_OBJECT *named = acpi_ps_to_extended_op (op);
X
X return (named ? named->name : 0);
X }
@@ -486,10 +539,10 @@
X */
X void
X acpi_ps_set_name (


- ACPI_GENERIC_OP *op,
+ ACPI_PARSE_OBJECT *op,

X u32 name)
X {
- ACPI_NAMED_OP *named = acpi_ps_to_named_op (op);
+ ACPI_PARSE2_OBJECT *named = acpi_ps_to_extended_op (op);
X
X if (named) {
X named->name = name;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/parser/pswalk.c linux/drivers/acpi/parser/pswalk.c
--- v2.4.0-test8/linux/drivers/acpi/parser/pswalk.c Wed Jul 5 11:23:13 2000
+++ linux/drivers/acpi/parser/pswalk.c Fri Sep 15 14:30:30 2000


@@ -1,6 +1,7 @@
X /******************************************************************************
X *

X * Module Name: pswalk - Parser routines to walk parsed op tree(s)
+ * $Revision: 45 $


X *
X *****************************************************************************/
X

@@ -25,13 +26,13 @@
X
X #include "acpi.h"


X #include "amlcode.h"
-#include "parser.h"
-#include "dispatch.h"

-#include "namesp.h"
-#include "interp.h"
+#include "acparser.h"
+#include "acdispat.h"
+#include "acnamesp.h"
+#include "acinterp.h"


X
X #define _COMPONENT PARSER

- MODULE_NAME ("pswalk");
+ MODULE_NAME ("pswalk")
X
X
X /*******************************************************************************
@@ -53,12 +54,12 @@
X ACPI_STATUS
X acpi_ps_get_next_walk_op (
X ACPI_WALK_STATE *walk_state,


- ACPI_GENERIC_OP *op,
- INTERPRETER_CALLBACK ascending_callback)

+ ACPI_PARSE_OBJECT *op,
+ ACPI_PARSE_UPWARDS ascending_callback)

X {
- ACPI_GENERIC_OP *next;
- ACPI_GENERIC_OP *parent;
- ACPI_GENERIC_OP *grand_parent;
+ ACPI_PARSE_OBJECT *next;
+ ACPI_PARSE_OBJECT *parent;


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 036'
echo 'File patch-2.4.0-test9 is continued in part 037'
echo "037" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part037

#!/bin/sh -x
# this is part 037 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 037; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ ACPI_PARSE_OBJECT *grand_parent;


X ACPI_STATUS status;
X
X

@@ -146,6 +147,18 @@
X
X default:
X /*
+ * If we are back to the starting point, the walk is complete.
+ */
+ if (op == walk_state->origin) {
+ /* Reached the point of origin, the walk is complete */


+
+ walk_state->prev_op = op;

+ walk_state->next_op = NULL;


+
+ return (status);
+ }
+

+ /*
X * Check for a sibling to the current op. A sibling means
X * we are still going "downward" in the tree.
X */
@@ -166,7 +179,7 @@
X * No sibling, but check status.
X * Abort on error from callback routine
X */


- if (status != AE_OK) {

+ if (ACPI_FAILURE (status)) {
X /* Next op will be the parent */
X
X walk_state->prev_op = op;
@@ -302,7 +315,7 @@
X * No sibling, check for an error from closing the parent
X * (Also, AE_PENDING if a method call was encountered)
X */


- if (status != AE_OK) {

+ if (ACPI_FAILURE (status)) {
X walk_state->prev_op = parent;
X walk_state->next_op = grand_parent;
X walk_state->next_op_info = NEXT_OP_UPWARD;
@@ -347,13 +360,13 @@
X ACPI_STATUS
X acpi_ps_walk_loop (
X ACPI_WALK_LIST *walk_list,
- ACPI_GENERIC_OP *start_op,
- INTERPRETER_CALLBACK descending_callback,
- INTERPRETER_CALLBACK ascending_callback)
+ ACPI_PARSE_OBJECT *start_op,


+ ACPI_PARSE_DOWNWARDS descending_callback,
+ ACPI_PARSE_UPWARDS ascending_callback)
X {

X ACPI_STATUS status = AE_OK;
X ACPI_WALK_STATE *walk_state;
- ACPI_GENERIC_OP *op = start_op;
+ ACPI_PARSE_OBJECT *op = start_op;
X
X
X walk_state = acpi_ds_get_current_walk_state (walk_list);
@@ -363,7 +376,7 @@
X
X while (op) {
X if (walk_state->next_op_info != NEXT_OP_UPWARD) {
- status = descending_callback (walk_state, op);
+ status = descending_callback (op->opcode, op, walk_state, NULL);
X }
X
X /*
@@ -437,19 +450,19 @@
X
X ACPI_STATUS
X acpi_ps_walk_parsed_aml (


- ACPI_GENERIC_OP *start_op,
- ACPI_GENERIC_OP *end_op,
- ACPI_OBJECT_INTERNAL *mth_desc,
- ACPI_NAME_TABLE *start_scope,

- ACPI_OBJECT_INTERNAL **params,
- ACPI_OBJECT_INTERNAL **caller_return_desc,


+ ACPI_PARSE_OBJECT *start_op,
+ ACPI_PARSE_OBJECT *end_op,
+ ACPI_OPERAND_OBJECT *mth_desc,
+ ACPI_NAMESPACE_NODE *start_node,

+ ACPI_OPERAND_OBJECT **params,
+ ACPI_OPERAND_OBJECT **caller_return_desc,

X ACPI_OWNER_ID owner_id,


- INTERPRETER_CALLBACK descending_callback,
- INTERPRETER_CALLBACK ascending_callback)

+ ACPI_PARSE_DOWNWARDS descending_callback,
+ ACPI_PARSE_UPWARDS ascending_callback)
X {

- ACPI_GENERIC_OP *op;
+ ACPI_PARSE_OBJECT *op;
X ACPI_WALK_STATE *walk_state;
- ACPI_OBJECT_INTERNAL *return_desc;
+ ACPI_OPERAND_OBJECT *return_desc;
X ACPI_STATUS status;
X ACPI_WALK_LIST walk_list;
X ACPI_WALK_LIST *prev_walk_list;
@@ -458,7 +471,7 @@


X /* Parameter Validation */
X

X if (!start_op || !end_op) {


- return AE_BAD_PARAMETER;
+ return (AE_BAD_PARAMETER);
X }
X

X /* Initialize a new walk list */
@@ -475,10 +488,10 @@
X prev_walk_list = acpi_gbl_current_walk_list;
X acpi_gbl_current_walk_list = &walk_list;
X
- if (start_scope) {
+ if (start_node) {
X /* Push start scope on scope stack and make it current */
X
- status = acpi_ds_scope_stack_push (start_scope, ACPI_TYPE_METHOD, walk_state);


+ status = acpi_ds_scope_stack_push (start_node, ACPI_TYPE_METHOD, walk_state);

X if (ACPI_FAILURE (status)) {
X return (status);
X }
@@ -489,7 +502,7 @@
X /* Init arguments if this is a control method */
X /* TBD: [Restructure] add walkstate as a param */
X
- acpi_ds_method_data_init_args (params, MTH_NUM_ARGS);


+ acpi_ds_method_data_init_args (params, MTH_NUM_ARGS, walk_state);
X }
X

X op = start_op;
@@ -502,7 +515,7 @@
X */
X
X while (walk_state) {


- if (status == AE_OK) {

+ if (ACPI_SUCCESS (status)) {
X status = acpi_ps_walk_loop (&walk_list, op, descending_callback,
X ascending_callback);


X }
@@ -526,9 +539,7 @@

X * there's lots of cleanup to do
X */
X
- if (walk_state->method_desc &&
- walk_state->method_desc->method.parser_op)
- {
+ if (walk_state->method_desc) {
X acpi_ds_terminate_control_method (walk_state);
X }
X
@@ -540,7 +551,7 @@
X
X walk_state = acpi_ds_get_current_walk_state (&walk_list);
X if (walk_state &&
- status == AE_OK)
+ ACPI_SUCCESS (status))
X {
X /* There is another walk state, restart it */
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/parser/psxface.c linux/drivers/acpi/parser/psxface.c
--- v2.4.0-test8/linux/drivers/acpi/parser/psxface.c Wed Jul 5 11:23:13 2000
+++ linux/drivers/acpi/parser/psxface.c Fri Sep 15 14:30:30 2000
@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *
X * Module Name: psxface - Parser external interfaces
+ * $Revision: 36 $


X *
X *****************************************************************************/
X

@@ -25,18 +25,15 @@


X
X
X #include "acpi.h"
-#include "parser.h"

-#include "dispatch.h"


-#include "interp.h"
+#include "acparser.h"
+#include "acdispat.h"

+#include "acinterp.h"


X #include "amlcode.h"
-#include "namesp.h"

+#include "acnamesp.h"
X

X
X #define _COMPONENT PARSER

- MODULE_NAME ("psxface");
-
-
-char *acpi_gbl_parser_id = "Non-recursive AML Parser";
+ MODULE_NAME ("psxface")
X
X
X /*****************************************************************************
@@ -57,29 +54,30 @@
X
X ACPI_STATUS
X acpi_psx_execute (


- ACPI_NAMED_OBJECT *method_entry,
- ACPI_OBJECT_INTERNAL **params,
- ACPI_OBJECT_INTERNAL **return_obj_desc)

+ ACPI_NAMESPACE_NODE *method_node,
+ ACPI_OPERAND_OBJECT **params,

+ ACPI_OPERAND_OBJECT **return_obj_desc)
X {
X ACPI_STATUS status;


- ACPI_OBJECT_INTERNAL *obj_desc;
+ ACPI_OPERAND_OBJECT *obj_desc;

X u32 i;
+ ACPI_PARSE_OBJECT *op;
X
X
- /* Validate the NTE and get the attached object */
+ /* Validate the Node and get the attached object */


X
- if (!method_entry) {
+ if (!method_node) {
X return (AE_NULL_ENTRY);
X }

X

- obj_desc = acpi_ns_get_attached_object (method_entry);
+ obj_desc = acpi_ns_get_attached_object (method_node);

X if (!obj_desc) {


X return (AE_NULL_OBJECT);
X }
X
- /* Parse method if necessary, wait on concurrency semaphore */

+ /* Init for new method, wait on concurrency semaphore */
X
- status = acpi_ds_begin_method_execution (method_entry, obj_desc);


+ status = acpi_ds_begin_method_execution (method_node, obj_desc);

X if (ACPI_FAILURE (status)) {
X return (status);
X }
@@ -96,15 +94,40 @@
X }
X
X /*
- * Method is parsed and ready to execute
- * The walk of the parse tree is where we actually execute the method
+ * Perform the first pass parse of the method to enter any
+ * named objects that it creates into the namespace
X */
X
- status = acpi_ps_walk_parsed_aml (obj_desc->method.parser_op,
- obj_desc->method.parser_op, obj_desc,
- method_entry->child_table, params, return_obj_desc,
- obj_desc->method.owning_id, acpi_ds_exec_begin_op,
- acpi_ds_exec_end_op);
+ /* Create and init a Root Node */
+


+ op = acpi_ps_alloc_op (AML_SCOPE_OP);
+ if (!op) {

+ return (AE_NO_MEMORY);
+ }
+

+ status = acpi_ps_parse_aml (op, obj_desc->method.pcode,
+ obj_desc->method.pcode_length,
+ ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE,

+ method_node, params, return_obj_desc,
+ acpi_ds_load1_begin_op, acpi_ds_load1_end_op);
+ acpi_ps_delete_parse_tree (op);
+
+ /* Create and init a Root Node */
+


+ op = acpi_ps_alloc_op (AML_SCOPE_OP);
+ if (!op) {
+ return (AE_NO_MEMORY);

+ }
+
+ /*
+ * The walk of the parse tree is where we actually execute the method
+ */


+ status = acpi_ps_parse_aml (op, obj_desc->method.pcode,

+ obj_desc->method.pcode_length,
+ ACPI_PARSE_EXECUTE | ACPI_PARSE_DELETE_TREE,
+ method_node, params, return_obj_desc,
+ acpi_ds_exec_begin_op, acpi_ds_exec_end_op);
+ acpi_ps_delete_parse_tree (op);
X
X if (params) {
X /* Take away the extra reference that we gave the parameters above */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/resources/Makefile linux/drivers/acpi/resources/Makefile
--- v2.4.0-test8/linux/drivers/acpi/resources/Makefile Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/resources/Makefile Fri Sep 15 18:21:44 2000

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/resources/rsaddr.c linux/drivers/acpi/resources/rsaddr.c
--- v2.4.0-test8/linux/drivers/acpi/resources/rsaddr.c Wed Jul 5 11:23:13 2000
+++ linux/drivers/acpi/resources/rsaddr.c Fri Sep 15 14:30:30 2000
@@ -4,6 +4,7 @@
X * Acpi_rs_address16_stream
X * Acpi_rs_address32_resource
X * Acpi_rs_address32_stream
+ * $Revision: 9 $


X *
X *****************************************************************************/
X

@@ -29,7 +30,7 @@
X #include "acpi.h"
X
X #define _COMPONENT RESOURCE_MANAGER
- MODULE_NAME ("rsaddr");
+ MODULE_NAME ("rsaddr")
X
X
X /***************************************************************************
@@ -63,8 +64,8 @@
X {
X u8 *buffer = byte_stream_buffer;
X RESOURCE *output_struct = (RESOURCE *) * output_buffer;
- u16 temp16 = 0;
- u8 temp8 = 0;
+ u16 temp16;
+ u8 temp8;
X u32 index;
X u32 struct_size = sizeof(ADDRESS16_RESOURCE) +
X RESOURCE_LENGTH_NO_DATA;
@@ -75,7 +76,7 @@
X */
X buffer += 1;
X
- temp16 = *(u16 *)buffer;
+ MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
X
X *bytes_consumed = temp16 + 3;
X
@@ -91,7 +92,7 @@
X
X /* Values 0-2 are valid */
X if (temp8 > 2) {
- return (AE_ERROR);
+ return (AE_AML_ERROR);
X }
X
X output_struct->data.address16.resource_type = temp8 & 0x03;
@@ -235,6 +236,7 @@
X */
X temp8 = (u8) (index + 1);
X struct_size += ROUND_UP_TO_32_bITS (temp8);
+ output_struct->length = struct_size;
X }
X else {
X output_struct->data.address16.resource_source_index = 0x00;
@@ -243,11 +245,6 @@
X }
X
X /*
- * Set the Length parameter
- */
- output_struct->length = struct_size;
-
- /*
X * Return the final size of the structure
X */
X *structure_size = struct_size;
@@ -281,8 +278,8 @@
X {
X u8 *buffer = *output_buffer;
X u8 *length_field;
- u8 temp8 = 0;
- u8 *temp_pointer = NULL;
+ u8 temp8;
+ NATIVE_CHAR *temp_pointer = NULL;
X u32 actual_bytes;
X
X
@@ -389,7 +386,7 @@
X *buffer = temp8;
X buffer += 1;
X
- temp_pointer = buffer;
+ temp_pointer = (NATIVE_CHAR *) buffer;
X
X /*
X * Copy the string
@@ -450,15 +447,21 @@
X u8 **output_buffer,
X u32 *structure_size)
X {
- u8 *buffer = byte_stream_buffer;
- RESOURCE *output_struct = (RESOURCE *) * output_buffer;
- u16 temp16 = 0;
- u8 temp8 = 0;
- u32 struct_size = sizeof (ADDRESS32_RESOURCE) +
- RESOURCE_LENGTH_NO_DATA;
+ u8 *buffer;
+ RESOURCE *output_struct;
+ u16 temp16;
+ u8 temp8;
+ u32 struct_size;
X u32 index;
X
X
+ buffer = byte_stream_buffer;
+
+ output_struct = (RESOURCE *) *output_buffer;
+
+ struct_size = sizeof (ADDRESS32_RESOURCE) +
+ RESOURCE_LENGTH_NO_DATA;
+
X /*
X * Point past the Descriptor to get the number of bytes consumed
X */
@@ -477,7 +480,7 @@
X
X /* Values 0-2 are valid */
X if(temp8 > 2) {
- return (AE_ERROR);
+ return (AE_AML_ERROR);
X }
X
X output_struct->data.address32.resource_type = temp8 & 0x03;
@@ -661,11 +664,13 @@
X u8 **output_buffer,
X u32 *bytes_consumed)
X {
- u8 *buffer = *output_buffer;
+ u8 *buffer;
X u16 *length_field;
- u8 temp8 = 0;
- u8 *temp_pointer = NULL;
+ u8 temp8;
+ NATIVE_CHAR *temp_pointer;
+
X
+ buffer = *output_buffer;
X
X /*
X * The descriptor field is static
@@ -779,7 +784,7 @@
X
X buffer += 1;
X
- temp_pointer = buffer;
+ temp_pointer = (NATIVE_CHAR *) buffer;
X
X /*
X * Copy the string
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/resources/rscalc.c linux/drivers/acpi/resources/rscalc.c
--- v2.4.0-test8/linux/drivers/acpi/resources/rscalc.c Wed Jul 5 11:23:13 2000
+++ linux/drivers/acpi/resources/rscalc.c Fri Sep 15 14:30:30 2000
@@ -2,6 +2,7 @@
X *
X * Module Name: rscalc - Acpi_rs_calculate_byte_stream_length
X * Acpi_rs_calculate_list_length
+ * $Revision: 9 $


X *
X *****************************************************************************/
X

@@ -27,7 +28,7 @@
X #include "acpi.h"
X
X #define _COMPONENT RESOURCE_MANAGER
- MODULE_NAME ("rscalc");
+ MODULE_NAME ("rscalc")
X
X
X /***************************************************************************
@@ -51,9 +52,8 @@
X RESOURCE *linked_list,
X u32 *size_needed)
X {


- ACPI_STATUS status = AE_OK;

X u32 byte_stream_size_needed = 0;
- u32 size_of_this_bit;
+ u32 segment_size;
X EXTENDED_IRQ_RESOURCE *ex_irq = NULL;
X u8 done = FALSE;
X
@@ -64,7 +64,7 @@
X * Init the variable that will hold the size to add to the
X * total.
X */
- size_of_this_bit = 0;
+ segment_size = 0;
X
X switch (linked_list->id)
X {
@@ -76,7 +76,7 @@
X * For an IRQ Resource, Byte 3, although optional, will
X * always be created - it holds IRQ information.
X */
- size_of_this_bit = 4;
+ segment_size = 4;
X break;
X
X case dma:
@@ -86,7 +86,7 @@
X /*
X * For this resource the size is static
X */
- size_of_this_bit = 3;
+ segment_size = 3;
X break;
X
X case start_dependent_functions:
@@ -97,7 +97,7 @@
X * For a Start_dependent_functions Resource, Byte 1,
X * although optional, will always be created.
X */
- size_of_this_bit = 2;
+ segment_size = 2;
X break;
X
X case end_dependent_functions:
@@ -107,7 +107,7 @@
X /*
X * For this resource the size is static
X */
- size_of_this_bit = 1;
+ segment_size = 1;
X break;
X
X case io:
@@ -117,7 +117,7 @@
X /*
X * For this resource the size is static
X */
- size_of_this_bit = 8;
+ segment_size = 8;
X break;
X
X case fixed_io:
@@ -127,7 +127,7 @@
X /*
X * For this resource the size is static
X */
- size_of_this_bit = 4;
+ segment_size = 4;
X break;
X
X case vendor_specific:
@@ -141,12 +141,12 @@
X * Resource data type.
X */
X if(linked_list->data.vendor_specific.length > 7) {
- size_of_this_bit = 3;
+ segment_size = 3;
X }
X else {
- size_of_this_bit = 1;
+ segment_size = 1;
X }
- size_of_this_bit +=
+ segment_size +=
X linked_list->data.vendor_specific.length;
X break;
X
@@ -157,7 +157,7 @@
X /*
X * For this resource the size is static
X */
- size_of_this_bit = 2;
+ segment_size = 2;
X done = TRUE;
X break;
X
@@ -168,7 +168,7 @@
X /*
X * For this resource the size is static
X */
- size_of_this_bit = 12;
+ segment_size = 12;
X break;
X
X case memory32:
@@ -178,7 +178,7 @@
X /*
X * For this resource the size is static
X */
- size_of_this_bit = 20;
+ segment_size = 20;
X break;
X
X case fixed_memory32:
@@ -188,7 +188,7 @@
X /*
X * For this resource the size is static
X */
- size_of_this_bit = 12;
+ segment_size = 12;
X break;
X
X case address16:
@@ -201,10 +201,10 @@
X * the Index + the length of the null terminated
X * string Resource Source + 1 for the null.
X */
- size_of_this_bit = 16;
+ segment_size = 16;
X
X if(NULL != linked_list->data.address16.resource_source) {
- size_of_this_bit += (1 +
+ segment_size += (1 +
X linked_list->data.address16.resource_source_string_length);
X }
X break;
@@ -219,10 +219,10 @@
X * length of the null terminated string Resource Source +
X * 1 for the null.
X */
- size_of_this_bit = 26;
+ segment_size = 26;
X
X if(NULL != linked_list->data.address16.resource_source) {
- size_of_this_bit += (1 +
+ segment_size += (1 +
X linked_list->data.address16.resource_source_string_length);
X }
X break;
@@ -239,14 +239,14 @@
X * Index + the length of the null terminated string
X * Resource Source + 1 for the null.
X */
- size_of_this_bit = 9;
+ segment_size = 9;
X
- size_of_this_bit +=
+ segment_size +=
X (linked_list->data.extended_irq.number_of_interrupts -
X 1) * 4;
X
X if(NULL != ex_irq->resource_source) {
- size_of_this_bit += (1 +
+ segment_size += (1 +
X linked_list->data.extended_irq.resource_source_string_length);
X }
X break;
@@ -256,7 +256,7 @@
X * If we get here, everything is out of sync,
X * so exit with an error
X */
- return (AE_ERROR);
+ return (AE_AML_ERROR);
X break;
X
X } /* switch (Linked_list->Id) */
@@ -264,7 +264,7 @@
X /*
X * Update the total
X */
- byte_stream_size_needed += size_of_this_bit;
+ byte_stream_size_needed += segment_size;
X
X /*
X * Point to the next object
@@ -278,7 +278,7 @@
X */
X *size_needed = byte_stream_size_needed;
X
- return (status);
+ return (AE_OK);
X
X } /* Acpi_rs_calculate_byte_stream_length */
X
@@ -309,16 +309,16 @@
X {
X u32 buffer_size = 0;
X u32 bytes_parsed = 0;
- u8 resource_type = 0;
- u32 structure_size = 0;
- u32 bytes_consumed = 0;
- u8 *buffer;
X u8 number_of_interrupts = 0;
+ u8 number_of_channels = 0;
+ u8 resource_type;
+ u32 structure_size;
+ u32 bytes_consumed;
+ u8 *buffer;
X u8 temp8;
X u16 temp16;
X u8 index;
- u8 number_of_channels = 0;
- u8 additional_bytes = 0;
+ u8 additional_bytes;
X
X
X while (bytes_parsed < byte_stream_buffer_length) {
@@ -532,7 +532,7 @@
X * If we get here, everything is out of sync,
X * so exit with an error
X */
- return (AE_ERROR);
+ return (AE_AML_ERROR);
X break;
X }
X }
@@ -723,7 +723,7 @@
X * If we get here, everything is out of sync,
X * so exit with an error
X */
- return (AE_ERROR);
+ return (AE_AML_ERROR);
X break;
X
X } /* switch */
@@ -752,3 +752,116 @@
X
X } /* Acpi_rs_calculate_list_length */
X
+/***************************************************************************
+ * FUNCTION: Acpi_rs_calculate_pci_routing_table_length


+ *
+ * PARAMETERS:

+ * Package_object - Pointer to the package object
+ * Buffer_size_needed - u32 pointer of the size buffer
+ * needed to properly return the
+ * parsed data
+ *
+ * RETURN: Status AE_OK
+ *
+ * DESCRIPTION: Given a package representing a PCI routing table, this
+ * calculates the size of the corresponding linked list of
+ * descriptions.
+ *
+ ***************************************************************************/


+
+ACPI_STATUS
+acpi_rs_calculate_pci_routing_table_length (
+ ACPI_OPERAND_OBJECT *package_object,
+ u32 *buffer_size_needed)

+{
+ u32 number_of_elements;
+ u32 temp_size_needed;
+ ACPI_OPERAND_OBJECT **top_object_list;
+ u32 index;
+
+ number_of_elements = package_object->package.count;
+
+ /*
+ * Calculate the size of the return buffer.
+ * The base size is the number of elements * the sizes of the
+ * structures. Additional space for the strings is added below.
+ * The minus one is to subtract the size of the u8 Source[1]
+ * member because it is added below.
+ *
+ * NOTE: The Number_of_elements is incremented by one to add an end
+ * table structure that is essentially a structure of zeros.
+ */
+ temp_size_needed = (number_of_elements + 1) *
+ (sizeof (PCI_ROUTING_TABLE) - 1);
+
+ /*
+ * But each PRT_ENTRY structure has a pointer to a string and
+ * the size of that string must be found.
+ */
+ top_object_list = package_object->package.elements;
+
+ for (index = 0; index < number_of_elements; index++) {
+ ACPI_OPERAND_OBJECT *package_element;
+ ACPI_OPERAND_OBJECT **sub_object_list;
+ u8 name_found;
+ u32 table_index;
+
+ /*
+ * Dereference the sub-package
+ */
+ package_element = *top_object_list;
+
+ /*
+ * The Sub_object_list will now point to an array of the
+ * four IRQ elements: Address, Pin, Source and Source_index
+ */
+ sub_object_list = package_element->package.elements;
+
+ /*
+ * Scan the Irq_table_elements for the Source Name String
+ */
+ name_found = FALSE;
+
+ for (table_index = 0; table_index < 4 && !name_found; table_index++) {
+ if (ACPI_TYPE_STRING == (*sub_object_list)->common.type) {
+ name_found = TRUE;


+ }
+
+ else {
+ /*

+ * Look at the next element
+ */
+ sub_object_list++;


+ }
+ }
+
+ /*

+ * Was a String type found?
+ */
+ if (TRUE == name_found) {
+ /*
+ * The length String.Length field includes the
+ * terminating NULL
+ */
+ temp_size_needed += (*sub_object_list)->string.length;
+ temp_size_needed = ROUND_UP_TO_32_bITS (temp_size_needed);


+ }
+
+ else {
+ /*

+ * If no name was found, then this is a NULL, which is
+ * translated as a u32 zero.
+ */
+ temp_size_needed += sizeof(u32);
+ }
+
+ /*
+ * Point to the next ACPI_OPERAND_OBJECT
+ */
+ top_object_list++;
+ }
+
+ *buffer_size_needed = temp_size_needed;


+
+ return (AE_OK);
+}

\ No newline at end of file

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/resources/rscreate.c linux/drivers/acpi/resources/rscreate.c
--- v2.4.0-test8/linux/drivers/acpi/resources/rscreate.c Wed Jul 5 11:23:13 2000
+++ linux/drivers/acpi/resources/rscreate.c Fri Sep 15 14:30:30 2000
@@ -3,6 +3,7 @@
X * Module Name: rscreate - Acpi_rs_create_resource_list
X * Acpi_rs_create_pci_routing_table
X * Acpi_rs_create_byte_stream
+ * $Revision: 16 $


X *
X *****************************************************************************/
X

@@ -26,13 +27,14 @@


X
X
X #include "acpi.h"

-#include "resource.h"
+#include "acresrc.h"
X
X #define _COMPONENT RESOURCE_MANAGER
- MODULE_NAME ("rscreate");
+ MODULE_NAME ("rscreate")
X
X
-/***************************************************************************
+/*******************************************************************************
+ *
X * FUNCTION: Acpi_rs_create_resource_list


X *
X * PARAMETERS:

@@ -40,53 +42,40 @@
X * Output_buffer - Pointer to the user's buffer
X * Output_buffer_length - Pointer to the size of Output_buffer
X *
- * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code
- * If Output_buffer is not large enough, Output_buffer_length
- * indicates how large Output_buffer should be, else it
- * indicates how may u8 elements of Output_buffer are
- * valid.
+ * RETURN: Status - AE_OK if okay, else a valid ACPI_STATUS code
+ * If Output_buffer is not large enough, Output_buffer_length
+ * indicates how large Output_buffer should be, else it
+ * indicates how may u8 elements of Output_buffer are valid.
X *
X * DESCRIPTION: Takes the byte stream returned from a _CRS, _PRS control method
- * execution and parses the stream to create a linked list
- * of device resources.
+ * execution and parses the stream to create a linked list
+ * of device resources.


X *
- ***************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS

X acpi_rs_create_resource_list (
- ACPI_OBJECT_INTERNAL *byte_stream_buffer,
+ ACPI_OPERAND_OBJECT *byte_stream_buffer,
X u8 *output_buffer,
X u32 *output_buffer_length)
X {
X
- ACPI_STATUS status = AE_UNKNOWN_STATUS;
+ ACPI_STATUS status;
X u8 *byte_stream_start = NULL;
X u32 list_size_needed = 0;
X u32 byte_stream_buffer_length = 0;
X
X
X /*
- * Validate parameters:
- *
- * 1. If Byte_stream_buffer is NULL after we know that
- * Byte_steam_length is not zero, or
- * 2. If Output_buffer is NULL and Output_buffer_length
- * is not zero
- *
- * Return an error
+ * Params already validated, so we don't re-validate here
X */
- if (!byte_stream_buffer ||
- (!output_buffer && 0 != *output_buffer_length))


- {
- return (AE_BAD_PARAMETER);
- }

X
X byte_stream_buffer_length = byte_stream_buffer->buffer.length;
X byte_stream_start = byte_stream_buffer->buffer.pointer;
X
X /*
X * Pass the Byte_stream_buffer into a module that can calculate
- * the buffer size needed for the linked list
+ * the buffer size needed for the linked list
X */
X status = acpi_rs_calculate_list_length (byte_stream_start,
X byte_stream_buffer_length,
@@ -95,13 +84,13 @@
X /*
X * Exit with the error passed back
X */


- if (AE_OK != status) {
+ if (ACPI_FAILURE (status)) {

X return (status);
X }
X

X /*
X * If the linked list will fit into the available buffer
- * call to fill in the list
+ * call to fill in the list
X */
X
X if (list_size_needed <= *output_buffer_length) {
@@ -117,7 +106,7 @@
X /*
X * Exit with the error passed back
X */


- if (AE_OK != status) {
+ if (ACPI_FAILURE (status)) {

X return (status);
X }
X

@@ -134,138 +123,53 @@
X }
X
X
-/***************************************************************************
+/*******************************************************************************
+ *
X * FUNCTION: Acpi_rs_create_pci_routing_table


X *
X * PARAMETERS:

- * Package_object - Pointer to an ACPI_OBJECT_INTERNAL
+ * Package_object - Pointer to an ACPI_OPERAND_OBJECT
X * package
X * Output_buffer - Pointer to the user's buffer
X * Output_buffer_length - Size of Output_buffer
X *
X * RETURN: Status AE_OK if okay, else a valid ACPI_STATUS code.
X * If the Output_buffer is too small, the error will be
- * AE_BUFFER_OVERFLOW and Output_buffer_length will point
- * to the size buffer needed.
+ * AE_BUFFER_OVERFLOW and Output_buffer_length will point
+ * to the size buffer needed.
X *
- * DESCRIPTION: Takes the ACPI_OBJECT_INTERNAL package and creates a
- * linked list of PCI interrupt descriptions
+ * DESCRIPTION: Takes the ACPI_OPERAND_OBJECT package and creates a
+ * linked list of PCI interrupt descriptions


X *
- ***************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS

X acpi_rs_create_pci_routing_table (
- ACPI_OBJECT_INTERNAL *package_object,
+ ACPI_OPERAND_OBJECT *package_object,
X u8 *output_buffer,
X u32 *output_buffer_length)
X {
X u8 *buffer = output_buffer;
- ACPI_OBJECT_INTERNAL **top_object_list = NULL;
- ACPI_OBJECT_INTERNAL **sub_object_list = NULL;
- ACPI_OBJECT_INTERNAL *package_element = NULL;
+ ACPI_OPERAND_OBJECT **top_object_list = NULL;
+ ACPI_OPERAND_OBJECT **sub_object_list = NULL;
+ ACPI_OPERAND_OBJECT *package_element = NULL;
X u32 buffer_size_needed = 0;
X u32 number_of_elements = 0;


X u32 index = 0;

- u8 table_index = 0;
- u8 name_found = FALSE;
X PCI_ROUTING_TABLE *user_prt = NULL;
+ ACPI_STATUS status;
X
X
X /*
- * Validate parameters:
- *
- * 1. If Method_return_object is NULL, or
- * 2. If Output_buffer is NULL and Output_buffer_length is not zero
- *
- * Return an error
+ * Params already validated, so we don't re-validate here
X */
- if (!package_object ||
- (!output_buffer && 0 != *output_buffer_length))


- {
- return (AE_BAD_PARAMETER);
- }

X
- /*
- * Calculate the buffer size needed for the routing table.
- */
- number_of_elements = package_object->package.count;
-
- /*
- * Properly calculate the size of the return buffer.
- * The base size is the number of elements * the sizes of the
- * structures. Additional space for the strings is added below.
- * The minus one is to subtract the size of the u8 Source[1]
- * member because it is added below.
- * NOTE: The Number_of_elements is incremented by one to add an end
- * table structure that is essentially a structure of zeros.
- */
- buffer_size_needed = (number_of_elements + 1) *
- (sizeof (PCI_ROUTING_TABLE) - 1);
-
- /*
- * But each PRT_ENTRY structure has a pointer to a string and
- * the size of that string must be found.
- */
- top_object_list = package_object->package.elements;
-
- for (index = 0; index < number_of_elements; index++) {
- /*
- * Dereference the sub-package
- */
- package_element = *top_object_list;
-
- /*
- * The Sub_object_list will now point to an array of the
- * four IRQ elements: Address, Pin, Source and Source_index
- */
- sub_object_list = package_element->package.elements;
-
- /*
- * Scan the Irq_table_elements for the Source Name String
- */
- name_found = FALSE;
-
- for (table_index = 0; table_index < 4 && !name_found; table_index++) {
- if (ACPI_TYPE_STRING == (*sub_object_list)->common.type) {
- name_found = TRUE;


- }
-
- else {
- /*

- * Look at the next element
- */
- sub_object_list++;


- }
- }
-
- /*

- * Was a String type found?
- */
- if (TRUE == name_found) {
- /*
- * The length String.Length field includes the
- * terminating NULL
- */
- buffer_size_needed += ((*sub_object_list)->string.length);
- }
-
- else {
- /*
- * If no name was found, then this is a NULL, which is
- * translated as a u32 zero.
- */
- buffer_size_needed += sizeof(u32);
- }
-
- /*
- * Point to the next ACPI_OBJECT_INTERNAL
- */
- top_object_list++;
- }
+ status = acpi_rs_calculate_pci_routing_table_length(package_object,
+ &buffer_size_needed);
X
X /*
X * If the data will fit into the available buffer
- * call to fill in the list
+ * call to fill in the list
X */
X if (buffer_size_needed <= *output_buffer_length) {
X /*
@@ -275,34 +179,32 @@
X
X /*
X * Loop through the ACPI_INTERNAL_OBJECTS - Each object should
- * contain a u32 Address, a u8 Pin, a Name and a u8
- * Source_index.
+ * contain a u32 Address, a u8 Pin, a Name and a u8
+ * Source_index.
X */
X top_object_list = package_object->package.elements;
X
X number_of_elements = package_object->package.count;
X
- user_prt = (PCI_ROUTING_TABLE *)buffer;
+ user_prt = (PCI_ROUTING_TABLE *) buffer;
X
X for (index = 0; index < number_of_elements; index++) {
X /*
X * Point User_prt past this current structure
X *
X * NOTE: On the first iteration, User_prt->Length will
- * be zero because we zero'ed out the return buffer
- * earlier
+ * be zero because we cleared the return buffer earlier
X */
X buffer += user_prt->length;
-
- user_prt = (PCI_ROUTING_TABLE *)buffer;
+ user_prt = (PCI_ROUTING_TABLE *) buffer;
X
X /*
X * Fill in the Length field with the information we
- * have at this point.
- * The minus one is to subtract the size of the
- * u8 Source[1] member because it is added below.
+ * have at this point.
+ * The minus one is to subtract the size of the
+ * u8 Source[1] member because it is added below.
X */
- user_prt->length = (sizeof(PCI_ROUTING_TABLE) - 1);
+ user_prt->length = (sizeof (PCI_ROUTING_TABLE) - 1);
X
X /*
X * Dereference the sub-package
@@ -311,8 +213,8 @@
X
X /*
X * The Sub_object_list will now point to an array of
- * the four IRQ elements: Address, Pin, Source and
- * Source_index
+ * the four IRQ elements: Address, Pin, Source and
+ * Source_index
X */
X sub_object_list = package_element->package.elements;
X
@@ -348,27 +250,29 @@
X sub_object_list++;
X
X if (ACPI_TYPE_STRING == (*sub_object_list)->common.type) {
- STRCPY(user_prt->data.source,
+ STRCPY (user_prt->data.source,
X (*sub_object_list)->string.pointer);
X
X /*
X * Add to the Length field the length of the string
X */
X user_prt->length += (*sub_object_list)->string.length;
+ user_prt->length =
+ ROUND_UP_TO_32_bITS (user_prt->length);


X }
X
X else {
X /*

X * If this is a number, then the Source Name
- * is NULL, since the entire buffer was zeroed
- * out, we can leave this alone.
+ * is NULL, since the entire buffer was zeroed
+ * out, we can leave this alone.
X */
X if (ACPI_TYPE_NUMBER == (*sub_object_list)->common.type) {
X /*
X * Add to the Length field the length of
- * the u32 NULL
+ * the u32 NULL
X */
- user_prt->length += sizeof(u32);
+ user_prt->length += sizeof (u32);
X }
X
X else {
@@ -391,7 +295,7 @@
X }
X
X /*
- * Point to the next ACPI_OBJECT_INTERNAL
+ * Point to the next ACPI_OPERAND_OBJECT
X */
X top_object_list++;


X }
@@ -414,7 +318,8 @@
X }

X
X
-/***************************************************************************
+/*******************************************************************************
+ *
X * FUNCTION: Acpi_rs_create_byte_stream


X *
X * PARAMETERS:

@@ -431,7 +336,7 @@
X * creates a bytestream to be used as input for the
X * _SRS control method.


X *
- ***************************************************************************/
+ ******************************************************************************/
X
X ACPI_STATUS

X acpi_rs_create_byte_stream (
@@ -439,27 +344,15 @@
X u8 *output_buffer,
X u32 *output_buffer_length)
X {
- ACPI_STATUS status = AE_UNKNOWN_STATUS;
+ ACPI_STATUS status;
X u32 byte_stream_size_needed = 0;
X
X
X /*
- * Validate parameters:
+ * Params already validated, so we don't re-validate here
X *
- * 1. If Linked_list_buffer is NULL, or
- * 2. If Output_buffer is NULL and Output_buffer_length is not zero
- *
- * Return an error
- */
- if (!linked_list_buffer ||
- (!output_buffer && 0 != *output_buffer_length))


- {
- return (AE_BAD_PARAMETER);
- }
-
- /*

X * Pass the Linked_list_buffer into a module that can calculate
- * the buffer size needed for the byte stream.
+ * the buffer size needed for the byte stream.
X */
X status = acpi_rs_calculate_byte_stream_length (linked_list_buffer,
X &byte_stream_size_needed);
@@ -467,13 +360,13 @@
X /*
X * Exit with the error passed back
X */


- if (AE_OK != status) {
+ if (ACPI_FAILURE (status)) {

X return (status);
X }
X

X /*
X * If the linked list will fit into the available buffer
- * call to fill in the list
+ * call to fill in the list
X */
X
X if (byte_stream_size_needed <= *output_buffer_length) {
@@ -489,7 +382,7 @@
X /*
X * Exit with the error passed back
X */


- if (AE_OK != status) {
+ if (ACPI_FAILURE (status)) {

X return (status);
X }
X

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/resources/rsdump.c linux/drivers/acpi/resources/rsdump.c
--- v2.4.0-test8/linux/drivers/acpi/resources/rsdump.c Wed Jul 5 11:23:13 2000
+++ linux/drivers/acpi/resources/rsdump.c Fri Sep 15 14:30:30 2000


@@ -1,6 +1,7 @@
X /******************************************************************************
X *

X * Module Name: rsdump - Functions do dump out the resource structures.
+ * $Revision: 10 $


X *
X *****************************************************************************/
X

@@ -26,7 +27,7 @@
X #include "acpi.h"
X
X #define _COMPONENT RESOURCE_MANAGER
- MODULE_NAME ("rsdump");
+ MODULE_NAME ("rsdump")
X
X
X /******************************************************************************
@@ -120,7 +121,7 @@
X break;
X }
X
- acpi_os_printf ("\t\t%s_bus Master\n",
+ acpi_os_printf ("\t\t%sBus Master\n",
X BUS_MASTER == dma_data->bus_master ?
X "" : "Not a ");
X
@@ -802,7 +803,7 @@
X acpi_rs_dump_resource_list (
X RESOURCE *resource)
X {
- s8 count = 0;
+ u8 count = 0;
X u8 done = FALSE;
X
X
@@ -902,7 +903,7 @@
X u8 *route_table)
X {
X u8 *buffer = route_table;
- s8 count = 0;
+ u8 count = 0;
X u8 done = FALSE;
X PCI_ROUTING_TABLE *prt_element;
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/resources/rsio.c linux/drivers/acpi/resources/rsio.c
--- v2.4.0-test8/linux/drivers/acpi/resources/rsio.c Wed Jul 5 11:23:13 2000
+++ linux/drivers/acpi/resources/rsio.c Fri Sep 15 14:30:30 2000
@@ -6,6 +6,7 @@
X * Acpi_rs_fixed_io_stream
X * Acpi_rs_dma_resource
X * Acpi_rs_dma_stream
+ * $Revision: 7 $


X *
X *****************************************************************************/
X

@@ -31,7 +32,7 @@
X #include "acpi.h"
X
X #define _COMPONENT RESOURCE_MANAGER
- MODULE_NAME ("rsio");
+ MODULE_NAME ("rsio")
X
X
X /***************************************************************************
@@ -90,7 +91,7 @@
X * Check Min_base Address
X */
X buffer += 1;
- temp16 = *(u16 *)buffer;
+ MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
X
X output_struct->data.io.min_base_address = temp16;


X
@@ -98,7 +99,7 @@

X * Check Max_base Address
X */
X buffer += 2;
- temp16 = *(u16 *)buffer;
+ MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
X
X output_struct->data.io.max_base_address = temp16;
X
@@ -255,7 +256,7 @@
X */
X temp16 = (u16) linked_list->data.io.min_base_address;
X
- *(u16 *)buffer = temp16;
+ MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
X
X buffer += 2;


X
@@ -264,7 +265,7 @@

X */
X temp16 = (u16) linked_list->data.io.max_base_address;
X
- *(u16 *)buffer = temp16;
+ MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
X
X buffer += 2;
X
@@ -336,7 +337,7 @@
X */
X temp16 = (u16) linked_list->data.fixed_io.base_address;
X
- *(u16 *)buffer = temp16;
+ MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
X
X buffer += 2;
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/resources/rsirq.c linux/drivers/acpi/resources/rsirq.c
--- v2.4.0-test8/linux/drivers/acpi/resources/rsirq.c Wed Jul 5 11:23:13 2000
+++ linux/drivers/acpi/resources/rsirq.c Fri Sep 15 14:30:30 2000
@@ -4,6 +4,7 @@
X * Acpi_rs_irq_stream
X * Acpi_rs_extended_irq_resource
X * Acpi_rs_extended_irq_stream
+ * $Revision: 8 $


X *
X *****************************************************************************/
X

@@ -29,7 +30,7 @@
X #include "acpi.h"
X
X #define _COMPONENT RESOURCE_MANAGER
- MODULE_NAME ("rsirq");
+ MODULE_NAME ("rsirq")
X
X
X /***************************************************************************
@@ -85,7 +86,7 @@
X * Point to the 16-bits of Bytes 1 and 2
X */
X buffer += 1;
- temp16 = *(u16 *)buffer;
+ MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
X
X output_struct->data.irq.number_of_interrupts = 0;
X
@@ -226,7 +227,7 @@
X temp16 |= 0x1 << temp8;
X }
X
- *(u16 *)buffer = temp16;
+ MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
X
X buffer += 2;
X
@@ -306,7 +307,7 @@
X * Point past the Descriptor to get the number of bytes consumed
X */
X buffer += 1;
- temp16 = *(u16 *)buffer;
+ MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
X
X *bytes_consumed = temp16 + 3;
X output_struct->id = extended_irq;
@@ -476,7 +477,7 @@
X u16 *length_field;
X u8 temp8 = 0;
X u8 index;
- u8 *temp_pointer = NULL;
+ NATIVE_CHAR *temp_pointer = NULL;
X
X
X /*
@@ -533,11 +534,10 @@
X * Resource Source Index and Resource Source are optional
X */
X if (0 != linked_list->data.extended_irq.resource_source_string_length) {
- temp8 = (u8) linked_list->data.extended_irq.resource_source_index;
-
- *buffer = temp8;
+ *buffer = (u8) linked_list->data.extended_irq.resource_source_index;
X buffer += 1;
- temp_pointer = buffer;
+
+ temp_pointer = (NATIVE_CHAR *) buffer;
X
X /*
X * Copy the string
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/resources/rslist.c linux/drivers/acpi/resources/rslist.c
--- v2.4.0-test8/linux/drivers/acpi/resources/rslist.c Wed Jul 5 11:23:13 2000
+++ linux/drivers/acpi/resources/rslist.c Fri Sep 15 14:30:30 2000
@@ -2,6 +2,7 @@
X *
X * Module Name: rslist - Acpi_rs_byte_stream_to_list
X * Acpi_list_to_byte_stream
+ * $Revision: 6 $


X *
X *****************************************************************************/
X

@@ -25,10 +26,10 @@


X
X
X #include "acpi.h"

-#include "resource.h"
+#include "acresrc.h"
X
X #define _COMPONENT RESOURCE_MANAGER
- MODULE_NAME ("rslist");
+ MODULE_NAME ("rslist")
X
X
X /***************************************************************************
@@ -53,7 +54,7 @@
X u32 byte_stream_buffer_length,
X u8 **output_buffer)
X {
- ACPI_STATUS status = AE_UNKNOWN_STATUS;
+ ACPI_STATUS status;
X u32 bytes_parsed = 0;
X u8 resource_type = 0;
X u32 bytes_consumed = 0;
@@ -167,7 +168,7 @@
X * If we get here, everything is out of sync,
X * so exit with an error
X */
- return (AE_ERROR);
+ return (AE_AML_ERROR);
X break;
X }
X }
@@ -275,11 +276,11 @@
X * If we get here, everything is out of sync,
X * so exit with an error
X */
- return (AE_ERROR);
+ return (AE_AML_ERROR);
X break;
X
X } /* switch */
- } /* if(Resource_type & 0x80) */
+ } /* end else */
X
X /*
X * Update the return value and counter
@@ -296,14 +297,15 @@
X */
X *buffer += structure_size;
X
- } /* while (Bytes_parsed < Byte_stream_buffer_length &&
- FALSE == End_tag_processed) */
+ } /* end while */
X
X /*
X * Check the reason for exiting the while loop
X */
- if (byte_stream_buffer_length != bytes_parsed || TRUE != end_tag_processed) {
- return (AE_ERROR);
+ if (!(byte_stream_buffer_length == bytes_parsed) ||
+ (TRUE != end_tag_processed))
+ {
+ return (AE_AML_ERROR);


X }
X
X return (AE_OK);

@@ -338,7 +340,7 @@
X u32 byte_stream_size_needed,
X u8 **output_buffer)
X {
- ACPI_STATUS status = AE_UNKNOWN_STATUS;
+ ACPI_STATUS status;
X u8 *buffer = *output_buffer;
X u32 bytes_consumed = 0;
X u8 done = FALSE;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/resources/rsmemory.c linux/drivers/acpi/resources/rsmemory.c
--- v2.4.0-test8/linux/drivers/acpi/resources/rsmemory.c Wed Jul 5 11:23:13 2000
+++ linux/drivers/acpi/resources/rsmemory.c Fri Sep 15 14:30:30 2000
@@ -6,6 +6,7 @@
X * Acpi_rs_fixed_memory32_resource
X * Acpi_rs_memory32_range_stream
X * Acpi_rs_fixed_memory32_stream
+ * $Revision: 7 $


X *
X *****************************************************************************/
X

@@ -31,7 +32,7 @@
X #include "acpi.h"
X
X #define _COMPONENT RESOURCE_MANAGER
- MODULE_NAME ("rsmemory");
+ MODULE_NAME ("rsmemory")
X
X
X /***************************************************************************
@@ -76,7 +77,7 @@
X */
X buffer += 1;
X
- temp16 = *(u16 *)buffer;
+ MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
X
X buffer += 2;
X
@@ -96,7 +97,7 @@
X /*
X * Get Min_base_address (Bytes 4-5)
X */
- temp16 = *(u16 *)buffer;
+ MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
X
X buffer += 2;
X
@@ -105,7 +106,7 @@
X /*
X * Get Max_base_address (Bytes 6-7)
X */
- temp16 = *(u16 *)buffer;
+ MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
X
X buffer += 2;
X
@@ -114,7 +115,7 @@
X /*
X * Get Alignment (Bytes 8-9)
X */
- temp16 = *(u16 *)buffer;
+ MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
X
X buffer += 2;
X
@@ -123,7 +124,7 @@
X /*
X * Get Range_length (Bytes 10-11)
X */
- temp16 = *(u16 *)buffer;
+ MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
X
X output_struct->data.memory24.range_length = temp16;
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/resources/rsmisc.c linux/drivers/acpi/resources/rsmisc.c
--- v2.4.0-test8/linux/drivers/acpi/resources/rsmisc.c Wed Jul 5 11:23:13 2000
+++ linux/drivers/acpi/resources/rsmisc.c Fri Sep 15 14:30:30 2000
@@ -8,6 +8,7 @@
X * Acpi_rs_end_dependent_functions_resource
X * Acpi_rs_start_dependent_functions_stream
X * Acpi_rs_end_dependent_functions_stream
+ * $Revision: 7 $


X *
X *****************************************************************************/
X

@@ -33,7 +34,7 @@
X #include "acpi.h"
X
X #define _COMPONENT RESOURCE_MANAGER
- MODULE_NAME ("rsmisc");
+ MODULE_NAME ("rsmisc")
X
X
X /***************************************************************************


@@ -199,7 +200,7 @@
X

X /* Dereference */
X
- temp16 = *(u16 *)buffer;
+ MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
X
X /* Calculate bytes consumed */


X
@@ -304,7 +305,7 @@
X

X temp16 = (u16) linked_list->data.vendor_specific.length;
X
- *(u16 *)buffer = temp16;
+ MOVE_UNALIGNED16_TO_16 (&temp16, buffer);
X
X buffer += 2;
X }
@@ -404,7 +405,7 @@
X temp8 & 0x03;
X
X if (3 == output_struct->data.start_dependent_functions.compatibility_priority) {
- return (AE_ERROR);
+ return (AE_AML_ERROR);
X }
X
X /*
@@ -414,7 +415,7 @@
X (temp8 >> 2) & 0x03;
X
X if (3 == output_struct->data.start_dependent_functions.performance_robustness) {
- return (AE_ERROR);
+ return (AE_AML_ERROR);
X }
X }
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/resources/rsutils.c linux/drivers/acpi/resources/rsutils.c
--- v2.4.0-test8/linux/drivers/acpi/resources/rsutils.c Wed Jul 5 11:23:13 2000
+++ linux/drivers/acpi/resources/rsutils.c Fri Sep 15 14:30:30 2000


@@ -1,6 +1,7 @@
X /******************************************************************************
X *

X * Module Name: rsutils - Utilities for the resource manager
+ * $Revision: 10 $


X *
X *****************************************************************************/
X

@@ -24,19 +25,19 @@


X
X
X #include "acpi.h"

-#include "namesp.h"
-#include "resource.h"
+#include "acnamesp.h"
+#include "acresrc.h"
X
X
X #define _COMPONENT RESOURCE_MANAGER
- MODULE_NAME ("rsutils");
+ MODULE_NAME ("rsutils")
X
X
X /******************************************************************************
X *
X * FUNCTION: Acpi_rs_get_prt_method_data
X *
- * PARAMETERS: Device_handle - a handle to the containing object
+ * PARAMETERS: Handle - a handle to the containing object
X * Ret_buffer - a pointer to a buffer structure for the
X * results
X *
@@ -55,28 +56,20 @@
X ACPI_HANDLE handle,
X ACPI_BUFFER *ret_buffer)
X {
- ACPI_OBJECT_INTERNAL *ret_obj;
+ ACPI_OPERAND_OBJECT *ret_obj;
X ACPI_STATUS status;
- u32 buffer_space_needed = ret_buffer->length;
+ u32 buffer_space_needed;
X
X
- /*
- * Must have a valid handle and buffer, So we have to have a handle
- * a return buffer structure and if there is a non-zero buffer length
- * we also need a valid pointer in the buffer
- */
- if ((!handle) ||
- (!ret_buffer) ||
- ((!ret_buffer->pointer) && (ret_buffer->length)))


- {
- return (AE_BAD_PARAMETER);
- }

+ /* already validated params, so we won't repeat here */
+
+ buffer_space_needed = ret_buffer->length;
X
X /*
X * Execute the method, no parameters
X */
X status = acpi_ns_evaluate_relative (handle, "_PRT", NULL, &ret_obj);


- if (status != AE_OK) {

+ if (ACPI_FAILURE (status)) {


X return (status);
X }
X

@@ -128,7 +121,7 @@
X *
X * FUNCTION: Acpi_rs_get_crs_method_data
X *
- * PARAMETERS: Device_handle - a handle to the containing object
+ * PARAMETERS: Handle - a handle to the containing object
X * Ret_buffer - a pointer to a buffer structure for the
X * results
X *
@@ -147,28 +140,18 @@
X ACPI_HANDLE handle,
X ACPI_BUFFER *ret_buffer)
X {
- ACPI_OBJECT_INTERNAL *ret_obj;
+ ACPI_OPERAND_OBJECT *ret_obj;
X ACPI_STATUS status;
X u32 buffer_space_needed = ret_buffer->length;
X
X
- /*
- * Must have a valid handle and buffer, So we have to have a handle
- * a return buffer structure and if there is a non-zero buffer length
- * we also need a valid pointer in the buffer
- */
- if ((!handle) ||
- (!ret_buffer) ||
- ((!ret_buffer->pointer) && (ret_buffer->length)))


- {
- return (AE_BAD_PARAMETER);
- }

+ /* already validated params, so we won't repeat here */
X
X /*
X * Execute the method, no parameters
X */
X status = acpi_ns_evaluate_relative (handle, "_CRS", NULL, &ret_obj);


- if (status != AE_OK) {

+ if (ACPI_FAILURE (status)) {


X return (status);
X }
X

@@ -198,9 +181,7 @@
X ret_buffer->pointer,
X &buffer_space_needed);


X
- if (AE_OK == status) {

- acpi_rs_dump_resource_list((RESOURCE *)ret_buffer->pointer);
- }
+
X
X /*
X * Tell the user how much of the buffer we have used or is needed
@@ -223,7 +204,7 @@
X *
X * FUNCTION: Acpi_rs_get_prs_method_data
X *
- * PARAMETERS: Device_handle - a handle to the containing object
+ * PARAMETERS: Handle - a handle to the containing object
X * Ret_buffer - a pointer to a buffer structure for the
X * results
X *
@@ -242,28 +223,18 @@
X ACPI_HANDLE handle,
X ACPI_BUFFER *ret_buffer)
X {
- ACPI_OBJECT_INTERNAL *ret_obj;
+ ACPI_OPERAND_OBJECT *ret_obj;
X ACPI_STATUS status;
X u32 buffer_space_needed = ret_buffer->length;
X
X
- /*
- * Must have a valid handle and buffer, So we have to have a handle
- * a return buffer structure and if there is a non-zero buffer length
- * we also need a valid pointer in the buffer
- */
- if ((!handle) ||
- (!ret_buffer) ||
- ((!ret_buffer->pointer) && (ret_buffer->length)))


- {
- return (AE_BAD_PARAMETER);
- }

+ /* already validated params, so we won't repeat here */
X
X /*
X * Execute the method, no parameters
X */
X status = acpi_ns_evaluate_relative (handle, "_PRS", NULL, &ret_obj);


- if (status != AE_OK) {

+ if (ACPI_FAILURE (status)) {


X return (status);
X }
X

@@ -314,9 +285,7 @@
X *
X * FUNCTION: Acpi_rs_set_srs_method_data
X *
- * PARAMETERS: Device_handle - a handle to the containing object
- * *Method_name - Name of method to execute, If NULL, the
- * handle is the object to execute
+ * PARAMETERS: Handle - a handle to the containing object
X * In_buffer - a pointer to a buffer structure of the
X * parameter
X *
@@ -335,22 +304,13 @@
X ACPI_HANDLE handle,
X ACPI_BUFFER *in_buffer)
X {
- ACPI_OBJECT_INTERNAL *params[2];
- ACPI_OBJECT_INTERNAL param_obj;
+ ACPI_OPERAND_OBJECT *params[2];
+ ACPI_OPERAND_OBJECT param_obj;
X ACPI_STATUS status;
X u8 *byte_stream = NULL;
X u32 buffer_size_needed = 0;
X
- /*
- * Must have a valid handle and buffer
- */
- if ((!handle) ||
- (!in_buffer) ||
- (!in_buffer->pointer) ||
- (!in_buffer->length))


- {
- return (AE_BAD_PARAMETER);
- }

+ /* already validated params, so we won't repeat here */
X
X /*
X * The In_buffer parameter will point to a linked list of
@@ -390,12 +350,8 @@
X byte_stream,
X &buffer_size_needed);
X
- if(AE_OK != status) {
- /*
- * Failed the call
- */
- acpi_cm_free (byte_stream);
- return (status);


+ if (ACPI_FAILURE (status)) {
+ goto cleanup;

X }
X
X /*
@@ -424,6 +380,9 @@
X /*
X * Clean up and return the status from Acpi_ns_evaluate_relative
X */
+
+cleanup:
+
X acpi_cm_free (byte_stream);
X return (status);
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/resources/rsxface.c linux/drivers/acpi/resources/rsxface.c
--- v2.4.0-test8/linux/drivers/acpi/resources/rsxface.c Wed Jul 5 11:23:13 2000
+++ linux/drivers/acpi/resources/rsxface.c Fri Sep 15 14:30:30 2000


@@ -1,6 +1,7 @@
X /******************************************************************************
X *

X * Module Name: rsxface - Public interfaces to the ACPI subsystem
+ * $Revision: 7 $


X *
X *****************************************************************************/
X

@@ -24,12 +25,12 @@


X
X
X #include "acpi.h"

-#include "interp.h"
-#include "namesp.h"
-#include "resource.h"
+#include "acinterp.h"
+#include "acnamesp.h"
+#include "acresrc.h"
X
X #define _COMPONENT RESOURCE_MANAGER
- MODULE_NAME ("rsxface");
+ MODULE_NAME ("rsxface")
X
X
X /******************************************************************************
@@ -37,19 +38,18 @@
X * FUNCTION: Acpi_get_irq_routing_table
X *
X * PARAMETERS: Device_handle - a handle to the Bus device we are querying
- * Out_buffer - a pointer to a buffer to receive the
+ * Ret_buffer - a pointer to a buffer to receive the
X * current resources for the device
- * Buffer_length - the number of bytes available in the buffer
X *
X * RETURN: Status - the status of the call
X *
X * DESCRIPTION: This function is called to get the IRQ routing table for a
X * specific bus. The caller must first acquire a handle for the
X * desired bus. The routine table is placed in the buffer pointed
- * to by the Out_buffer variable parameter.
+ * to by the Ret_buffer variable parameter.
X *
X * If the function fails an appropriate status will be returned
- * and the value of Out_buffer is undefined.
+ * and the value of Ret_buffer is undefined.
X *
X * This function attempts to execute the _PRT method contained in
X * the object indicated by the passed Device_handle.
@@ -64,6 +64,19 @@
X ACPI_STATUS status;
X
X
+ /*
+ * Must have a valid handle and buffer, So we have to have a handle
+ * and a return buffer structure, and if there is a non-zero buffer length
+ * we also need a valid pointer in the buffer. If it's a zero buffer length,
+ * we'll be returning the needed buffer size, so keep going.
+ */
+ if ((!device_handle) ||
+ (!ret_buffer) ||
+ ((!ret_buffer->pointer) && (ret_buffer->length)))
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
X status = acpi_rs_get_prt_method_data (device_handle, ret_buffer);
X
X return (status);
@@ -76,19 +89,18 @@
X *
X * PARAMETERS: Device_handle - a handle to the device object for the
X * device we are querying


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 037'
echo 'File patch-2.4.0-test9 is continued in part 038'
echo "038" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part038

#!/bin/sh -x
# this is part 038 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 038; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

- * Out_buffer - a pointer to a buffer to receive the
+ * Ret_buffer - a pointer to a buffer to receive the
X * current resources for the device
- * Buffer_length - the number of bytes available in the buffer
X *
X * RETURN: Status - the status of the call
X *

X * DESCRIPTION: This function is called to get the current resources for a
X * specific device. The caller must first acquire a handle for
X * the desired device. The resource data is placed in the buffer
- * pointed to by the Out_buffer variable parameter.
+ * pointed to by the Ret_buffer variable parameter.


X *
X * If the function fails an appropriate status will be returned
- * and the value of Out_buffer is undefined.
+ * and the value of Ret_buffer is undefined.
X *

X * This function attempts to execute the _CRS method contained in


X * the object indicated by the passed Device_handle.

@@ -103,6 +115,19 @@


X ACPI_STATUS status;
X
X
+ /*
+ * Must have a valid handle and buffer, So we have to have a handle
+ * and a return buffer structure, and if there is a non-zero buffer length
+ * we also need a valid pointer in the buffer. If it's a zero buffer length,
+ * we'll be returning the needed buffer size, so keep going.
+ */
+ if ((!device_handle) ||
+ (!ret_buffer) ||

+ ((ret_buffer->length) && (!ret_buffer->pointer)))


+ {
+ return (AE_BAD_PARAMETER);
+ }
+

X status = acpi_rs_get_crs_method_data (device_handle, ret_buffer);
X
X return (status);
@@ -115,19 +140,18 @@


X *
X * PARAMETERS: Device_handle - a handle to the device object for the
X * device we are querying

- * Out_buffer - a pointer to a buffer to receive the
+ * Ret_buffer - a pointer to a buffer to receive the

X * resources for the device


- * Buffer_length - the number of bytes available in the buffer

- *
+ *


X * RETURN: Status - the status of the call
X *

X * DESCRIPTION: This function is called to get a list of the possible resources
X * for a specific device. The caller must first acquire a handle
X * for the desired device. The resource data is placed in the
- * buffer pointed to by the Out_buffer variable.
+ * buffer pointed to by the Ret_buffer variable.


X *
X * If the function fails an appropriate status will be returned
- * and the value of Out_buffer is undefined.
+ * and the value of Ret_buffer is undefined.
X *

X ******************************************************************************/
X
@@ -139,6 +163,19 @@


X ACPI_STATUS status;
X
X
+ /*
+ * Must have a valid handle and buffer, So we have to have a handle
+ * and a return buffer structure, and if there is a non-zero buffer length
+ * we also need a valid pointer in the buffer. If it's a zero buffer length,
+ * we'll be returning the needed buffer size, so keep going.
+ */
+ if ((!device_handle) ||
+ (!ret_buffer) ||

+ ((ret_buffer->length) && (!ret_buffer->pointer)))


+ {
+ return (AE_BAD_PARAMETER);
+ }
+

X status = acpi_rs_get_prs_method_data (device_handle, ret_buffer);
X
X return (status);
@@ -151,7 +188,7 @@


X *
X * PARAMETERS: Device_handle - a handle to the device object for the

X * device we are changing the resources of
- * Out_buffer - a pointer to a buffer containing the
+ * In_buffer - a pointer to a buffer containing the
X * resources to be set for the device


X *
X * RETURN: Status - the status of the call

@@ -170,6 +207,17 @@


X {
X ACPI_STATUS status;
X

+
+ /*
+ * Must have a valid handle and buffer


+ */
+ if ((!device_handle) ||

+ (!in_buffer) ||
+ (!in_buffer->pointer) ||
+ (!in_buffer->length))


+ {
+ return (AE_BAD_PARAMETER);
+ }

X
X status = acpi_rs_set_srs_method_data (device_handle, in_buffer);
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/sys.c linux/drivers/acpi/sys.c
--- v2.4.0-test8/linux/drivers/acpi/sys.c Thu Jul 13 09:39:49 2000
+++ linux/drivers/acpi/sys.c Fri Sep 15 14:30:30 2000
@@ -24,6 +24,9 @@
X #include "acpi.h"


X #include "driver.h"
X
+#define _COMPONENT OS_DEPENDENT

+ MODULE_NAME ("sys")
+
X #define ACPI_SLP_TYP(typa, typb) (((int)(typa) << 8) | (int)(typb))
X #define ACPI_SLP_TYPA(value) \
X ((((value) >> 8) << ACPI_SLP_TYP_SHIFT) & ACPI_SLP_TYP_MASK)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/table.c linux/drivers/acpi/table.c
--- v2.4.0-test8/linux/drivers/acpi/table.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/table.c Fri Sep 15 14:30:30 2000
@@ -0,0 +1,306 @@
+/*
+ * tables.c - ACPI tables, chipset, and errata handling
+ *
+ * Copyright (C) 2000 Andrew Henroid


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+

+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/pm.h>
+#include <linux/acpi.h>
+#include "acpi.h"
+#include "driver.h"
+
+#define _COMPONENT OS_DEPENDENT
+ MODULE_NAME ("tables")
+
+struct acpi_facp acpi_facp;
+
+#define ACPI_DUMMY_CHECKSUM 9
+#define ACPI_DUMMY_PBLK 51
+
+static u8 acpi_dummy_dsdt[] =
+{
+ 0x44, 0x53, 0x44, 0x54, // "DSDT"
+ 0x38, 0x00, 0x00, 0x00, // length
+ 0x01, // revision
+ 0x00, // checksum
+ 0x4c, 0x49, 0x4e, 0x55, 0x58, 0x00, // "LINUX"
+ 0x44, 0x55, 0x4d, 0x4d, 0x59, 0x00, 0x00, 0x00, // "DUMMY"
+ 0x01, 0x00, 0x00, 0x00, // OEM rev
+ 0x4c, 0x4e, 0x55, 0x58, // "LNUX"
+ 0x01, 0x00, 0x00, 0x00, // creator rev
+ 0x10, // Scope
+ 0x13, // PkgLength
+ 0x5c, 0x5f, 0x50, 0x52, 0x5f, // \_PR_
+ 0x5b, 0x83, // Processor
+ 0x0b, // PkgLength
+ 0x43, 0x50, 0x55, 0x30, // CPU0
+ 0x00, // ID
+ 0x00, 0x00, 0x00, 0x00, // PBLK
+ 0x06 // PBLK size
+};
+
+/*
+ * Calculate and set ACPI table checksum
+ */
+static void
+acpi_set_checksum(u8 *table, int size)
+{
+ int i, sum = 0;
+ for (i = 0; i < size; i++)
+ sum += (int) table[i];
+ sum = (0x100 - ((sum - table[ACPI_DUMMY_CHECKSUM]) & 0xff));
+ table[ACPI_DUMMY_CHECKSUM] = sum;
+}
+
+/*
+ * Init PIIX4 device, create a fake FACP
+ */
+static int
+acpi_init_piix4(struct pci_dev *dev)
+{
+ u32 base, pblk;
+ u16 cmd;
+ u8 pmregmisc;
+
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ if (!(cmd & PCI_COMMAND_IO))
+ return -ENODEV;
+
+ pci_read_config_byte(dev, ACPI_PIIX4_PMREGMISC, &pmregmisc);
+ if (!(pmregmisc & ACPI_PIIX4_PMIOSE))
+ return -ENODEV;
+
+ base = pci_resource_start (dev, PCI_BRIDGE_RESOURCES);
+ if (!base)
+ return -ENODEV;
+
+ printk(KERN_INFO "ACPI: found \"%s\" at 0x%04x\n", dev->name, base);
+
+ memset(&acpi_facp, 0, sizeof(acpi_facp));
+ acpi_facp.hdr.signature = ACPI_FACP_SIG;
+ acpi_facp.hdr.length = sizeof(acpi_facp);
+ acpi_facp.int_model = ACPI_PIIX4_INT_MODEL;
+ acpi_facp.sci_int = ACPI_PIIX4_SCI_INT;
+ acpi_facp.smi_cmd = ACPI_PIIX4_SMI_CMD;
+ acpi_facp.acpi_enable = ACPI_PIIX4_ACPI_ENABLE;
+ acpi_facp.acpi_disable = ACPI_PIIX4_ACPI_DISABLE;
+ acpi_facp.s4bios_req = ACPI_PIIX4_S4BIOS_REQ;
+ acpi_facp.pm1a_evt = base + ACPI_PIIX4_PM1_EVT;
+ acpi_facp.pm1a_cnt = base + ACPI_PIIX4_PM1_CNT;
+ acpi_facp.pm2_cnt = ACPI_PIIX4_PM2_CNT;
+ acpi_facp.pm_tmr = base + ACPI_PIIX4_PM_TMR;
+ acpi_facp.gpe0 = base + ACPI_PIIX4_GPE0;
+ acpi_facp.pm1_evt_len = ACPI_PIIX4_PM1_EVT_LEN;
+ acpi_facp.pm1_cnt_len = ACPI_PIIX4_PM1_CNT_LEN;
+ acpi_facp.pm2_cnt_len = ACPI_PIIX4_PM2_CNT_LEN;
+ acpi_facp.pm_tm_len = ACPI_PIIX4_PM_TM_LEN;
+ acpi_facp.gpe0_len = ACPI_PIIX4_GPE0_LEN;
+ acpi_facp.p_lvl2_lat = (__u16) ACPI_INFINITE_LAT;
+ acpi_facp.p_lvl3_lat = (__u16) ACPI_INFINITE_LAT;
+
+ acpi_set_checksum((u8*) &acpi_facp, sizeof(acpi_facp));
+ acpi_load_table((ACPI_TABLE_HEADER*) &acpi_facp);
+
+ pblk = base + ACPI_PIIX4_P_BLK;
+ memcpy(acpi_dummy_dsdt + ACPI_DUMMY_PBLK, &pblk, sizeof(pblk));
+ acpi_set_checksum(acpi_dummy_dsdt, sizeof(acpi_dummy_dsdt));
+ acpi_load_table((ACPI_TABLE_HEADER*) acpi_dummy_dsdt);
+
+ return 0;
+}
+
+/*
+ * Init VIA ACPI device and create a fake FACP
+ */
+static int
+acpi_init_via(struct pci_dev *dev)
+{
+ u32 base, pblk;
+ u8 tmp, irq;
+
+ pci_read_config_byte(dev, 0x41, &tmp);
+ if (!(tmp & 0x80))
+ return -ENODEV;
+
+ base = pci_resource_start(dev, PCI_BRIDGE_RESOURCES);
+ if (!base) {
+ base = pci_resource_start(dev, PCI_BASE_ADDRESS_4);
+ if (!base)
+ return -ENODEV;
+ }
+
+ pci_read_config_byte(dev, 0x42, &irq);
+
+ printk(KERN_INFO "ACPI: found \"%s\" at 0x%04x\n", dev->name, base);
+
+ memset(&acpi_facp, 0, sizeof(acpi_facp));
+ acpi_facp.hdr.signature = ACPI_FACP_SIG;
+ acpi_facp.hdr.length = sizeof(acpi_facp);
+ acpi_facp.int_model = ACPI_VIA_INT_MODEL;
+ acpi_facp.sci_int = irq;
+ acpi_facp.smi_cmd = base + ACPI_VIA_SMI_CMD;
+ acpi_facp.acpi_enable = ACPI_VIA_ACPI_ENABLE;
+ acpi_facp.acpi_disable = ACPI_VIA_ACPI_DISABLE;
+ acpi_facp.pm1a_evt = base + ACPI_VIA_PM1_EVT;
+ acpi_facp.pm1a_cnt = base + ACPI_VIA_PM1_CNT;
+ acpi_facp.pm_tmr = base + ACPI_VIA_PM_TMR;
+ acpi_facp.gpe0 = base + ACPI_VIA_GPE0;
+
+ acpi_facp.pm1_evt_len = ACPI_VIA_PM1_EVT_LEN;
+ acpi_facp.pm1_cnt_len = ACPI_VIA_PM1_CNT_LEN;
+ acpi_facp.pm_tm_len = ACPI_VIA_PM_TM_LEN;
+ acpi_facp.gpe0_len = ACPI_VIA_GPE0_LEN;
+ acpi_facp.p_lvl2_lat = (__u16) ACPI_INFINITE_LAT;
+ acpi_facp.p_lvl3_lat = (__u16) ACPI_INFINITE_LAT;
+
+ acpi_facp.duty_offset = ACPI_VIA_DUTY_OFFSET;
+ acpi_facp.duty_width = ACPI_VIA_DUTY_WIDTH;
+
+ acpi_facp.day_alarm = ACPI_VIA_DAY_ALARM;
+ acpi_facp.mon_alarm = ACPI_VIA_MON_ALARM;
+ acpi_facp.century = ACPI_VIA_CENTURY;
+
+ acpi_set_checksum((u8*) &acpi_facp, sizeof(acpi_facp));
+ acpi_load_table((ACPI_TABLE_HEADER*) &acpi_facp);
+
+ pblk = base + ACPI_VIA_P_BLK;
+ memcpy(acpi_dummy_dsdt + ACPI_DUMMY_PBLK, &pblk, sizeof(pblk));
+ acpi_set_checksum(acpi_dummy_dsdt, sizeof(acpi_dummy_dsdt));
+ acpi_load_table((ACPI_TABLE_HEADER*) acpi_dummy_dsdt);
+
+ return 0;
+}
+
+typedef enum
+{
+ CH_UNKNOWN = 0,
+ CH_INTEL_PIIX4,
+ CH_VIA_586,
+ CH_VIA_686A,
+} acpi_chip_t;
+
+/* indexed by value of each enum in acpi_chip_t */
+const static struct
+{
+ int (*chip_init)(struct pci_dev *dev);
+} acpi_chip_info[] =
+{
+ {NULL,},
+ {acpi_init_piix4},
+ {acpi_init_via},
+ {acpi_init_via},
+};
+
+static struct pci_device_id acpi_pci_tbl[] =
+{
+ {0x8086, 0x7113, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_INTEL_PIIX4},
+ {0x1106, 0x3040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_VIA_586},
+ {0x1106, 0x3057, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_VIA_686A},
+ {0,} /* terminate list */
+};
+
+static int
+acpi_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+ return acpi_chip_info[id->driver_data].chip_init(dev);
+}
+
+static struct pci_driver acpi_driver =
+{
+ name: "acpi",
+ id_table: acpi_pci_tbl,
+ probe: acpi_probe,
+};
+static int acpi_driver_registered = 0;
+
+/*
+ * Locate a known ACPI chipset
+ */
+static int
+acpi_find_chipset(void)
+{
+ if (pci_register_driver(&acpi_driver) < 1)
+ return -ENODEV;
+ acpi_driver_registered = 1;
+ return 0;
+}
+
+/*
+ * Fetch the FACP information
+ */
+static int
+acpi_fetch_facp(void)
+{
+ ACPI_BUFFER buffer;
+
+ memset(&acpi_facp, 0, sizeof(acpi_facp));
+ buffer.pointer = &acpi_facp;
+ buffer.length = sizeof(acpi_facp);
+ if (!ACPI_SUCCESS(acpi_get_table(ACPI_TABLE_FACP, 1, &buffer))) {
+ printk(KERN_ERR "ACPI: missing FACP\n");
+ return -ENODEV;
+ }
+
+ if (acpi_facp.p_lvl2_lat
+ && acpi_facp.p_lvl2_lat <= ACPI_MAX_P_LVL2_LAT) {
+ acpi_c2_exit_latency
+ = ACPI_uS_TO_TMR_TICKS(acpi_facp.p_lvl2_lat);
+ acpi_c2_enter_latency
+ = ACPI_uS_TO_TMR_TICKS(ACPI_TMR_HZ / 1000);
+ }
+ if (acpi_facp.p_lvl3_lat
+ && acpi_facp.p_lvl3_lat <= ACPI_MAX_P_LVL3_LAT) {
+ acpi_c3_exit_latency
+ = ACPI_uS_TO_TMR_TICKS(acpi_facp.p_lvl3_lat);
+ acpi_c3_enter_latency
+ = ACPI_uS_TO_TMR_TICKS(acpi_facp.p_lvl3_lat * 5);
+ }
+
+ return 0;
+}
+
+/*
+ * Find and load ACPI tables
+ */
+int
+acpi_load_tables(void)
+{
+ if (ACPI_SUCCESS(acpi_load_firmware_tables()))
+ {
+ printk(KERN_INFO "ACPI: support found\n");
+ }
+ else if (acpi_find_chipset()) {
+ acpi_terminate();
+ return -1;
+ }
+
+ if (acpi_fetch_facp()) {
+ acpi_terminate();
+ return -1;
+ }
+
+ if (!ACPI_SUCCESS(acpi_load_namespace())) {
+ printk(KERN_ERR "ACPI: namespace load failed\n");
+ acpi_terminate();
+ return -1;
+ }
+
+ return 0;
+}
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/tables/Makefile linux/drivers/acpi/tables/Makefile
--- v2.4.0-test8/linux/drivers/acpi/tables/Makefile Wed Dec 31 16:00:00 1969
+++ linux/drivers/acpi/tables/Makefile Fri Sep 15 18:21:44 2000

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/tables/tbget.c linux/drivers/acpi/tables/tbget.c
--- v2.4.0-test8/linux/drivers/acpi/tables/tbget.c Wed Jul 5 11:23:13 2000
+++ linux/drivers/acpi/tables/tbget.c Fri Sep 15 14:30:30 2000


@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *

X * Module Name: tbget - ACPI Table get* routines
+ * $Revision: 22 $


X *
X *****************************************************************************/
X

@@ -25,12 +25,12 @@


X
X
X #include "acpi.h"

-#include "hardware.h"
-#include "tables.h"
+#include "achware.h"
+#include "actables.h"
X
X
X #define _COMPONENT TABLE_MANAGER
- MODULE_NAME ("tbget");
+ MODULE_NAME ("tbget")
X
X
X /*******************************************************************************
@@ -90,10 +90,15 @@
X return (AE_NOT_EXIST);
X }
X
- /* Walk the list to get the table */
-
+ /* Walk the list to get the desired table
+ * Since the if (Instance == 1) check above checked for the
+ * first table, setting Table_desc equal to the .Next member
+ * is actually pointing to the second table. Therefore, we
+ * need to walk from the 2nd table until we reach the Instance
+ * that the user is looking for and return its table pointer.
+ */
X table_desc = acpi_gbl_acpi_tables[table_type].next;
- for (i = 1; i < acpi_gbl_acpi_tables[table_type].count; i++) {
+ for (i = 2; i < instance; i++) {
X table_desc = table_desc->next;
X }
X
@@ -110,8 +115,8 @@
X * FUNCTION: Acpi_tb_get_table
X *
X * PARAMETERS: Physical_address - Physical address of table to retrieve
- * *Buffer_ptr - If == NULL, read data from buffer
- * rather than searching memory
+ * *Buffer_ptr - If Buffer_ptr is valid, read data from
+ * buffer rather than searching memory
X * *Table_info - Where the table info is returned


X *
X * RETURN: Status

@@ -123,7 +128,7 @@
X ACPI_STATUS
X acpi_tb_get_table (
X void *physical_address,
- char *buffer_ptr,
+ ACPI_TABLE_HEADER *buffer_ptr,
X ACPI_TABLE_DESC *table_info)
X {
X ACPI_TABLE_HEADER *table_header = NULL;
@@ -143,7 +148,7 @@
X * Getting data from a buffer, not BIOS tables
X */
X
- table_header = (ACPI_TABLE_HEADER *) buffer_ptr;
+ table_header = buffer_ptr;
X status = acpi_tb_validate_table_header (table_header);
X if (ACPI_FAILURE (status)) {
X /* Table failed verification, map all errors to BAD_DATA */


@@ -160,7 +165,7 @@
X

X /* Copy the entire table (including header) to the local buffer */
X
- size = (ACPI_SIZE) table_header->length;
+ size = table_header->length;
X MEMCPY (full_table, buffer_ptr, size);
X
X /* Save allocation type */
@@ -216,7 +221,7 @@
X ACPI_STATUS
X acpi_tb_get_all_tables (
X u32 number_of_tables,
- char *table_ptr)
+ ACPI_TABLE_HEADER *table_ptr)


X {
X ACPI_STATUS status = AE_OK;

X u32 index;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/tables/tbinstal.c linux/drivers/acpi/tables/tbinstal.c
--- v2.4.0-test8/linux/drivers/acpi/tables/tbinstal.c Wed Jul 5 11:23:13 2000
+++ linux/drivers/acpi/tables/tbinstal.c Fri Sep 15 14:30:30 2000


@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *

X * Module Name: tbinstal - ACPI table installation and removal
+ * $Revision: 29 $


X *
X *****************************************************************************/
X

@@ -25,12 +25,12 @@


X
X
X #include "acpi.h"

-#include "hardware.h"
-#include "tables.h"
+#include "achware.h"
+#include "actables.h"
X
X
X #define _COMPONENT TABLE_MANAGER
- MODULE_NAME ("tbinstal");
+ MODULE_NAME ("tbinstal")
X
X
X /*******************************************************************************
@@ -50,11 +50,9 @@
X
X ACPI_STATUS
X acpi_tb_install_table (
- char *table_ptr,
+ ACPI_TABLE_HEADER *table_ptr,
X ACPI_TABLE_DESC *table_info)
X {
- ACPI_TABLE_TYPE table_type;
- ACPI_TABLE_HEADER *table_header;


X ACPI_STATUS status;
X
X

@@ -68,11 +66,6 @@


X return (status);
X }
X

- /* Table type is returned by Recognize_table */
-
- table_type = table_info->type;
- table_header = table_info->pointer;
-
X /* Lock tables while installing */
X
X acpi_cm_acquire_mutex (ACPI_MTX_TABLES);
@@ -80,12 +73,9 @@
X /* Install the table into the global data structure */
X
X status = acpi_tb_init_table_descriptor (table_info->type, table_info);


- if (ACPI_FAILURE (status)) {
- return (status);
- }

X
X acpi_cm_release_mutex (ACPI_MTX_TABLES);
- return (AE_OK);
+ return (status);
X }
X
X
@@ -112,7 +102,7 @@
X
X ACPI_STATUS
X acpi_tb_recognize_table (
- char *table_ptr,
+ ACPI_TABLE_HEADER *table_ptr,
X ACPI_TABLE_DESC *table_info)
X {
X ACPI_TABLE_HEADER *table_header;
@@ -215,9 +205,10 @@
X * the table are allowed. This includes SSDT and PSDTs.
X */
X
- if (acpi_gbl_acpi_table_data[table_type].flags == ACPI_TABLE_SINGLE) {
+ if (IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags)) {
X /*
- * Only one table allowed, just update the list head
+ * Only one table allowed, and a table has alread been installed
+ * at this location, so return an error.
X */
X
X if (list_head->pointer) {
@@ -249,7 +240,7 @@
X /* Update new entry */
X
X table_desc->prev = list_head->prev;
- table_desc->next = (ACPI_TABLE_DESC *) list_head;
+ table_desc->next = list_head;
X
X /* Update list head */
X
@@ -308,7 +299,7 @@
X void
X acpi_tb_delete_acpi_tables (void)
X {
- u32 i;
+ ACPI_TABLE_TYPE type;
X
X
X /*
@@ -316,8 +307,8 @@
X * Memory can either be mapped or allocated
X */
X
- for (i = 0; i < ACPI_TABLE_MAX; i++) {
- acpi_tb_delete_acpi_table (i);
+ for (type = 0; type < ACPI_TABLE_MAX; type++) {
+ acpi_tb_delete_acpi_table (type);
X }
X
X }
@@ -402,6 +393,46 @@


X
X /*******************************************************************************
X *

+ * FUNCTION: Acpi_tb_free_acpi_tables_of_type
+ *
+ * PARAMETERS: Table_info - A table info struct
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Free the memory associated with an internal ACPI table
+ * Table mutex should be locked.


+ *
+ ******************************************************************************/
+

+void
+acpi_tb_free_acpi_tables_of_type (
+ ACPI_TABLE_DESC *list_head)
+{
+ ACPI_TABLE_DESC *table_desc;
+ u32 count;
+ u32 i;
+
+
+ /* Get the head of the list */
+
+ table_desc = list_head;
+ count = list_head->count;
+
+ /*
+ * Walk the entire list, deleting both the allocated tables
+ * and the table descriptors
+ */
+
+ for (i = 0; i < count; i++) {
+ table_desc = acpi_tb_delete_single_table (table_desc);
+ }
+


+ return;
+}
+
+

+/*******************************************************************************
+ *
X * FUNCTION: Acpi_tb_delete_single_table
X *
X * PARAMETERS: Table_info - A table info struct
@@ -488,46 +519,6 @@
X
X
X return (next_desc);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: Acpi_tb_free_acpi_tables_of_type
- *
- * PARAMETERS: Table_info - A table info struct
- *
- * RETURN: None.
- *
- * DESCRIPTION: Free the memory associated with an internal ACPI table
- * Table mutex should be locked.


- *
- ******************************************************************************/
-
-void

-acpi_tb_free_acpi_tables_of_type (
- ACPI_TABLE_DESC *list_head)
-{
- ACPI_TABLE_DESC *table_desc;
- u32 count;
- u32 i;
-
-
- /* Get the head of the list */
-
- table_desc = list_head;
- count = list_head->count;
-
- /*
- * Walk the entire list, deleting both the allocated tables
- * and the table descriptors
- */
-
- for (i = 0; i < count; i++) {
- table_desc = acpi_tb_delete_single_table (table_desc);
- }
-
- return;
X }
X
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/tables/tbtable.c linux/drivers/acpi/tables/tbtable.c
--- v2.4.0-test8/linux/drivers/acpi/tables/tbtable.c Wed Jul 5 11:23:13 2000
+++ linux/drivers/acpi/tables/tbtable.c Fri Sep 15 14:30:30 2000


@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *

X * Module Name: tbtable - ACPI tables: FACP, FACS, and RSDP utilities
+ * $Revision: 24 $


X *
X *****************************************************************************/
X

@@ -25,12 +25,12 @@


X
X
X #include "acpi.h"

-#include "hardware.h"
-#include "tables.h"
+#include "achware.h"
+#include "actables.h"
X
X
X #define _COMPONENT TABLE_MANAGER
- MODULE_NAME ("tbtable");
+ MODULE_NAME ("tbtable")
X
X
X /*******************************************************************************
@@ -38,7 +38,6 @@
X * FUNCTION: Acpi_tb_get_table_rsdt
X *
X * PARAMETERS: Number_of_tables - Where the table count is placed
- * Table_ptr - Input buffer pointer, optional


X *
X * RETURN: Status

X *
@@ -85,15 +84,15 @@
X REPORT_ERROR ("Invalid signature where RSDP indicates RSDT should be located");
X
X }
+ REPORT_ERROR ("Unable to locate RSDT");
+
+ return (status);
X }
X
X
X /* Always delete the RSDP mapping */
X
X acpi_tb_delete_acpi_table (ACPI_TABLE_RSDP);


- if (ACPI_FAILURE (status)) {
- return (status);
- }

X
X /* Save the table pointers and allocation info */
X
@@ -109,10 +108,15 @@
X
X status = acpi_tb_verify_table_checksum ((ACPI_TABLE_HEADER *) acpi_gbl_RSDT);
X
- /* Determine the number of tables pointed to by the RSDT */
+ /*
+ * Determine the number of tables pointed to by the RSDT.
+ * This is defined by the ACPI Specification to be the number of
+ * pointers contained within the RSDT. The size of the pointers
+ * is architecture-dependent.
+ */
X
- *number_of_tables = (s32) DIV_4 (acpi_gbl_RSDT->header.length -
- sizeof (ACPI_TABLE_HEADER));
+ *number_of_tables = ((acpi_gbl_RSDT->header.length -
+ sizeof (ACPI_TABLE_HEADER)) / sizeof (void *));
X
X
X return (status);
@@ -132,13 +136,13 @@


X *
X ******************************************************************************/
X

-char *
+u8 *
X acpi_tb_scan_memory_for_rsdp (
- char *start_address,
+ u8 *start_address,
X u32 length)
X {
X u32 offset;
- char *mem_rover;
+ u8 *mem_rover;
X
X
X /* Search from given start addr for the requested length */
@@ -150,19 +154,19 @@
X
X /* The signature and checksum must both be correct */
X
- if (STRNCMP (mem_rover, RSDP_SIG, sizeof (RSDP_SIG)-1) == 0 &&
+ if (STRNCMP ((NATIVE_CHAR *) mem_rover, RSDP_SIG, sizeof (RSDP_SIG)-1) == 0 &&
X acpi_tb_checksum (mem_rover,
X sizeof (ROOT_SYSTEM_DESCRIPTOR_POINTER)) == 0)
X {
X /* If so, we have found the RSDP */
X
- return mem_rover;
+ return (mem_rover);
X }
X }
X
X /* Searched entire block, no RSDP was found */


X
- return NULL;
+ return (NULL);
X }
X
X

@@ -189,8 +193,8 @@
X acpi_tb_find_rsdp (
X ACPI_TABLE_DESC *table_info)
X {
- char *table_ptr;
- char *mem_rover;
+ u8 *table_ptr;
+ u8 *mem_rover;


X ACPI_STATUS status = AE_OK;
X

X if (acpi_gbl_acpi_init_data.RSDP_physical_address) {
@@ -214,9 +218,9 @@
X * The signature and checksum must both be correct
X */
X
- if (STRNCMP (table_ptr, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
+ if (STRNCMP ((NATIVE_CHAR *) table_ptr, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
X /* Nope, BAD Signature */
-
+ acpi_os_unmap_memory (table_ptr, sizeof (ROOT_SYSTEM_DESCRIPTOR_POINTER));
X return (AE_BAD_SIGNATURE);
X }
X
@@ -226,7 +230,7 @@
X sizeof (ROOT_SYSTEM_DESCRIPTOR_POINTER)) != 0)
X {
X /* Nope, BAD Checksum */
-
+ acpi_os_unmap_memory (table_ptr, sizeof (ROOT_SYSTEM_DESCRIPTOR_POINTER));
X return (AE_BAD_CHECKSUM);
X }
X
@@ -309,12 +313,12 @@
X }
X
X
-/*******************************************************************************
+/******************************************************************************
X *
X * FUNCTION: Acpi_tb_get_table_facs
X *
- * PARAMETERS: *Buffer_ptr - If == NULL, read data from buffer
- * rather than searching memory
+ * PARAMETERS: *Buffer_ptr - If Buffer_ptr is valid, read data from
+ * buffer rather than searching memory
X * *Table_info - Where the table info is returned


X *
X * RETURN: Status

@@ -324,11 +328,11 @@
X * correctly initialized. The value of FACP->Firmware_ctrl
X * into a far pointer which is returned.
X *
- ******************************************************************************/
+ *****************************************************************************/
X
X ACPI_STATUS
X acpi_tb_get_table_facs (
- char *buffer_ptr,
+ ACPI_TABLE_HEADER *buffer_ptr,
X ACPI_TABLE_DESC *table_info)
X {
X void *table_ptr = NULL;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/tables/tbutils.c linux/drivers/acpi/tables/tbutils.c
--- v2.4.0-test8/linux/drivers/acpi/tables/tbutils.c Wed Jul 5 11:23:13 2000
+++ linux/drivers/acpi/tables/tbutils.c Fri Sep 15 14:30:30 2000


@@ -1,7 +1,7 @@
-
X /******************************************************************************
X *

X * Module Name: tbutils - Table manipulation utilities
+ * $Revision: 26 $


X *
X *****************************************************************************/
X

@@ -25,23 +25,24 @@


X
X
X #include "acpi.h"

-#include "tables.h"
-#include "interp.h"
+#include "actables.h"
+#include "acinterp.h"
X
X
X #define _COMPONENT TABLE_MANAGER
- MODULE_NAME ("tbutils");
+ MODULE_NAME ("tbutils")
X
X
X /*******************************************************************************
X *
- * FUNCTION: Acpi_tb_system_table_pointer
+ * FUNCTION: Acpi_tb_handle_to_object
X *
- * PARAMETERS: *Where - Pointer to be examined
+ * PARAMETERS: Table_id - Id for which the function is searching
+ * Table_desc - Pointer to return the matching table
+ * descriptor.
X *
- * RETURN: TRUE if Where is within the AML stream (in one of the ACPI
- * system tables such as the DSDT or an SSDT.)
- * FALSE otherwise
+ * RETURN: Search the tables to find one with a matching Table_id and
+ * return a pointer to that table descriptor.


X *
X ******************************************************************************/
X

@@ -60,7 +61,7 @@
X {
X if (list_head->table_id == table_id) {
X *table_desc = list_head;
- return AE_OK;


+ return (AE_OK);
X }
X

X list_head = list_head->next;
@@ -69,7 +70,7 @@
X }
X
X

- return AE_BAD_PARAMETER;
+ return (AE_BAD_PARAMETER);
X }
X
X

@@ -177,7 +178,7 @@
X /* Verify that this is a valid address */
X
X if (!acpi_os_readable (table_header, sizeof (ACPI_TABLE_HEADER))) {
- return AE_BAD_ADDRESS;
+ return (AE_BAD_ADDRESS);
X }


X
X
@@ -186,7 +187,7 @@

X MOVE_UNALIGNED32_TO_32 (&signature, &table_header->signature);
X if (!acpi_cm_valid_acpi_name (signature)) {
X REPORT_WARNING ("Invalid table signature found");
- return AE_BAD_SIGNATURE;
+ return (AE_BAD_SIGNATURE);
X }
X
X
@@ -194,10 +195,10 @@
X
X if (table_header->length < sizeof (ACPI_TABLE_HEADER)) {
X REPORT_WARNING ("Invalid table header length found");
- return AE_BAD_HEADER;
+ return (AE_BAD_HEADER);


X }
X
- return AE_OK;

+ return (AE_OK);
X }
X

X
@@ -236,7 +237,7 @@
X status = acpi_os_map_memory (physical_address, sizeof (ACPI_TABLE_HEADER),
X (void **) &table);
X if (ACPI_FAILURE (status)) {
- return status;
+ return (status);
X }
X
X /* Extract the full table length before we delete the mapping */
@@ -257,7 +258,7 @@
X /* Exit if header invalid */
X
X if (ACPI_FAILURE (status)) {
- return status;
+ return (status);
X }
X }
X
@@ -266,13 +267,13 @@
X
X status = acpi_os_map_memory (physical_address, table_size, (void **) &table);
X if (ACPI_FAILURE (status)) {
- return status;
+ return (status);
X }
X
X *size = table_size;
X *logical_address = table;
X
- return status;
+ return (status);
X }
X
X
@@ -346,7 +347,7 @@
X }
X }
X
- return sum;
+ return (sum);
X }
X
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/tables/tbxface.c linux/drivers/acpi/tables/tbxface.c
--- v2.4.0-test8/linux/drivers/acpi/tables/tbxface.c Wed Jul 5 11:23:13 2000
+++ linux/drivers/acpi/tables/tbxface.c Fri Sep 15 14:30:30 2000
@@ -1,8 +1,8 @@


-
X /******************************************************************************
X *

X * Module Name: tbxface - Public interfaces to the ACPI subsystem
X * ACPI table oriented interfaces
+ * $Revision: 24 $


X *
X *****************************************************************************/
X

@@ -26,13 +26,13 @@


X
X
X #include "acpi.h"
-#include "namesp.h"

-#include "interp.h"
-#include "tables.h"
+#include "acnamesp.h"
+#include "acinterp.h"
+#include "actables.h"

X
X
X #define _COMPONENT TABLE_MANAGER
- MODULE_NAME ("tbxface");
+ MODULE_NAME ("tbxface")
X
X
X /*******************************************************************************
@@ -57,7 +57,7 @@
X /* Get the RSDT first */
X
X status = acpi_tb_get_table_rsdt (&number_of_tables);


- if (status != AE_OK) {
+ if (ACPI_FAILURE (status)) {

X goto error_exit;
X }
X
@@ -65,7 +65,7 @@
X /* Now get the rest of the tables */
X
X status = acpi_tb_get_all_tables (number_of_tables, NULL);


- if (status != AE_OK) {
+ if (ACPI_FAILURE (status)) {

X goto error_exit;
X }
X
@@ -105,12 +105,12 @@
X
X
X if (!table_ptr) {


- return AE_BAD_PARAMETER;
+ return (AE_BAD_PARAMETER);
X }
X

X /* Copy the table to a local buffer */
X
- status = acpi_tb_get_table (NULL, ((char *) table_ptr), &table_info);
+ status = acpi_tb_get_table (NULL, table_ptr, &table_info);


X if (ACPI_FAILURE (status)) {
X return (status);
X }

@@ -157,7 +157,12 @@
X list_head = &acpi_gbl_acpi_tables[table_type];
X do
X {
- /* Delete the entire namespace under this table NTE */
+ /*
+ * Delete all namespace entries owned by this table. Note that these
+ * entries can appear anywhere in the namespace by virtue of the AML
+ * "Scope" operator. Thus, we need to track ownership by an ID, not
+ * simply a position within the hierarchy
+ */
X
X acpi_ns_delete_namespace_by_owner (list_head->table_id);
X
@@ -205,8 +210,6 @@


X ACPI_STATUS status;
X
X

- status = AE_OK;
-
X if ((instance == 0) ||
X (table_type == ACPI_TABLE_RSDP) ||
X (!out_table_header))
@@ -217,7 +220,7 @@
X /* Check the table type and instance */
X
X if ((table_type > ACPI_TABLE_MAX) ||
- (acpi_gbl_acpi_table_data[table_type].flags == ACPI_TABLE_SINGLE &&
+ (IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags) &&
X instance > 1))
X {
X return (AE_BAD_PARAMETER);
@@ -227,7 +230,7 @@
X /* Get a pointer to the entire table */
X
X status = acpi_tb_get_table_ptr (table_type, instance, &tbl_ptr);


- if (status != AE_OK) {
+ if (ACPI_FAILURE (status)) {
X return (status);
X }
X

@@ -285,8 +288,6 @@
X u32 ret_buf_len;
X
X
- status = AE_OK;
-
X /*
X * Must have a buffer
X */
@@ -301,7 +302,7 @@
X /* Check the table type and instance */
X
X if ((table_type > ACPI_TABLE_MAX) ||
- (acpi_gbl_acpi_table_data[table_type].flags == ACPI_TABLE_SINGLE &&
+ (IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags) &&
X instance > 1))
X {
X return (AE_BAD_PARAMETER);
@@ -311,12 +312,13 @@
X /* Get a pointer to the entire table */
X
X status = acpi_tb_get_table_ptr (table_type, instance, &tbl_ptr);


- if (status != AE_OK) {
+ if (ACPI_FAILURE (status)) {
X return (status);
X }
X

X /*
- * The function will return a NULL pointer if the table is not loaded
+ * Acpi_tb_get_table_ptr will return a NULL pointer if the
+ * table is not loaded.
X */
X if (tbl_ptr == NULL) {
X return (AE_NOT_EXIST);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/acpi/tables.c linux/drivers/acpi/tables.c
--- v2.4.0-test8/linux/drivers/acpi/tables.c Thu Jul 13 09:39:49 2000
+++ linux/drivers/acpi/tables.c Wed Dec 31 16:00:00 1969
@@ -1,303 +0,0 @@
-/*
- * tables.c - ACPI tables, chipset, and errata handling
- *
- * Copyright (C) 2000 Andrew Henroid
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/pm.h>
-#include <linux/acpi.h>
-#include "acpi.h"
-#include "driver.h"
-
-struct acpi_facp acpi_facp;
-
-#define ACPI_DUMMY_CHECKSUM 9
-#define ACPI_DUMMY_PBLK 51
-
-static u8 acpi_dummy_dsdt[] =
-{
- 0x44, 0x53, 0x44, 0x54, // "DSDT"
- 0x38, 0x00, 0x00, 0x00, // length
- 0x01, // revision
- 0x00, // checksum
- 0x4c, 0x49, 0x4e, 0x55, 0x58, 0x00, // "LINUX"
- 0x44, 0x55, 0x4d, 0x4d, 0x59, 0x00, 0x00, 0x00, // "DUMMY"
- 0x01, 0x00, 0x00, 0x00, // OEM rev
- 0x4c, 0x4e, 0x55, 0x58, // "LNUX"
- 0x01, 0x00, 0x00, 0x00, // creator rev
- 0x10, // Scope
- 0x13, // PkgLength
- 0x5c, 0x5f, 0x50, 0x52, 0x5f, // \_PR_
- 0x5b, 0x83, // Processor
- 0x0b, // PkgLength
- 0x43, 0x50, 0x55, 0x30, // CPU0
- 0x00, // ID
- 0x00, 0x00, 0x00, 0x00, // PBLK
- 0x06 // PBLK size
-};
-
-/*
- * Calculate and set ACPI table checksum
- */
-static void
-acpi_set_checksum(u8 *table, int size)
-{
- int i, sum = 0;
- for (i = 0; i < size; i++)
- sum += (int) table[i];
- sum = (0x100 - ((sum - table[ACPI_DUMMY_CHECKSUM]) & 0xff));
- table[ACPI_DUMMY_CHECKSUM] = sum;
-}
-
-/*
- * Init PIIX4 device, create a fake FACP
- */
-static int
-acpi_init_piix4(struct pci_dev *dev)
-{
- u32 base, pblk;
- u16 cmd;
- u8 pmregmisc;
-
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- if (!(cmd & PCI_COMMAND_IO))
- return -ENODEV;
-
- pci_read_config_byte(dev, ACPI_PIIX4_PMREGMISC, &pmregmisc);
- if (!(pmregmisc & ACPI_PIIX4_PMIOSE))
- return -ENODEV;
-
- base = pci_resource_start (dev, PCI_BRIDGE_RESOURCES);
- if (!base)
- return -ENODEV;
-
- printk(KERN_INFO "ACPI: found \"%s\" at 0x%04x\n", dev->name, base);
-
- memset(&acpi_facp, 0, sizeof(acpi_facp));
- acpi_facp.hdr.signature = ACPI_FACP_SIG;
- acpi_facp.hdr.length = sizeof(acpi_facp);
- acpi_facp.int_model = ACPI_PIIX4_INT_MODEL;
- acpi_facp.sci_int = ACPI_PIIX4_SCI_INT;
- acpi_facp.smi_cmd = ACPI_PIIX4_SMI_CMD;
- acpi_facp.acpi_enable = ACPI_PIIX4_ACPI_ENABLE;
- acpi_facp.acpi_disable = ACPI_PIIX4_ACPI_DISABLE;
- acpi_facp.s4bios_req = ACPI_PIIX4_S4BIOS_REQ;
- acpi_facp.pm1a_evt = base + ACPI_PIIX4_PM1_EVT;
- acpi_facp.pm1a_cnt = base + ACPI_PIIX4_PM1_CNT;
- acpi_facp.pm2_cnt = ACPI_PIIX4_PM2_CNT;
- acpi_facp.pm_tmr = base + ACPI_PIIX4_PM_TMR;
- acpi_facp.gpe0 = base + ACPI_PIIX4_GPE0;
- acpi_facp.pm1_evt_len = ACPI_PIIX4_PM1_EVT_LEN;
- acpi_facp.pm1_cnt_len = ACPI_PIIX4_PM1_CNT_LEN;
- acpi_facp.pm2_cnt_len = ACPI_PIIX4_PM2_CNT_LEN;
- acpi_facp.pm_tm_len = ACPI_PIIX4_PM_TM_LEN;
- acpi_facp.gpe0_len = ACPI_PIIX4_GPE0_LEN;
- acpi_facp.p_lvl2_lat = (__u16) ACPI_INFINITE_LAT;
- acpi_facp.p_lvl3_lat = (__u16) ACPI_INFINITE_LAT;
-
- acpi_set_checksum((u8*) &acpi_facp, sizeof(acpi_facp));
- acpi_load_table((ACPI_TABLE_HEADER*) &acpi_facp);
-
- pblk = base + ACPI_PIIX4_P_BLK;
- memcpy(acpi_dummy_dsdt + ACPI_DUMMY_PBLK, &pblk, sizeof(pblk));
- acpi_set_checksum(acpi_dummy_dsdt, sizeof(acpi_dummy_dsdt));
- acpi_load_table((ACPI_TABLE_HEADER*) acpi_dummy_dsdt);
-
- return 0;
-}
-
-/*
- * Init VIA ACPI device and create a fake FACP
- */
-static int
-acpi_init_via(struct pci_dev *dev)
-{
- u32 base, pblk;
- u8 tmp, irq;
-
- pci_read_config_byte(dev, 0x41, &tmp);
- if (!(tmp & 0x80))
- return -ENODEV;
-
- base = pci_resource_start(dev, PCI_BRIDGE_RESOURCES);
- if (!base) {
- base = pci_resource_start(dev, PCI_BASE_ADDRESS_4);
- if (!base)
- return -ENODEV;
- }
-
- pci_read_config_byte(dev, 0x42, &irq);
-
- printk(KERN_INFO "ACPI: found \"%s\" at 0x%04x\n", dev->name, base);
-
- memset(&acpi_facp, 0, sizeof(acpi_facp));
- acpi_facp.hdr.signature = ACPI_FACP_SIG;
- acpi_facp.hdr.length = sizeof(acpi_facp);
- acpi_facp.int_model = ACPI_VIA_INT_MODEL;
- acpi_facp.sci_int = irq;
- acpi_facp.smi_cmd = base + ACPI_VIA_SMI_CMD;
- acpi_facp.acpi_enable = ACPI_VIA_ACPI_ENABLE;
- acpi_facp.acpi_disable = ACPI_VIA_ACPI_DISABLE;
- acpi_facp.pm1a_evt = base + ACPI_VIA_PM1_EVT;
- acpi_facp.pm1a_cnt = base + ACPI_VIA_PM1_CNT;
- acpi_facp.pm_tmr = base + ACPI_VIA_PM_TMR;
- acpi_facp.gpe0 = base + ACPI_VIA_GPE0;
-
- acpi_facp.pm1_evt_len = ACPI_VIA_PM1_EVT_LEN;
- acpi_facp.pm1_cnt_len = ACPI_VIA_PM1_CNT_LEN;
- acpi_facp.pm_tm_len = ACPI_VIA_PM_TM_LEN;
- acpi_facp.gpe0_len = ACPI_VIA_GPE0_LEN;
- acpi_facp.p_lvl2_lat = (__u16) ACPI_INFINITE_LAT;
- acpi_facp.p_lvl3_lat = (__u16) ACPI_INFINITE_LAT;
-
- acpi_facp.duty_offset = ACPI_VIA_DUTY_OFFSET;
- acpi_facp.duty_width = ACPI_VIA_DUTY_WIDTH;
-
- acpi_facp.day_alarm = ACPI_VIA_DAY_ALARM;
- acpi_facp.mon_alarm = ACPI_VIA_MON_ALARM;
- acpi_facp.century = ACPI_VIA_CENTURY;
-
- acpi_set_checksum((u8*) &acpi_facp, sizeof(acpi_facp));
- acpi_load_table((ACPI_TABLE_HEADER*) &acpi_facp);
-
- pblk = base + ACPI_VIA_P_BLK;
- memcpy(acpi_dummy_dsdt + ACPI_DUMMY_PBLK, &pblk, sizeof(pblk));
- acpi_set_checksum(acpi_dummy_dsdt, sizeof(acpi_dummy_dsdt));
- acpi_load_table((ACPI_TABLE_HEADER*) acpi_dummy_dsdt);
-
- return 0;


-}
-
-typedef enum
-{

- CH_UNKNOWN = 0,
- CH_INTEL_PIIX4,
- CH_VIA_586,
- CH_VIA_686A,
-} acpi_chip_t;
-
-/* indexed by value of each enum in acpi_chip_t */
-const static struct
-{
- int (*chip_init)(struct pci_dev *dev);
-} acpi_chip_info[] =
-{
- {NULL,},
- {acpi_init_piix4},
- {acpi_init_via},
- {acpi_init_via},
-};
-
-static struct pci_device_id acpi_pci_tbl[] =
-{
- {0x8086, 0x7113, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_INTEL_PIIX4},
- {0x1106, 0x3040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_VIA_586},
- {0x1106, 0x3057, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_VIA_686A},
- {0,} /* terminate list */
-};
-
-static int
-acpi_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
- return acpi_chip_info[id->driver_data].chip_init(dev);
-}
-
-static struct pci_driver acpi_driver =
-{
- name: "acpi",
- id_table: acpi_pci_tbl,
- probe: acpi_probe,
-};
-static int acpi_driver_registered = 0;
-
-/*
- * Locate a known ACPI chipset
- */
-static int
-acpi_find_chipset(void)
-{
- if (pci_register_driver(&acpi_driver) < 1)
- return -ENODEV;
- acpi_driver_registered = 1;
- return 0;
-}
-
-/*
- * Fetch the FACP information
- */
-static int
-acpi_fetch_facp(void)
-{
- ACPI_BUFFER buffer;
-
- memset(&acpi_facp, 0, sizeof(acpi_facp));
- buffer.pointer = &acpi_facp;
- buffer.length = sizeof(acpi_facp);
- if (!ACPI_SUCCESS(acpi_get_table(ACPI_TABLE_FACP, 1, &buffer))) {
- printk(KERN_ERR "ACPI: missing FACP\n");
- return -ENODEV;
- }
-
- if (acpi_facp.p_lvl2_lat
- && acpi_facp.p_lvl2_lat <= ACPI_MAX_P_LVL2_LAT) {
- acpi_c2_exit_latency
- = ACPI_uS_TO_TMR_TICKS(acpi_facp.p_lvl2_lat);
- acpi_c2_enter_latency
- = ACPI_uS_TO_TMR_TICKS(ACPI_TMR_HZ / 1000);
- }
- if (acpi_facp.p_lvl3_lat
- && acpi_facp.p_lvl3_lat <= ACPI_MAX_P_LVL3_LAT) {
- acpi_c3_exit_latency
- = ACPI_uS_TO_TMR_TICKS(acpi_facp.p_lvl3_lat);
- acpi_c3_enter_latency
- = ACPI_uS_TO_TMR_TICKS(acpi_facp.p_lvl3_lat * 5);
- }
-
- return 0;
-}
-
-/*
- * Find and load ACPI tables
- */
-int
-acpi_load_tables(void)
-{
- if (ACPI_SUCCESS(acpi_load_firmware_tables()))
- {
- printk(KERN_INFO "ACPI: support found\n");
- }
- else if (acpi_find_chipset()) {
- acpi_terminate();
- return -1;
- }
-
- if (acpi_fetch_facp()) {
- acpi_terminate();
- return -1;
- }
-
- if (!ACPI_SUCCESS(acpi_load_namespace())) {
- printk(KERN_ERR "ACPI: namespace load failed\n");
- acpi_terminate();
- return -1;
- }
-
- return 0;
-}
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/block/Config.in linux/drivers/block/Config.in
--- v2.4.0-test8/linux/drivers/block/Config.in Tue Jul 25 18:23:48 2000
+++ linux/drivers/block/Config.in Fri Sep 22 17:11:37 2000
@@ -34,25 +34,12 @@
X source drivers/block/paride/Config.in
X fi
X dep_tristate 'Compaq SMART2 support' CONFIG_BLK_CPQ_DA $CONFIG_PCI
+dep_tristate 'Compaq CISS Array support' CONFIG_BLK_CPQ_CISS_DA $CONFIG_PCI
X dep_tristate 'Mylex DAC960/DAC1100 PCI RAID Controller support' CONFIG_BLK_DEV_DAC960 $CONFIG_PCI
X
X tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
X dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET
X
-tristate 'Logical volume manager (LVM) support' CONFIG_BLK_DEV_LVM N
-if [ "$CONFIG_BLK_DEV_LVM" != "n" ]; then
- bool ' LVM information in proc filesystem' CONFIG_LVM_PROC_FS Y
-fi
-


-tristate 'Multiple devices driver support' CONFIG_BLK_DEV_MD
-dep_tristate ' Linear (append) mode' CONFIG_MD_LINEAR $CONFIG_BLK_DEV_MD
-dep_tristate ' RAID-0 (striping) mode' CONFIG_MD_RAID0 $CONFIG_BLK_DEV_MD
-dep_tristate ' RAID-1 (mirroring) mode' CONFIG_MD_RAID1 $CONFIG_BLK_DEV_MD

-dep_tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5 $CONFIG_BLK_DEV_MD
-if [ "$CONFIG_MD_LINEAR" = "y" -o "$CONFIG_MD_RAID0" = "y" -o "$CONFIG_MD_RAID1" = "y" -o "$CONFIG_MD_RAID5" = "y" ]; then
- bool ' Boot support' CONFIG_MD_BOOT
- bool ' Auto Detect support' CONFIG_AUTODETECT_RAID
-fi


X tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
X if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then

X int ' Default RAM disk size' CONFIG_BLK_DEV_RAM_SIZE 4096
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/block/Makefile linux/drivers/block/Makefile
--- v2.4.0-test8/linux/drivers/block/Makefile Sun Aug 6 11:23:40 2000
+++ linux/drivers/block/Makefile Fri Sep 22 17:11:37 2000
@@ -14,9 +14,7 @@
X
X O_TARGET := block.o
X
-export-objs := ll_rw_blk.o blkpg.o loop.o DAC960.o md.o xor.o
-list-multi := lvm-mod.o
-lvm-mod-objs := lvm.o lvm-snap.o
+export-objs := ll_rw_blk.o blkpg.o loop.o DAC960.o
X
X obj-y := ll_rw_blk.o blkpg.o genhd.o elevator.o
X
@@ -33,14 +31,8 @@
X obj-$(CONFIG_BLK_DEV_PS2) += ps2esdi.o
X obj-$(CONFIG_BLK_DEV_XD) += xd.o
X obj-$(CONFIG_BLK_CPQ_DA) += cpqarray.o
+obj-$(CONFIG_BLK_CPQ_CISS_DA) += cciss.o
X obj-$(CONFIG_BLK_DEV_DAC960) += DAC960.o
-obj-$(CONFIG_BLK_DEV_LVM) += lvm-mod.o
-
-obj-$(CONFIG_BLK_DEV_MD) += md.o
-obj-$(CONFIG_MD_LINEAR) += linear.o
-obj-$(CONFIG_MD_RAID0) += raid0.o
-obj-$(CONFIG_MD_RAID1) += raid1.o
-obj-$(CONFIG_MD_RAID5) += raid5.o xor.o
X
X obj-$(CONFIG_BLK_DEV_NBD) += nbd.o
X
@@ -71,6 +63,3 @@
X MX_OBJS := $(sort $(filter $(export-objs), $(obj-m)))
X
X include $(TOPDIR)/Rules.make
-
-lvm-mod.o: $(lvm-mod-objs)
- $(LD) -r -o $@ $(lvm-mod-objs)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/block/amiflop.c linux/drivers/block/amiflop.c
--- v2.4.0-test8/linux/drivers/block/amiflop.c Tue Jun 20 07:24:52 2000
+++ linux/drivers/block/amiflop.c Sun Oct 1 20:35:15 2000
@@ -140,7 +140,7 @@
X
X /* defaults for 3 1/2" HD-Disks */
X static int floppy_sizes[256]={880,880,880,880,720,720,720,720,};


-static int floppy_blocksizes[256]={0,};
+static int floppy_blocksizes[256];

X /* hardsector size assumed to be 512 */
X
X static int amiga_read(int), dos_read(int);
@@ -151,7 +151,7 @@
X };
X

X /* current info on each unit */

-static struct amiga_floppy_struct unit[FD_MAX_UNITS] = {{ 0,}};
+static struct amiga_floppy_struct unit[FD_MAX_UNITS];
X
X static struct timer_list flush_track_timer[FD_MAX_UNITS];
X static struct timer_list post_write_timer;
@@ -162,15 +162,15 @@
X /* Synchronization of FDC access */
X /* request loop (trackbuffer) */
X static volatile int fdc_busy = -1;
-static volatile int fdc_nested = 0;
+static volatile int fdc_nested;
X static DECLARE_WAIT_QUEUE_HEAD(fdc_wait);
X
X static DECLARE_WAIT_QUEUE_HEAD(motor_wait);
X
X static volatile int selected = -1; /* currently selected drive */
X
-static int writepending = 0;
-static int writefromint = 0;
+static int writepending;
+static int writefromint;
X static char *raw_buf;
X
X #define RAW_BUF_SIZE 30000 /* size of raw disk data */
@@ -180,7 +180,7 @@
X * information to interrupts. They are the data used for the current
X * request.
X */
-static volatile char block_flag = 0;
+static volatile char block_flag;
X static DECLARE_WAIT_QUEUE_HEAD(wait_fd_block);
X
X /* MS-Dos MFM Coding tables (should go quick and easy) */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/block/cciss.c linux/drivers/block/cciss.c
--- v2.4.0-test8/linux/drivers/block/cciss.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/block/cciss.c Wed Sep 27 13:39:23 2000
@@ -0,0 +1,1917 @@
+/*
+ * Disk Array driver for Compaq SMART2 Controllers
+ * Copyright 2000 Compaq Computer Corporation


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for more details.


+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software

+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Questions/Comments/Bugfixes to arr...@compaq.com
+ *
+ */
+
+#include <linux/config.h> /* CONFIG_PROC_FS */
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/malloc.h>
+#include <linux/delay.h>
+#include <linux/major.h>
+#include <linux/fs.h>
+#include <linux/blkpg.h>
+#include <linux/timer.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/hdreg.h>
+#include <linux/spinlock.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#include <linux/blk.h>
+#include <linux/blkdev.h>
+#include <linux/genhd.h>
+
+#define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
+#define DRIVER_NAME "Compaq CISS Driver (v 2.4.0)"
+#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,4,0)
+
+/* Embedded module documentation macros - see modules.h */
+MODULE_AUTHOR("Charles M. White III - Compaq Computer Corporation");
+MODULE_DESCRIPTION("Driver for Compaq Smart Array Controller 5300");
+
+#include "cciss_cmd.h"
+#include "cciss.h"
+#include <linux/cciss_ioctl.h>
+
+#define NR_PRODUCTS (sizeof(products)/sizeof(struct board_type))
+
+/* board_id = Subsystem Device ID & Vendor ID
+ * product = Marketing Name for the board
+ * access = Address of the struct of function pointers
+ */
+static struct board_type products[] = {
+ { 0x40700E11, "Smart Array 5300", &SA5_access },
+};
+
+/* How long to wait (in millesconds) for board to go into simple mode */
+#define MAX_CONFIG_WAIT 1000
+
+#define READ_AHEAD 128
+#define NR_CMDS 128 /* #commands that can be outstanding */
+#define MAX_CTLR 8
+static int nr_ctlr =0;
+static ctlr_info_t *hba[MAX_CTLR] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+static struct proc_dir_entry *proc_cciss = NULL;
+
+static void do_cciss_request(int i);
+/*
+ * This is a hack. This driver eats a major number for each controller, and
+ * sets blkdev[xxx].request_fn to each one of these so the real request
+ * function knows what controller its working with.
+ */
+#define DO_CCISS_REQUEST(x) { do_cciss_request(x); }
+
+static void do_cciss_request0(request_queue_t * q) DO_CCISS_REQUEST(0);
+static void do_cciss_request1(request_queue_t * q) DO_CCISS_REQUEST(1);
+static void do_cciss_request2(request_queue_t * q) DO_CCISS_REQUEST(2);
+static void do_cciss_request3(request_queue_t * q) DO_CCISS_REQUEST(3);
+static void do_cciss_request4(request_queue_t * q) DO_CCISS_REQUEST(4);
+static void do_cciss_request5(request_queue_t * q) DO_CCISS_REQUEST(5);
+static void do_cciss_request6(request_queue_t * q) DO_CCISS_REQUEST(6);
+static void do_cciss_request7(request_queue_t * q) DO_CCISS_REQUEST(7);
+
+static int cciss_open(struct inode *inode, struct file *filep);
+static int cciss_release(struct inode *inode, struct file *filep);
+static int cciss_ioctl(struct inode *inode, struct file *filep,
+ unsigned int cmd, unsigned long arg);
+
+static int revalidate_allvol(kdev_t dev);
+static int revalidate_logvol(kdev_t dev, int maxusage);
+static int frevalidate_logvol(kdev_t dev);
+
+static void cciss_getgeometry(int cntl_num);
+
+static inline void addQ(CommandList_struct **Qptr, CommandList_struct *c);
+static void start_io( ctlr_info_t *h);
+
+#ifdef CONFIG_PROC_FS
+static int cciss_proc_get_info(char *buffer, char **start, off_t offset,
+ int length, int *eof, void *data);
+static void cciss_procinit(int i);
+#else
+static int cciss_proc_get_info(char *buffer, char **start, off_t offset,
+ int length, int *eof, void *data) {}
+static void cciss_procinit(int i) {}
+#endif /* CONFIG_PROC_FS */
+
+static struct block_device_operations cciss_fops = {
+ open: cciss_open,
+ release: cciss_release,
+ ioctl: cciss_ioctl,
+ revalidate: frevalidate_logvol,
+};
+
+/*
+ * Report information about this controller.
+ */
+#ifdef CONFIG_PROC_FS
+static int cciss_proc_get_info(char *buffer, char **start, off_t offset,
+ int length, int *eof, void *data)
+{
+ off_t pos = 0;
+ off_t len = 0;
+ int size, i, ctlr;
+ ctlr_info_t *h = (ctlr_info_t*)data;
+ drive_info_struct *drv;
+
+ ctlr = h->ctlr;
+ size = sprintf(buffer, "%s: Compaq %s Controller\n"
+ " Board ID: %08lx\n"
+ " Firmware Version: %c%c%c%c\n"
+ " Memory Address: %08lx\n"
+ " IRQ: 0x%x\n"
+ " Logical drives: %d\n"
+ " Current Q depth: %d\n"
+ " Current # commands on controller %d\n"
+ " Max Q depth since init: %d\n"
+ " Max # commands on controller since init: %d\n"
+ " Max SG entries since init: %d\n\n",
+ h->devname,
+ h->product_name,
+ (unsigned long)h->board_id,
+ h->firm_ver[0], h->firm_ver[1], h->firm_ver[2], h->firm_ver[3],
+ (unsigned long)h->vaddr,
+ (unsigned int)h->intr,
+ h->num_luns,
+ h->Qdepth, h->commands_outstanding,
+ h->maxQsinceinit, h->max_outstanding, h->maxSG);
+
+ pos += size; len += size;
+ for(i=0; i<h->num_luns; i++) {
+ drv = &h->drv[i];
+ size = sprintf(buffer+len, "cciss/c%dd%d: blksz=%d nr_blocks=%d\n",
+ ctlr, i, drv->block_size, drv->nr_blocks);
+ pos += size; len += size;
+ }
+
+ size = sprintf(buffer+len, "nr_allocs = %d\nnr_frees = %d\n",
+ h->nr_allocs, h->nr_frees);
+ pos += size; len += size;
+
+ *eof = 1;
+ *start = buffer+offset;
+ len -= offset;
+ if (len>length)
+ len = length;
+ return len;
+}
+
+/*
+ * Get us a file in /proc/cciss that says something about each controller.
+ * Create /proc/cciss if it doesn't exist yet.
+ */
+static void __init cciss_procinit(int i)
+{
+ if (proc_cciss == NULL) {
+ proc_cciss = proc_mkdir("driver/cciss", NULL);
+ if (!proc_cciss)
+ return;
+ }
+
+ create_proc_read_entry(hba[i]->devname, 0, proc_cciss,
+ cciss_proc_get_info, hba[i]);
+}
+#endif /* CONFIG_PROC_FS */
+
+/*
+ * For operations that cannot sleep, a command block is allocated at init,
+ * and managed by cmd_alloc() and cmd_free() using a simple bitmap to track
+ * which ones are free or in use. For operations that can wait for kmalloc
+ * to possible sleep, this routine can be called with a NULL pointer.
+ * cmd_free() MUST be called with a NULL pointer if cmd_alloc was.
+ */
+static CommandList_struct * cmd_alloc(ctlr_info_t *h)
+{
+ CommandList_struct *c;
+ int i;
+ u64bit temp64;
+
+ if (h == NULL)
+ {
+ c = (CommandList_struct *)kmalloc(sizeof(CommandList_struct),
+ GFP_KERNEL);
+ if(c==NULL)
+ return NULL;
+ memset(c, 0, sizeof(CommandList_struct));
+
+ c->err_info = (ErrorInfo_struct *)kmalloc(
+ sizeof(ErrorInfo_struct), GFP_KERNEL);
+
+ if (c->err_info == NULL)
+ {
+ kfree(c);
+ return NULL;
+ }
+ memset(c->err_info, 0, sizeof(ErrorInfo_struct));
+ } else /* get it out of the controllers pool */
+ {
+ do {
+ i = find_first_zero_bit(h->cmd_pool_bits, NR_CMDS);
+ if (i == NR_CMDS)
+ return NULL;
+ } while(test_and_set_bit(i%32, h->cmd_pool_bits+(i/32)) != 0);


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 038'
echo 'File patch-2.4.0-test9 is continued in part 039'
echo "039" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part039

#!/bin/sh -x
# this is part 039 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 039; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+#ifdef CCISS_DEBUG
+ printk(KERN_DEBUG "cciss: using command buffer %d\n", i);
+#endif
+ c = h->cmd_pool + i;
+ memset(c, 0, sizeof(CommandList_struct));
+ c->err_info = h->errinfo_pool + i;


+ memset(c->err_info, 0, sizeof(ErrorInfo_struct));

+ h->nr_allocs++;
+ }
+
+
+ temp64.val = (__u64) virt_to_bus(c->err_info);
+ c->ErrDesc.Addr.lower = temp64.val32.lower;
+ c->ErrDesc.Addr.upper = temp64.val32.upper;
+ c->ErrDesc.Len = sizeof(ErrorInfo_struct);
+ c->busaddr = virt_to_bus(c);
+ return c;
+
+
+}
+
+/*
+ * Frees a command block that was previously allocated with cmd_alloc().
+ */
+static void cmd_free(ctlr_info_t *h, CommandList_struct *c)
+{
+ int i;


+
+ if( h == NULL)
+ {

+ kfree(c->err_info);
+ kfree(c);
+ } else
+ {
+ i = c - h->cmd_pool;
+ clear_bit(i%32, h->cmd_pool_bits+(i/32));
+ h->nr_frees++;
+ }
+}
+
+/*
+ * fills in the disk information.
+ */
+static void cciss_geninit( int ctlr)
+{
+ drive_info_struct *drv;
+ int i,j;
+
+ /* Loop through each real device */
+ hba[ctlr]->gendisk.nr_real = 0;
+ for(i=0; i< NWD; i++)
+ {
+ drv = &(hba[ctlr]->drv[i]);
+ if( !(drv->nr_blocks))
+ continue;
+ hba[ctlr]->hd[i << NWD_SHIFT].nr_sects =
+ hba[ctlr]->sizes[i << NWD_SHIFT] = drv->nr_blocks;
+
+ /* for each partition */
+ for(j=0; j<MAX_PART; j++)
+ {
+ hba[ctlr]->blocksizes[(i<<NWD_SHIFT) + j] = 1024;
+
+ hba[ctlr]->hardsizes[ (i<<NWD_SHIFT) + j] =
+ drv->block_size;
+ }
+ hba[ctlr]->gendisk.nr_real++;
+ }
+}
+/*
+ * Open. Make sure the device is really there.
+ */


+static int cciss_open(struct inode *inode, struct file *filep)

+{
+ int ctlr = MAJOR(inode->i_rdev) - MAJOR_NR;
+ int dsk = MINOR(inode->i_rdev) >> NWD_SHIFT;
+
+#ifdef CCISS_DEBUG
+ printk(KERN_DEBUG "cciss_open %x (%x:%x)\n", inode->i_rdev, ctlr, dsk);
+#endif /* CCISS_DEBUG */
+
+ if (ctlr > MAX_CTLR || hba[ctlr] == NULL)
+ return -ENXIO;
+
+ if (!suser() && hba[ctlr]->sizes[ MINOR(inode->i_rdev)] == 0)
+ return -ENXIO;
+
+ /*
+ * Root is allowed to open raw volume zero even if its not configured
+ * so array config can still work. I don't think I really like this,
+ * but I'm already using way to many device nodes to claim another one
+ * for "raw controller".
+ */
+ if (suser()
+ && (hba[ctlr]->sizes[MINOR(inode->i_rdev)] == 0)
+ && (MINOR(inode->i_rdev)!= 0))
+ return -ENXIO;
+
+ hba[ctlr]->drv[dsk].usage_count++;
+ hba[ctlr]->usage_count++;
+ MOD_INC_USE_COUNT;
+ return 0;
+}
+/*
+ * Close. Sync first.
+ */


+static int cciss_release(struct inode *inode, struct file *filep)

+{
+ int ctlr = MAJOR(inode->i_rdev) - MAJOR_NR;
+ int dsk = MINOR(inode->i_rdev) >> NWD_SHIFT;
+
+#ifdef CCISS_DEBUG
+ printk(KERN_DEBUG "cciss_release %x (%x:%x)\n", inode->i_rdev, ctlr, dsk);
+#endif /* CCISS_DEBUG */
+
+ /* fsync_dev(inode->i_rdev); */
+
+ hba[ctlr]->drv[dsk].usage_count--;
+ hba[ctlr]->usage_count--;
+ MOD_DEC_USE_COUNT;


+ return 0;
+}
+
+/*

+ * ioctl
+ */


+static int cciss_ioctl(struct inode *inode, struct file *filep,
+ unsigned int cmd, unsigned long arg)

+{
+ int ctlr = MAJOR(inode->i_rdev) - MAJOR_NR;
+ int dsk = MINOR(inode->i_rdev) >> NWD_SHIFT;
+ int diskinfo[4];
+ struct hd_geometry *geo = (struct hd_geometry *)arg;
+
+#ifdef CCISS_DEBUG
+ printk(KERN_DEBUG "cciss_ioctl: Called with cmd=%x %lx\n", cmd, arg);
+#endif /* CCISS_DEBUG */
+
+ switch(cmd) {
+ case HDIO_GETGEO:
+ if (hba[ctlr]->drv[dsk].cylinders) {
+ diskinfo[0] = hba[ctlr]->drv[dsk].heads;
+ diskinfo[1] = hba[ctlr]->drv[dsk].sectors;
+ diskinfo[2] = hba[ctlr]->drv[dsk].cylinders;
+ } else {
+ diskinfo[0] = 0xff;
+ diskinfo[1] = 0x3f;
+ diskinfo[2] = hba[ctlr]->drv[dsk].nr_blocks / (0xff*0x3f); }
+ put_user(diskinfo[0], &geo->heads);
+ put_user(diskinfo[1], &geo->sectors);
+ put_user(diskinfo[2], &geo->cylinders);
+ put_user(hba[ctlr]->hd[MINOR(inode->i_rdev)].start_sect, &geo->start);
+ return 0;
+ case BLKGETSIZE:
+ if (!arg) return -EINVAL;
+ put_user(hba[ctlr]->hd[MINOR(inode->i_rdev)].nr_sects, (long*)arg);
+ return 0;
+ case BLKRRPART:
+ return revalidate_logvol(inode->i_rdev, 1);
+ case BLKFLSBUF:
+ case BLKROSET:
+ case BLKROGET:
+ case BLKRASET:
+ case BLKRAGET:
+ case BLKPG:
+ return( blk_ioctl(inode->i_rdev, cmd, arg));
+ case CCISS_GETPCIINFO:
+ {
+ cciss_pci_info_struct pciinfo;
+
+ if (!arg) return -EINVAL;
+ pciinfo.bus = hba[ctlr]->pci_bus;
+ pciinfo.dev_fn = hba[ctlr]->pci_dev_fn;
+ pciinfo.board_id = hba[ctlr]->board_id;
+ if (copy_to_user((void *) arg, &pciinfo, sizeof( cciss_pci_info_struct )))
+ return -EFAULT;
+ return(0);
+ }
+ case CCISS_GETINTINFO:
+ {
+ cciss_coalint_struct intinfo;
+ ctlr_info_t *c = hba[ctlr];
+
+ if (!arg) return -EINVAL;
+ intinfo.delay = readl(&c->cfgtable->HostWrite.CoalIntDelay);
+ intinfo.count = readl(&c->cfgtable->HostWrite.CoalIntCount);
+ if (copy_to_user((void *) arg, &intinfo, sizeof( cciss_coalint_struct )))
+ return -EFAULT;
+ return(0);
+ }
+ case CCISS_SETINTINFO:
+ {
+ cciss_coalint_struct intinfo;
+ ctlr_info_t *c = hba[ctlr];
+ unsigned long flags;
+ int i;
+
+ if (!arg) return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN)) return -EPERM;
+ if (copy_from_user(&intinfo, (void *) arg, sizeof( cciss_coalint_struct)))
+ return -EFAULT;
+ if ( (intinfo.delay == 0 ) && (intinfo.count == 0))
+
+ {
+// printk("cciss_ioctl: delay and count cannot be 0\n");
+ return( -EINVAL);
+ }
+ spin_lock_irqsave(&io_request_lock, flags);
+ /* Can only safely update if no commands outstanding */
+ if (c->commands_outstanding > 0 )
+ {
+// printk("cciss_ioctl: cannot change coalasing "
+// "%d commands outstanding on controller\n",
+// c->commands_outstanding);
+ spin_unlock_irqrestore(&io_request_lock, flags);
+ return(-EINVAL);
+ }
+ /* Update the field, and then ring the doorbell */
+ writel( intinfo.delay,
+ &(c->cfgtable->HostWrite.CoalIntDelay));
+ writel( intinfo.count,
+ &(c->cfgtable->HostWrite.CoalIntCount));
+ writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL);
+
+ for(i=0;i<MAX_CONFIG_WAIT;i++)
+ {
+ if (!(readl(c->vaddr + SA5_DOORBELL)
+ & CFGTBL_ChangeReq))
+ break;
+ /* delay and try again */
+ udelay(1000);
+ }
+ spin_unlock_irqrestore(&io_request_lock, flags);
+ if (i >= MAX_CONFIG_WAIT)
+ return( -EFAULT);
+ return(0);
+ }
+ case CCISS_GETNODENAME:
+ {
+ NodeName_type NodeName;
+ ctlr_info_t *c = hba[ctlr];
+ int i;
+
+ if (!arg) return -EINVAL;
+ for(i=0;i<16;i++)
+ NodeName[i] = readb(&c->cfgtable->ServerName[i]);
+ if (copy_to_user((void *) arg, NodeName, sizeof( NodeName_type)))
+ return -EFAULT;
+ return(0);
+ }
+ case CCISS_SETNODENAME:
+ {
+ NodeName_type NodeName;
+ ctlr_info_t *c = hba[ctlr];
+ unsigned long flags;
+ int i;
+
+ if (!arg) return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN)) return -EPERM;
+
+ if (copy_from_user(NodeName, (void *) arg, sizeof( NodeName_type)))
+ return -EFAULT;
+
+ spin_lock_irqsave(&io_request_lock, flags);
+
+ /* Update the field, and then ring the doorbell */
+ for(i=0;i<16;i++)
+ writeb( NodeName[i], &c->cfgtable->ServerName[i]);
+
+ writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL);
+
+ for(i=0;i<MAX_CONFIG_WAIT;i++)
+ {
+ if (!(readl(c->vaddr + SA5_DOORBELL)
+ & CFGTBL_ChangeReq))
+ break;
+ /* delay and try again */
+ udelay(1000);
+ }
+ spin_unlock_irqrestore(&io_request_lock, flags);
+ if (i >= MAX_CONFIG_WAIT)
+ return( -EFAULT);
+ return(0);
+ }
+
+ case CCISS_GETHEARTBEAT:
+ {
+ Heartbeat_type heartbeat;
+ ctlr_info_t *c = hba[ctlr];
+
+ if (!arg) return -EINVAL;
+ heartbeat = readl(&c->cfgtable->HeartBeat);
+ if (copy_to_user((void *) arg, &heartbeat, sizeof( Heartbeat_type)))
+ return -EFAULT;
+ return(0);
+ }
+ case CCISS_GETBUSTYPES:
+ {
+ BusTypes_type BusTypes;
+ ctlr_info_t *c = hba[ctlr];
+
+ if (!arg) return -EINVAL;
+ BusTypes = readl(&c->cfgtable->BusTypes);
+ if (copy_to_user((void *) arg, &BusTypes, sizeof( BusTypes_type) ))
+ return -EFAULT;
+ return(0);
+ }
+ case CCISS_GETFIRMVER:
+ {
+ FirmwareVer_type firmware;
+
+ if (!arg) return -EINVAL;
+ memcpy(firmware, hba[ctlr]->firm_ver, 4);
+
+ if (copy_to_user((void *) arg, firmware, sizeof( FirmwareVer_type)))
+ return -EFAULT;
+ return(0);
+ }
+ case CCISS_GETDRIVVER:
+ {
+ DriverVer_type DriverVer = DRIVER_VERSION;
+
+ if (!arg) return -EINVAL;
+
+ if (copy_to_user((void *) arg, &DriverVer, sizeof( DriverVer_type) ))
+ return -EFAULT;
+ return(0);
+ }
+
+ case CCISS_REVALIDVOLS:
+ return( revalidate_allvol(inode->i_rdev));
+
+ case CCISS_PASSTHRU:
+ {
+ IOCTL_Command_struct iocommand;
+ ctlr_info_t *h = hba[ctlr];
+ CommandList_struct *c;
+ char *buff = NULL;
+ u64bit temp64;


+ unsigned long flags;
+

+ if (!arg) return -EINVAL;
+
+ if (!capable(CAP_SYS_RAWIO)) return -EPERM;
+
+ if (copy_from_user(&iocommand, (void *) arg, sizeof( IOCTL_Command_struct) ))
+ return -EFAULT;
+ if((iocommand.buf_size < 1) &&
+ (iocommand.Request.Type.Direction != XFER_NONE))
+ {
+ return -EINVAL;
+ }
+ /* Check kmalloc limits */
+ if(iocommand.buf_size > 128000)
+ return -EINVAL;
+ if(iocommand.buf_size > 0)
+ {
+ buff = kmalloc(iocommand.buf_size, GFP_KERNEL);
+ if( buff == NULL)
+ return -EFAULT;
+ }
+ if (iocommand.Request.Type.Direction == XFER_WRITE)
+ {
+ /* Copy the data into the buffer we created */
+ if (copy_from_user(buff, iocommand.buf, iocommand.buf_size))
+ return -EFAULT;
+ }
+ if ((c = cmd_alloc(NULL)) == NULL)
+ {
+ if(buff!=NULL)
+ kfree(buff);
+ return -ENOMEM;
+ }
+ // Fill in the command type
+ c->cmd_type = CMD_IOCTL_PEND;
+ // Fill in Command Header
+ c->Header.ReplyQueue = 0; // unused in simple mode
+ if( iocommand.buf_size > 0) // buffer to fill
+ {
+ c->Header.SGList = 1;
+ c->Header.SGTotal= 1;
+ } else // no buffers to fill
+ {
+ c->Header.SGList = 0;
+ c->Header.SGTotal= 0;
+ }
+ c->Header.LUN = iocommand.LUN_info;
+ c->Header.Tag.lower = c->busaddr; // use the kernel address the cmd block for tag
+
+ // Fill in Request block
+ c->Request = iocommand.Request;
+
+ // Fill in the scatter gather information
+ if (iocommand.buf_size > 0 )
+ {
+ temp64.val = (__u64) virt_to_bus(buff);
+ c->SG[0].Addr.lower = temp64.val32.lower;
+ c->SG[0].Addr.upper = temp64.val32.upper;
+ c->SG[0].Len = iocommand.buf_size;
+ c->SG[0].Ext = 0; // we are not chaining
+ }
+ /* Put the request on the tail of the request queue */
+ spin_lock_irqsave(&io_request_lock, flags);
+ addQ(&h->reqQ, c);
+ h->Qdepth++;
+ start_io(h);
+ spin_unlock_irqrestore(&io_request_lock, flags);
+
+ /* Wait for completion */
+ while(c->cmd_type != CMD_IOCTL_DONE)
+ schedule_timeout(1);
+
+ /* Copy the error information out */
+ iocommand.error_info = *(c->err_info);
+ if ( copy_to_user((void *) arg, &iocommand, sizeof( IOCTL_Command_struct) ) )
+ {
+ cmd_free(NULL, c);
+ if (buff != NULL)
+ kfree(buff);
+ return( -EFAULT);
+ }
+
+ if (iocommand.Request.Type.Direction == XFER_READ)
+ {
+ /* Copy the data out of the buffer we created */
+ if (copy_to_user(iocommand.buf, buff, iocommand.buf_size))
+ {
+ cmd_free(NULL, c);
+ kfree(buff);
+ }
+ }
+ cmd_free(NULL, c);
+ if (buff != NULL)
+ kfree(buff);
+ return(0);
+ }
+
+ default:
+ return -EBADRQC;
+ }
+
+}
+
+/* Borrowed and adapted from sd.c */


+static int revalidate_logvol(kdev_t dev, int maxusage)

+{
+ int ctlr, target;
+ struct gendisk *gdev;
+ unsigned long flags;
+ int max_p;
+ int start;
+ int i;
+
+ target = MINOR(dev) >> NWD_SHIFT;
+ ctlr = MAJOR(dev) - MAJOR_NR;
+ gdev = &(hba[ctlr]->gendisk);
+
+ spin_lock_irqsave(&io_request_lock, flags);
+ if (hba[ctlr]->drv[target].usage_count > maxusage) {
+ spin_unlock_irqrestore(&io_request_lock, flags);
+ printk(KERN_WARNING "cpqarray: Device busy for "
+ "revalidation (usage=%d)\n",
+ hba[ctlr]->drv[target].usage_count);
+ return -EBUSY;
+ }
+ hba[ctlr]->drv[target].usage_count++;
+ spin_unlock_irqrestore(&io_request_lock, flags);
+
+ max_p = gdev->max_p;
+ start = target << gdev->minor_shift;
+
+ for(i=max_p; i>=0; i--) {
+ int minor = start+i;
+ kdev_t devi = MKDEV(MAJOR_NR + ctlr, minor);
+ struct super_block *sb = get_super(devi);
+ sync_dev(devi);
+ if (sb) invalidate_inodes(sb);
+ invalidate_buffers(devi);
+ gdev->part[minor].start_sect = 0;
+ gdev->part[minor].nr_sects = 0;
+
+ /* reset the blocksize so we can read the partition table */
+ blksize_size[MAJOR_NR+ctlr][minor] = 1024;
+ }
+ /* setup partitions per disk */
+ grok_partitions(gdev, target, MAX_PART,
+ hba[ctlr]->drv[target].nr_blocks);
+ hba[ctlr]->drv[target].usage_count--;


+ return 0;
+}
+

+static int frevalidate_logvol(kdev_t dev)
+{
+#ifdef CCISS_DEBUG
+ printk(KERN_DEBUG "cciss: frevalidate has been called\n");
+#endif /* CCISS_DEBUG */
+ return revalidate_logvol(dev, 0);
+}
+
+/*
+ * revalidate_allvol is for online array config utilities. After a
+ * utility reconfigures the drives in the array, it can use this function
+ * (through an ioctl) to make the driver zap any previous disk structs for
+ * that controller and get new ones.
+ *
+ * Right now I'm using the getgeometry() function to do this, but this
+ * function should probably be finer grained and allow you to revalidate one
+ * particualar logical volume (instead of all of them on a particular
+ * controller).
+ */
+static int revalidate_allvol(kdev_t dev)
+{
+ int ctlr, i;


+ unsigned long flags;
+

+ ctlr = MAJOR(dev) - MAJOR_NR;
+ if (MINOR(dev) != 0)
+ return -ENXIO;
+
+ spin_lock_irqsave(&io_request_lock, flags);
+ if (hba[ctlr]->usage_count > 1) {
+ spin_unlock_irqrestore(&io_request_lock, flags);
+ printk(KERN_WARNING "cciss: Device busy for volume"
+ " revalidation (usage=%d)\n", hba[ctlr]->usage_count);
+ return -EBUSY;
+ }
+ spin_unlock_irqrestore(&io_request_lock, flags);
+ hba[ctlr]->usage_count++;
+
+ /*
+ * Set the partition and block size structures for all volumes
+ * on this controller to zero. We will reread all of this data
+ */
+ memset(hba[ctlr]->hd, 0, sizeof(struct hd_struct) * 256);
+ memset(hba[ctlr]->sizes, 0, sizeof(int) * 256);
+ memset(hba[ctlr]->blocksizes, 0, sizeof(int) * 256);
+ memset(hba[ctlr]->hardsizes, 0, sizeof(int) * 256);
+ memset(hba[ctlr]->drv, 0, sizeof(drive_info_struct)
+ * CISS_MAX_LUN);
+ hba[ctlr]->gendisk.nr_real = 0;
+
+ /*
+ * Tell the array controller not to give us any interupts while
+ * we check the new geometry. Then turn interrupts back on when
+ * we're done.
+ */
+ hba[ctlr]->access.set_intr_mask(hba[ctlr], CCISS_INTR_OFF);
+ cciss_getgeometry(ctlr);
+ hba[ctlr]->access.set_intr_mask(hba[ctlr], CCISS_INTR_ON);
+
+ cciss_geninit(ctlr);
+ for(i=0; i<NWD; i++)
+ if (hba[ctlr]->sizes[ i<<NWD_SHIFT ])
+ revalidate_logvol(dev+(i<<NWD_SHIFT), 2);
+
+ hba[ctlr]->usage_count--;


+ return 0;
+}
+

+
+
+/*
+ * Wait polling for a command to complete.
+ * The memory mapped FIFO is polled for the completion.
+ * Used only at init time, interrupts disabled.
+ */
+static unsigned long pollcomplete(int ctlr)
+{
+ unsigned long done;
+ int i;
+
+ /* Wait (up to 2 seconds) for a command to complete */
+
+ for (i = 200000; i > 0; i--) {
+ done = hba[ctlr]->access.command_completed(hba[ctlr]);
+ if (done == FIFO_EMPTY) {
+ udelay(10); /* a short fixed delay */
+ } else
+ return (done);
+ }
+ /* Invalid address to tell caller we ran out of time */
+ return 1;
+}
+/*
+ * Send a command to the controller, and wait for it to complete.
+ * Only used at init time.
+ */
+static int sendcmd(
+ __u8 cmd,
+ int ctlr,
+ void *buff,
+ size_t size,
+ unsigned int use_unit_num,
+ unsigned int log_unit,
+ __u8 page_code )


+{
+ CommandList_struct *c;
+ int i;

+ unsigned long complete;
+ ctlr_info_t *info_p= hba[ctlr];
+ u64bit temp64;
+
+ c = cmd_alloc(info_p);
+ if (c == NULL)
+ {
+ printk(KERN_WARNING "cciss: unable to get memory");
+ return(IO_ERROR);
+ }
+ // Fill in Command Header
+ c->Header.ReplyQueue = 0; // unused in simple mode
+ if( buff != NULL) // buffer to fill
+ {
+ c->Header.SGList = 1;
+ c->Header.SGTotal= 1;
+ } else // no buffers to fill
+ {
+ c->Header.SGList = 0;
+ c->Header.SGTotal= 0;
+ }
+ c->Header.Tag.lower = c->busaddr; // use the kernel address the cmd block for tag
+ // Fill in Request block
+ switch(cmd)
+ {
+ case CISS_INQUIRY:
+ /* If the logical unit number is 0 then, this is going
+ to controller so It's a physical command
+ mode = 0 target = 0.
+ So we have nothing to write.
+ Otherwise
+ mode = 1 target = LUNID
+ */
+ if(use_unit_num != 0)
+ {
+ c->Header.LUN.LogDev.VolId=
+ hba[ctlr]->drv[log_unit].LunID;
+ c->Header.LUN.LogDev.Mode = 1;
+ }
+ /* are we trying to read a vital product page */
+ if(page_code != 0)
+ {
+ c->Request.CDB[1] = 0x01;
+ c->Request.CDB[2] = page_code;
+ }
+ c->Request.CDBLen = 6;
+ c->Request.Type.Type = TYPE_CMD; // It is a command.
+ c->Request.Type.Attribute = ATTR_SIMPLE;
+ c->Request.Type.Direction = XFER_READ; // Read
+ c->Request.Timeout = 0; // Don't time out
+ c->Request.CDB[0] = CISS_INQUIRY;
+ c->Request.CDB[4] = size & 0xFF;
+ break;
+ case CISS_REPORT_LOG:
+ /* Talking to controller so It's a physical command
+ mode = 00 target = 0.
+ So we have nothing to write.
+ */
+ c->Request.CDBLen = 12;
+ c->Request.Type.Type = TYPE_CMD; // It is a command.
+ c->Request.Type.Attribute = ATTR_SIMPLE;
+ c->Request.Type.Direction = XFER_READ; // Read
+ c->Request.Timeout = 0; // Don't time out
+ c->Request.CDB[0] = CISS_REPORT_LOG;
+ c->Request.CDB[6] = (size >> 24) & 0xFF; //MSB
+ c->Request.CDB[7] = (size >> 16) & 0xFF;
+ c->Request.CDB[8] = (size >> 8) & 0xFF;
+ c->Request.CDB[9] = size & 0xFF;
+ break;
+
+ case CCISS_READ_CAPACITY:
+ c->Header.LUN.LogDev.VolId=
+ hba[ctlr]->drv[log_unit].LunID;
+ c->Header.LUN.LogDev.Mode = 1;
+ c->Request.CDBLen = 10;
+ c->Request.Type.Type = TYPE_CMD; // It is a command.
+ c->Request.Type.Attribute = ATTR_SIMPLE;
+ c->Request.Type.Direction = XFER_READ; // Read
+ c->Request.Timeout = 0; // Don't time out
+ c->Request.CDB[0] = CCISS_READ_CAPACITY;
+ break;
+ default:
+ printk(KERN_WARNING
+ "cciss: Unknown Command 0x%c sent attempted\n",
+ cmd);
+ cmd_free(info_p, c);
+ return(IO_ERROR);
+ };
+ // Fill in the scatter gather information
+ if (size > 0 )
+ {
+ temp64.val = (__u64) virt_to_bus(buff);
+ c->SG[0].Addr.lower = temp64.val32.lower;
+ c->SG[0].Addr.upper = temp64.val32.upper;
+ c->SG[0].Len = size;
+ c->SG[0].Ext = 0; // we are not chaining
+ }
+ /*
+ * Disable interrupt
+ */
+#ifdef CCISS_DEBUG
+ printk(KERN_DEBUG "cciss: turning intr off\n");
+#endif /* CCISS_DEBUG */
+ info_p->access.set_intr_mask(info_p, CCISS_INTR_OFF);
+
+ /* Make sure there is room in the command FIFO */
+ /* Actually it should be completely empty at this time. */
+ for (i = 200000; i > 0; i--)
+ {
+ /* if fifo isn't full go */
+ if (!(info_p->access.fifo_full(info_p)))
+ {
+
+ break;
+ }
+ udelay(10);
+ printk(KERN_WARNING "cciss cciss%d: SendCmd FIFO full,"
+ " waiting!\n", ctlr);
+ }
+ /*
+ * Send the cmd
+ */
+ info_p->access.submit_command(info_p, c);
+ complete = pollcomplete(ctlr);
+
+#ifdef CCISS_DEBUG
+ printk(KERN_DEBUG "cciss: command completed\n");
+#endif /* CCISS_DEBUG */
+
+ if (complete != 1) {
+ if ( (complete & CISS_ERROR_BIT)
+ && (complete & ~CISS_ERROR_BIT) == c->busaddr)
+ {
+ /* if data overrun or underun on Report command
+ ignore it
+ */
+ if (((c->Request.CDB[0] == CISS_REPORT_LOG) ||
+ (c->Request.CDB[0] == CISS_INQUIRY)) &&
+ ((c->err_info->CommandStatus ==
+ CMD_DATA_OVERRUN) ||
+ (c->err_info->CommandStatus ==
+ CMD_DATA_UNDERRUN)
+ ))
+ {
+ complete = c->busaddr;
+ } else
+ {
+ printk(KERN_WARNING "ciss ciss%d: sendcmd"
+ " Error %x \n", ctlr,
+ c->err_info->CommandStatus);
+ printk(KERN_WARNING "ciss ciss%d: sendcmd"
+ " offensive info\n"
+ " size %x\n num %x value %x\n", ctlr,
+ c->err_info->MoreErrInfo.Invalid_Cmd.offense_size,
+ c->err_info->MoreErrInfo.Invalid_Cmd.offense_num,
+ c->err_info->MoreErrInfo.Invalid_Cmd.offense_value);
+ cmd_free(info_p,c);
+ return(IO_ERROR);
+ }
+ }
+ if (complete != c->busaddr) {
+ printk( KERN_WARNING "cciss cciss%d: SendCmd "
+ "Invalid command list address returned! (%lx)\n",
+ ctlr, complete);
+ cmd_free(info_p, c);
+ return (IO_ERROR);
+ }
+ } else {
+ printk( KERN_WARNING
+ "cciss cciss%d: SendCmd Timeout out, "
+ "No command list address returned!\n",
+ ctlr);
+ cmd_free(info_p, c);
+ return (IO_ERROR);
+ }
+ cmd_free(info_p, c);
+ return (IO_OK);
+}
+/*
+ * Map (physical) PCI mem into (virtual) kernel space
+ */
+static ulong remap_pci_mem(ulong base, ulong size)
+{
+ ulong page_base = ((ulong) base) & PAGE_MASK;
+ ulong page_offs = ((ulong) base) - page_base;
+ ulong page_remapped = (ulong) ioremap(page_base, page_offs+size);
+
+ return (ulong) (page_remapped ? (page_remapped + page_offs) : 0UL);
+}
+
+/*
+ * Enqueuing and dequeuing functions for cmdlists.
+ */


+static inline void addQ(CommandList_struct **Qptr, CommandList_struct *c)

+{
+ if (*Qptr == NULL) {
+ *Qptr = c;
+ c->next = c->prev = c;
+ } else {
+ c->prev = (*Qptr)->prev;
+ c->next = (*Qptr);
+ (*Qptr)->prev->next = c;
+ (*Qptr)->prev = c;
+ }
+}
+
+static inline CommandList_struct *removeQ(CommandList_struct **Qptr,
+ CommandList_struct *c)
+{
+ if (c && c->next != c) {
+ if (*Qptr == c) *Qptr = c->next;
+ c->prev->next = c->next;
+ c->next->prev = c->prev;
+ } else {
+ *Qptr = NULL;
+ }
+ return c;
+}
+
+/*
+ * Takes jobs of the Q and sends them to the hardware, then puts it on
+ * the Q to wait for completion.
+ */

+static void start_io( ctlr_info_t *h)

+{
+ CommandList_struct *c;
+
+ while(( c = h->reqQ) != NULL )
+ {
+ /* can't do anything if fifo is full */
+ if ((h->access.fifo_full(h)))
+ {
+ printk(KERN_WARNING "cciss: fifo full \n");
+ return;
+ }
+ /* Get the frist entry from the Request Q */
+ removeQ(&(h->reqQ), c);
+ h->Qdepth--;
+
+ /* Tell the controller execute command */
+ h->access.submit_command(h, c);
+
+ /* Put job onto the completed Q */
+ addQ (&(h->cmpQ), c);
+ }
+}
+
+static inline void complete_buffers( struct buffer_head *bh, int status)
+{
+ struct buffer_head *xbh;
+
+ while(bh)
+ {
+ xbh = bh->b_reqnext;
+ bh->b_reqnext = NULL;
+ bh->b_end_io(bh, status);
+ bh = xbh;
+ }
+}
+/* checks the status of the job and calls complete buffers to mark all
+ * buffers for the completed job.
+ */
+static inline void complete_command( CommandList_struct *cmd, int timeout)
+{
+ int status = 1;
+
+ if (timeout)
+ status = 0;
+ if(cmd->err_info->CommandStatus != 0)
+ { /* an error has occured */
+ switch(cmd->err_info->CommandStatus)
+ {
+ case CMD_TARGET_STATUS:
+ printk(KERN_WARNING "cciss: cmd %p has "
+ " completed with errors\n", cmd);
+ if( cmd->err_info->ScsiStatus)
+ {
+ printk(KERN_WARNING "cciss: cmd %p "
+ "has SCSI Status = %x\n",
+ cmd,
+ cmd->err_info->ScsiStatus);
+ }
+
+ break;
+ case CMD_DATA_UNDERRUN:
+ printk(KERN_WARNING "cciss: cmd %p has"
+ " completed with data underrun "
+ "reported\n", cmd);
+ break;
+ case CMD_DATA_OVERRUN:
+ printk(KERN_WARNING "cciss: cmd %p has"
+ " completed with data overrun "
+ "reported\n", cmd);
+ break;
+ case CMD_INVALID:
+ printk(KERN_WARNING "cciss: cmd %p is "
+ "reported invalid\n", cmd);
+ status = 0;
+ break;
+ case CMD_PROTOCOL_ERR:
+ printk(KERN_WARNING "cciss: cmd %p has "
+ "protocol error \n", cmd);
+ status = 0;
+ break;
+ case CMD_HARDWARE_ERR:
+ printk(KERN_WARNING "cciss: cmd %p had "
+ " hardware error\n", cmd);
+ status = 0;
+ break;
+ case CMD_CONNECTION_LOST:
+ printk(KERN_WARNING "cciss: cmd %p had "
+ "connection lost\n", cmd);
+ status=0;
+ break;
+ case CMD_ABORTED:
+ printk(KERN_WARNING "cciss: cmd %p was "
+ "aborted\n", cmd);
+ status=0;
+ break;
+ case CMD_ABORT_FAILED:
+ printk(KERN_WARNING "cciss: cmd %p reports "
+ "abort failed\n", cmd);
+ status=0;
+ break;
+ case CMD_UNSOLICITED_ABORT:
+ printk(KERN_WARNING "cciss: cmd %p aborted "
+ "do to an unsolicited abort\n", cmd);
+ status=0;
+ break;
+ case CMD_TIMEOUT:
+ printk(KERN_WARNING "cciss: cmd %p timedout\n",
+ cmd);
+ status=0;
+ break;
+ default:
+ printk(KERN_WARNING "cciss: cmd %p returned "
+ "unknown status %x\n", cmd,
+ cmd->err_info->CommandStatus);
+ status=0;
+ }
+ }
+ complete_buffers(cmd->bh, status);
+}
+/*
+ * Get a request and submit it to the controller.
+ * Currently we do one request at a time. Ideally we would like to send
+ * everything to the controller on the first call, but there is a danger
+ * of holding the io_request_lock for to long.
+ */
+static void do_cciss_request(int ctlr)
+{
+ ctlr_info_t *h= hba[ctlr];
+ CommandList_struct *c;
+ int log_unit, start_blk, seg, sect;
+ char *lastdataend;
+ struct buffer_head *bh;
+ struct list_head *queue_head;
+ struct request *creq;
+ u64bit temp64;
+
+ queue_head = &blk_dev[MAJOR_NR+ctlr].request_queue.queue_head;
+ if (list_empty(queue_head))
+ {
+ /* nothing to do... */
+ start_io(h);
+ return;
+ }
+ creq = blkdev_entry_next_request(queue_head);
+ if ((creq == NULL) || (creq->rq_status == RQ_INACTIVE))
+ {
+ /* nothing to do... restart processing and return */
+ start_io(h);
+ return;
+ }
+ if ((ctlr != (MAJOR(creq->rq_dev)-MAJOR_NR)) || (ctlr > nr_ctlr)
+ || (h == NULL))
+ {
+#ifdef CCISS_DEBUG
+ printk(KERN_WARNING "cciss: doreq cmd of %d, %x at %p\n",
+ ctlr, creq->rq_dev, creq);
+#endif /* CCISS_DEBUG */
+ complete_buffers(creq->bh, 0);
+ start_io(h);
+ return;
+ }
+ if (( c = cmd_alloc(h)) == NULL)
+ {
+ start_io(h);
+ return;
+ }
+ c->cmd_type = CMD_RWREQ;
+ bh = c->bh = creq->bh;
+
+ /* fill in the request */
+ log_unit = MINOR(creq->rq_dev) >> NWD_SHIFT;
+ c->Header.ReplyQueue = 0; // unused in simple mode
+ c->Header.Tag.lower = c->busaddr; // use the physical address the cmd block for tag
+ c->Header.LUN.LogDev.VolId= hba[ctlr]->drv[log_unit].LunID;
+ c->Header.LUN.LogDev.Mode = 1;
+ c->Request.CDBLen = 10; // 12 byte commands not in FW yet;
+ c->Request.Type.Type = TYPE_CMD; // It is a command.
+ c->Request.Type.Attribute = ATTR_SIMPLE;
+ c->Request.Type.Direction =
+ (creq->cmd == READ) ? XFER_READ: XFER_WRITE;
+ c->Request.Timeout = 0; // Don't time out
+ c->Request.CDB[0] = (creq->cmd == READ) ? CCISS_READ : CCISS_WRITE;
+ start_blk = hba[ctlr]->hd[MINOR(creq->rq_dev)].start_sect + creq->sector;
+ if (bh == NULL)
+ panic("cciss: bh== NULL?");
+#ifdef CCISS_DEBUG
+ printk(KERN_DEBUG "ciss: sector =%d nr_sectors=%d\n",(int) creq->sector,
+ (int) creq->nr_sectors);
+#endif /* CCISS_DEBUG */
+ seg = 0;
+ lastdataend = NULL;
+ sect = 0;
+ while(bh)
+ {
+ sect += bh->b_size/512;
+ if (bh->b_size % 512)
+ {
+ printk(KERN_CRIT "cciss: Oh Man. %d+%d, size=%d\n",
+ (int) creq->sector, sect, (int) bh->b_size);
+ panic("b_size 512 != 0\n");
+ }
+ if (bh->b_data == lastdataend)
+ { // tack it on to the last segment
+ c->SG[seg-1].Len +=bh->b_size;
+ lastdataend += bh->b_size;
+ } else
+ {
+ c->SG[seg].Len = bh->b_size;
+ temp64.val = (__u64) virt_to_bus(bh->b_data);
+ c->SG[seg].Addr.lower = temp64.val32.lower;
+ c->SG[seg].Addr.upper = temp64.val32.upper;
+ c->SG[0].Ext = 0; // we are not chaining
+ lastdataend = bh->b_data + bh->b_size;
+ if( ++seg == MAXSGENTRIES)


+ {
+ break;
+ }
+ }

+ bh = bh->b_reqnext;
+ }
+ /* track how many SG entries we are using */
+ if( seg > h->maxSG)
+ h->maxSG = seg;
+
+ /* adjusting the remaining request, if any */
+ creq-> sector+= sect;
+ creq->nr_sectors -= sect;
+
+#ifdef CCISS_DEBUG
+ printk(KERN_DEBUG "cciss: Submitting %d sectors in %d segments\n", sect, seg);
+#endif /* CCISS_DEBUG */
+
+ c->Header.SGList = c->Header.SGTotal = seg;
+ c->Request.CDB[1]= 0;
+ c->Request.CDB[2]= (start_blk >> 24) & 0xff; //MSB
+ c->Request.CDB[3]= (start_blk >> 16) & 0xff;
+ c->Request.CDB[4]= (start_blk >> 8) & 0xff;
+ c->Request.CDB[5]= start_blk & 0xff;
+ c->Request.CDB[6]= 0; // (sect >> 24) & 0xff; MSB
+ // c->Request.CDB[7]= (sect >> 16) & 0xff;
+ c->Request.CDB[7]= (sect >> 8) & 0xff;
+ c->Request.CDB[8]= sect & 0xff;
+ c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0;
+
+ /* check to see if we going to complete the entire request */
+ /* if so, mark this request as Done and ready the next one */
+ if (creq->nr_sectors)
+ {
+#ifdef CCISS_DEBUG
+ printk(KERN_DEBUG "cciss: More to do on the same request %p %ld\n",
+ creq, creq->nr_sectors);
+#endif /* CCISS_DEBUG */
+
+ creq->bh = bh->b_reqnext;
+ bh->b_reqnext = NULL;
+ } else
+ {
+#ifdef CCISS_DEBUG
+ printk("cciss: Done with %p, queueing %p\n", creq);
+#endif /* CCISS_DEBUG */
+
+ blkdev_dequeue_request(creq);
+ end_that_request_last(creq);
+ }
+ addQ(&(h->reqQ),c);
+ h->Qdepth++;
+ if(h->Qdepth > h->maxQsinceinit)
+ h->maxQsinceinit = h->Qdepth;
+ start_io(h);
+}
+
+static void do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+ ctlr_info_t *h = dev_id;
+ CommandList_struct *c;
+ unsigned long flags;
+ __u32 a, a1;
+
+
+ /* Is this interrupt for us? */
+ if ( h->access.intr_pending(h) == 0)
+ return;
+
+ /*
+ * If there are completed commands in the completion queue,
+ * we had better do something about it.
+ */
+ spin_lock_irqsave(&io_request_lock, flags);
+ while( h->access.intr_pending(h))
+ {
+ while((a = h->access.command_completed(h)) != FIFO_EMPTY)
+ {
+ a1 = a;
+ a &= ~3;
+ if ((c = h->cmpQ) == NULL)
+ {
+ printk(KERN_WARNING "cpqarray: Completion of %08lx ignored\n", (unsigned long)a1);
+ continue;
+ }
+ while(c->busaddr != a) {
+ c = c->next;
+ if (c == h->cmpQ)
+ break;
+ }
+ /*
+ * If we've found the command, take it off the
+ * completion Q and free it
+ */
+ if (c->busaddr == a) {
+ removeQ(&h->cmpQ, c);
+ if (c->cmd_type == CMD_RWREQ) {
+ complete_command(c, 0);
+ cmd_free(h, c);
+ } else if (c->cmd_type == CMD_IOCTL_PEND) {
+ c->cmd_type = CMD_IOCTL_DONE;
+ }
+ continue;
+ }
+ }
+ }
+ /*
+ * See if we can queue up some more IO
+ */
+ do_cciss_request(h->ctlr);
+ spin_unlock_irqrestore(&io_request_lock, flags);
+}
+/*
+ * We cannot read the structure directly, for portablity we must use
+ * the io functions.
+ * This is for debug only.
+ */
+#ifdef CCISS_DEBUG
+static void print_cfg_table( CfgTable_struct *tb)
+{
+ int i;
+ char temp_name[17];
+
+ printk("Controller Configuration information\n");
+ printk("------------------------------------\n");
+ for(i=0;i<4;i++)
+ temp_name[i] = readb(&(tb->Signature[i]));
+ temp_name[4]='\0';
+ printk(" Signature = %s\n", temp_name);
+ printk(" Spec Number = %d\n", readl(&(tb->SpecValence)));
+ printk(" Transport methods supported = 0x%x\n",
+ readl(&(tb-> TransportSupport)));
+ printk(" Transport methods active = 0x%x\n",
+ readl(&(tb->TransportActive)));
+ printk(" Requested transport Method = 0x%x\n",
+ readl(&(tb->HostWrite.TransportRequest)));
+ printk(" Coalese Interrupt Delay = 0x%x\n",
+ readl(&(tb->HostWrite.CoalIntDelay)));
+ printk(" Coalese Interrupt Count = 0x%x\n",
+ readl(&(tb->HostWrite.CoalIntCount)));
+ printk(" Max outstanding commands = 0x%d\n",
+ readl(&(tb->CmdsOutMax)));
+ printk(" Bus Types = 0x%x\n", readl(&(tb-> BusTypes)));
+ for(i=0;i<16;i++)
+ temp_name[i] = readb(&(tb->ServerName[i]));
+ temp_name[16] = '\0';
+ printk(" Server Name = %s\n", temp_name);
+ printk(" Heartbeat Counter = 0x%x\n\n\n",
+ readl(&(tb->HeartBeat)));
+}
+#endif /* CCISS_DEBUG */
+
+static int cciss_pci_init(ctlr_info_t *c, unchar bus, unchar device_fn)
+{
+ ushort vendor_id, device_id, command;
+ unchar cache_line_size, latency_timer;
+ unchar irq, revision;
+ uint addr[6];
+ __u32 board_id;
+ struct pci_dev *pdev;
+
+ int i;
+
+ pdev = pci_find_slot(bus, device_fn);
+ vendor_id = pdev->vendor;
+ device_id = pdev->device;
+ irq = pdev->irq;
+
+ for(i=0; i<6; i++)
+ addr[i] = pdev->resource[i].start;
+
+ if (pci_enable_device(pdev))
+ return( -1);
+
+ (void) pci_read_config_word(pdev, PCI_COMMAND,&command);
+ (void) pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
+ (void) pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE,
+ &cache_line_size);
+ (void) pci_read_config_byte(pdev, PCI_LATENCY_TIMER,
+ &latency_timer);
+
+ (void) pci_read_config_dword(pdev, PCI_SUBSYSTEM_VENDOR_ID,
+ &board_id);
+
+#ifdef CCISS_DEBUG
+ printk("vendor_id = %x\n", vendor_id);
+ printk("device_id = %x\n", device_id);
+ printk("command = %x\n", command);
+ for(i=0; i<6; i++)
+ printk("addr[%d] = %x\n", i, addr[i]);
+ printk("revision = %x\n", revision);
+ printk("irq = %x\n", irq);
+ printk("cache_line_size = %x\n", cache_line_size);
+ printk("latency_timer = %x\n", latency_timer);
+ printk("board_id = %x\n", board_id);
+#endif /* CCISS_DEBUG */
+
+ c->intr = irq;
+
+ /*
+ * Memory base addr is first addr , the second points to the config
+ * table
+ */
+ c->paddr = pci_resource_start(pdev, 0);
+ c->vaddr = remap_pci_mem(c->paddr, 128);
+ c->cfgtable = (CfgTable_struct *) remap_pci_mem(addr[1],
+ sizeof(CfgTable_struct));
+ c->board_id = board_id;
+
+#ifdef CCISS_DEBUG
+ print_cfg_table(c->cfgtable);
+#endif /* CCISS_DEBUG */
+ for(i=0; i<NR_PRODUCTS; i++) {
+ if (board_id == products[i].board_id) {
+ c->product_name = products[i].product_name;
+ c->access = *(products[i].access);
+ break;
+ }
+ }
+ if (i == NR_PRODUCTS) {
+ printk(KERN_WARNING "cciss: Sorry, I don't know how"
+ " to access the Smart Array controller %08lx\n",
+ (unsigned long)board_id);
+ return -1;
+ }
+#ifdef CCISS_DEBUG
+ printk("Trying to put board into Simple mode\n");
+#endif /* CCISS_DEBUG */
+ c->max_commands = readl(&(c->cfgtable->CmdsOutMax));
+ /* Update the field, and then ring the doorbell */
+ writel( CFGTBL_Trans_Simple,
+ &(c->cfgtable->HostWrite.TransportRequest));
+ writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL);
+
+ for(i=0;i<MAX_CONFIG_WAIT;i++)
+ {
+ if (!(readl(c->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq))
+ break;
+ /* delay and try again */
+ udelay(1000);
+ }
+
+#ifdef CCISS_DEBUG
+ printk(KERN_DEBUG "I counter got to %d %x\n", i, readl(c->vaddr + SA5_DOORBELL));
+#endif /* CCISS_DEBUG */
+#ifdef CCISS_DEBUG
+ print_cfg_table(c->cfgtable);
+#endif /* CCISS_DEBUG */
+
+ if (!(readl(&(c->cfgtable->TransportActive)) & CFGTBL_Trans_Simple))
+ {
+ printk(KERN_WARNING "cciss: unable to get board into"
+ " simple mode\n");
+ return -1;
+ }


+ return 0;
+
+}
+/*

+ * Scans PCI space for any controllers that this driver can control.
+ */
+static int cciss_pci_detect(void)
+{
+
+ int index;
+ unchar bus=0, dev_fn=0;
+
+ for(index=0; ; index++) {
+ if (pcibios_find_device(PCI_VENDOR_ID_COMPAQ,
+ PCI_DEVICE_ID_COMPAQ_CISS,
+ index, &bus, &dev_fn))
+ break;
+ printk(KERN_DEBUG "cciss: Device %x has been found at %x %x\n",
+ PCI_DEVICE_ID_COMPAQ_CISS, bus, dev_fn);
+ if (index == 1000000) break;
+ if (nr_ctlr == 8) {
+ printk(KERN_WARNING "cciss: This driver"
+ " supports a maximum of 8 controllers.\n");
+ break;
+ }
+ hba[nr_ctlr] = kmalloc(sizeof(ctlr_info_t), GFP_KERNEL);
+ if(hba[nr_ctlr]==NULL)
+ {
+ printk(KERN_ERR "cciss: out of memory.\n");
+ continue;
+ }
+ memset(hba[nr_ctlr], 0, sizeof(ctlr_info_t));
+ if (cciss_pci_init(hba[nr_ctlr], bus, dev_fn) != 0)
+ {
+ kfree(hba[nr_ctlr]);
+ continue;
+ }
+ sprintf(hba[nr_ctlr]->devname, "cciss%d", nr_ctlr);
+ hba[nr_ctlr]->ctlr = nr_ctlr;
+ hba[nr_ctlr]->pci_bus = bus;
+ hba[nr_ctlr]->pci_dev_fn = dev_fn;
+ nr_ctlr++;
+
+ }
+ return nr_ctlr;
+
+}
+
+/*
+ * Gets information about the local volumes attached to the controller.
+ */
+static void cciss_getgeometry(int cntl_num)
+{
+ ReportLunData_struct *ld_buff;
+ ReadCapdata_struct *size_buff;
+ InquiryData_struct *inq_buff;
+ int return_code;
+ int i;
+ int listlength = 0;
+ int lunid = 0;
+ int block_size;
+ int total_size;
+
+ ld_buff = kmalloc(sizeof(ReportLunData_struct), GFP_KERNEL);
+ if (ld_buff == NULL)
+ {
+ printk(KERN_ERR "cciss: out of memory\n");
+ return;
+ }
+ memset(ld_buff, 0, sizeof(ReportLunData_struct));
+ size_buff = kmalloc(sizeof( ReadCapdata_struct), GFP_KERNEL);
+ if (size_buff == NULL)
+ {
+ printk(KERN_ERR "cciss: out of memory\n");
+ kfree(ld_buff);
+ return;
+ }
+ inq_buff = kmalloc(sizeof( InquiryData_struct), GFP_KERNEL);
+ if (inq_buff == NULL)
+ {
+ printk(KERN_ERR "cciss: out of memory\n");
+ kfree(ld_buff);
+ kfree(size_buff);
+ return;
+ }
+ /* Get the firmware version */
+ return_code = sendcmd(CISS_INQUIRY, cntl_num, inq_buff,
+ sizeof(InquiryData_struct), 0, 0 ,0 );
+ if (return_code == IO_OK)
+ {
+ hba[cntl_num]->firm_ver[0] = inq_buff->data_byte[32];
+ hba[cntl_num]->firm_ver[1] = inq_buff->data_byte[33];
+ hba[cntl_num]->firm_ver[2] = inq_buff->data_byte[34];
+ hba[cntl_num]->firm_ver[3] = inq_buff->data_byte[35];
+ } else /* send command failed */
+ {
+ printk(KERN_WARNING "cciss: unable to determine firmware"
+ " version of controller\n");
+ }
+ /* Get the number of logical volumes */
+ return_code = sendcmd(CISS_REPORT_LOG, cntl_num, ld_buff,
+ sizeof(ReportLunData_struct), 0, 0, 0 );
+
+ if( return_code == IO_OK)
+ {
+#ifdef CCISS_DEBUG
+ printk("LUN Data\n--------------------------\n");
+#endif /* CCISS_DEBUG */
+
+ listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[0])) << 24;
+ listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[1])) << 16;
+ listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[2])) << 8;
+ listlength |= 0xff & (unsigned int)(ld_buff->LUNListLength[3]);
+ } else /* reading number of logical volumes failed */
+ {
+ printk(KERN_WARNING "cciss: report logical volume"
+ " command failed\n");
+ listlength = 0;
+ }
+ hba[cntl_num]->num_luns = listlength / 8; // 8 bytes pre entry
+ if (hba[cntl_num]->num_luns > CISS_MAX_LUN)
+ {
+ printk(KERN_ERR "ciss: only %d number of logical volumes supported\n",
+ CISS_MAX_LUN);
+ hba[cntl_num]->num_luns = CISS_MAX_LUN;
+ }
+#ifdef CCISS_DEBUG
+ printk(KERN_DEBUG "Length = %x %x %x %x = %d\n", ld_buff->LUNListLength[0],
+ ld_buff->LUNListLength[1], ld_buff->LUNListLength[2],
+ ld_buff->LUNListLength[3], hba[cntl_num]->num_luns);
+#endif /* CCISS_DEBUG */
+ for(i=0; i< hba[cntl_num]->num_luns ; i++)
+ {
+ lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3])) << 24;
+ lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][2])) << 16;
+ lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][1])) << 8;
+ lunid |= 0xff & (unsigned int)(ld_buff->LUN[i][0]);
+ hba[cntl_num]->drv[i].LunID = lunid;
+
+#ifdef CCISS_DEBUG
+ printk(KERN_DEBUG "LUN[%d]: %x %x %x %x = %x\n", i,
+ ld_buff->LUN[i][0], ld_buff->LUN[i][1],ld_buff->LUN[i][2],
+ ld_buff->LUN[i][3], hba[cntl_num]->drv[i].LunID);
+#endif /* CCISS_DEBUG */
+
+ memset(size_buff, 0, sizeof(ReadCapdata_struct));
+ return_code = sendcmd(CCISS_READ_CAPACITY, cntl_num, size_buff,
+ sizeof( ReadCapdata_struct), 1, i, 0 );
+ if (return_code == IO_OK)
+ {
+ total_size = (0xff &
+ (unsigned int)(size_buff->total_size[0])) << 24;
+ total_size |= (0xff &
+ (unsigned int)(size_buff->total_size[1])) << 16;
+ total_size |= (0xff &
+ (unsigned int)(size_buff->total_size[2])) << 8;
+ total_size |= (0xff & (unsigned int)
+ (size_buff->total_size[3]));
+ total_size++; // command returns highest block address
+
+ block_size = (0xff &
+ (unsigned int)(size_buff->block_size[0])) << 24;
+ block_size |= (0xff &
+ (unsigned int)(size_buff->block_size[1])) << 16;
+ block_size |= (0xff &
+ (unsigned int)(size_buff->block_size[2])) << 8;
+ block_size |= (0xff &
+ (unsigned int)(size_buff->block_size[3]));
+ } else /* read capacity command failed */
+ {
+ printk(KERN_WARNING "cciss: read capacity failed\n");
+ total_size = block_size = 0;
+ }
+ printk(" blocks= %d block_size= %d\n", total_size,
+ block_size);
+
+ /* Execute the command to read the disk geometry */
+ memset(inq_buff, 0, sizeof(InquiryData_struct));
+ return_code = sendcmd(CISS_INQUIRY, cntl_num, inq_buff,
+ sizeof(InquiryData_struct), 1, i ,0xC1 );
+ if (return_code == IO_OK)
+ {
+ if(inq_buff->data_byte[8] == 0xFF)
+ {
+ printk(KERN_WARNING "cciss: reading geometry failed, volume does not support reading geometry\n");
+
+ hba[cntl_num]->drv[i].block_size = block_size;
+ hba[cntl_num]->drv[i].nr_blocks = total_size;
+ hba[cntl_num]->drv[i].heads = 255;
+ hba[cntl_num]->drv[i].sectors = 32; // Sectors per track
+ hba[cntl_num]->drv[i].cylinders = total_size / 255 / 32; } else
+ {
+
+ hba[cntl_num]->drv[i].block_size = block_size;
+ hba[cntl_num]->drv[i].nr_blocks = total_size;
+ hba[cntl_num]->drv[i].heads =
+ inq_buff->data_byte[6];
+ hba[cntl_num]->drv[i].sectors =
+ inq_buff->data_byte[7];
+ hba[cntl_num]->drv[i].cylinders =
+ (inq_buff->data_byte[4] & 0xff) << 8;
+ hba[cntl_num]->drv[i].cylinders +=
+ inq_buff->data_byte[5];
+ }
+ }
+ else /* Get geometry failed */
+ {
+ printk(KERN_WARNING "cciss: reading geometry failed, continuing with default geometry\n");
+
+ hba[cntl_num]->drv[i].block_size = block_size;
+ hba[cntl_num]->drv[i].nr_blocks = total_size;
+ hba[cntl_num]->drv[i].heads = 255;
+ hba[cntl_num]->drv[i].sectors = 32; // Sectors per track
+ hba[cntl_num]->drv[i].cylinders = total_size / 255 / 32;
+ }
+ printk(KERN_INFO " heads= %d, sectors= %d, cylinders= %d\n\n",
+ hba[cntl_num]->drv[i].heads,
+ hba[cntl_num]->drv[i].sectors,
+ hba[cntl_num]->drv[i].cylinders);
+
+ }
+ kfree(ld_buff);
+ kfree(size_buff);
+}
+
+/*
+ * This is it. Find all the controllers and register them. I really hate
+ * stealing all these major device numbers.
+ * returns the number of block devices registered.
+ */
+int __init cciss_init(void)
+{
+ int num_cntlrs_reg = 0;
+ int i,j;
+
+ void (*request_fns[MAX_CTLR])(request_queue_t *) = {
+ do_cciss_request0, do_cciss_request1,
+ do_cciss_request2, do_cciss_request3,
+ do_cciss_request4, do_cciss_request5,
+ do_cciss_request6, do_cciss_request7,
+ };
+
+ /* detect controllers */
+ cciss_pci_detect();
+
+ if (nr_ctlr == 0)
+ return(num_cntlrs_reg);
+
+ printk(KERN_INFO DRIVER_NAME "\n");
+ printk(KERN_INFO "Found %d controller(s)\n", nr_ctlr);
+ for(i=0;i<nr_ctlr;i++)
+ {
+ if( register_blkdev(MAJOR_NR+i, hba[i]->devname, &cciss_fops))
+ {
+ printk(KERN_ERR "cciss: Unable to get major number "
+ "%d for %s\n", MAJOR_NR+i, hba[i]->devname);
+ continue;
+ }
+ /* make sure the board interrupts are off */
+ hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF);
+ if( request_irq(hba[i]->intr, do_cciss_intr, SA_INTERRUPT|SA_SHIRQ, hba[i]->devname, hba[i]))
+ {
+ printk(KERN_ERR "ciss: Unable to get irq %d for %s\n",
+ hba[i]->intr, hba[i]->devname);
+ unregister_blkdev( MAJOR_NR+i, hba[i]->devname);
+ continue;
+ }
+ num_cntlrs_reg++;
+ hba[i]->cmd_pool_bits = (__u32*)kmalloc(
+ ((NR_CMDS+31)/32)*sizeof(__u32), GFP_KERNEL);
+ hba[i]->cmd_pool = (CommandList_struct *)kmalloc(
+ NR_CMDS * sizeof(CommandList_struct),
+ GFP_KERNEL);
+ hba[i]->errinfo_pool = (ErrorInfo_struct *)kmalloc(
+ NR_CMDS * sizeof( ErrorInfo_struct),
+ GFP_KERNEL);
+ if((hba[i]->cmd_pool_bits == NULL)
+ || (hba[i]->cmd_pool == NULL)
+ || (hba[i]->errinfo_pool == NULL))
+ {
+ nr_ctlr = i;
+ if(hba[i]->cmd_pool_bits)
+ kfree(hba[i]->cmd_pool_bits);
+ if(hba[i]->cmd_pool)
+ kfree(hba[i]->cmd_pool);
+ if(hba[i]->errinfo_pool)
+ kfree(hba[i]->errinfo_pool);
+ free_irq(hba[i]->intr, hba[i]);
+ unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
+ num_cntlrs_reg--;
+ printk( KERN_ERR "cciss: out of memory");
+ return(num_cntlrs_reg);
+ }
+
+ /* command and error info recs zeroed out before
+ they are used */
+ memset(hba[i]->cmd_pool_bits, 0,
+ ((NR_CMDS+31)/32)*sizeof(__u32));
+
+#ifdef CCISS_DEBUG
+ printk(KERN_DEBUG "Scanning for drives on controller cciss%d\n",i);
+#endif /* CCISS_DEBUG */
+
+ cciss_getgeometry(i);
+
+ /* Turn the interrupts on so we can service requests */
+ hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON);
+
+ cciss_procinit(i);
+
+ blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR+i),
+ request_fns[i]);
+ blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR+i), 0);
+
+ /* fill in the other Kernel structs */
+ blksize_size[MAJOR_NR+i] = hba[i]->blocksizes;
+ hardsect_size[MAJOR_NR+i] = hba[i]->hardsizes;
+ read_ahead[MAJOR_NR+i] = READ_AHEAD;
+
+ /* Fill in the gendisk data */
+ hba[i]->gendisk.major = MAJOR_NR + i;
+ hba[i]->gendisk.major_name = "cciss";
+ hba[i]->gendisk.minor_shift = NWD_SHIFT;
+ hba[i]->gendisk.max_p = MAX_PART;
+ hba[i]->gendisk.part = hba[i]->hd;
+ hba[i]->gendisk.sizes = hba[i]->sizes;
+ hba[i]->gendisk.nr_real = hba[i]->num_luns;
+
+ /* Get on the disk list */
+ hba[i]->gendisk.next = gendisk_head;
+ gendisk_head = &(hba[i]->gendisk);
+
+ cciss_geninit(i);
+ for(j=0; j<NWD; j++)
+ register_disk(&(hba[i]->gendisk),
+ MKDEV(MAJOR_NR+i, j <<4),
+ MAX_PART, &cciss_fops,
+ hba[i]->drv[j].nr_blocks);
+ }
+ return(nr_ctlr);
+}
+
+EXPORT_NO_SYMBOLS;
+
+/* This is a bit of a hack... */
+static int __init init_cciss_module(void)
+{
+
+ if (cciss_init() == 0) /* all the block dev numbers already used */
+ return -EIO; /* or no controllers were found */


+ return 0;
+}
+

+static void __exit cleanup_cciss_module(void)
+{
+ int i;
+ struct gendisk *g;
+
+ for(i=0; i<nr_ctlr; i++)
+ {
+ /* Turn board interrupts off */
+ hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF);
+ free_irq(hba[i]->intr, hba[i]);
+ iounmap((void*)hba[i]->vaddr);
+ unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
+ remove_proc_entry(hba[i]->devname, proc_cciss);
+
+ /* remove it from the disk list */
+ if (gendisk_head == &(hba[i]->gendisk))
+ {
+ gendisk_head = hba[i]->gendisk.next;
+ } else
+ {
+ for(g=gendisk_head; g ; g=g->next)
+ {
+ if(g->next == &(hba[i]->gendisk))
+ {
+ g->next = hba[i]->gendisk.next;
+ }
+ }
+ }
+ remove_proc_entry("driver/cciss", &proc_root);
+ kfree(hba[i]->cmd_pool);
+ kfree(hba[i]->errinfo_pool);
+ kfree(hba[i]->cmd_pool_bits);
+ kfree(hba[i]);
+ }
+}
+
+module_init(init_cciss_module);
+module_exit(cleanup_cciss_module);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/block/cciss.h linux/drivers/block/cciss.h
--- v2.4.0-test8/linux/drivers/block/cciss.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/block/cciss.h Fri Sep 22 17:11:37 2000
@@ -0,0 +1,201 @@
+#ifndef CCISS_H
+#define CCISS_H
+
+#include <linux/genhd.h>
+
+#include "cciss_cmd.h"
+
+
+#define NWD 16
+#define NWD_SHIFT 4
+#define MAX_PART 16
+
+#define IO_OK 0
+#define IO_ERROR 1
+
+#define MAJOR_NR COMPAQ_CISS_MAJOR
+
+struct ctlr_info;
+typedef struct ctlr_info ctlr_info_t;
+
+struct access_method {
+ void (*submit_command)(ctlr_info_t *h, CommandList_struct *c);
+ void (*set_intr_mask)(ctlr_info_t *h, unsigned long val);
+ unsigned long (*fifo_full)(ctlr_info_t *h);
+ unsigned long (*intr_pending)(ctlr_info_t *h);
+ unsigned long (*command_completed)(ctlr_info_t *h);
+};
+typedef struct _drive_info_struct
+{
+ __u32 LunID;
+ int usage_count;
+ int nr_blocks;
+ int block_size;
+ int heads;
+ int sectors;
+ int cylinders;
+} drive_info_struct;
+
+struct ctlr_info
+{
+ int ctlr;
+ char devname[8];
+ char *product_name;
+ char firm_ver[4]; // Firmware version
+ unchar pci_bus;
+ unchar pci_dev_fn;
+ __u32 board_id;
+ ulong vaddr;
+ __u32 paddr;
+ CfgTable_struct *cfgtable;
+ int intr;
+
+ int max_commands;
+ int commands_outstanding;
+ int max_outstanding; /* Debug */
+ int num_luns;
+ int usage_count; /* number of opens all all minor devices */
+
+ // information about each logical volume
+ drive_info_struct drv[CISS_MAX_LUN];
+
+ struct access_method access;
+
+ /* queue and queue Info */
+ CommandList_struct *reqQ;
+ CommandList_struct *cmpQ;
+ unsigned int Qdepth;
+ unsigned int maxQsinceinit;
+ unsigned int maxSG;
+
+ //* pointers to command and error info pool */
+ CommandList_struct *cmd_pool;
+ ErrorInfo_struct *errinfo_pool;
+ __u32 *cmd_pool_bits;
+ int nr_allocs;
+ int nr_frees;
+
+ // Disk structures we need to pass back
+ struct gendisk gendisk;
+ // indexed by minor numbers
+ struct hd_struct hd[256];
+ int sizes[256];
+ int blocksizes[256];
+ int hardsizes[256];
+};
+
+/* Defining the diffent access_menthods */
+/*
+ * Memory mapped FIFO interface (SMART 53xx cards)
+ */
+#define SA5_DOORBELL 0x20
+#define SA5_REQUEST_PORT_OFFSET 0x40
+#define SA5_REPLY_INTR_MASK_OFFSET 0x34
+#define SA5_REPLY_PORT_OFFSET 0x44
+#define SA5_INTR_STATUS 0x30
+
+#define SA5_INTR_OFF 0x08
+#define SA5_INTR_PENDING 0x08
+#define FIFO_EMPTY 0xffffffff
+
+#define CISS_ERROR_BIT 0x02
+
+#define CCISS_INTR_ON 1
+#define CCISS_INTR_OFF 0
+/*
+ Send the command to the hardware
+*/
+static void SA5_submit_command( ctlr_info_t *h, CommandList_struct *c)
+{
+#ifdef CCISS_DEBUG
+ printk("Sending %x - down to controller\n", c->busaddr );
+#endif /* CCISS_DEBUG */
+ writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET);
+ h->commands_outstanding++;
+ if ( h->commands_outstanding > h->max_outstanding)
+ h->max_outstanding = h->commands_outstanding;
+}
+
+/*
+ * This card is the oposite of the other cards.
+ * 0 turns interrupts on...
+ * 0x08 turns them off...
+ */
+static void SA5_intr_mask(ctlr_info_t *h, unsigned long val)
+{
+ if (val)
+ { /* Turn interrupts on */
+ writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
+ } else /* Turn them off */
+ {
+ writel( SA5_INTR_OFF,
+ h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
+ }
+}
+/*
+ * Returns true if fifo is full.
+ *
+ */
+static unsigned long SA5_fifo_full(ctlr_info_t *h)
+{
+ if( h->commands_outstanding >= h->max_commands)
+ return(1);
+ else
+ return(0);
+
+}
+/*
+ * returns value read from hardware.
+ * returns FIFO_EMPTY if there is nothing to read
+ */
+static unsigned long SA5_completed(ctlr_info_t *h)
+{
+ unsigned long register_value
+ = readl(h->vaddr + SA5_REPLY_PORT_OFFSET);
+ if(register_value != FIFO_EMPTY)
+ {
+ h->commands_outstanding--;
+#ifdef CCISS_DEBUG
+ printk("cciss: Read %lx back from board\n", register_value);
+#endif /* CCISS_DEBUG */
+ }
+#ifdef CCISS_DEBUG
+ else
+ {
+ printk("cciss: FIFO Empty read\n");
+ }
+#endif
+ return ( register_value);
+
+}
+/*
+ * Returns true if an interrupt is pending..
+ */
+static unsigned long SA5_intr_pending(ctlr_info_t *h)
+{
+ unsigned long register_value =
+ readl(h->vaddr + SA5_INTR_STATUS);
+#ifdef CCISS_DEBUG
+ printk("cciss: intr_pending %lx\n", register_value);
+#endif /* CCISS_DEBUG */
+ if( register_value & SA5_INTR_PENDING)
+ return 1;

+ return 0 ;
+}
+
+

+static struct access_method SA5_access = {
+ SA5_submit_command,
+ SA5_intr_mask,
+ SA5_fifo_full,
+ SA5_intr_pending,
+ SA5_completed,
+};
+
+struct board_type {
+ __u32 board_id;
+ char *product_name;
+ struct access_method *access;
+};
+#endif /* CCISS_H */
+
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/block/cciss_cmd.h linux/drivers/block/cciss_cmd.h
--- v2.4.0-test8/linux/drivers/block/cciss_cmd.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/block/cciss_cmd.h Fri Sep 22 17:11:37 2000
@@ -0,0 +1,254 @@
+#ifndef CCISS_CMD_H
+#define CCISS_CMD_H
+//###########################################################################
+//DEFINES
+//###########################################################################
+#define CISS_VERSION "1.00"
+
+//general boundary defintions
+#define SENSEINFOBYTES 32//note that this value may vary between host implementations
+#define MAXSGENTRIES 31
+#define MAXREPLYQS 256
+
+//Command Status value
+#define CMD_SUCCESS 0x0000
+#define CMD_TARGET_STATUS 0x0001
+#define CMD_DATA_UNDERRUN 0x0002
+#define CMD_DATA_OVERRUN 0x0003
+#define CMD_INVALID 0x0004
+#define CMD_PROTOCOL_ERR 0x0005
+#define CMD_HARDWARE_ERR 0x0006
+#define CMD_CONNECTION_LOST 0x0007
+#define CMD_ABORTED 0x0008
+#define CMD_ABORT_FAILED 0x0009
+#define CMD_UNSOLICITED_ABORT 0x000A
+#define CMD_TIMEOUT 0x000B
+#define CMD_UNABORTABLE 0x000C
+
+//transfer direction
+#define XFER_NONE 0x00
+#define XFER_WRITE 0x01
+#define XFER_READ 0x02
+#define XFER_RSVD 0x03
+
+//task attribute
+#define ATTR_UNTAGGED 0x00
+#define ATTR_SIMPLE 0x04
+#define ATTR_HEADOFQUEUE 0x05
+#define ATTR_ORDERED 0x06
+#define ATTR_ACA 0x07
+
+//cdb type
+#define TYPE_CMD 0x00
+#define TYPE_MSG 0x01
+
+//config space register offsets
+#define CFG_VENDORID 0x00
+#define CFG_DEVICEID 0x02
+#define CFG_I2OBAR 0x10
+#define CFG_MEM1BAR 0x14
+
+//i2o space register offsets
+#define I2O_IBDB_SET 0x20
+#define I2O_IBDB_CLEAR 0x70
+#define I2O_INT_STATUS 0x30
+#define I2O_INT_MASK 0x34
+#define I2O_IBPOST_Q 0x40
+#define I2O_OBPOST_Q 0x44
+
+//Configuration Table
+#define CFGTBL_ChangeReq 0x00000001l
+#define CFGTBL_AccCmds 0x00000001l
+
+#define CFGTBL_Trans_Simple 0x00000002l
+
+#define CFGTBL_BusType_Ultra2 0x00000001l
+#define CFGTBL_BusType_Ultra3 0x00000002l


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 039'
echo 'File patch-2.4.0-test9 is continued in part 040'
echo "040" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part040

#!/bin/sh -x
# this is part 040 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 040; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+#define CFGTBL_BusType_Fibre1G 0x00000100l
+#define CFGTBL_BusType_Fibre2G 0x00000200l
+typedef struct _vals32
+{
+ __u32 lower;
+ __u32 upper;
+} vals32;
+
+typedef union _u64bit
+{
+ vals32 val32;
+ __u64 val;
+} u64bit;
+
+// Type defs used in the following structs
+#define BYTE __u8
+#define WORD __u16
+#define HWORD __u16
+#define DWORD __u32
+#define QWORD vals32
+
+//###########################################################################
+//STRUCTURES
+//###########################################################################
+#define CISS_MAX_LUN 16
+// SCSI-3 Cmmands
+
+#pragma pack(1)
+
+#define CISS_INQUIRY 0x12
+//Date returned
+typedef struct _InquiryData_struct
+{
+ BYTE data_byte[36];
+} InquiryData_struct;
+
+#define CISS_REPORT_LOG 0xc2 /* Report Logical LUNs */
+// Data returned
+typedef struct _ReportLUNdata_struct
+{
+ BYTE LUNListLength[4];
+ DWORD reserved;
+ BYTE LUN[CISS_MAX_LUN][8];
+} ReportLunData_struct;
+
+#define CCISS_READ_CAPACITY 0x25 /* Read Capacity */
+typedef struct _ReadCapdata_struct
+{
+ BYTE total_size[4]; // Total size in blocks
+ BYTE block_size[4]; // Size of blocks in bytes
+} ReadCapdata_struct;
+
+// 12 byte commands not implemented in firmware yet.
+// #define CCISS_READ 0xa8 // Read(12)
+// #define CCISS_WRITE 0xaa // Write(12)
+ #define CCISS_READ 0x28 // Read(10)
+ #define CCISS_WRITE 0x2a // Write(10)
+
+//Command List Structure
+typedef union _SCSI3Addr_struct {
+ struct {
+ BYTE Bus:6;
+ BYTE Mode:2; // b00
+ BYTE Dev;
+ } PeripDev;
+ struct {
+ BYTE DevMSB:6;
+ BYTE Mode:2; // b01
+ BYTE DevLSB;
+ } LogDev;
+ struct {
+ BYTE Targ:6;
+ BYTE Mode:2; // b10
+ BYTE Dev:5;
+ BYTE Bus:3;
+ } LogUnit;
+} SCSI3Addr_struct;
+
+typedef struct _PhysDevAddr_struct {
+ DWORD TargetId:24;
+ DWORD Bus:6;
+ DWORD Mode:2;
+ SCSI3Addr_struct Target[2]; //2 level target device addr
+} PhysDevAddr_struct;
+
+typedef struct _LogDevAddr_struct {
+ DWORD VolId:30;
+ DWORD Mode:2;
+ BYTE reserved[4];
+} LogDevAddr_struct;
+
+typedef union _LUNAddr_struct {
+ BYTE LunAddrBytes[8];
+ SCSI3Addr_struct SCSI3Lun[4];
+ PhysDevAddr_struct PhysDev;
+ LogDevAddr_struct LogDev;
+} LUNAddr_struct;
+
+typedef struct _CommandListHeader_struct {
+ BYTE ReplyQueue;
+ BYTE SGList;
+ HWORD SGTotal;
+ QWORD Tag;
+ LUNAddr_struct LUN;
+} CommandListHeader_struct;
+typedef struct _RequestBlock_struct {
+ BYTE CDBLen;
+ struct {
+ BYTE Type:3;
+ BYTE Attribute:3;
+ BYTE Direction:2;
+ } Type;
+ HWORD Timeout;
+ BYTE CDB[16];
+} RequestBlock_struct;
+typedef struct _ErrDescriptor_struct {
+ QWORD Addr;
+ DWORD Len;
+} ErrDescriptor_struct;
+typedef struct _SGDescriptor_struct {
+ QWORD Addr;
+ DWORD Len;
+ DWORD Ext;
+} SGDescriptor_struct;
+
+typedef union _MoreErrInfo_struct{
+ struct {
+ BYTE Reserved[3];
+ BYTE Type;
+ DWORD ErrorInfo;
+ }Common_Info;
+ struct{
+ BYTE Reserved[2];
+ BYTE offense_size;//size of offending entry
+ BYTE offense_num; //byte # of offense 0-base
+ DWORD offense_value;
+ }Invalid_Cmd;
+}MoreErrInfo_struct;
+typedef struct _ErrorInfo_struct {
+ BYTE ScsiStatus;
+ BYTE SenseLen;
+ HWORD CommandStatus;
+ DWORD ResidualCnt;
+ MoreErrInfo_struct MoreErrInfo;
+ BYTE SenseInfo[SENSEINFOBYTES];
+} ErrorInfo_struct;
+
+/* Command types */
+#define CMD_RWREQ 0x00
+#define CMD_IOCTL_PEND 0x01
+#define CMD_IOCTL_DONE 0x02
+
+typedef struct _CommandList_struct {
+ CommandListHeader_struct Header;
+ RequestBlock_struct Request;
+ ErrDescriptor_struct ErrDesc;
+ SGDescriptor_struct SG[MAXSGENTRIES];
+ /* information associated with the command */
+ __u32 busaddr; /* physical addres of this record */
+ ErrorInfo_struct * err_info; /* pointer to the allocated mem */
+ int cmd_type;
+ struct _CommandList_struct *prev;
+ struct _CommandList_struct *next;
+ struct buffer_head * bh;
+} CommandList_struct;
+
+//Configuration Table Structure
+typedef struct _HostWrite_struct {
+ DWORD TransportRequest;
+ DWORD Reserved;
+ DWORD CoalIntDelay;
+ DWORD CoalIntCount;
+} HostWrite_struct;
+
+typedef struct _CfgTable_struct {
+ BYTE Signature[4];
+ DWORD SpecValence;
+ DWORD TransportSupport;
+ DWORD TransportActive;
+ HostWrite_struct HostWrite;
+ DWORD CmdsOutMax;
+ DWORD BusTypes;
+ DWORD Reserved;
+ BYTE ServerName[16];
+ DWORD HeartBeat;
+} CfgTable_struct;
+#pragma pack()
+#endif // CCISS_CMD_H
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/block/cpqarray.c linux/drivers/block/cpqarray.c
--- v2.4.0-test8/linux/drivers/block/cpqarray.c Thu Jul 6 19:25:21 2000
+++ linux/drivers/block/cpqarray.c Fri Sep 22 14:17:18 2000
@@ -46,6 +46,12 @@
X
X #define DRIVER_NAME "Compaq SMART2 Driver (v 2.4.0)"
X #define DRIVER_VERSION SMART2_DRIVER_VERSION(2,4,0)


+
+/* Embedded module documentation macros - see modules.h */

+/* Original author Chris Frantz - Compaq Computer Corporation */
+MODULE_AUTHOR("Compaq Computer Corporation");
+MODULE_DESCRIPTION("Driver for Compaq Smart2 Array Controllers");
+
X #define MAJOR_NR COMPAQ_SMART2_MAJOR
X #include <linux/blk.h>
X #include <linux/blkdev.h>
@@ -85,6 +91,7 @@
X { 0x40330E11, "Smart Array 3100ES", &smart2_access },
X { 0x40340E11, "Smart Array 221", &smart2_access },
X { 0x40400E11, "Integrated Array", &smart4_access },
+ { 0x40480E11, "Compaq Raid LC2", &smart4_access },
X { 0x40500E11, "Smart Array 4200", &smart4_access },
X { 0x40510E11, "Smart Array 4250ES", &smart4_access },
X { 0x40580E11, "Smart Array 431", &smart4_access },


@@ -109,8 +116,8 @@
X

X int cpqarray_init(void);
X static int cpqarray_pci_detect(void);
-static int cpqarray_pci_init(ctlr_info_t *c, unchar bus, unchar device_fn);
-static ulong remap_pci_mem(ulong base, ulong size);
+static int cpqarray_pci_init(ctlr_info_t *c, struct pci_dev *pdev);
+static void *remap_pci_mem(ulong base, ulong size);
X static int cpqarray_eisa_detect(void);
X static int pollcomplete(int ctlr);
X static void getgeometry(int ctlr);
@@ -328,7 +335,7 @@
X for(i=0; i<nr_ctlr; i++) {
X hba[i]->access.set_intr_mask(hba[i], 0);
X free_irq(hba[i]->intr, hba[i]);
- iounmap((void*)hba[i]->vaddr);
+ iounmap(hba[i]->vaddr);
X unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
X del_timer(&hba[i]->timer);
X blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR + i));
@@ -535,8 +542,7 @@
X */
X static int cpqarray_pci_detect(void)
X {
- int index;
- unchar bus=0, dev_fn=0;
+ struct pci_dev *pdev;
X
X #define IDA_BOARD_TYPES 3
X static int ida_vendor_id[IDA_BOARD_TYPES] = { PCI_VENDOR_ID_DEC,
@@ -547,29 +553,22 @@
X /* search for all PCI board types that could be for this driver */
X for(brdtype=0; brdtype<IDA_BOARD_TYPES; brdtype++)
X {
- for(index=0; ; index++) {
- if (pcibios_find_device(ida_vendor_id[brdtype],
- ida_device_id[brdtype], index, &bus, &dev_fn))
- break;
+ pdev = pci_find_device(ida_vendor_id[brdtype],
+ ida_device_id[brdtype], NULL);
+ while (pdev) {
X printk(KERN_DEBUG "cpqarray: Device %x has been found at %x %x\n",
- ida_vendor_id[brdtype], bus, dev_fn);
- if (index == 1000000) break;
+ ida_vendor_id[brdtype],
+ pdev->bus->number, pdev->devfn);
X if (nr_ctlr == 8) {
X printk(KERN_WARNING "cpqarray: This driver"
X " supports a maximum of 8 controllers.\n");
X break;
X }
-
+
X /* if it is a PCI_DEVICE_ID_NCR_53C1510, make sure it's the Compaq version of the chip */
X
X if (ida_device_id[brdtype] == PCI_DEVICE_ID_NCR_53C1510) {
- unsigned short subvendor=0;
- if(pcibios_read_config_word(bus, dev_fn,
- PCI_SUBSYSTEM_VENDOR_ID, &subvendor))
- {
- printk(KERN_DEBUG "cpqarray: failed to read subvendor\n");
- continue;
- }
+ unsigned short subvendor=pdev->subsystem_vendor;
X if(subvendor != PCI_VENDOR_ID_COMPAQ)
X {
X printk(KERN_DEBUG
@@ -584,7 +583,7 @@
X continue;
X }
X memset(hba[nr_ctlr], 0, sizeof(ctlr_info_t));
- if (cpqarray_pci_init(hba[nr_ctlr], bus, dev_fn) != 0)
+ if (cpqarray_pci_init(hba[nr_ctlr], pdev) != 0)
X {
X kfree(hba[nr_ctlr]);
X continue;
@@ -593,6 +592,8 @@
X hba[nr_ctlr]->ctlr = nr_ctlr;
X nr_ctlr++;
X
+ pdev = pci_find_device(ida_vendor_id[brdtype],
+ ida_device_id[brdtype], pdev);
X }
X }
X
@@ -603,24 +604,23 @@
X * Find the IO address of the controller, its IRQ and so forth. Fill
X * in some basic stuff into the ctlr_info_t structure.
X */
-static int cpqarray_pci_init(ctlr_info_t *c, unchar bus, unchar device_fn)
+static int cpqarray_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
X {
X ushort vendor_id, device_id, command;
X unchar cache_line_size, latency_timer;
X unchar irq, revision;
- uint addr[6];
+ unsigned long addr[6];
X __u32 board_id;
- struct pci_dev *pdev;


X
X int i;
X

- pdev = pci_find_slot(bus, device_fn);
+ c->pci_dev = pdev;
X vendor_id = pdev->vendor;
X device_id = pdev->device;
X irq = pdev->irq;
X
X for(i=0; i<6; i++)
- addr[i] = pdev->resource[i].flags;
+ addr[i] = pci_resource_start(pdev, i);
X
X if (pci_enable_device(pdev))
X return -1;
@@ -637,7 +637,7 @@
X printk("device_id = %x\n", device_id);
X printk("command = %x\n", command);
X for(i=0; i<6; i++)
- printk("addr[%d] = %x\n", i, addr[i]);
+ printk("addr[%d] = %lx\n", i, addr[i]);
X printk("revision = %x\n", revision);
X printk("irq = %x\n", irq);
X printk("cache_line_size = %x\n", cache_line_size);
@@ -646,17 +646,19 @@
X );
X
X c->intr = irq;
- c->ioaddr = addr[0] & ~0x1;
+ c->ioaddr = addr[0];
X
- /*
- * Memory base addr is first addr with the first bit _not_ set
- */
+ c->paddr = 0;
X for(i=0; i<6; i++)
- if (!(addr[i] & 0x1)) {
+ if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) {
X c->paddr = pci_resource_start (pdev, i);
X break;
X }
+ if (!c->paddr)
+ return -1;
X c->vaddr = remap_pci_mem(c->paddr, 128);
+ if (!c->vaddr)
+ return -1;
X c->board_id = board_id;
X
X for(i=0; i<NR_PRODUCTS; i++) {
@@ -679,13 +681,13 @@
X /*
X * Map (physical) PCI mem into (virtual) kernel space
X */
-static ulong remap_pci_mem(ulong base, ulong size)
+static void *remap_pci_mem(ulong base, ulong size)
X {
X ulong page_base = ((ulong) base) & PAGE_MASK;
X ulong page_offs = ((ulong) base) - page_base;
- ulong page_remapped = (ulong) ioremap(page_base, page_offs+size);
+ void *page_remapped = ioremap(page_base, page_offs+size);
X
- return (ulong) (page_remapped ? (page_remapped + page_offs) : 0UL);
+ return (page_remapped ? (page_remapped + page_offs) : NULL);
X }
X
X #ifndef MODULE
@@ -769,6 +771,7 @@
X hba[nr_ctlr]->access = *(products[j].access);
X hba[nr_ctlr]->ctlr = nr_ctlr;
X hba[nr_ctlr]->board_id = board_id;
+ hba[nr_ctlr]->pci_dev = NULL; /* not PCI */
X
X DBGINFO(
X printk("i = %d, j = %d\n", i, j);
@@ -898,7 +901,7 @@
X if (ctlr != MAJOR(creq->rq_dev)-MAJOR_NR ||
X ctlr > nr_ctlr || h == NULL)
X {
- printk("doreq cmd for %d, %x at %p\n",
+ printk(KERN_WARNING "doreq cmd for %d, %x at %p\n",
X ctlr, creq->rq_dev, creq);
X complete_buffers(creq->bh, 0);
X start_io(h);
@@ -1188,6 +1191,20 @@
X if (!arg) return -EINVAL;
X put_user(DRIVER_VERSION, (unsigned long*)arg);
X return 0;
+ case IDAGETPCIINFO:
+ {
+
+ ida_pci_info_struct pciinfo;


+
+ if (!arg) return -EINVAL;

+ pciinfo.bus = hba[ctlr]->pci_dev->bus->number;
+ pciinfo.dev_fn = hba[ctlr]->pci_dev->devfn;


+ pciinfo.board_id = hba[ctlr]->board_id;
+ if(copy_to_user((void *) arg, &pciinfo,

+ sizeof( ida_pci_info_struct)))


+ return -EFAULT;
+ return(0);
+ }

X
X case BLKFLSBUF:
X case BLKROSET:
@@ -1198,7 +1215,7 @@
X return blk_ioctl(inode->i_rdev, cmd, arg);
X
X default:
- return -EBADRQC;
+ return -EINVAL;
X }
X
X }
@@ -1378,6 +1395,8 @@
X ctlr_info_t *info_p = hba[ctlr];
X
X c = cmd_alloc(info_p);
+ if(!c)
+ return IO_ERROR;
X c->ctlr = ctlr;
X c->hdr.unit = log_unit;
X c->hdr.prio = 0;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/block/cpqarray.h linux/drivers/block/cpqarray.h
--- v2.4.0-test8/linux/drivers/block/cpqarray.h Fri Mar 3 12:54:44 2000
+++ linux/drivers/block/cpqarray.h Fri Sep 22 14:17:18 2000
@@ -87,12 +87,13 @@
X int log_drives;
X int phys_drives;
X
+ struct pci_dev *pci_dev; /* NULL if EISA */
X __u32 board_id;
X char *product_name;
X
- __u32 vaddr;
- __u32 paddr;
- __u32 ioaddr;
+ void *vaddr;
+ unsigned long paddr;
+ unsigned long ioaddr;
X int intr;
X int usage_count;
X drv_info_t drv[NWD];
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/block/floppy.c linux/drivers/block/floppy.c
--- v2.4.0-test8/linux/drivers/block/floppy.c Mon Aug 28 21:31:47 2000
+++ linux/drivers/block/floppy.c Sun Oct 1 20:35:15 2000
@@ -168,7 +168,7 @@
X * It's been recommended that take about 1/4 of the default speed
X * in some more extreme cases.
X */
-static int slow_floppy = 0;
+static int slow_floppy;
X
X #include <asm/dma.h>
X #include <asm/irq.h>
@@ -203,7 +203,7 @@
X void floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs);
X static int set_dor(int fdc, char mask, char data);
X static void register_devfs_entries (int drive) __init;
-static devfs_handle_t devfs_handle = NULL;
+static devfs_handle_t devfs_handle;
X
X #define K_64 0x10000 /* 64KB */
X

@@ -221,7 +221,7 @@
X

X #include <asm/floppy.h>
X
-static int irqdma_allocated = 0;
+static int irqdma_allocated;
X
X #define MAJOR_NR FLOPPY_MAJOR
X

@@ -259,7 +259,7 @@
X

X /* End dma memory related stuff */
X
-static unsigned long fake_change = 0;
+static unsigned long fake_change;
X static int initialising=1;
X
X static inline int TYPE(kdev_t x) {
@@ -460,10 +460,7 @@
X #define SECTSIZE (_FD_SECTSIZE(*floppy))
X
X /* Auto-detection: Disk type used until the next media change occurs. */
-static struct floppy_struct *current_type[N_DRIVE] = {
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL
-};
+static struct floppy_struct *current_type[N_DRIVE];
X
X /*
X * User-provided type information. current_type points to
@@ -472,14 +469,14 @@
X static struct floppy_struct user_params[N_DRIVE];
X
X static int floppy_sizes[256];


-static int floppy_blocksizes[256] = { 0, };
+static int floppy_blocksizes[256];
X

X /*
X * The driver is trying to determine the correct media format
X * while probing is set. rw_interrupt() clears it after a
X * successful access.
X */
-static int probing = 0;
+static int probing;
X
X /* Synchronization of FDC access. */
X #define FD_COMMAND_NONE -1
@@ -487,7 +484,7 @@
X #define FD_COMMAND_OKAY 3
X
X static volatile int command_status = FD_COMMAND_NONE;
-static unsigned long fdc_busy = 0;
+static unsigned long fdc_busy;
X static DECLARE_WAIT_QUEUE_HEAD(fdc_wait);
X static DECLARE_WAIT_QUEUE_HEAD(command_done);
X
@@ -558,9 +555,7 @@
X #define NEED_1_RECAL -2
X #define NEED_2_RECAL -3
X
-/* */
-static int usage_count = 0;
-
+static int usage_count;
X
X /* buffer related variables */
X static int buffer_track = -1;
@@ -573,8 +568,8 @@
X static int fdc; /* current fdc */
X
X static struct floppy_struct *_floppy = floppy_type;
-static unsigned char current_drive = 0;
-static long current_count_sectors = 0;
+static unsigned char current_drive;
+static long current_count_sectors;
X static unsigned char sector_t; /* sector in track */
X static unsigned char in_sector_offset; /* offset within physical sector,
X * expressed in units of 512 bytes */


@@ -625,7 +620,7 @@
X

X #define OLOGSIZE 20
X
-static void (*lasthandler)(void) = NULL;
+static void (*lasthandler)(void);
X static unsigned long interruptjiffies;
X static unsigned long resultjiffies;
X static int resultsize;
@@ -991,8 +986,7 @@
X {
X }
X
-static struct tq_struct floppy_tq =
-{ 0, 0, 0, 0 };
+static struct tq_struct floppy_tq;
X
X static void schedule_bh( void (*handler)(void*) )
X {
@@ -1269,7 +1263,7 @@
X } /* perpendicular_mode */
X
X static int fifo_depth = 0xa;
-static int no_fifo = 0;
+static int no_fifo;
X
X static int fdc_configure(void)
X {
@@ -2288,6 +2282,7 @@
X static void request_done(int uptodate)
X {
X int block;
+ unsigned long flags;
X
X probing = 0;
X reschedule_timeout(MAXTIMEOUT, "request done %d", uptodate);
@@ -2306,6 +2301,7 @@
X DRS->maxtrack = 1;
X
X /* unlock chained buffers */
+ spin_lock_irqsave(&io_request_lock, flags);
X while (current_count_sectors && !QUEUE_EMPTY &&
X current_count_sectors >= CURRENT->current_nr_sectors){
X current_count_sectors -= CURRENT->current_nr_sectors;
@@ -2313,6 +2309,8 @@
X CURRENT->sector += CURRENT->current_nr_sectors;
X end_request(1);
X }
+ spin_unlock_irqrestore(&io_request_lock, flags);
+
X if (current_count_sectors && !QUEUE_EMPTY){
X /* "unlock" last subsector */
X CURRENT->buffer += current_count_sectors <<9;
@@ -2336,7 +2334,9 @@
X DRWE->last_error_sector = CURRENT->sector;
X DRWE->last_error_generation = DRS->generation;
X }
+ spin_lock_irqsave(&io_request_lock, flags);
X end_request(0);
+ spin_unlock_irqrestore(&io_request_lock, flags);
X }
X }
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/block/genhd.c linux/drivers/block/genhd.c
--- v2.4.0-test8/linux/drivers/block/genhd.c Wed Apr 12 09:38:52 2000
+++ linux/drivers/block/genhd.c Sun Sep 17 23:16:35 2000
@@ -23,7 +23,6 @@
X #ifdef CONFIG_BLK_DEV_DAC960
X extern void DAC960_Initialize(void);
X #endif
-extern int scsi_dev_init(void);
X extern int net_dev_init(void);
X extern void console_map_init(void);
X extern int soc_probe(void);
@@ -49,9 +48,6 @@
X #ifdef CONFIG_FC4_SOC
X /* This has to be done before scsi_dev_init */
X soc_probe();
-#endif
-#ifdef CONFIG_SCSI
- scsi_dev_init();
X #endif
X #ifdef CONFIG_IEEE1394
X ieee1394_init();
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/block/ida_ioctl.h linux/drivers/block/ida_ioctl.h
--- v2.4.0-test8/linux/drivers/block/ida_ioctl.h Mon Jul 5 19:52:13 1999
+++ linux/drivers/block/ida_ioctl.h Tue Sep 19 08:01:34 2000
@@ -33,7 +33,14 @@
X #define IDAGETCTLRSIG 0x29293030
X #define IDAREVALIDATEVOLS 0x30303131
X #define IDADRIVERVERSION 0x31313232
+#define IDAGETPCIINFO 0x32323333
X
+typedef struct _ida_pci_info_struct
+{
+ unsigned char bus;
+ unsigned char dev_fn;
+ __u32 board_id;
+} ida_pci_info_struct;
X /*
X * Normally, the ioctl determines the logical unit for this command by
X * the major,minor number of the fd passed to ioctl. If you need to send
@@ -60,7 +67,7 @@
X
X union ctlr_cmds {
X drv_info_t drv;
- unsigned char buf[512];
+ unsigned char buf[1024];
X
X id_ctlr_t id_ctlr;
X drv_param_t drv_param;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/block/linear.c linux/drivers/block/linear.c
--- v2.4.0-test8/linux/drivers/block/linear.c Thu Aug 10 12:35:50 2000
+++ linux/drivers/block/linear.c Wed Dec 31 16:00:00 1969
@@ -1,213 +0,0 @@
-/*
- linear.c : Multiple Devices driver for Linux
- Copyright (C) 1994-96 Marc ZYNGIER
- <zyn...@ufr-info-p7.ibp.fr> or
- <m...@gloups.fdn.fr>
-
- Linear mode management functions.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- You should have received a copy of the GNU General Public License
- (for example /usr/src/linux/COPYING); if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <linux/module.h>
-
-#include <linux/raid/md.h>
-#include <linux/malloc.h>
-
-#include <linux/raid/linear.h>
-
-#define MAJOR_NR MD_MAJOR
-#define MD_DRIVER
-#define MD_PERSONALITY
-
-static int linear_run (mddev_t *mddev)
-{
- linear_conf_t *conf;
- struct linear_hash *table;
- mdk_rdev_t *rdev;
- int size, i, j, nb_zone;
- unsigned int curr_offset;
-
- MOD_INC_USE_COUNT;
-
- conf = kmalloc (sizeof (*conf), GFP_KERNEL);
- if (!conf)
- goto out;
- mddev->private = conf;
-
- if (md_check_ordering(mddev)) {
- printk("linear: disks are not ordered, aborting!\n");
- goto out;
- }
- /*
- * Find the smallest device.
- */
-
- conf->smallest = NULL;
- curr_offset = 0;
- ITERATE_RDEV_ORDERED(mddev,rdev,j) {
- dev_info_t *disk = conf->disks + j;
-
- disk->dev = rdev->dev;
- disk->size = rdev->size;
- disk->offset = curr_offset;
-
- curr_offset += disk->size;
-
- if (!conf->smallest || (disk->size < conf->smallest->size))
- conf->smallest = disk;
- }
-
- nb_zone = conf->nr_zones =
- md_size[mdidx(mddev)] / conf->smallest->size +
- ((md_size[mdidx(mddev)] % conf->smallest->size) ? 1 : 0);
-
- conf->hash_table = kmalloc (sizeof (struct linear_hash) * nb_zone,
- GFP_KERNEL);
- if (!conf->hash_table)
- goto out;
-
- /*
- * Here we generate the linear hash table
- */
- table = conf->hash_table;
- i = 0;
- size = 0;
- for (j = 0; j < mddev->nb_dev; j++) {
- dev_info_t *disk = conf->disks + j;
-
- if (size < 0) {
- table->dev1 = disk;
- table++;
- }
- size += disk->size;
-
- while (size) {
- table->dev0 = disk;
- size -= conf->smallest->size;
- if (size < 0)
- break;
- table->dev1 = NULL;
- table++;
- }
- }
- table->dev1 = NULL;


-
- return 0;
-

-out:
- if (conf)
- kfree(conf);
- MOD_DEC_USE_COUNT;
- return 1;
-}
-
-static int linear_stop (mddev_t *mddev)
-{
- linear_conf_t *conf = mddev_to_conf(mddev);
-
- kfree(conf->hash_table);
- kfree(conf);
-
- MOD_DEC_USE_COUNT;


-
- return 0;
-}
-

-static int linear_make_request (mddev_t *mddev,
- int rw, struct buffer_head * bh)
-{
- linear_conf_t *conf = mddev_to_conf(mddev);
- struct linear_hash *hash;
- dev_info_t *tmp_dev;
- long block;
-
- block = bh->b_rsector >> 1;
- hash = conf->hash_table + (block / conf->smallest->size);
-
- if (block >= (hash->dev0->size + hash->dev0->offset)) {
- if (!hash->dev1) {
- printk ("linear_make_request : hash->dev1==NULL for block %ld\n",
- block);
- return -1;
- }
- tmp_dev = hash->dev1;
- } else
- tmp_dev = hash->dev0;
-
- if (block >= (tmp_dev->size + tmp_dev->offset)
- || block < tmp_dev->offset) {
- printk ("linear_make_request: Block %ld out of bounds on dev %s size %ld offset %ld\n", block, kdevname(tmp_dev->dev), tmp_dev->size, tmp_dev->offset);
- return -1;
- }
- bh->b_rdev = tmp_dev->dev;
- bh->b_rsector = bh->b_rsector - (tmp_dev->offset << 1);
-
- return 1;
-}
-
-static int linear_status (char *page, mddev_t *mddev)
-{
- int sz = 0;
-
-#undef MD_DEBUG
-#ifdef MD_DEBUG
- int j;
- linear_conf_t *conf = mddev_to_conf(mddev);
-
- sz += sprintf(page+sz, " ");
- for (j = 0; j < conf->nr_zones; j++)
- {
- sz += sprintf(page+sz, "[%s",
- partition_name(conf->hash_table[j].dev0->dev));
-
- if (conf->hash_table[j].dev1)
- sz += sprintf(page+sz, "/%s] ",
- partition_name(conf->hash_table[j].dev1->dev));
- else
- sz += sprintf(page+sz, "] ");
- }
- sz += sprintf(page+sz, "\n");
-#endif
- sz += sprintf(page+sz, " %dk rounding", mddev->param.chunk_size/1024);
- return sz;
-}
-
-
-static mdk_personality_t linear_personality=
-{
- name: "linear",
- make_request: linear_make_request,
- run: linear_run,
- stop: linear_stop,
- status: linear_status,
-};
-
-#ifndef MODULE
-
-void md__init linear_init (void)
-{
- register_md_personality (LINEAR, &linear_personality);
-}
-
-#else
-
-int init_module (void)
-{
- return (register_md_personality (LINEAR, &linear_personality));
-}
-
-void cleanup_module (void)
-{
- unregister_md_personality (LINEAR);
-}
-
-#endif
-
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
--- v2.4.0-test8/linux/drivers/block/ll_rw_blk.c Mon Aug 14 08:26:34 2000
+++ linux/drivers/block/ll_rw_blk.c Fri Sep 22 17:11:37 2000
@@ -600,6 +600,8 @@
X major = MAJOR(req->rq_dev);
X if (major >= COMPAQ_SMART2_MAJOR+0 && major <= COMPAQ_SMART2_MAJOR+7)
X (q->request_fn)(q);
+ if (major >= COMPAQ_CISS_MAJOR+0 && major <= COMPAQ_CISS_MAJOR+7)
+ (q->request_fn)(q);
X if (major >= DAC960_MAJOR+0 && major <= DAC960_MAJOR+7)
X (q->request_fn)(q);
X }
@@ -1128,9 +1130,6 @@
X #ifdef CONFIG_SJCD
X sjcd_init();
X #endif CONFIG_SJCD
-#ifdef CONFIG_BLK_DEV_MD
- md_init();
-#endif CONFIG_BLK_DEV_MD
X #ifdef CONFIG_APBLOCK
X ap_init();
X #endif
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/block/loop.c linux/drivers/block/loop.c
--- v2.4.0-test8/linux/drivers/block/loop.c Tue Sep 5 14:07:30 2000
+++ linux/drivers/block/loop.c Tue Sep 19 08:31:35 2000
@@ -584,6 +584,8 @@
X type = info.lo_encrypt_type;
X if (type >= MAX_LO_CRYPT || xfer_funcs[type] == NULL)
X return -EINVAL;
+ if (type == LO_CRYPT_XOR && info.lo_encrypt_key_size == 0)
+ return -EINVAL;
X err = loop_release_xfer(lo);
X if (!err)
X err = loop_init_xfer(lo, type, &info);
@@ -793,7 +795,6 @@
X max_loop = 8;
X }
X
- printk(KERN_INFO "loop: registered device at major %d\n", MAJOR_NR);
X printk(KERN_INFO "loop: enabling %d loop devices\n", max_loop);
X
X loop_dev = kmalloc (max_loop * sizeof(struct loop_device), GFP_KERNEL);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/block/lvm-snap.c linux/drivers/block/lvm-snap.c
--- v2.4.0-test8/linux/drivers/block/lvm-snap.c Mon Aug 7 21:01:35 2000
+++ linux/drivers/block/lvm-snap.c Wed Dec 31 16:00:00 1969
@@ -1,434 +0,0 @@
-/*
- * kernel/lvm-snap.c
- *
- * Copyright (C) 2000 Andrea Arcangeli <and...@suse.de> SuSE
- *
- * LVM snapshot driver is free software; you can redistribute it and/or modify


- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * LVM driver is distributed in the hope that it will be useful,


- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License

- * along with GNU CC; see the file COPYING. If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *


- */
-
-#include <linux/kernel.h>

-#include <linux/vmalloc.h>
-#include <linux/blkdev.h>
-#include <linux/smp_lock.h>
-#include <linux/types.h>
-#include <linux/iobuf.h>
-#include <linux/lvm.h>
-
-
-static char *lvm_snap_version __attribute__ ((unused)) = "LVM 0.8final (15/02/2000)\n";
-
-extern const char *const lvm_name;
-extern int lvm_blocksizes[];
-
-void lvm_snapshot_release(lv_t *);
-
-#define hashfn(dev,block,mask,chunk_size) \
- ((HASHDEV(dev)^((block)/(chunk_size))) & (mask))
-
-static inline lv_block_exception_t *
-lvm_find_exception_table(kdev_t org_dev, unsigned long org_start, lv_t * lv)
-{
- struct list_head * hash_table = lv->lv_snapshot_hash_table, * next;
- unsigned long mask = lv->lv_snapshot_hash_mask;
- int chunk_size = lv->lv_chunk_size;
- lv_block_exception_t * ret;
- int i = 0;
-
- hash_table = &hash_table[hashfn(org_dev, org_start, mask, chunk_size)];
- ret = NULL;
- for (next = hash_table->next; next != hash_table; next = next->next)
- {
- lv_block_exception_t * exception;
-
- exception = list_entry(next, lv_block_exception_t, hash);
- if (exception->rsector_org == org_start &&
- exception->rdev_org == org_dev)
- {
- if (i)
- {
- /* fun, isn't it? :) */
- list_del(next);
- list_add(next, hash_table);
- }
- ret = exception;
- break;
- }
- i++;
- }
- return ret;
-}
-
-static inline void lvm_hash_link(lv_block_exception_t * exception,
- kdev_t org_dev, unsigned long org_start,
- lv_t * lv)
-{
- struct list_head * hash_table = lv->lv_snapshot_hash_table;
- unsigned long mask = lv->lv_snapshot_hash_mask;
- int chunk_size = lv->lv_chunk_size;
-
- hash_table = &hash_table[hashfn(org_dev, org_start, mask, chunk_size)];
- list_add(&exception->hash, hash_table);
-}
-
-int lvm_snapshot_remap_block(kdev_t * org_dev, unsigned long * org_sector,
- unsigned long pe_start, lv_t * lv)
-{
- int ret;
- unsigned long pe_off, pe_adjustment, __org_start;
- kdev_t __org_dev;
- int chunk_size = lv->lv_chunk_size;
- lv_block_exception_t * exception;
-
- pe_off = pe_start % chunk_size;
- pe_adjustment = (*org_sector-pe_off) % chunk_size;
- __org_start = *org_sector - pe_adjustment;
- __org_dev = *org_dev;
-
- ret = 0;
- exception = lvm_find_exception_table(__org_dev, __org_start, lv);
- if (exception)
- {
- *org_dev = exception->rdev_new;
- *org_sector = exception->rsector_new + pe_adjustment;
- ret = 1;
- }
- return ret;
-}
-
-static void lvm_drop_snapshot(lv_t * lv_snap, const char * reason)
-{
- kdev_t last_dev;
- int i;
-
- /* no exception storage space available for this snapshot
- or error on this snapshot --> release it */
- invalidate_buffers(lv_snap->lv_dev);
-
- for (i = last_dev = 0; i < lv_snap->lv_remap_ptr; i++) {
- if ( lv_snap->lv_block_exception[i].rdev_new != last_dev) {
- last_dev = lv_snap->lv_block_exception[i].rdev_new;
- invalidate_buffers(last_dev);
- }
- }
-
- lvm_snapshot_release(lv_snap);
-
- printk(KERN_INFO
- "%s -- giving up to snapshot %s on %s due %s\n",
- lvm_name, lv_snap->lv_snapshot_org->lv_name, lv_snap->lv_name,
- reason);
-}
-
-static inline void lvm_snapshot_prepare_blocks(unsigned long * blocks,
- unsigned long start,
- int nr_sectors,
- int blocksize)
-{
- int i, sectors_per_block, nr_blocks;
-
- sectors_per_block = blocksize >> 9;
- nr_blocks = nr_sectors / sectors_per_block;
- start /= sectors_per_block;
-
- for (i = 0; i < nr_blocks; i++)
- blocks[i] = start++;
-}
-
-static inline int get_blksize(kdev_t dev)
-{
- int correct_size = BLOCK_SIZE, i, major;
-
- major = MAJOR(dev);
- if (blksize_size[major])
- {
- i = blksize_size[major][MINOR(dev)];
- if (i)
- correct_size = i;
- }
- return correct_size;
-}
-
-#ifdef DEBUG_SNAPSHOT
-static inline void invalidate_snap_cache(unsigned long start, unsigned long nr,
- kdev_t dev)
-{
- struct buffer_head * bh;
- int sectors_per_block, i, blksize, minor;
-
- minor = MINOR(dev);
- blksize = lvm_blocksizes[minor];
- sectors_per_block = blksize >> 9;
- nr /= sectors_per_block;
- start /= sectors_per_block;
-
- for (i = 0; i < nr; i++)
- {
- bh = get_hash_table(dev, start++, blksize);
- if (bh)
- bforget(bh);
- }
-}
-#endif
-
-/*
- * copy on write handler for one snapshot logical volume
- *
- * read the original blocks and store it/them on the new one(s).
- * if there is no exception storage space free any longer --> release snapshot.
- *
- * this routine gets called for each _first_ write to a physical chunk.
- */
-int lvm_snapshot_COW(kdev_t org_phys_dev,
- unsigned long org_phys_sector,
- unsigned long org_pe_start,
- unsigned long org_virt_sector,
- lv_t * lv_snap)
-{
- const char * reason;
- unsigned long org_start, snap_start, snap_phys_dev, virt_start, pe_off;
- int idx = lv_snap->lv_remap_ptr, chunk_size = lv_snap->lv_chunk_size;
- struct kiobuf * iobuf;
- unsigned long blocks[KIO_MAX_SECTORS];
- int blksize_snap, blksize_org, min_blksize, max_blksize;
- int max_sectors, nr_sectors;
-
- /* check if we are out of snapshot space */
- if (idx >= lv_snap->lv_remap_end)
- goto fail_out_of_space;
-
- /* calculate physical boundaries of source chunk */
- pe_off = org_pe_start % chunk_size;
- org_start = org_phys_sector - ((org_phys_sector-pe_off) % chunk_size);
- virt_start = org_virt_sector - (org_phys_sector - org_start);
-
- /* calculate physical boundaries of destination chunk */
- snap_phys_dev = lv_snap->lv_block_exception[idx].rdev_new;
- snap_start = lv_snap->lv_block_exception[idx].rsector_new;
-
-#ifdef DEBUG_SNAPSHOT
- printk(KERN_INFO
- "%s -- COW: "
- "org %02d:%02d faulting %lu start %lu, "
- "snap %02d:%02d start %lu, "
- "size %d, pe_start %lu pe_off %lu, virt_sec %lu\n",
- lvm_name,
- MAJOR(org_phys_dev), MINOR(org_phys_dev), org_phys_sector,
- org_start,
- MAJOR(snap_phys_dev), MINOR(snap_phys_dev), snap_start,
- chunk_size,
- org_pe_start, pe_off,
- org_virt_sector);
-#endif
-
- iobuf = lv_snap->lv_iobuf;
-
- blksize_org = get_blksize(org_phys_dev);
- blksize_snap = get_blksize(snap_phys_dev);
- max_blksize = max(blksize_org, blksize_snap);
- min_blksize = min(blksize_org, blksize_snap);
- max_sectors = KIO_MAX_SECTORS * (min_blksize>>9);
-
- if (chunk_size % (max_blksize>>9))
- goto fail_blksize;
-
- while (chunk_size)
- {
- nr_sectors = min(chunk_size, max_sectors);
- chunk_size -= nr_sectors;
-
- iobuf->length = nr_sectors << 9;
-
- lvm_snapshot_prepare_blocks(blocks, org_start,
- nr_sectors, blksize_org);
- if (brw_kiovec(READ, 1, &iobuf, org_phys_dev,
- blocks, blksize_org) != (nr_sectors<<9))
- goto fail_raw_read;
-
- lvm_snapshot_prepare_blocks(blocks, snap_start,
- nr_sectors, blksize_snap);
- if (brw_kiovec(WRITE, 1, &iobuf, snap_phys_dev,
- blocks, blksize_snap) != (nr_sectors<<9))
- goto fail_raw_write;
- }
-
-#ifdef DEBUG_SNAPSHOT
- /* invalidate the logcial snapshot buffer cache */
- invalidate_snap_cache(virt_start, lv_snap->lv_chunk_size,
- lv_snap->lv_dev);
-#endif
-
- /* the original chunk is now stored on the snapshot volume
- so update the execption table */
- lv_snap->lv_block_exception[idx].rdev_org = org_phys_dev;
- lv_snap->lv_block_exception[idx].rsector_org = org_start;
- lvm_hash_link(lv_snap->lv_block_exception + idx,
- org_phys_dev, org_start, lv_snap);
- lv_snap->lv_remap_ptr = idx + 1;
- return 1;
-
- /* slow path */
- out:
- lvm_drop_snapshot(lv_snap, reason);
- return -1;
-
- fail_out_of_space:
- reason = "out of space";
- goto out;
- fail_raw_read:
- reason = "read error";
- goto out;
- fail_raw_write:
- reason = "write error";
- goto out;
- fail_blksize:
- reason = "blocksize error";
- goto out;
-}
-
-static int lvm_snapshot_alloc_iobuf_pages(struct kiobuf * iobuf, int sectors)
-{
- int bytes, nr_pages, err, i;
-
- bytes = sectors << 9;
- nr_pages = (bytes + ~PAGE_MASK) >> PAGE_SHIFT;
- err = expand_kiobuf(iobuf, nr_pages);
- if (err)
- goto out;
-
- err = -ENOMEM;
- iobuf->locked = 1;
- iobuf->nr_pages = 0;
- for (i = 0; i < nr_pages; i++)
- {
- struct page * page;
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,27)
- page = alloc_page(GFP_KERNEL);
- if (!page)
- goto out;
-#else
- {
- unsigned long addr = __get_free_page(GFP_USER);
- if (!addr)
- goto out;
- iobuf->pagelist[i] = addr;
- page = virt_to_page(addr);
- }
-#endif
-
- iobuf->maplist[i] = page;
- /* the only point to lock the page here is to be allowed
- to share unmap_kiobuf() in the fail-path */
-#ifndef LockPage
-#define LockPage(map) set_bit(PG_locked, &(map)->flags)
-#endif
- LockPage(page);
- iobuf->nr_pages++;
- }
- iobuf->offset = 0;
-
- err = 0;
- out:
- return err;
-}
-
-static int calc_max_buckets(void)
-{
- unsigned long mem;
-
- mem = num_physpages << PAGE_SHIFT;
- mem /= 100;
- mem *= 2;
- mem /= sizeof(struct list_head);
-
- return mem;
-}
-
-static int lvm_snapshot_alloc_hash_table(lv_t * lv)
-{
- int err;
- unsigned long buckets, max_buckets, size;
- struct list_head * hash;
-
- buckets = lv->lv_remap_end;
- max_buckets = calc_max_buckets();
- buckets = min(buckets, max_buckets);
- while (buckets & (buckets-1))
- buckets &= (buckets-1);
-
- size = buckets * sizeof(struct list_head);
-
- err = -ENOMEM;
- hash = vmalloc(size);
- lv->lv_snapshot_hash_table = hash;
-
- if (!hash)
- goto out;
-
- lv->lv_snapshot_hash_mask = buckets-1;
- while (buckets--)
- INIT_LIST_HEAD(hash+buckets);
- err = 0;
- out:
- return err;
-}
-
-int lvm_snapshot_alloc(lv_t * lv_snap)
-{
- int err, blocksize, max_sectors;
-
- err = alloc_kiovec(1, &lv_snap->lv_iobuf);
- if (err)
- goto out;
-
- blocksize = lvm_blocksizes[MINOR(lv_snap->lv_dev)];
- max_sectors = KIO_MAX_SECTORS << (PAGE_SHIFT-9);
-
- err = lvm_snapshot_alloc_iobuf_pages(lv_snap->lv_iobuf, max_sectors);
- if (err)
- goto out_free_kiovec;
-
- err = lvm_snapshot_alloc_hash_table(lv_snap);
- if (err)
- goto out_free_kiovec;
- out:
- return err;
-
- out_free_kiovec:
- unmap_kiobuf(lv_snap->lv_iobuf);
- free_kiovec(1, &lv_snap->lv_iobuf);
- goto out;
-}
-
-void lvm_snapshot_release(lv_t * lv)
-{
- if (lv->lv_block_exception)
- {
- vfree(lv->lv_block_exception);
- lv->lv_block_exception = NULL;
- }
- if (lv->lv_snapshot_hash_table)
- {
- vfree(lv->lv_snapshot_hash_table);
- lv->lv_snapshot_hash_table = NULL;
- }
- if (lv->lv_iobuf)
- {
- free_kiovec(1, &lv->lv_iobuf);
- lv->lv_iobuf = NULL;
- }
-}
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/block/lvm.c linux/drivers/block/lvm.c
--- v2.4.0-test8/linux/drivers/block/lvm.c Tue Sep 5 13:56:57 2000
+++ linux/drivers/block/lvm.c Wed Dec 31 16:00:00 1969
@@ -1,2569 +0,0 @@
-/*
- * kernel/lvm.c
- *
- * Copyright (C) 1997 - 2000 Heinz Mauelshagen, Germany
- *
- * February-November 1997
- * April-May,July-August,November 1998
- * January-March,May,July,September,October 1999
- * January,February 2000
- *
- *
- * LVM driver is free software; you can redistribute it and/or modify


- * it under the terms of the GNU General Public License as published by

- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * LVM driver is distributed in the hope that it will be useful,


- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License

- * along with GNU CC; see the file COPYING. If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- */
-
-/*
- * Changelog
- *
- * 09/11/1997 - added chr ioctls VG_STATUS_GET_COUNT
- * and VG_STATUS_GET_NAMELIST
- * 18/01/1998 - change lvm_chr_open/close lock handling
- * 30/04/1998 - changed LV_STATUS ioctl to LV_STATUS_BYNAME and
- * - added LV_STATUS_BYINDEX ioctl
- * - used lvm_status_byname_req_t and
- * lvm_status_byindex_req_t vars
- * 04/05/1998 - added multiple device support
- * 08/05/1998 - added support to set/clear extendable flag in volume group
- * 09/05/1998 - changed output of lvm_proc_get_info() because of
- * support for free (eg. longer) logical volume names
- * 12/05/1998 - added spin_locks (thanks to Pascal van Dam
- * <pas...@ramoth.xs4all.nl>)
- * 25/05/1998 - fixed handling of locked PEs in lvm_map() and lvm_chr_ioctl()
- * 26/05/1998 - reactivated verify_area by access_ok
- * 07/06/1998 - used vmalloc/vfree instead of kmalloc/kfree to go
- * beyond 128/256 KB max allocation limit per call
- * - #ifdef blocked spin_lock calls to avoid compile errors
- * with 2.0.x
- * 11/06/1998 - another enhancement to spinlock code in lvm_chr_open()
- * and use of LVM_VERSION_CODE instead of my own macros
- * (thanks to Michael Marxmeier <mi...@msede.com>)
- * 07/07/1998 - added statistics in lvm_map()
- * 08/07/1998 - saved statistics in lvm_do_lv_extend_reduce()
- * 25/07/1998 - used __initfunc macro
- * 02/08/1998 - changes for official char/block major numbers
- * 07/08/1998 - avoided init_module() and cleanup_module() to be static
- * 30/08/1998 - changed VG lv_open counter from sum of LV lv_open counters
- * to sum of LVs open (no matter how often each is)
- * 01/09/1998 - fixed lvm_gendisk.part[] index error
- * 07/09/1998 - added copying of lv_current_pe-array
- * in LV_STATUS_BYINDEX ioctl
- * 17/11/1998 - added KERN_* levels to printk
- * 13/01/1999 - fixed LV index bug in lvm_do_lv_create() which hit lvrename
- * 07/02/1999 - fixed spinlock handling bug in case of LVM_RESET
- * by moving spinlock code from lvm_chr_open()
- * to lvm_chr_ioctl()
- * - added LVM_LOCK_LVM ioctl to lvm_chr_ioctl()
- * - allowed LVM_RESET and retrieval commands to go ahead;
- * only other update ioctls are blocked now
- * - fixed pv->pe to NULL for pv_status
- * - using lv_req structure in lvm_chr_ioctl() now
- * - fixed NULL ptr reference bug in lvm_do_lv_extend_reduce()
- * caused by uncontiguous PV array in lvm_chr_ioctl(VG_REDUCE)
- * 09/02/1999 - changed BLKRASET and BLKRAGET in lvm_chr_ioctl() to
- * handle lgoical volume private read ahead sector
- * - implemented LV read_ahead handling with lvm_blk_read()
- * and lvm_blk_write()
- * 10/02/1999 - implemented 2.[12].* support function lvm_hd_name()
- * to be used in drivers/block/genhd.c by disk_name()
- * 12/02/1999 - fixed index bug in lvm_blk_ioctl(), HDIO_GETGEO
- * - enhanced gendisk insert/remove handling
- * 16/02/1999 - changed to dynamic block minor number allocation to
- * have as much as 99 volume groups with 256 logical volumes
- * as the grand total; this allows having 1 volume group with
- * up to 256 logical volumes in it
- * 21/02/1999 - added LV open count information to proc filesystem
- * - substituted redundant LVM_RESET code by calls
- * to lvm_do_vg_remove()
- * 22/02/1999 - used schedule_timeout() to be more responsive
- * in case of lvm_do_vg_remove() with lots of logical volumes
- * 19/03/1999 - fixed NULL pointer bug in module_init/lvm_init
- * 17/05/1999 - used DECLARE_WAIT_QUEUE_HEAD macro (>2.3.0)
- * - enhanced lvm_hd_name support
- * 03/07/1999 - avoided use of KERNEL_VERSION macro based ifdefs and
- * memcpy_tofs/memcpy_fromfs macro redefinitions
- * 06/07/1999 - corrected reads/writes statistic counter copy in case
- * of striped logical volume
- * 28/07/1999 - implemented snapshot logical volumes
- * - lvm_chr_ioctl
- * - LV_STATUS_BYINDEX
- * - LV_STATUS_BYNAME
- * - lvm_do_lv_create
- * - lvm_do_lv_remove
- * - lvm_map
- * - new lvm_snapshot_remap_block
- * - new lvm_snapshot_remap_new_block
- * 08/10/1999 - implemented support for multiple snapshots per
- * original logical volume
- * 12/10/1999 - support for 2.3.19
- * 11/11/1999 - support for 2.3.28
- * 21/11/1999 - changed lvm_map() interface to buffer_head based
- * 19/12/1999 - support for 2.3.33
- * 01/01/2000 - changed locking concept in lvm_map(),
- * lvm_do_vg_create() and lvm_do_lv_remove()
- * 15/01/2000 - fixed PV_FLUSH bug in lvm_chr_ioctl()
- * 24/01/2000 - ported to 2.3.40 including Alan Cox's pointer changes etc.
- * 29/01/2000 - used kmalloc/kfree again for all small structures
- * 20/01/2000 - cleaned up lvm_chr_ioctl by moving code
- * to seperated functions
- * - avoided "/dev/" in proc filesystem output
- * - avoided inline strings functions lvm_strlen etc.
- * 14/02/2000 - support for 2.3.43
- * - integrated Andrea Arcangeli's snapshot code


- *
- */
-
-

-static char *lvm_version = "LVM version 0.8final by Heinz Mauelshagen (15/02/2000)\n";
-static char *lvm_short_version = "version 0.8final (15/02/2000)";
-
-#define MAJOR_NR LVM_BLK_MAJOR
-#define DEVICE_OFF(device)
-
-#include <linux/config.h>
-#include <linux/version.h>
-
-#ifdef MODVERSIONS
-#undef MODULE
-#define MODULE
-#include <linux/modversions.h>
-#endif
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/vmalloc.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-
-#include <linux/hdreg.h>
-#include <linux/stat.h>
-#include <linux/fs.h>
-#include <linux/proc_fs.h>
-#include <linux/blkdev.h>
-#include <linux/genhd.h>
-#include <linux/locks.h>
-#include <linux/smp_lock.h>
-#include <asm/ioctl.h>
-#include <asm/segment.h>
-#include <asm/uaccess.h>
-
-#ifdef CONFIG_KERNELD
-#include <linux/kerneld.h>
-#endif
-
-#define LOCAL_END_REQUEST
-
-#include <linux/blk.h>
-#include <linux/blkpg.h>
-
-#include <linux/errno.h>
-#include <linux/lvm.h>
-
-#define LVM_CORRECT_READ_AHEAD(a) \
- (((a) < LVM_MIN_READ_AHEAD || (a) > LVM_MAX_READ_AHEAD) \
- ? LVM_MAX_READ_AHEAD : (a))
-
-#ifndef WRITEA
-# define WRITEA WRITE
-#endif
-
-/*
- * External function prototypes
- */
-#ifdef MODULE
-int init_module(void);
-void cleanup_module(void);
-#else
-extern int lvm_init(void);
-#endif
-
-static void lvm_dummy_device_request(request_queue_t *);
-#define DEVICE_REQUEST lvm_dummy_device_request
-
-static int lvm_make_request_fn(request_queue_t *, int, struct buffer_head*);
-static void lvm_plug_device_noop(request_queue_t *, kdev_t);
-
-static int lvm_blk_ioctl(struct inode *, struct file *, uint, ulong);
-static int lvm_blk_open(struct inode *, struct file *);
-
-static int lvm_chr_open(struct inode *, struct file *);
-
-static int lvm_chr_close(struct inode *, struct file *);
-static int lvm_blk_close(struct inode *, struct file *);
-
-static int lvm_chr_ioctl(struct inode *, struct file *, uint, ulong);
-
-#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS
-static int lvm_proc_get_info(char *, char **, off_t, int);
-static int (*lvm_proc_get_info_ptr) (char *, char **, off_t, int) =
-&lvm_proc_get_info;
-#endif
-
-#ifdef LVM_HD_NAME
-void lvm_hd_name(char *, int);
-#endif
-/* End external function prototypes */
-
-
-/*
- * Internal function prototypes
- */
-static void lvm_init_vars(void);
-
-/* external snapshot calls */
-int lvm_snapshot_remap_block(kdev_t *, ulong *, ulong, lv_t *);
-int lvm_snapshot_COW(kdev_t, ulong, ulong, ulong, lv_t *);
-int lvm_snapshot_alloc(lv_t *);
-void lvm_snapshot_release(lv_t *);
-
-#ifdef LVM_HD_NAME
-extern void (*lvm_hd_name_ptr) (char *, int);
-#endif
-static int lvm_map(struct buffer_head *, int);
-static int lvm_do_lock_lvm(void);
-static int lvm_do_le_remap(vg_t *, void *);
-static int lvm_do_pe_lock_unlock(vg_t *r, void *);
-static int lvm_do_vg_create(int, void *);
-static int lvm_do_vg_extend(vg_t *, void *);
-static int lvm_do_vg_reduce(vg_t *, void *);
-static int lvm_do_vg_remove(int);
-static int lvm_do_lv_create(int, char *, lv_t *);
-static int lvm_do_lv_remove(int, char *, int);
-static int lvm_do_lv_extend_reduce(int, char *, lv_t *);
-static int lvm_do_lv_status_byname(vg_t *r, void *);
-static int lvm_do_lv_status_byindex(vg_t *, void *arg);
-static int lvm_do_pv_change(vg_t*, void*);
-static int lvm_do_pv_status(vg_t *, void *);
-static void lvm_geninit(struct gendisk *);
-#ifdef LVM_GET_INODE
-static struct inode *lvm_get_inode(int);
-void lvm_clear_inode(struct inode *);
-#endif
-/* END Internal function prototypes */
-
-
-/* volume group descriptor area pointers */
-static vg_t *vg[ABS_MAX_VG];
-static pv_t *pvp = NULL;
-static lv_t *lvp = NULL;
-static pe_t *pep = NULL;
-static pe_t *pep1 = NULL;
-
-
-/* map from block minor number to VG and LV numbers */
-typedef struct {
- int vg_number;
- int lv_number;
-} vg_lv_map_t;
-static vg_lv_map_t vg_lv_map[ABS_MAX_LV];
-
-
-/* Request structures (lvm_chr_ioctl()) */
-static pv_change_req_t pv_change_req;
-static pv_flush_req_t pv_flush_req;
-static pv_status_req_t pv_status_req;
-static pe_lock_req_t pe_lock_req;
-static le_remap_req_t le_remap_req;
-static lv_req_t lv_req;
-
-#ifdef LVM_TOTAL_RESET
-static int lvm_reset_spindown = 0;
-#endif
-
-static char pv_name[NAME_LEN];
-/* static char rootvg[NAME_LEN] = { 0, }; */
-static uint lv_open = 0;
-const char *const lvm_name = LVM_NAME;
-static int lock = 0;
-static int loadtime = 0;
-static uint vg_count = 0;
-static long lvm_chr_open_count = 0;
-static ushort lvm_iop_version = LVM_DRIVER_IOP_VERSION;
-static DECLARE_WAIT_QUEUE_HEAD(lvm_snapshot_wait);
-static DECLARE_WAIT_QUEUE_HEAD(lvm_wait);
-static DECLARE_WAIT_QUEUE_HEAD(lvm_map_wait);
-
-static spinlock_t lvm_lock = SPIN_LOCK_UNLOCKED;
-
-static devfs_handle_t lvm_devfs_handle;
-static devfs_handle_t vg_devfs_handle[MAX_VG];
-static devfs_handle_t ch_devfs_handle[MAX_VG];
-static devfs_handle_t lv_devfs_handle[MAX_LV];
-
-static struct file_operations lvm_chr_fops =
-{
- owner: THIS_MODULE,
- open: lvm_chr_open,
- release: lvm_chr_close,
- ioctl: lvm_chr_ioctl,
-};
-
-static struct block_device_operations lvm_blk_dops =
-{
- open: lvm_blk_open,
- release: lvm_blk_close,
- ioctl: lvm_blk_ioctl
-};
-
-/* gendisk structures */
-static struct hd_struct lvm_hd_struct[MAX_LV];
-static int lvm_blocksizes[MAX_LV] =
-{0,};
-static int lvm_size[MAX_LV] =
-{0,};
-static struct gendisk lvm_gendisk =
-{
- MAJOR_NR, /* major # */
- LVM_NAME, /* name of major */
- 0, /* number of times minor is shifted
- to get real minor */
- 1, /* maximum partitions per device */
- lvm_hd_struct, /* partition table */
- lvm_size, /* device size in blocks, copied
- to block_size[] */
- MAX_LV, /* number or real devices */
- NULL, /* internal */
- NULL, /* pointer to next gendisk struct (internal) */
-};
-
-
-#ifdef MODULE
-/*
- * Module initialization...
- */
-int init_module(void)
-#else
-/*
- * Driver initialization...
- */
-#ifdef __initfunc
-__initfunc(int lvm_init(void))
-#else
-int __init lvm_init(void)
-#endif
-#endif /* #ifdef MODULE */
-{
- struct gendisk *gendisk_ptr = NULL;
-
- if (register_chrdev(LVM_CHAR_MAJOR, lvm_name, &lvm_chr_fops) < 0) {
- printk(KERN_ERR "%s -- register_chrdev failed\n", lvm_name);
- return -EIO;
- }
- if (register_blkdev(MAJOR_NR, lvm_name, &lvm_blk_dops) < 0) {
- printk("%s -- register_blkdev failed\n", lvm_name);
- if (unregister_chrdev(LVM_CHAR_MAJOR, lvm_name) < 0)
- printk(KERN_ERR "%s -- unregister_chrdev failed\n", lvm_name);
- return -EIO;
- }
-
- lvm_devfs_handle = devfs_register(
- 0 , "lvm", 0, 0, LVM_CHAR_MAJOR,
- S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,
- &lvm_chr_fops, NULL);
-
-#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS
- create_proc_info_entry(LVM_NAME, S_IFREG | S_IRUGO,
- &proc_root, lvm_proc_get_info_ptr);
-#endif
-
- lvm_init_vars();
- lvm_geninit(&lvm_gendisk);
-
- /* insert our gendisk at the corresponding major */
- if (gendisk_head != NULL) {
- gendisk_ptr = gendisk_head;
- while (gendisk_ptr->next != NULL &&
- gendisk_ptr->major > lvm_gendisk.major) {
- gendisk_ptr = gendisk_ptr->next;
- }
- lvm_gendisk.next = gendisk_ptr->next;
- gendisk_ptr->next = &lvm_gendisk;
- } else {
- gendisk_head = &lvm_gendisk;
- lvm_gendisk.next = NULL;
- }
-
-#ifdef LVM_HD_NAME
- /* reference from drivers/block/genhd.c */
- lvm_hd_name_ptr = lvm_hd_name;
-#endif
-
- blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
- blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR), lvm_make_request_fn);
- blk_queue_pluggable(BLK_DEFAULT_QUEUE(MAJOR_NR), lvm_plug_device_noop);
- /* optional read root VGDA */
-/*
- if ( *rootvg != 0) vg_read_with_pv_and_lv ( rootvg, &vg);
-*/
-
- printk(KERN_INFO
- "%s%s -- "
-#ifdef MODULE
- "Module"
-#else
- "Driver"
-#endif
- " successfully initialized\n",
- lvm_version, lvm_name);
-
- return 0;
-} /* init_module() / lvm_init() */
-
-
-#ifdef MODULE
-/*
- * Module cleanup...
- */
-void cleanup_module(void)
-{
- struct gendisk *gendisk_ptr = NULL, *gendisk_ptr_prev = NULL;
-
- devfs_unregister (lvm_devfs_handle);
-
- if (unregister_chrdev(LVM_CHAR_MAJOR, lvm_name) < 0) {
- printk(KERN_ERR "%s -- unregister_chrdev failed\n", lvm_name);
- }
- if (unregister_blkdev(MAJOR_NR, lvm_name) < 0) {
- printk(KERN_ERR "%s -- unregister_blkdev failed\n", lvm_name);
- }
- blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-
- gendisk_ptr = gendisk_ptr_prev = gendisk_head;
- while (gendisk_ptr != NULL) {
- if (gendisk_ptr == &lvm_gendisk)
- break;
- gendisk_ptr_prev = gendisk_ptr;
- gendisk_ptr = gendisk_ptr->next;
- }
- /* delete our gendisk from chain */
- if (gendisk_ptr == &lvm_gendisk)
- gendisk_ptr_prev->next = gendisk_ptr->next;
-
- blk_size[MAJOR_NR] = NULL;
- blksize_size[MAJOR_NR] = NULL;
-
-#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS
- remove_proc_entry(LVM_NAME, &proc_root);
-#endif
-
-#ifdef LVM_HD_NAME
- /* reference from linux/drivers/block/genhd.c */
- lvm_hd_name_ptr = NULL;
-#endif
-
- printk(KERN_INFO "%s -- Module successfully deactivated\n", lvm_name);
-
- return;
-} /* void cleanup_module() */
-#endif /* #ifdef MODULE */
-
-
-/*
- * support function to initialize lvm variables
- */
-#ifdef __initfunc
-__initfunc(void lvm_init_vars(void))
-#else
-void __init lvm_init_vars(void)
-#endif
-{
- int v;
-
- loadtime = CURRENT_TIME;
-
- pe_lock_req.lock = UNLOCK_PE;
- pe_lock_req.data.lv_dev = \
- pe_lock_req.data.pv_dev = \
- pe_lock_req.data.pv_offset = 0;
-
- /* Initialize VG pointers */
- for (v = 0; v < ABS_MAX_VG; v++) vg[v] = NULL;
-
- /* Initialize LV -> VG association */
- for (v = 0; v < ABS_MAX_LV; v++) {
- /* index ABS_MAX_VG never used for real VG */
- vg_lv_map[v].vg_number = ABS_MAX_VG;
- vg_lv_map[v].lv_number = -1;
- }
-
- return;
-} /* lvm_init_vars() */
-
-
-/********************************************************************
- *
- * Character device functions
- *
- ********************************************************************/
-
-/*
- * character device open routine
- */
-static int lvm_chr_open(struct inode *inode,
- struct file *file)
-{
- int minor = MINOR(inode->i_rdev);
-
-#ifdef DEBUG
- printk(KERN_DEBUG
- "%s -- lvm_chr_open MINOR: %d VG#: %d mode: 0x%X lock: %d\n",
- lvm_name, minor, VG_CHR(minor), file->f_mode, lock);
-#endif
-
- /* super user validation */
- if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-
- /* Group special file open */
- if (VG_CHR(minor) > MAX_VG) return -ENXIO;
-
- lvm_chr_open_count++;
- return 0;
-} /* lvm_chr_open() */
-
-
-/*
- * character device i/o-control routine
- *
- * Only one changing process can do changing ioctl at one time,
- * others will block.
- *
- */
-static int lvm_chr_ioctl(struct inode *inode, struct file *file,
- uint command, ulong a)
-{
- int minor = MINOR(inode->i_rdev);
- uint extendable, l, v;
- void *arg = (void *) a;
- lv_t lv;
- vg_t* vg_ptr = vg[VG_CHR(minor)];
-
- /* otherwise cc will complain about unused variables */
- (void) lvm_lock;
-
-
-#ifdef DEBUG_IOCTL
- printk(KERN_DEBUG
- "%s -- lvm_chr_ioctl: command: 0x%X MINOR: %d "
- "VG#: %d mode: 0x%X\n",
- lvm_name, command, minor, VG_CHR(minor), file->f_mode);
-#endif
-
-#ifdef LVM_TOTAL_RESET
- if (lvm_reset_spindown > 0) return -EACCES;
-#endif
-
- /* Main command switch */
- switch (command) {
- case LVM_LOCK_LVM:
- /* lock the LVM */
- return lvm_do_lock_lvm();
-
- case LVM_GET_IOP_VERSION:
- /* check lvm version to ensure driver/tools+lib
- interoperability */
- if (copy_to_user(arg, &lvm_iop_version, sizeof(ushort)) != 0)
- return -EFAULT;
- return 0;
-
-#ifdef LVM_TOTAL_RESET
- case LVM_RESET:
- /* lock reset function */
- lvm_reset_spindown = 1;
- for (v = 0; v < ABS_MAX_VG; v++) {
- if (vg[v] != NULL) lvm_do_vg_remove(v);
- }
-
-#ifdef MODULE
- while (GET_USE_COUNT(&__this_module) < 1)
- MOD_INC_USE_COUNT;
- while (GET_USE_COUNT(&__this_module) > 1)
- MOD_DEC_USE_COUNT;
-#endif /* MODULE */
- lock = 0; /* release lock */
- wake_up_interruptible(&lvm_wait);
- return 0;
-#endif /* LVM_TOTAL_RESET */
-
-
- case LE_REMAP:
- /* remap a logical extent (after moving the physical extent) */
- return lvm_do_le_remap(vg_ptr,arg);
-
- case PE_LOCK_UNLOCK:
- /* lock/unlock i/o to a physical extent to move it to another
- physical volume (move's done in user space's pvmove) */
- return lvm_do_pe_lock_unlock(vg_ptr,arg);
-
- case VG_CREATE:
- /* create a VGDA */
- return lvm_do_vg_create(minor, arg);
-
- case VG_REMOVE:
- /* remove an inactive VGDA */
- return lvm_do_vg_remove(minor);
-
- case VG_EXTEND:
- /* extend a volume group */
- return lvm_do_vg_extend(vg_ptr,arg);
-
- case VG_REDUCE:
- /* reduce a volume group */
- return lvm_do_vg_reduce(vg_ptr,arg);
-
-
- case VG_SET_EXTENDABLE:
- /* set/clear extendability flag of volume group */
- if (vg_ptr == NULL) return -ENXIO;
- if (copy_from_user(&extendable, arg, sizeof(extendable)) != 0)
- return -EFAULT;
-
- if (extendable == VG_EXTENDABLE ||
- extendable == ~VG_EXTENDABLE) {
- if (extendable == VG_EXTENDABLE)
- vg_ptr->vg_status |= VG_EXTENDABLE;
- else
- vg_ptr->vg_status &= ~VG_EXTENDABLE;
- } else return -EINVAL;


- return 0;
-
-

- case VG_STATUS:
- /* get volume group data (only the vg_t struct) */
- if (vg_ptr == NULL) return -ENXIO;
- if (copy_to_user(arg, vg_ptr, sizeof(vg_t)) != 0)
- return -EFAULT;


- return 0;
-
-

- case VG_STATUS_GET_COUNT:
- /* get volume group count */
- if (copy_to_user(arg, &vg_count, sizeof(vg_count)) != 0)
- return -EFAULT;


- return 0;
-
-

- case VG_STATUS_GET_NAMELIST:
- /* get volume group count */
- for (l = v = 0; v < ABS_MAX_VG; v++) {
- if (vg[v] != NULL) {
- if (copy_to_user(arg + l++ * NAME_LEN,
- vg[v]->vg_name,
- NAME_LEN) != 0)


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 040'
echo 'File patch-2.4.0-test9 is continued in part 041'
echo "041" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part041

#!/bin/sh -x
# this is part 041 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 041; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

- return -EFAULT;
- }
- }

- return 0;
-
-

- case LV_CREATE:
- case LV_REMOVE:
- case LV_EXTEND:
- case LV_REDUCE:
- /* create, remove, extend or reduce a logical volume */


- if (vg_ptr == NULL) return -ENXIO;

- if (copy_from_user(&lv_req, arg, sizeof(lv_req)) != 0)
- return -EFAULT;
-
- if (command != LV_REMOVE) {
- if (copy_from_user(&lv, lv_req.lv, sizeof(lv_t)) != 0)
- return -EFAULT;
- }
- switch (command) {
- case LV_CREATE:
- return lvm_do_lv_create(minor, lv_req.lv_name, &lv);
-
- case LV_REMOVE:
- return lvm_do_lv_remove(minor, lv_req.lv_name, -1);
-
- case LV_EXTEND:
- case LV_REDUCE:
- return lvm_do_lv_extend_reduce(minor, lv_req.lv_name, &lv);
- }
-
-
- case LV_STATUS_BYNAME:
- /* get status of a logical volume by name */
- return lvm_do_lv_status_byname(vg_ptr,arg);
-
- case LV_STATUS_BYINDEX:
- /* get status of a logical volume by index */
- return lvm_do_lv_status_byindex(vg_ptr,arg);
-
- case PV_CHANGE:
- /* change a physical volume */
- return lvm_do_pv_change(vg_ptr,arg);
-
- case PV_STATUS:
- /* get physical volume data (pv_t structure only) */
- return lvm_do_pv_status(vg_ptr,arg);
-
- case PV_FLUSH:
- /* physical volume buffer flush/invalidate */
- if (copy_from_user(&pv_flush_req, arg,
- sizeof(pv_flush_req)) != 0)
- return -EFAULT;
-
- for ( v = 0; v < ABS_MAX_VG; v++) {
- unsigned int p;
- if ( vg[v] == NULL) continue;
- for ( p = 0; p < vg[v]->pv_max; p++) {
- if ( vg[v]->pv[p] != NULL &&
- strcmp ( vg[v]->pv[p]->pv_name,
- pv_flush_req.pv_name) == 0) {
- fsync_dev ( vg[v]->pv[p]->pv_dev);
- invalidate_buffers ( vg[v]->pv[p]->pv_dev);


- return 0;
- }
- }
- }

- return 0;
-
- default:
- printk(KERN_WARNING
- "%s -- lvm_chr_ioctl: unknown command %x\n",
- lvm_name, command);
- return -EINVAL;
- }
-
- return 0;
-} /* lvm_chr_ioctl */
-
-
-/*
- * character device close routine
- */
-static int lvm_chr_close(struct inode *inode, struct file *file)
-{
-#ifdef DEBUG


- int minor = MINOR(inode->i_rdev);

- printk(KERN_DEBUG
- "%s -- lvm_chr_close VG#: %d\n", lvm_name, VG_CHR(minor));
-#endif
-
- lock_kernel();
-#ifdef LVM_TOTAL_RESET
- if (lvm_reset_spindown > 0) {
- lvm_reset_spindown = 0;
- lvm_chr_open_count = 1;
- }
-#endif
-
- if (lvm_chr_open_count > 0) lvm_chr_open_count--;
- if (lock == current->pid) {


- lock = 0; /* release lock */
- wake_up_interruptible(&lvm_wait);
- }

- unlock_kernel();
-
- return 0;
-} /* lvm_chr_close() */
-


-
-
-/********************************************************************
- *

- * Block device functions


- *
- ********************************************************************/
-
-/*

- * block device open routine
- */
-static int lvm_blk_open(struct inode *inode, struct file *file)


-{
- int minor = MINOR(inode->i_rdev);

- lv_t *lv_ptr;
- vg_t *vg_ptr = vg[VG_BLK(minor)];
-
-#ifdef DEBUG_LVM_BLK_OPEN
- printk(KERN_DEBUG
- "%s -- lvm_blk_open MINOR: %d VG#: %d LV#: %d mode: 0x%X\n",
- lvm_name, minor, VG_BLK(minor), LV_BLK(minor), file->f_mode);


-#endif
-
-#ifdef LVM_TOTAL_RESET
- if (lvm_reset_spindown > 0)

- return -EPERM;
-#endif
-
- if (vg_ptr != NULL &&
- (vg_ptr->vg_status & VG_ACTIVE) &&
- (lv_ptr = vg_ptr->lv[LV_BLK(minor)]) != NULL &&
- LV_BLK(minor) >= 0 &&
- LV_BLK(minor) < vg_ptr->lv_max) {
-
- /* Check parallel LV spindown (LV remove) */
- if (lv_ptr->lv_status & LV_SPINDOWN) return -EPERM;
-
- /* Check inactive LV and open for read/write */
- if (file->f_mode & O_RDWR) {
- if (!(lv_ptr->lv_status & LV_ACTIVE)) return -EPERM;
- if (!(lv_ptr->lv_access & LV_WRITE)) return -EACCES;
- }
-
- /* be sure to increment VG counter */
- if (lv_ptr->lv_open == 0) vg_ptr->lv_open++;
- lv_ptr->lv_open++;
-
- MOD_INC_USE_COUNT;
-
-#ifdef DEBUG_LVM_BLK_OPEN
- printk(KERN_DEBUG
- "%s -- lvm_blk_open MINOR: %d VG#: %d LV#: %d size: %d\n",
- lvm_name, minor, VG_BLK(minor), LV_BLK(minor),
- lv_ptr->lv_size);
-#endif


-
- return 0;
- }

- return -ENXIO;
-} /* lvm_blk_open() */
-
-
-/*
- * block device i/o-control routine
- */
-static int lvm_blk_ioctl(struct inode *inode, struct file *file,


- uint command, ulong a)
-{
- int minor = MINOR(inode->i_rdev);

- vg_t *vg_ptr = vg[VG_BLK(minor)];
- lv_t *lv_ptr = vg_ptr->lv[LV_BLK(minor)];


- void *arg = (void *) a;

- struct hd_geometry *hd = (struct hd_geometry *) a;


-
-#ifdef DEBUG_IOCTL
- printk(KERN_DEBUG

- "%s -- lvm_blk_ioctl MINOR: %d command: 0x%X arg: %X "
- "VG#: %dl LV#: %d\n",
- lvm_name, minor, command, (ulong) arg,
- VG_BLK(minor), LV_BLK(minor));
-#endif
-
- switch (command) {
- case BLKGETSIZE:
- /* return device size */
-#ifdef DEBUG_IOCTL
- printk(KERN_DEBUG
- "%s -- lvm_blk_ioctl -- BLKGETSIZE: %u\n",
- lvm_name, lv_ptr->lv_size);
-#endif
- if (put_user(lv_ptr->lv_size, (long *)arg))
- return -EFAULT;
- break;
-
-
- case BLKFLSBUF:
- /* flush buffer cache */


- if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-

-#ifdef DEBUG_IOCTL
- printk(KERN_DEBUG
- "%s -- lvm_blk_ioctl -- BLKFLSBUF\n", lvm_name);
-#endif
- fsync_dev(inode->i_rdev);
- invalidate_buffers(inode->i_rdev);
- break;
-
-
- case BLKRASET:
- /* set read ahead for block device */


- if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-

-#ifdef DEBUG_IOCTL
- printk(KERN_DEBUG
- "%s -- lvm_blk_ioctl -- BLKRASET: %d sectors for %02X:%02X\n",
- lvm_name, (long) arg, MAJOR(inode->i_rdev), minor);
-#endif
- if ((long) arg < LVM_MIN_READ_AHEAD ||
- (long) arg > LVM_MAX_READ_AHEAD)
- return -EINVAL;
- read_ahead[MAJOR_NR] = lv_ptr->lv_read_ahead = (long) arg;
- break;
-
-
- case BLKRAGET:
- /* get current read ahead setting */
-#ifdef DEBUG_IOCTL
- printk(KERN_DEBUG
- "%s -- lvm_blk_ioctl -- BLKRAGET\n", lvm_name);
-#endif
- if (put_user(lv_ptr->lv_read_ahead, (long *)arg))
- return -EFAULT;
- break;
-
-
- case HDIO_GETGEO:
- /* get disk geometry */
-#ifdef DEBUG_IOCTL
- printk(KERN_DEBUG
- "%s -- lvm_blk_ioctl -- HDIO_GETGEO\n", lvm_name);
-#endif
- if (hd == NULL)
- return -EINVAL;
- {
- unsigned char heads = 64;
- unsigned char sectors = 32;
- long start = 0;
- short cylinders = lv_ptr->lv_size / heads / sectors;
-
- if (copy_to_user((char *) &hd->heads, &heads,
- sizeof(heads)) != 0 ||
- copy_to_user((char *) &hd->sectors, &sectors,
- sizeof(sectors)) != 0 ||
- copy_to_user((short *) &hd->cylinders,
- &cylinders, sizeof(cylinders)) != 0 ||
- copy_to_user((long *) &hd->start, &start,
- sizeof(start)) != 0)


- return -EFAULT;
- }
-

-#ifdef DEBUG_IOCTL
- printk(KERN_DEBUG
- "%s -- lvm_blk_ioctl -- cylinders: %d\n",
- lvm_name, lv_ptr->lv_size / heads / sectors);
-#endif
- break;
-
-
- case LV_SET_ACCESS:
- /* set access flags of a logical volume */


- if (!capable(CAP_SYS_ADMIN)) return -EACCES;

- lv_ptr->lv_access = (ulong) arg;
- break;
-
-
- case LV_SET_STATUS:
- /* set status flags of a logical volume */


- if (!capable(CAP_SYS_ADMIN)) return -EACCES;

- if (!((ulong) arg & LV_ACTIVE) && lv_ptr->lv_open > 1)
- return -EPERM;
- lv_ptr->lv_status = (ulong) arg;
- break;
-
-
- case LV_SET_ALLOCATION:
- /* set allocation flags of a logical volume */


- if (!capable(CAP_SYS_ADMIN)) return -EACCES;

- lv_ptr->lv_allocation = (ulong) arg;
- break;
-
-
- default:
- printk(KERN_WARNING
- "%s -- lvm_blk_ioctl: unknown command %d\n",
- lvm_name, command);
- return -EINVAL;
- }
-
- return 0;
-} /* lvm_blk_ioctl() */
-
-
-/*
- * block device close routine
- */
-static int lvm_blk_close(struct inode *inode, struct file *file)


-{
- int minor = MINOR(inode->i_rdev);

- vg_t *vg_ptr = vg[VG_BLK(minor)];
- lv_t *lv_ptr = vg_ptr->lv[LV_BLK(minor)];


-
-#ifdef DEBUG
- printk(KERN_DEBUG

- "%s -- lvm_blk_close MINOR: %d VG#: %d LV#: %d\n",
- lvm_name, minor, VG_BLK(minor), LV_BLK(minor));
-#endif
-
- sync_dev(inode->i_rdev);
- if (lv_ptr->lv_open == 1) vg_ptr->lv_open--;
- lv_ptr->lv_open--;


-
- MOD_DEC_USE_COUNT;
-
- return 0;

-} /* lvm_blk_close() */
-


-
-#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS

-/*
- * Support function /proc-Filesystem
- */
-#define LVM_PROC_BUF ( i == 0 ? dummy_buf : &buf[sz])
-
-static int lvm_proc_get_info(char *page, char **start, off_t pos, int count)
-{
- int c, i, l, p, v, vg_counter, pv_counter, lv_counter, lv_open_counter,
- lv_open_total, pe_t_bytes, lv_block_exception_t_bytes, seconds;
- static off_t sz;
- off_t sz_last;
- char allocation_flag, inactive_flag, rw_flag, stripes_flag;
- char *lv_name, *pv_name;
- static char *buf = NULL;
- static char dummy_buf[160]; /* sized for 2 lines */
- vg_t *vg_ptr;
- lv_t *lv_ptr;
- pv_t *pv_ptr;
-
-
-#ifdef DEBUG_LVM_PROC_GET_INFO
- printk(KERN_DEBUG
- "%s - lvm_proc_get_info CALLED pos: %lu count: %d whence: %d\n",
- lvm_name, pos, count, whence);
-#endif
-
- if (pos == 0 || buf == NULL) {
- sz_last = vg_counter = pv_counter = lv_counter = lv_open_counter = \
- lv_open_total = pe_t_bytes = lv_block_exception_t_bytes = 0;
-
- /* search for activity */
- for (v = 0; v < ABS_MAX_VG; v++) {
- if ((vg_ptr = vg[v]) != NULL) {
- vg_counter++;
- pv_counter += vg_ptr->pv_cur;
- lv_counter += vg_ptr->lv_cur;
- if (vg_ptr->lv_cur > 0) {
- for (l = 0; l < vg[v]->lv_max; l++) {
- if ((lv_ptr = vg_ptr->lv[l]) != NULL) {
- pe_t_bytes += lv_ptr->lv_allocated_le;
- if (lv_ptr->lv_block_exception != NULL)
- lv_block_exception_t_bytes += lv_ptr->lv_remap_end;
- if (lv_ptr->lv_open > 0) {
- lv_open_counter++;
- lv_open_total += lv_ptr->lv_open;
- }
- }
- }
- }
- }
- }
- pe_t_bytes *= sizeof(pe_t);
- lv_block_exception_t_bytes *= sizeof(lv_block_exception_t);
-
- if (buf != NULL) {
-#ifdef DEBUG_KFREE
- printk(KERN_DEBUG
- "%s -- kfree %d\n", lvm_name, __LINE__);
-#endif
- kfree(buf);
- buf = NULL;
- }
- /* 2 times: first to get size to allocate buffer,
- 2nd to fill the malloced buffer */
- for (i = 0; i < 2; i++) {
- sz = 0;
- sz += sprintf(LVM_PROC_BUF,
- "LVM "
-#ifdef MODULE
- "module"
-#else
- "driver"
-#endif
- " %s\n\n"
- "Total: %d VG%s %d PV%s %d LV%s ",
- lvm_short_version,
- vg_counter, vg_counter == 1 ? "" : "s",
- pv_counter, pv_counter == 1 ? "" : "s",
- lv_counter, lv_counter == 1 ? "" : "s");
- sz += sprintf(LVM_PROC_BUF,
- "(%d LV%s open",
- lv_open_counter,
- lv_open_counter == 1 ? "" : "s");
- if (lv_open_total > 0)
- sz += sprintf(LVM_PROC_BUF,
- " %d times)\n",
- lv_open_total);
- else
- sz += sprintf(LVM_PROC_BUF, ")");
- sz += sprintf(LVM_PROC_BUF,
- "\nGlobal: %lu bytes malloced IOP version: %d ",
- vg_counter * sizeof(vg_t) +
- pv_counter * sizeof(pv_t) +
- lv_counter * sizeof(lv_t) +
- pe_t_bytes + lv_block_exception_t_bytes + sz_last,
- lvm_iop_version);
-
- seconds = CURRENT_TIME - loadtime;
- if (seconds < 0)
- loadtime = CURRENT_TIME + seconds;
- if (seconds / 86400 > 0) {
- sz += sprintf(LVM_PROC_BUF, "%d day%s ",
- seconds / 86400,
- seconds / 86400 == 0 ||
- seconds / 86400 > 1 ? "s" : "");
- }
- sz += sprintf(LVM_PROC_BUF, "%d:%02d:%02d active\n",
- (seconds % 86400) / 3600,
- (seconds % 3600) / 60,
- seconds % 60);
-
- if (vg_counter > 0) {


- for (v = 0; v < ABS_MAX_VG; v++) {

- /* volume group */
- if ((vg_ptr = vg[v]) != NULL) {
- inactive_flag = ' ';
- if (!(vg_ptr->vg_status & VG_ACTIVE)) inactive_flag = 'I';
- sz += sprintf(LVM_PROC_BUF,
- "\nVG: %c%s [%d PV, %d LV/%d open] "
- " PE Size: %d KB\n"
- " Usage [KB/PE]: %d /%d total "
- "%d /%d used %d /%d free",
- inactive_flag,
- vg_ptr->vg_name,
- vg_ptr->pv_cur,
- vg_ptr->lv_cur,
- vg_ptr->lv_open,
- vg_ptr->pe_size >> 1,
- vg_ptr->pe_size * vg_ptr->pe_total >> 1,
- vg_ptr->pe_total,
- vg_ptr->pe_allocated * vg_ptr->pe_size >> 1,
- vg_ptr->pe_allocated,
- (vg_ptr->pe_total - vg_ptr->pe_allocated) *
- vg_ptr->pe_size >> 1,
- vg_ptr->pe_total - vg_ptr->pe_allocated);
-
- /* physical volumes */
- sz += sprintf(LVM_PROC_BUF,
- "\n PV%s ",
- vg_ptr->pv_cur == 1 ? ": " : "s:");
- c = 0;
- for (p = 0; p < vg_ptr->pv_max; p++) {
- if ((pv_ptr = vg_ptr->pv[p]) != NULL) {
- inactive_flag = 'A';
- if (!(pv_ptr->pv_status & PV_ACTIVE))
- inactive_flag = 'I';
- allocation_flag = 'A';
- if (!(pv_ptr->pv_allocatable & PV_ALLOCATABLE))
- allocation_flag = 'N';
- pv_name = strchr(pv_ptr->pv_name+1,'/');
- if ( pv_name == 0) pv_name = pv_ptr->pv_name;
- else pv_name++;
- sz += sprintf(LVM_PROC_BUF,
- "[%c%c] %-21s %8d /%-6d "
- "%8d /%-6d %8d /%-6d",
- inactive_flag,
- allocation_flag,
- pv_name,
- pv_ptr->pe_total *
- pv_ptr->pe_size >> 1,
- pv_ptr->pe_total,
- pv_ptr->pe_allocated *
- pv_ptr->pe_size >> 1,
- pv_ptr->pe_allocated,
- (pv_ptr->pe_total -
- pv_ptr->pe_allocated) *
- pv_ptr->pe_size >> 1,
- pv_ptr->pe_total -
- pv_ptr->pe_allocated);
- c++;
- if (c < vg_ptr->pv_cur)
- sz += sprintf(LVM_PROC_BUF,
- "\n ");
- }
- }
-
- /* logical volumes */
- sz += sprintf(LVM_PROC_BUF,
- "\n LV%s ",
- vg_ptr->lv_cur == 1 ? ": " : "s:");
- c = 0;
- for (l = 0; l < vg[v]->lv_max; l++) {
- if ((lv_ptr = vg_ptr->lv[l]) != NULL) {
- inactive_flag = 'A';
- if (!(lv_ptr->lv_status & LV_ACTIVE))
- inactive_flag = 'I';
- rw_flag = 'R';
- if (lv_ptr->lv_access & LV_WRITE)
- rw_flag = 'W';
- allocation_flag = 'D';
- if (lv_ptr->lv_allocation & LV_CONTIGUOUS)
- allocation_flag = 'C';
- stripes_flag = 'L';
- if (lv_ptr->lv_stripes > 1)
- stripes_flag = 'S';
- sz += sprintf(LVM_PROC_BUF,
- "[%c%c%c%c",
- inactive_flag,
- rw_flag,
- allocation_flag,
- stripes_flag);
- if (lv_ptr->lv_stripes > 1)
- sz += sprintf(LVM_PROC_BUF, "%-2d",
- lv_ptr->lv_stripes);
- else
- sz += sprintf(LVM_PROC_BUF, " ");
- lv_name = strrchr(lv_ptr->lv_name, '/');
- if ( lv_name == 0) lv_name = lv_ptr->lv_name;
- else lv_name++;
- sz += sprintf(LVM_PROC_BUF, "] %-25s", lv_name);
- if (strlen(lv_name) > 25)
- sz += sprintf(LVM_PROC_BUF,
- "\n ");
- sz += sprintf(LVM_PROC_BUF, "%9d /%-6d ",
- lv_ptr->lv_size >> 1,
- lv_ptr->lv_size / vg[v]->pe_size);
-
- if (lv_ptr->lv_open == 0)
- sz += sprintf(LVM_PROC_BUF, "close");
- else
- sz += sprintf(LVM_PROC_BUF, "%dx open",
- lv_ptr->lv_open);
- c++;
- if (c < vg_ptr->lv_cur)
- sz += sprintf(LVM_PROC_BUF,
- "\n ");
- }
- }
- if (vg_ptr->lv_cur == 0) sz += sprintf(LVM_PROC_BUF, "none");
- sz += sprintf(LVM_PROC_BUF, "\n");
- }
- }
- }
- if (buf == NULL) {
- if ((buf = vmalloc(sz)) == NULL) {
- sz = 0;
- return sprintf(page, "%s - vmalloc error at line %d\n",
- lvm_name, __LINE__);
- }
- }
- sz_last = sz;
- }
- }
- if (pos > sz - 1) {
- vfree(buf);
- buf = NULL;
- return 0;
- }
- *start = &buf[pos];
- if (sz - pos < count)
- return sz - pos;
- else
- return count;
-} /* lvm_proc_get_info() */
-#endif /* #if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS */
-
-
-/*
- * block device support function for /usr/src/linux/drivers/block/ll_rw_blk.c
- * (see init_module/lvm_init)
- */
-static int lvm_map(struct buffer_head *bh, int rw)
-{
- int minor = MINOR(bh->b_rdev);
- ulong index;
- ulong pe_start;
- ulong size = bh->b_size >> 9;
- ulong rsector_tmp = bh->b_rsector;
- ulong rsector_sav;
- kdev_t rdev_tmp = bh->b_rdev;
- kdev_t rdev_sav;
- lv_t *lv = vg[VG_BLK(minor)]->lv[LV_BLK(minor)];
-
-
- if (!(lv->lv_status & LV_ACTIVE)) {
- printk(KERN_ALERT
- "%s - lvm_map: ll_rw_blk for inactive LV %s\n",
- lvm_name, lv->lv_name);
- goto error;
- }
-/*
- if ( lv->lv_access & LV_SNAPSHOT)
- printk ( "%s -- %02d:%02d block: %lu rw: %d\n", lvm_name, MAJOR ( bh->b_dev), MINOR ( bh->b_dev), bh->b_blocknr, rw);
- */
-
- /* take care of snapshot chunk writes before
- check for writable logical volume */
- if ((lv->lv_access & LV_SNAPSHOT) &&
- MAJOR(bh->b_rdev) != 0 &&
- MAJOR(bh->b_rdev) != MAJOR_NR &&
- (rw == WRITEA || rw == WRITE))
- {
- printk ( "%s -- doing snapshot write for %02d:%02d[%02d:%02d] b_blocknr: %lu b_rsector: %lu\n", lvm_name, MAJOR ( bh->b_dev), MINOR ( bh->b_dev), MAJOR ( bh->b_rdev), MINOR ( bh->b_rdev), bh->b_blocknr, bh->b_rsector);
- goto error;
- }
-
- if ((rw == WRITE || rw == WRITEA) &&
- !(lv->lv_access & LV_WRITE)) {
- printk(KERN_CRIT
- "%s - lvm_map: ll_rw_blk write for readonly LV %s\n",
- lvm_name, lv->lv_name);
- goto error;
- }
-#ifdef DEBUG_MAP
- printk(KERN_DEBUG
- "%s - lvm_map minor:%d *rdev: %02d:%02d *rsector: %lu "
- "size:%lu\n",
- lvm_name, minor,
- MAJOR(rdev_tmp),
- MINOR(rdev_tmp),
- rsector_tmp, size);
-#endif
-
- if (rsector_tmp + size > lv->lv_size) {
- printk(KERN_ALERT
- "%s - lvm_map *rsector: %lu or size: %lu wrong for"
- " minor: %2d\n", lvm_name, rsector_tmp, size, minor);
- goto error;
- }
- rsector_sav = rsector_tmp;
- rdev_sav = rdev_tmp;
-
-lvm_second_remap:
- /* linear mapping */
- if (lv->lv_stripes < 2) {
- /* get the index */
- index = rsector_tmp / vg[VG_BLK(minor)]->pe_size;
- pe_start = lv->lv_current_pe[index].pe;
- rsector_tmp = lv->lv_current_pe[index].pe +
- (rsector_tmp % vg[VG_BLK(minor)]->pe_size);
- rdev_tmp = lv->lv_current_pe[index].dev;
-
-#ifdef DEBUG_MAP
- printk(KERN_DEBUG
- "lv_current_pe[%ld].pe: %ld rdev: %02d:%02d rsector:%ld\n",
- index,
- lv->lv_current_pe[index].pe,
- MAJOR(rdev_tmp),
- MINOR(rdev_tmp),
- rsector_tmp);
-#endif
-
- /* striped mapping */
- } else {
- ulong stripe_index;
- ulong stripe_length;
-
- stripe_length = vg[VG_BLK(minor)]->pe_size * lv->lv_stripes;
- stripe_index = (rsector_tmp % stripe_length) / lv->lv_stripesize;
- index = rsector_tmp / stripe_length +
- (stripe_index % lv->lv_stripes) *
- (lv->lv_allocated_le / lv->lv_stripes);
- pe_start = lv->lv_current_pe[index].pe;
- rsector_tmp = lv->lv_current_pe[index].pe +
- (rsector_tmp % stripe_length) -
- (stripe_index % lv->lv_stripes) * lv->lv_stripesize -
- stripe_index / lv->lv_stripes *
- (lv->lv_stripes - 1) * lv->lv_stripesize;
- rdev_tmp = lv->lv_current_pe[index].dev;
- }
-
-#ifdef DEBUG_MAP
- printk(KERN_DEBUG
- "lv_current_pe[%ld].pe: %ld rdev: %02d:%02d rsector:%ld\n"
- "stripe_length: %ld stripe_index: %ld\n",
- index,
- lv->lv_current_pe[index].pe,
- MAJOR(rdev_tmp),
- MINOR(rdev_tmp),
- rsector_tmp,
- stripe_length,
- stripe_index);
-#endif
-
- /* handle physical extents on the move */
- if (pe_lock_req.lock == LOCK_PE) {
- if (rdev_tmp == pe_lock_req.data.pv_dev &&
- rsector_tmp >= pe_lock_req.data.pv_offset &&
- rsector_tmp < (pe_lock_req.data.pv_offset +
- vg[VG_BLK(minor)]->pe_size)) {
- sleep_on(&lvm_map_wait);
- rsector_tmp = rsector_sav;
- rdev_tmp = rdev_sav;
- goto lvm_second_remap;
- }
- }
- /* statistic */
- if (rw == WRITE || rw == WRITEA)
- lv->lv_current_pe[index].writes++;
- else
- lv->lv_current_pe[index].reads++;
-
- /* snapshot volume exception handling on physical device address base */
- if (lv->lv_access & (LV_SNAPSHOT | LV_SNAPSHOT_ORG)) {
- /* original logical volume */
- if (lv->lv_access & LV_SNAPSHOT_ORG) {
- if (rw == WRITE || rw == WRITEA)
- {
- lv_t *lv_ptr;
-
- /* start with first snapshot and loop thrugh all of them */
- for (lv_ptr = lv->lv_snapshot_next;
- lv_ptr != NULL;
- lv_ptr = lv_ptr->lv_snapshot_next) {
- down(&lv->lv_snapshot_org->lv_snapshot_sem);
- /* do we still have exception storage for this snapshot free? */
- if (lv_ptr->lv_block_exception != NULL) {
- rdev_sav = rdev_tmp;
- rsector_sav = rsector_tmp;
- if (!lvm_snapshot_remap_block(&rdev_tmp,
- &rsector_tmp,
- pe_start,
- lv_ptr)) {
- /* create a new mapping */
- lvm_snapshot_COW(rdev_tmp,
- rsector_tmp,
- pe_start,
- rsector_sav,
- lv_ptr);
- }
- rdev_tmp = rdev_sav;
- rsector_tmp = rsector_sav;
- }
- up(&lv->lv_snapshot_org->lv_snapshot_sem);
- }
- }
- } else {
- /* remap snapshot logical volume */
- down(&lv->lv_snapshot_sem);
- if (lv->lv_block_exception != NULL)
- lvm_snapshot_remap_block(&rdev_tmp, &rsector_tmp, pe_start, lv);
- up(&lv->lv_snapshot_sem);
- }
- }
- bh->b_rdev = rdev_tmp;
- bh->b_rsector = rsector_tmp;


-
- return 1;
-

- error:
- buffer_IO_error(bh);
- return -1;
-} /* lvm_map() */
-
-
-/*
- * internal support functions
- */
-
-#ifdef LVM_HD_NAME
-/*
- * generate "hard disk" name
- */
-void lvm_hd_name(char *buf, int minor)
-{
- int len = 0;
- lv_t *lv_ptr;
-
- if (vg[VG_BLK(minor)] == NULL ||
- (lv_ptr = vg[VG_BLK(minor)]->lv[LV_BLK(minor)]) == NULL)
- return;
- len = strlen(lv_ptr->lv_name) - 5;
- memcpy(buf, &lv_ptr->lv_name[5], len);
- buf[len] = 0;
- return;
-}
-#endif
-
-
-/*
- * this one never should be called...
- */
-static void lvm_dummy_device_request(request_queue_t * t)
-{
- printk(KERN_EMERG
- "%s -- oops, got lvm request for %02d:%02d [sector: %lu]\n",
- lvm_name,
- MAJOR(CURRENT->rq_dev),
- MINOR(CURRENT->rq_dev),
- CURRENT->sector);
- return;
-}
-
-
-/*
- * make request function
- */
-static int lvm_make_request_fn(request_queue_t *q, int rw, struct buffer_head *bh)
-{
- lvm_map(bh, rw);


- return 1;
-}
-

-/*
- * plug device function is a noop because plugging has to happen
- * in the queue of the physical blockdevice to allow the
- * elevator to do a better job.
- */
-static void lvm_plug_device_noop(request_queue_t *q, kdev_t dev) { }
-
-/********************************************************************
- *
- * Character device support functions
- *
- ********************************************************************/
-/*
- * character device support function logical volume manager lock
- */
-static int lvm_do_lock_lvm(void)
-{
-lock_try_again:
- spin_lock(&lvm_lock);
- if (lock != 0 && lock != current->pid) {
-#ifdef DEBUG_IOCTL
- printk(KERN_INFO "lvm_do_lock_lvm: %s is locked by pid %d ...\n",
- lvm_name, lock);
-#endif
- spin_unlock(&lvm_lock);
- interruptible_sleep_on(&lvm_wait);
- if (current->sigpending != 0)
- return -EINTR;


-#ifdef LVM_TOTAL_RESET
- if (lvm_reset_spindown > 0)

- return -EACCES;
-#endif
- goto lock_try_again;
- }
- lock = current->pid;
- spin_unlock(&lvm_lock);
- return 0;
-} /* lvm_do_lock_lvm */
-
-
-/*
- * character device support function lock/unlock physical extend
- */
-static int lvm_do_pe_lock_unlock(vg_t *vg_ptr, void *arg)
-{
- uint p;
-


- if (vg_ptr == NULL) return -ENXIO;

- if (copy_from_user(&pe_lock_req, arg,
- sizeof(pe_lock_req_t)) != 0) return -EFAULT;
-
- switch (pe_lock_req.lock) {
- case LOCK_PE:
- for (p = 0; p < vg_ptr->pv_max; p++) {
- if (vg_ptr->pv[p] != NULL &&
- pe_lock_req.data.pv_dev ==
- vg_ptr->pv[p]->pv_dev)
- break;
- }
- if (p == vg_ptr->pv_max) return -ENXIO;


-
- pe_lock_req.lock = UNLOCK_PE;

- fsync_dev(pe_lock_req.data.lv_dev);
- pe_lock_req.lock = LOCK_PE;
- break;
-
- case UNLOCK_PE:


- pe_lock_req.lock = UNLOCK_PE;
- pe_lock_req.data.lv_dev = \
- pe_lock_req.data.pv_dev = \
- pe_lock_req.data.pv_offset = 0;

- wake_up(&lvm_map_wait);
- break;
-
- default:
- return -EINVAL;


- }
- return 0;
-}
-

-
-/*
- * character device support function logical extend remap
- */
-static int lvm_do_le_remap(vg_t *vg_ptr, void *arg)
-{
- uint l, le;
- lv_t *lv_ptr;
-


- if (vg_ptr == NULL) return -ENXIO;

- if (copy_from_user(&le_remap_req, arg,
- sizeof(le_remap_req_t)) != 0)
- return -EFAULT;
-
- for (l = 0; l < vg_ptr->lv_max; l++) {
- lv_ptr = vg_ptr->lv[l];
- if (lv_ptr != NULL &&
- strcmp(lv_ptr->lv_name,
- le_remap_req.lv_name) == 0) {
- for (le = 0; le < lv_ptr->lv_allocated_le;
- le++) {
- if (lv_ptr->lv_current_pe[le].dev ==
- le_remap_req.old_dev &&
- lv_ptr->lv_current_pe[le].pe ==
- le_remap_req.old_pe) {
- lv_ptr->lv_current_pe[le].dev =
- le_remap_req.new_dev;
- lv_ptr->lv_current_pe[le].pe =
- le_remap_req.new_pe;


- return 0;
- }
- }

- return -EINVAL;
- }
- }
- return -ENXIO;
-} /* lvm_do_le_remap() */
-
-
-/*
- * character device support function VGDA create
- */
-int lvm_do_vg_create(int minor, void *arg)
-{
- int snaporg_minor = 0;
- ulong l, p;
- lv_t lv;
- vg_t *vg_ptr;
- pv_t *pv_ptr;
- lv_t *lv_ptr;
-
- if (vg[VG_CHR(minor)] != NULL) return -EPERM;
-
- if ((vg_ptr = kmalloc(sizeof(vg_t),GFP_KERNEL)) == NULL) {
- printk(KERN_CRIT
- "%s -- VG_CREATE: kmalloc error VG at line %d\n",
- lvm_name, __LINE__);
- return -ENOMEM;
- }
- /* get the volume group structure */
- if (copy_from_user(vg_ptr, arg, sizeof(vg_t)) != 0) {
- kfree(vg_ptr);


- return -EFAULT;
- }
-

- vg_devfs_handle[vg_ptr->vg_number] = devfs_mk_dir(0, vg_ptr->vg_name, NULL);
- ch_devfs_handle[vg_ptr->vg_number] = devfs_register(
- vg_devfs_handle[vg_ptr->vg_number] , "group",
- DEVFS_FL_DEFAULT, LVM_CHAR_MAJOR, vg_ptr->vg_number,


- S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,
- &lvm_chr_fops, NULL);
-

- /* we are not that active so far... */
- vg_ptr->vg_status &= ~VG_ACTIVE;
- vg[VG_CHR(minor)] = vg_ptr;
-
- vg[VG_CHR(minor)]->pe_allocated = 0;
- if (vg_ptr->pv_max > ABS_MAX_PV) {
- printk(KERN_WARNING
- "%s -- Can't activate VG: ABS_MAX_PV too small\n",
- lvm_name);
- kfree(vg_ptr);
- vg[VG_CHR(minor)] = NULL;
- return -EPERM;
- }
- if (vg_ptr->lv_max > ABS_MAX_LV) {
- printk(KERN_WARNING
- "%s -- Can't activate VG: ABS_MAX_LV too small for %u\n",
- lvm_name, vg_ptr->lv_max);
- kfree(vg_ptr);
- vg_ptr = NULL;
- return -EPERM;
- }
- /* get the physical volume structures */
- vg_ptr->pv_act = vg_ptr->pv_cur = 0;
- for (p = 0; p < vg_ptr->pv_max; p++) {
- /* user space address */
- if ((pvp = vg_ptr->pv[p]) != NULL) {
- pv_ptr = vg_ptr->pv[p] = kmalloc(sizeof(pv_t),GFP_KERNEL);
- if (pv_ptr == NULL) {
- printk(KERN_CRIT
- "%s -- VG_CREATE: kmalloc error PV at line %d\n",
- lvm_name, __LINE__);
- lvm_do_vg_remove(minor);
- return -ENOMEM;
- }
- if (copy_from_user(pv_ptr, pvp, sizeof(pv_t)) != 0) {
- lvm_do_vg_remove(minor);
- return -EFAULT;
- }
- /* We don't need the PE list
- in kernel space as with LVs pe_t list (see below) */
- pv_ptr->pe = NULL;
- pv_ptr->pe_allocated = 0;
- pv_ptr->pv_status = PV_ACTIVE;
- vg_ptr->pv_act++;
- vg_ptr->pv_cur++;
-
-#ifdef LVM_GET_INODE
- /* insert a dummy inode for fs_may_mount */
- pv_ptr->inode = lvm_get_inode(pv_ptr->pv_dev);
-#endif
- }
- }
-
- /* get the logical volume structures */
- vg_ptr->lv_cur = 0;
- for (l = 0; l < vg_ptr->lv_max; l++) {
- /* user space address */
- if ((lvp = vg_ptr->lv[l]) != NULL) {
- if (copy_from_user(&lv, lvp, sizeof(lv_t)) != 0) {
- lvm_do_vg_remove(minor);
- return -EFAULT;
- }
- vg_ptr->lv[l] = NULL;
- if (lvm_do_lv_create(minor, lv.lv_name, &lv) != 0) {
- lvm_do_vg_remove(minor);


- return -EFAULT;
- }
- }

- }
-
- /* Second path to correct snapshot logical volumes which are not
- in place during first path above */
- for (l = 0; l < vg_ptr->lv_max; l++) {
- if ((lv_ptr = vg_ptr->lv[l]) != NULL &&
- vg_ptr->lv[l]->lv_access & LV_SNAPSHOT) {
- snaporg_minor = lv_ptr->lv_snapshot_minor;
- if (vg_ptr->lv[LV_BLK(snaporg_minor)] != NULL) {
- /* get pointer to original logical volume */
- lv_ptr = vg_ptr->lv[l]->lv_snapshot_org =
- vg_ptr->lv[LV_BLK(snaporg_minor)];
-
- /* set necessary fields of original logical volume */
- lv_ptr->lv_access |= LV_SNAPSHOT_ORG;
- lv_ptr->lv_snapshot_minor = 0;
- lv_ptr->lv_snapshot_org = lv_ptr;
- lv_ptr->lv_snapshot_prev = NULL;
-
- /* find last snapshot logical volume in the chain */
- while (lv_ptr->lv_snapshot_next != NULL)
- lv_ptr = lv_ptr->lv_snapshot_next;
-
- /* set back pointer to this last one in our new logical volume */
- vg_ptr->lv[l]->lv_snapshot_prev = lv_ptr;
-
- /* last logical volume now points to our new snapshot volume */
- lv_ptr->lv_snapshot_next = vg_ptr->lv[l];
-
- /* now point to the new one */
- lv_ptr = lv_ptr->lv_snapshot_next;
-
- /* set necessary fields of new snapshot logical volume */
- lv_ptr->lv_snapshot_next = NULL;
- lv_ptr->lv_current_pe =
- vg_ptr->lv[LV_BLK(snaporg_minor)]->lv_current_pe;
- lv_ptr->lv_allocated_le =
- vg_ptr->lv[LV_BLK(snaporg_minor)]->lv_allocated_le;
- lv_ptr->lv_current_le =
- vg_ptr->lv[LV_BLK(snaporg_minor)]->lv_current_le;
- lv_ptr->lv_size =
- vg_ptr->lv[LV_BLK(snaporg_minor)]->lv_size;
- }
- }
- }
-
- vg_count++;
-
- /* let's go active */
- vg_ptr->vg_status |= VG_ACTIVE;
-
- MOD_INC_USE_COUNT;
-
- return 0;
-} /* lvm_do_vg_create() */
-
-
-/*
- * character device support function VGDA extend
- */
-static int lvm_do_vg_extend(vg_t *vg_ptr, void *arg)
-{
- uint p;
- pv_t *pv_ptr;
-


- if (vg_ptr == NULL) return -ENXIO;

- if (vg_ptr->pv_cur < vg_ptr->pv_max) {
- for (p = 0; p < vg_ptr->pv_max; p++) {
- if (vg_ptr->pv[p] == NULL) {
- if ((pv_ptr = vg_ptr->pv[p] = kmalloc(sizeof(pv_t),GFP_KERNEL)) == NULL) {
- printk(KERN_CRIT
- "%s -- VG_EXTEND: kmalloc error PV at line %d\n",
- lvm_name, __LINE__);
- return -ENOMEM;
- }
- if (copy_from_user(pv_ptr, arg, sizeof(pv_t)) != 0) {
- kfree(pv_ptr);
- vg_ptr->pv[p] = NULL;


- return -EFAULT;
- }
-

- pv_ptr->pv_status = PV_ACTIVE;
- /* We don't need the PE list
- in kernel space like LVs pe_t list */
- pv_ptr->pe = NULL;
- vg_ptr->pv_cur++;
- vg_ptr->pv_act++;
- vg_ptr->pe_total +=
- pv_ptr->pe_total;
-#ifdef LVM_GET_INODE
- /* insert a dummy inode for fs_may_mount */
- pv_ptr->inode = lvm_get_inode(pv_ptr->pv_dev);
-#endif


- return 0;
- }
- }
- }

-return -EPERM;
-} /* lvm_do_vg_extend() */
-
-
-/*
- * character device support function VGDA reduce
- */
-static int lvm_do_vg_reduce(vg_t *vg_ptr, void *arg)
-{
- uint p;
- pv_t *pv_ptr;
-


- if (vg_ptr == NULL) return -ENXIO;

- if (copy_from_user(pv_name, arg, sizeof(pv_name)) != 0)
- return -EFAULT;
-
- for (p = 0; p < vg_ptr->pv_max; p++) {
- pv_ptr = vg_ptr->pv[p];
- if (pv_ptr != NULL &&
- strcmp(pv_ptr->pv_name,
- pv_name) == 0) {
- if (pv_ptr->lv_cur > 0) return -EPERM;
- vg_ptr->pe_total -=
- pv_ptr->pe_total;
- vg_ptr->pv_cur--;
- vg_ptr->pv_act--;
-#ifdef LVM_GET_INODE
- lvm_clear_inode(pv_ptr->inode);
-#endif
- kfree(pv_ptr);
- /* Make PV pointer array contiguous */
- for (; p < vg_ptr->pv_max - 1; p++)
- vg_ptr->pv[p] = vg_ptr->pv[p + 1];
- vg_ptr->pv[p + 1] = NULL;


- return 0;
- }
- }

- return -ENXIO;
-} /* lvm_do_vg_reduce */
-
-
-/*
- * character device support function VGDA remove
- */
-static int lvm_do_vg_remove(int minor)
-{
- int i;


- vg_t *vg_ptr = vg[VG_CHR(minor)];

- pv_t *pv_ptr;
-


- if (vg_ptr == NULL) return -ENXIO;
-

-#ifdef LVM_TOTAL_RESET
- if (vg_ptr->lv_open > 0 && lvm_reset_spindown == 0)
-#else
- if (vg_ptr->lv_open > 0)
-#endif
- return -EPERM;
-
- /* let's go inactive */
- vg_ptr->vg_status &= ~VG_ACTIVE;
-
- devfs_unregister (ch_devfs_handle[vg_ptr->vg_number]);
- devfs_unregister (vg_devfs_handle[vg_ptr->vg_number]);
-
- /* free LVs */
- /* first free snapshot logical volumes */
- for (i = 0; i < vg_ptr->lv_max; i++) {
- if (vg_ptr->lv[i] != NULL &&
- vg_ptr->lv[i]->lv_access & LV_SNAPSHOT) {
- lvm_do_lv_remove(minor, NULL, i);
- current->state = TASK_UNINTERRUPTIBLE;
- schedule_timeout(1);
- }
- }
- /* then free the rest of the LVs */
- for (i = 0; i < vg_ptr->lv_max; i++) {
- if (vg_ptr->lv[i] != NULL) {
- lvm_do_lv_remove(minor, NULL, i);
- current->state = TASK_UNINTERRUPTIBLE;
- schedule_timeout(1);
- }
- }
-
- /* free PVs */
- for (i = 0; i < vg_ptr->pv_max; i++) {
- if ((pv_ptr = vg_ptr->pv[i]) != NULL) {
-#ifdef DEBUG_KFREE
- printk(KERN_DEBUG
- "%s -- kfree %d\n", lvm_name, __LINE__);
-#endif
-#ifdef LVM_GET_INODE
- lvm_clear_inode(pv_ptr->inode);
-#endif
- kfree(pv_ptr);
- vg[VG_CHR(minor)]->pv[i] = NULL;
- }
- }
-
-#ifdef DEBUG_KFREE
- printk(KERN_DEBUG "%s -- kfree %d\n", lvm_name, __LINE__);
-#endif
- kfree(vg_ptr);
- vg[VG_CHR(minor)] = NULL;
-
- vg_count--;


-
- MOD_DEC_USE_COUNT;
-
- return 0;

-} /* lvm_do_vg_remove() */
-
-
-/*
- * character device support function logical volume create
- */
-static int lvm_do_lv_create(int minor, char *lv_name, lv_t *lv)
-{
- int l, le, l_new, p, size;
- ulong lv_status_save;
- char *lv_tmp, *lv_buf;
- lv_block_exception_t *lvbe = lv->lv_block_exception;


- vg_t *vg_ptr = vg[VG_CHR(minor)];

- lv_t *lv_ptr = NULL;
-
- if ((pep = lv->lv_current_pe) == NULL) return -EINVAL;
- if (lv->lv_chunk_size > LVM_SNAPSHOT_MAX_CHUNK)
- return -EINVAL;
-
- for (l = 0; l < vg_ptr->lv_max; l++) {
- if (vg_ptr->lv[l] != NULL &&
- strcmp(vg_ptr->lv[l]->lv_name, lv_name) == 0)
- return -EEXIST;
- }
-
- /* in case of lv_remove(), lv_create() pair; for eg. lvrename does this */
- l_new = -1;
- if (vg_ptr->lv[lv->lv_number] == NULL)
- l_new = lv->lv_number;
- else {
- for (l = 0; l < vg_ptr->lv_max; l++) {
- if (vg_ptr->lv[l] == NULL)
- if (l_new == -1) l_new = l;
- }
- }
- if (l_new == -1) return -EPERM;
- else l = l_new;
-
- if ((lv_ptr = kmalloc(sizeof(lv_t),GFP_KERNEL)) == NULL) {;
- printk(KERN_CRIT "%s -- LV_CREATE: kmalloc error LV at line %d\n",
- lvm_name, __LINE__);
- return -ENOMEM;
- }
- /* copy preloaded LV */
- memcpy((char *) lv_ptr, (char *) lv, sizeof(lv_t));
-
- lv_status_save = lv_ptr->lv_status;
- lv_ptr->lv_status &= ~LV_ACTIVE;
- lv_ptr->lv_snapshot_org = \
- lv_ptr->lv_snapshot_prev = \
- lv_ptr->lv_snapshot_next = NULL;
- lv_ptr->lv_block_exception = NULL;
- init_MUTEX(&lv_ptr->lv_snapshot_sem);
- vg_ptr->lv[l] = lv_ptr;
-
- /* get the PE structures from user space if this
- is no snapshot logical volume */
- if (!(lv_ptr->lv_access & LV_SNAPSHOT)) {
- size = lv_ptr->lv_allocated_le * sizeof(pe_t);
- if ((lv_ptr->lv_current_pe = vmalloc(size)) == NULL) {
- printk(KERN_CRIT
- "%s -- LV_CREATE: vmalloc error LV_CURRENT_PE of %d Byte "
- "at line %d\n",
- lvm_name, size, __LINE__);
-#ifdef DEBUG_KFREE
- printk(KERN_DEBUG "%s -- kfree %d\n", lvm_name, __LINE__);
-#endif
- kfree(lv_ptr);
- vg[VG_CHR(minor)]->lv[l] = NULL;
- return -ENOMEM;
- }
- if (copy_from_user(lv_ptr->lv_current_pe, pep, size)) {
- vfree(lv_ptr->lv_current_pe);
- kfree(lv_ptr);
- vg_ptr->lv[l] = NULL;
- return -EFAULT;
- }
- /* correct the PE count in PVs */
- for (le = 0; le < lv_ptr->lv_allocated_le; le++) {
- vg_ptr->pe_allocated++;
- for (p = 0; p < vg_ptr->pv_cur; p++) {
- if (vg_ptr->pv[p]->pv_dev ==
- lv_ptr->lv_current_pe[le].dev)
- vg_ptr->pv[p]->pe_allocated++;
- }
- }
- } else {
- /* Get snapshot exception data and block list */
- if (lvbe != NULL) {
- lv_ptr->lv_snapshot_org =
- vg_ptr->lv[LV_BLK(lv_ptr->lv_snapshot_minor)];
- if (lv_ptr->lv_snapshot_org != NULL) {
- size = lv_ptr->lv_remap_end * sizeof(lv_block_exception_t);
- if ((lv_ptr->lv_block_exception = vmalloc(size)) == NULL) {
- printk(KERN_CRIT
- "%s -- lvm_do_lv_create: vmalloc error LV_BLOCK_EXCEPTION "
- "of %d byte at line %d\n",
- lvm_name, size, __LINE__);
-#ifdef DEBUG_KFREE
- printk(KERN_DEBUG "%s -- kfree %d\n", lvm_name, __LINE__);
-#endif
- kfree(lv_ptr);
- vg_ptr->lv[l] = NULL;
- return -ENOMEM;
- }
- if (copy_from_user(lv_ptr->lv_block_exception, lvbe, size)) {
- vfree(lv_ptr->lv_block_exception);
- kfree(lv_ptr);
- vg[VG_CHR(minor)]->lv[l] = NULL;
- return -EFAULT;
- }
- /* get pointer to original logical volume */
- lv_ptr = lv_ptr->lv_snapshot_org;
-
- lv_ptr->lv_snapshot_minor = 0;
- lv_ptr->lv_snapshot_org = lv_ptr;
- lv_ptr->lv_snapshot_prev = NULL;
- /* walk thrugh the snapshot list */
- while (lv_ptr->lv_snapshot_next != NULL)
- lv_ptr = lv_ptr->lv_snapshot_next;
- /* now lv_ptr points to the last existing snapshot in the chain */
- vg_ptr->lv[l]->lv_snapshot_prev = lv_ptr;
- /* our new one now back points to the previous last in the chain */
- lv_ptr = vg_ptr->lv[l];
- /* now lv_ptr points to our new last snapshot logical volume */
- lv_ptr->lv_snapshot_org = lv_ptr->lv_snapshot_prev->lv_snapshot_org;
- lv_ptr->lv_snapshot_next = NULL;
- lv_ptr->lv_current_pe = lv_ptr->lv_snapshot_org->lv_current_pe;
- lv_ptr->lv_allocated_le = lv_ptr->lv_snapshot_org->lv_allocated_le;
- lv_ptr->lv_current_le = lv_ptr->lv_snapshot_org->lv_current_le;
- lv_ptr->lv_size = lv_ptr->lv_snapshot_org->lv_size;
- lv_ptr->lv_stripes = lv_ptr->lv_snapshot_org->lv_stripes;
- lv_ptr->lv_stripesize = lv_ptr->lv_snapshot_org->lv_stripesize;
- {
- int err = lvm_snapshot_alloc(lv_ptr);
- if (err)
- {
- vfree(lv_ptr->lv_block_exception);
- kfree(lv_ptr);
- vg[VG_CHR(minor)]->lv[l] = NULL;


- return err;
- }
- }

- } else {
- vfree(lv_ptr->lv_block_exception);
- kfree(lv_ptr);
- vg_ptr->lv[l] = NULL;
- return -EFAULT;
- }
- } else {
- kfree(vg_ptr->lv[l]);
- vg_ptr->lv[l] = NULL;
- return -EINVAL;
- }
- } /* if ( vg[VG_CHR(minor)]->lv[l]->lv_access & LV_SNAPSHOT) */
-
- lv_ptr = vg_ptr->lv[l];
- lvm_gendisk.part[MINOR(lv_ptr->lv_dev)].start_sect = 0;
- lvm_gendisk.part[MINOR(lv_ptr->lv_dev)].nr_sects = lv_ptr->lv_size;
- lvm_size[MINOR(lv_ptr->lv_dev)] = lv_ptr->lv_size >> 1;
- vg_lv_map[MINOR(lv_ptr->lv_dev)].vg_number = vg_ptr->vg_number;
- vg_lv_map[MINOR(lv_ptr->lv_dev)].lv_number = lv_ptr->lv_number;
- read_ahead[MAJOR_NR] = lv_ptr->lv_read_ahead = LVM_CORRECT_READ_AHEAD(lv_ptr->lv_read_ahead);
- vg_ptr->lv_cur++;
- lv_ptr->lv_status = lv_status_save;
-
- strtok(lv->lv_name, "/"); /* /dev */
-
- while((lv_tmp = strtok(NULL, "/")) != NULL)
- lv_buf = lv_tmp;
-
- lv_devfs_handle[lv->lv_number] = devfs_register(
- vg_devfs_handle[vg_ptr->vg_number], lv_buf,
- DEVFS_FL_DEFAULT, LVM_BLK_MAJOR, lv->lv_number,
- S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP,
- &lvm_blk_dops, NULL);
-
- /* optionally add our new snapshot LV */
- if (lv_ptr->lv_access & LV_SNAPSHOT) {
- /* sync the original logical volume */
- fsync_dev(lv_ptr->lv_snapshot_org->lv_dev);
- /* put ourselve into the chain */
- lv_ptr->lv_snapshot_prev->lv_snapshot_next = lv_ptr;
- lv_ptr->lv_snapshot_org->lv_access |= LV_SNAPSHOT_ORG;
- }
- return 0;
-} /* lvm_do_lv_create() */
-
-
-/*
- * character device support function logical volume remove
- */
-static int lvm_do_lv_remove(int minor, char *lv_name, int l)
-{
- uint le, p;


- vg_t *vg_ptr = vg[VG_CHR(minor)];

- lv_t *lv_ptr;
-
- if (l == -1) {
- for (l = 0; l < vg_ptr->lv_max; l++) {
- if (vg_ptr->lv[l] != NULL &&
- strcmp(vg_ptr->lv[l]->lv_name, lv_name) == 0) {


- break;
- }
- }
- }

- if (l == vg_ptr->lv_max) return -ENXIO;
-
- lv_ptr = vg_ptr->lv[l];
-#ifdef LVM_TOTAL_RESET
- if (lv_ptr->lv_open > 0 && lvm_reset_spindown == 0)
-#else
- if (lv_ptr->lv_open > 0)
-#endif
- return -EBUSY;
-
- /* check for deletion of snapshot source while
- snapshot volume still exists */
- if ((lv_ptr->lv_access & LV_SNAPSHOT_ORG) &&
- lv_ptr->lv_snapshot_next != NULL)
- return -EPERM;
-
- lv_ptr->lv_status |= LV_SPINDOWN;
-
- /* sync the buffers */
- fsync_dev(lv_ptr->lv_dev);
-
- lv_ptr->lv_status &= ~LV_ACTIVE;
-
- /* invalidate the buffers */
- invalidate_buffers(lv_ptr->lv_dev);
-
- /* reset generic hd */
- lvm_gendisk.part[MINOR(lv_ptr->lv_dev)].start_sect = -1;
- lvm_gendisk.part[MINOR(lv_ptr->lv_dev)].nr_sects = 0;
- lvm_size[MINOR(lv_ptr->lv_dev)] = 0;
-
- /* reset VG/LV mapping */
- vg_lv_map[MINOR(lv_ptr->lv_dev)].vg_number = ABS_MAX_VG;
- vg_lv_map[MINOR(lv_ptr->lv_dev)].lv_number = -1;
-
- /* correct the PE count in PVs if this is no snapshot logical volume */
- if (!(lv_ptr->lv_access & LV_SNAPSHOT)) {
- /* only if this is no snapshot logical volume because
- we share the lv_current_pe[] structs with the
- original logical volume */
- for (le = 0; le < lv_ptr->lv_allocated_le; le++) {
- vg_ptr->pe_allocated--;
- for (p = 0; p < vg_ptr->pv_cur; p++) {
- if (vg_ptr->pv[p]->pv_dev ==
- lv_ptr->lv_current_pe[le].dev)
- vg_ptr->pv[p]->pe_allocated--;
- }
- }
- vfree(lv_ptr->lv_current_pe);
- /* LV_SNAPSHOT */
- } else {
- /* remove this snapshot logical volume from the chain */
- lv_ptr->lv_snapshot_prev->lv_snapshot_next = lv_ptr->lv_snapshot_next;
- if (lv_ptr->lv_snapshot_next != NULL) {
- lv_ptr->lv_snapshot_next->lv_snapshot_prev =
- lv_ptr->lv_snapshot_prev;
- }
- /* no more snapshots? */
- if (lv_ptr->lv_snapshot_org->lv_snapshot_next == NULL)
- lv_ptr->lv_snapshot_org->lv_access &= ~LV_SNAPSHOT_ORG;
- lvm_snapshot_release(lv_ptr);
- }
-
- devfs_unregister(lv_devfs_handle[lv_ptr->lv_number]);
-
-#ifdef DEBUG_KFREE
- printk(KERN_DEBUG "%s -- kfree %d\n", lvm_name, __LINE__);
-#endif
- kfree(lv_ptr);
- vg_ptr->lv[l] = NULL;
- vg_ptr->lv_cur--;
- return 0;
-} /* lvm_do_lv_remove() */
-
-
-/*
- * character device support function logical volume extend / reduce
- */
-static int lvm_do_lv_extend_reduce(int minor, char *lv_name, lv_t *lv)
-{
- int l, le, p, size, old_allocated_le;
- uint32_t end, lv_status_save;


- vg_t *vg_ptr = vg[VG_CHR(minor)];

- lv_t *lv_ptr;
- pe_t *pe;
-
- if ((pep = lv->lv_current_pe) == NULL) return -EINVAL;
-
- for (l = 0; l < vg_ptr->lv_max; l++) {
- if (vg_ptr->lv[l] != NULL &&
- strcmp(vg_ptr->lv[l]->lv_name, lv_name) == 0)
- break;
- }
- if (l == vg_ptr->lv_max) return -ENXIO;
- lv_ptr = vg_ptr->lv[l];
-
- /* check for active snapshot */
- if (lv->lv_access & (LV_SNAPSHOT | LV_SNAPSHOT_ORG)) return -EPERM;
-
- if ((pe = vmalloc(size = lv->lv_current_le * sizeof(pe_t))) == NULL) {
- printk(KERN_CRIT
- "%s -- lvm_do_lv_extend_reduce: vmalloc error LV_CURRENT_PE "
- "of %d Byte at line %d\n",
- lvm_name, size, __LINE__);
- return -ENOMEM;
- }
- /* get the PE structures from user space */
- if (copy_from_user(pe, pep, size)) {
- vfree(pe);


- return -EFAULT;
- }
-

-#ifdef DEBUG
- printk(KERN_DEBUG
- "%s -- fsync_dev and "
- "invalidate_buffers for %s [%s] in %s\n",
- lvm_name, lv_ptr->lv_name,
- kdevname(lv_ptr->lv_dev),
- vg_ptr->vg_name);
-#endif
-
- lv_ptr->lv_status |= LV_SPINDOWN;
- fsync_dev(lv_ptr->lv_dev);
- lv_ptr->lv_status &= ~LV_ACTIVE;
- invalidate_buffers(lv_ptr->lv_dev);
-
- /* reduce allocation counters on PV(s) */
- for (le = 0; le < lv_ptr->lv_allocated_le; le++) {
- vg_ptr->pe_allocated--;
- for (p = 0; p < vg_ptr->pv_cur; p++) {
- if (vg_ptr->pv[p]->pv_dev ==
- lv_ptr->lv_current_pe[le].dev) {
- vg_ptr->pv[p]->pe_allocated--;
- break;
- }
- }
- }
-
-
- /* save pointer to "old" lv/pe pointer array */
- pep1 = lv_ptr->lv_current_pe;
- end = lv_ptr->lv_current_le;
-
- /* save open counter */
- lv_open = lv_ptr->lv_open;
-
- /* save # of old allocated logical extents */
- old_allocated_le = lv_ptr->lv_allocated_le;
-
- /* copy preloaded LV */
- lv_status_save = lv->lv_status;
- lv->lv_status |= LV_SPINDOWN;
- lv->lv_status &= ~LV_ACTIVE;
- memcpy((char *) lv_ptr, (char *) lv, sizeof(lv_t));
- lv_ptr->lv_current_pe = pe;
- lv_ptr->lv_open = lv_open;
-
- /* save availiable i/o statistic data */
- /* linear logical volume */
- if (lv_ptr->lv_stripes < 2) {
- /* Check what last LE shall be used */
- if (end > lv_ptr->lv_current_le) end = lv_ptr->lv_current_le;
- for (le = 0; le < end; le++) {
- lv_ptr->lv_current_pe[le].reads = pep1[le].reads;
- lv_ptr->lv_current_pe[le].writes = pep1[le].writes;
- }
- /* striped logical volume */
- } else {
- uint i, j, source, dest, end, old_stripe_size, new_stripe_size;
-
- old_stripe_size = old_allocated_le / lv_ptr->lv_stripes;
- new_stripe_size = lv_ptr->lv_allocated_le / lv_ptr->lv_stripes;
- end = old_stripe_size;
- if (end > new_stripe_size) end = new_stripe_size;
- for (i = source = dest = 0;
- i < lv_ptr->lv_stripes; i++) {
- for (j = 0; j < end; j++) {
- lv_ptr->lv_current_pe[dest + j].reads =
- pep1[source + j].reads;
- lv_ptr->lv_current_pe[dest + j].writes =
- pep1[source + j].writes;
- }
- source += old_stripe_size;
- dest += new_stripe_size;
- }
- }
- vfree(pep1);
- pep1 = NULL;
-
-
- /* extend the PE count in PVs */
- for (le = 0; le < lv_ptr->lv_allocated_le; le++) {
- vg_ptr->pe_allocated++;
- for (p = 0; p < vg_ptr->pv_cur; p++) {
- if (vg_ptr->pv[p]->pv_dev ==
- vg_ptr->lv[l]->lv_current_pe[le].dev) {
- vg_ptr->pv[p]->pe_allocated++;


- break;
- }
- }
- }
-

- lvm_gendisk.part[MINOR(lv_ptr->lv_dev)].start_sect = 0;
- lvm_gendisk.part[MINOR(lv_ptr->lv_dev)].nr_sects = lv_ptr->lv_size;
- lvm_size[MINOR(lv_ptr->lv_dev)] = lv_ptr->lv_size >> 1;
- /* vg_lv_map array doesn't have to be changed here */
-
- read_ahead[MAJOR_NR] = lv_ptr->lv_read_ahead = LVM_CORRECT_READ_AHEAD(lv_ptr->lv_read_ahead);
- lv_ptr->lv_status = lv_status_save;
-
- return 0;
-} /* lvm_do_lv_extend_reduce() */
-
-
-/*
- * character device support function logical volume status by name
- */
-static int lvm_do_lv_status_byname(vg_t *vg_ptr, void *arg)
-{
- uint l;
- ulong size;
- lv_t lv;
- lv_t *lv_ptr;
- lv_status_byname_req_t lv_status_byname_req;
-


- if (vg_ptr == NULL) return -ENXIO;

- if (copy_from_user(&lv_status_byname_req, arg,
- sizeof(lv_status_byname_req_t)) != 0)
- return -EFAULT;
-
- if (lv_status_byname_req.lv == NULL) return -EINVAL;
- if (copy_from_user(&lv, lv_status_byname_req.lv,
- sizeof(lv_t)) != 0)
- return -EFAULT;
-
- for (l = 0; l < vg_ptr->lv_max; l++) {
- lv_ptr = vg_ptr->lv[l];
- if (lv_ptr != NULL &&
- strcmp(lv_ptr->lv_name,
- lv_status_byname_req.lv_name) == 0) {
- if (copy_to_user(lv_status_byname_req.lv,
- lv_ptr,
- sizeof(lv_t)) != 0)
- return -EFAULT;
-
- if (lv.lv_current_pe != NULL) {
- size = lv_ptr->lv_allocated_le *
- sizeof(pe_t);
- if (copy_to_user(lv.lv_current_pe,
- lv_ptr->lv_current_pe,
- size) != 0)
- return -EFAULT;
- }


- return 0;
- }
- }

- return -ENXIO;
-} /* lvm_do_lv_status_byname() */
-
-
-/*
- * character device support function logical volume status by index
- */
-static int lvm_do_lv_status_byindex(vg_t *vg_ptr,void *arg)
-{
- ulong size;
- lv_t lv;
- lv_t *lv_ptr;
- lv_status_byindex_req_t lv_status_byindex_req;
-


- if (vg_ptr == NULL) return -ENXIO;

- if (copy_from_user(&lv_status_byindex_req, arg,
- sizeof(lv_status_byindex_req)) != 0)
- return -EFAULT;
-
- if ((lvp = lv_status_byindex_req.lv) == NULL)
- return -EINVAL;
- if ( ( lv_ptr = vg_ptr->lv[lv_status_byindex_req.lv_index]) == NULL)
- return -ENXIO;
-
- if (copy_from_user(&lv, lvp, sizeof(lv_t)) != 0)
- return -EFAULT;
-
- if (copy_to_user(lvp, lv_ptr, sizeof(lv_t)) != 0)
- return -EFAULT;
-
- if (lv.lv_current_pe != NULL) {
- size = lv_ptr->lv_allocated_le * sizeof(pe_t);
- if (copy_to_user(lv.lv_current_pe,
- lv_ptr->lv_current_pe,
- size) != 0)
- return -EFAULT;
- }
- return 0;
-} /* lvm_do_lv_status_byindex() */
-
-
-/*
- * character device support function physical volume change
- */
-static int lvm_do_pv_change(vg_t *vg_ptr, void *arg)
-{
- uint p;
- pv_t *pv_ptr;
-#ifdef LVM_GET_INODE
- struct inode *inode_sav;
-#endif
-


- if (vg_ptr == NULL) return -ENXIO;

- if (copy_from_user(&pv_change_req, arg,
- sizeof(pv_change_req)) != 0)
- return -EFAULT;
-
- for (p = 0; p < vg_ptr->pv_max; p++) {
- pv_ptr = vg_ptr->pv[p];
- if (pv_ptr != NULL &&
- strcmp(pv_ptr->pv_name,
- pv_change_req.pv_name) == 0) {
-#ifdef LVM_GET_INODE
- inode_sav = pv_ptr->inode;
-#endif
- if (copy_from_user(pv_ptr,
- pv_change_req.pv,
- sizeof(pv_t)) != 0)
- return -EFAULT;
-
- /* We don't need the PE list
- in kernel space as with LVs pe_t list */
- pv_ptr->pe = NULL;
-#ifdef LVM_GET_INODE
- pv_ptr->inode = inode_sav;
-#endif


- return 0;
- }
- }

- return -ENXIO;
-} /* lvm_do_pv_change() */
-
-/*
- * character device support function get physical volume status
- */
-static int lvm_do_pv_status(vg_t *vg_ptr, void *arg)
-{
- uint p;
- pv_t *pv_ptr;
-


- if (vg_ptr == NULL) return -ENXIO;

- if (copy_from_user(&pv_status_req, arg,
- sizeof(pv_status_req)) != 0)
- return -EFAULT;
-
- for (p = 0; p < vg_ptr->pv_max; p++) {
- pv_ptr = vg_ptr->pv[p];
- if (pv_ptr != NULL &&
- strcmp(pv_ptr->pv_name,
- pv_status_req.pv_name) == 0) {
- if (copy_to_user(pv_status_req.pv,
- pv_ptr,
- sizeof(pv_t)) != 0)


- return -EFAULT;
- return 0;
- }
- }

- return -ENXIO;
-} /* lvm_do_pv_status() */
-
-
-/*
- * support function initialize gendisk variables
- */
-#ifdef __initfunc
-__initfunc(void lvm_geninit(struct gendisk *lvm_gdisk))
-#else
-void __init
- lvm_geninit(struct gendisk *lvm_gdisk)
-#endif
-{


- int i = 0;
-

-#ifdef DEBUG_GENDISK
- printk(KERN_DEBUG "%s -- lvm_gendisk\n", lvm_name);
-#endif
-
- for (i = 0; i < MAX_LV; i++) {
- lvm_gendisk.part[i].start_sect = -1; /* avoid partition check */
- lvm_size[i] = lvm_gendisk.part[i].nr_sects = 0;
- lvm_blocksizes[i] = BLOCK_SIZE;
- }
-
- blksize_size[MAJOR_NR] = lvm_blocksizes;
- blk_size[MAJOR_NR] = lvm_size;
-
- return;
-} /* lvm_gen_init() */
-
-
-#ifdef LVM_GET_INODE
-/*
- * support function to get an empty inode
- *
- * Gets an empty inode to be inserted into the inode hash,
- * so that a physical volume can't be mounted.
- * This is analog to drivers/block/md.c
- *
- * Is this the real thing?
- *
- * No, it's bollocks. md.c tries to do a bit different thing that might
- * _somewhat_ work eons ago. Neither does any good these days. mount() couldn't
- * care less for icache (it cares only for ->s_root->d_count and if we want
- * loopback mounts even that will stop). BTW, with the form used here mount()
- * would have to scan the _whole_ icache to detect the attempt - how on the
- * Earth could it guess the i_ino of your dummy inode? Official line on the
- * exclusion between mount()/swapon()/open()/etc. is Just Don't Do It(tm).
- * If you can convince Linus that it's worth changing - fine, then you'll need
- * to do blkdev_get()/blkdev_put(). Until then...
- */
-struct inode *lvm_get_inode(int dev)
-{
- struct inode *inode_this = NULL;
-
- /* Lock the device by inserting a dummy inode. */
- inode_this = get_empty_inode();
- inode_this->i_dev = dev;
- insert_inode_hash(inode_this);
- return inode_this;
-}
-
-
-/*
- * support function to clear an inode
- *
- */
-void lvm_clear_inode(struct inode *inode)
-{
-#ifdef I_FREEING
- inode->i_state |= I_FREEING;
-#endif
- clear_inode(inode);
- return;
-}
-#endif /* #ifdef LVM_GET_INODE */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/block/md.c linux/drivers/block/md.c
--- v2.4.0-test8/linux/drivers/block/md.c Tue Sep 5 14:07:30 2000
+++ linux/drivers/block/md.c Wed Dec 31 16:00:00 1969
@@ -1,3867 +0,0 @@
-/*
- md.c : Multiple Devices driver for Linux
- Copyright (C) 1998, 1999, 2000 Ingo Molnar
-
- completely rewritten, based on the MD driver code from Marc Zyngier
-
- Changes:
-
- - RAID-1/RAID-5 extensions by Miguel de Icaza, Gadi Oxman, Ingo Molnar
- - boot support for linear and striped mode by Harald Hoyer <Har...@Royal.Net>
- - kerneld support by Boris Tobotras <bo...@xtalk.msk.su>
- - kmod support by: Cyrus Durgin
- - RAID0 bugfixes: Mark Anthony Lisher <mar...@iname.com>
- - Devfs support by Richard Gooch <rgo...@atnf.csiro.au>
-
- - lots of fixes and improvements to the RAID1/RAID5 and generic
- RAID code (such as request based resynchronization):
-
- Neil Brown <ne...@cse.unsw.edu.au>.


-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- You should have received a copy of the GNU General Public License
- (for example /usr/src/linux/COPYING); if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <linux/module.h>

-#include <linux/config.h>
-#include <linux/raid/md.h>
-#include <linux/raid/xor.h>
-#include <linux/devfs_fs_kernel.h>
-
-#ifdef CONFIG_KMOD
-#include <linux/kmod.h>
-#endif
-
-#define __KERNEL_SYSCALLS__
-#include <linux/unistd.h>
-
-#include <asm/unaligned.h>
-
-extern asmlinkage int sys_sched_yield(void);
-extern asmlinkage long sys_setsid(void);


-
-#define MAJOR_NR MD_MAJOR
-#define MD_DRIVER
-

-#include <linux/blk.h>
-
-#define DEBUG 0
-#if DEBUG
-# define dprintk(x...) printk(x)
-#else
-# define dprintk(x...) do { } while(0)
-#endif
-
-static mdk_personality_t *pers[MAX_PERSONALITY] = {NULL, };
-
-/*
- * Current RAID-1,4,5 parallel reconstruction 'guaranteed speed limit'
- * is 100 KB/sec, so the extra system load does not show up that much.
- * Increase it if you want to have more _guaranteed_ speed. Note that
- * the RAID driver will use the maximum available bandwith if the IO
- * subsystem is idle. There is also an 'absolute maximum' reconstruction
- * speed limit - in case reconstruction slows down your system despite
- * idle IO detection.
- *
- * you can change it via /proc/sys/dev/raid/speed_limit_min and _max.
- */
-
-static int sysctl_speed_limit_min = 100;
-static int sysctl_speed_limit_max = 100000;
-
-static struct ctl_table_header *raid_table_header;
-
-static ctl_table raid_table[] = {
- {DEV_RAID_SPEED_LIMIT_MIN, "speed_limit_min",
- &sysctl_speed_limit_min, sizeof(int), 0644, NULL, &proc_dointvec},
- {DEV_RAID_SPEED_LIMIT_MAX, "speed_limit_max",
- &sysctl_speed_limit_max, sizeof(int), 0644, NULL, &proc_dointvec},
- {0}
-};
-
-static ctl_table raid_dir_table[] = {
- {DEV_RAID, "raid", NULL, 0, 0555, raid_table},
- {0}
-};
-
-static ctl_table raid_root_table[] = {
- {CTL_DEV, "dev", NULL, 0, 0555, raid_dir_table},
- {0}
-};
-
-/*
- * these have to be allocated separately because external
- * subsystems want to have a pre-defined structure
- */
-struct hd_struct md_hd_struct[MAX_MD_DEVS];
-static int md_blocksizes[MAX_MD_DEVS];
-static int md_hardsect_sizes[MAX_MD_DEVS];
-static int md_maxreadahead[MAX_MD_DEVS];
-static mdk_thread_t *md_recovery_thread = NULL;
-
-int md_size[MAX_MD_DEVS] = {0, };
-
-extern struct block_device_operations md_fops;


-static devfs_handle_t devfs_handle = NULL;

-
-static struct gendisk md_gendisk=
-{
- major: MD_MAJOR,
- major_name: "md",
- minor_shift: 0,
- max_p: 1,
- part: md_hd_struct,
- sizes: md_size,
- nr_real: MAX_MD_DEVS,
- real_devices: NULL,
- next: NULL,
- fops: &md_fops,
-};
-
-/*
- * Enables to iterate over all existing md arrays
- */
-static MD_LIST_HEAD(all_mddevs);
-
-/*
- * The mapping between kdev and mddev is not necessary a simple
- * one! Eg. HSM uses several sub-devices to implement Logical
- * Volumes. All these sub-devices map to the same mddev.
- */
-dev_mapping_t mddev_map [MAX_MD_DEVS] = { {NULL, 0}, };
-
-void add_mddev_mapping (mddev_t * mddev, kdev_t dev, void *data)
-{
- unsigned int minor = MINOR(dev);
-
- if (MAJOR(dev) != MD_MAJOR) {
- MD_BUG();
- return;
- }
- if (mddev_map[minor].mddev != NULL) {
- MD_BUG();
- return;
- }
- mddev_map[minor].mddev = mddev;
- mddev_map[minor].data = data;
-}
-
-void del_mddev_mapping (mddev_t * mddev, kdev_t dev)
-{
- unsigned int minor = MINOR(dev);
-
- if (MAJOR(dev) != MD_MAJOR) {
- MD_BUG();
- return;
- }
- if (mddev_map[minor].mddev != mddev) {
- MD_BUG();
- return;
- }
- mddev_map[minor].mddev = NULL;
- mddev_map[minor].data = NULL;
-}
-
-static int md_make_request (request_queue_t *q, int rw, struct buffer_head * bh)
-{
- mddev_t *mddev = kdev_to_mddev(bh->b_rdev);
-
- if (mddev && mddev->pers)
- return mddev->pers->make_request(mddev, rw, bh);
- else {
- buffer_IO_error(bh);


- return -1;
- }
-}

-
-static mddev_t * alloc_mddev (kdev_t dev)
-{
- mddev_t *mddev;
-
- if (MAJOR(dev) != MD_MAJOR) {
- MD_BUG();
- return 0;
- }
- mddev = (mddev_t *) kmalloc(sizeof(*mddev), GFP_KERNEL);
- if (!mddev)
- return NULL;
-
- memset(mddev, 0, sizeof(*mddev));
-
- mddev->__minor = MINOR(dev);
- init_MUTEX(&mddev->reconfig_sem);
- init_MUTEX(&mddev->recovery_sem);
- init_MUTEX(&mddev->resync_sem);
- MD_INIT_LIST_HEAD(&mddev->disks);
- MD_INIT_LIST_HEAD(&mddev->all_mddevs);
-
- /*


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 041'
echo 'File patch-2.4.0-test9 is continued in part 042'
echo "042" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part042

#!/bin/sh -x
# this is part 042 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 042; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

- * The 'base' mddev is the one with data NULL.
- * personalities can create additional mddevs
- * if necessary.
- */
- add_mddev_mapping(mddev, dev, 0);
- md_list_add(&mddev->all_mddevs, &all_mddevs);
-
- MOD_INC_USE_COUNT;
-
- return mddev;
-}
-
-struct gendisk * find_gendisk (kdev_t dev)
-{
- struct gendisk *tmp = gendisk_head;
-
- while (tmp != NULL) {
- if (tmp->major == MAJOR(dev))
- return (tmp);
- tmp = tmp->next;


- }
- return (NULL);
-}
-

-mdk_rdev_t * find_rdev_nr(mddev_t *mddev, int nr)
-{
- mdk_rdev_t * rdev;
- struct md_list_head *tmp;
-
- ITERATE_RDEV(mddev,rdev,tmp) {
- if (rdev->desc_nr == nr)
- return rdev;
- }


- return NULL;
-}
-

-mdk_rdev_t * find_rdev(mddev_t * mddev, kdev_t dev)
-{
- struct md_list_head *tmp;
- mdk_rdev_t *rdev;
-
- ITERATE_RDEV(mddev,rdev,tmp) {
- if (rdev->dev == dev)
- return rdev;
- }


- return NULL;
-}
-

-static MD_LIST_HEAD(device_names);
-
-char * partition_name (kdev_t dev)
-{
- struct gendisk *hd;
- static char nomem [] = "<nomem>";
- dev_name_t *dname;
- struct md_list_head *tmp = device_names.next;
-
- while (tmp != &device_names) {
- dname = md_list_entry(tmp, dev_name_t, list);
- if (dname->dev == dev)
- return dname->name;
- tmp = tmp->next;
- }
-
- dname = (dev_name_t *) kmalloc(sizeof(*dname), GFP_KERNEL);
-
- if (!dname)
- return nomem;
- /*
- * ok, add this new device name to the list
- */
- hd = find_gendisk (dev);
- dname->name = NULL;
- if (hd)
- dname->name = disk_name (hd, MINOR(dev), dname->namebuf);
- if (!dname->name) {
- sprintf (dname->namebuf, "[dev %s]", kdevname(dev));
- dname->name = dname->namebuf;
- }
-
- dname->dev = dev;
- MD_INIT_LIST_HEAD(&dname->list);
- md_list_add(&dname->list, &device_names);
-
- return dname->name;
-}
-
-static unsigned int calc_dev_sboffset (kdev_t dev, mddev_t *mddev,
- int persistent)
-{
- unsigned int size = 0;
-
- if (blk_size[MAJOR(dev)])
- size = blk_size[MAJOR(dev)][MINOR(dev)];
- if (persistent)
- size = MD_NEW_SIZE_BLOCKS(size);
- return size;
-}
-
-static unsigned int calc_dev_size (kdev_t dev, mddev_t *mddev, int persistent)
-{
- unsigned int size;
-
- size = calc_dev_sboffset(dev, mddev, persistent);
- if (!mddev->sb) {
- MD_BUG();
- return size;
- }
- if (mddev->sb->chunk_size)
- size &= ~(mddev->sb->chunk_size/1024 - 1);
- return size;
-}
-
-static unsigned int zoned_raid_size (mddev_t *mddev)
-{
- unsigned int mask;
- mdk_rdev_t * rdev;
- struct md_list_head *tmp;
-
- if (!mddev->sb) {
- MD_BUG();


- return -EINVAL;
- }
- /*

- * do size and offset calculations.
- */
- mask = ~(mddev->sb->chunk_size/1024 - 1);
-
- ITERATE_RDEV(mddev,rdev,tmp) {
- rdev->size &= mask;
- md_size[mdidx(mddev)] += rdev->size;


- }
- return 0;
-}
-

-/*
- * We check wether all devices are numbered from 0 to nb_dev-1. The
- * order is guaranteed even after device name changes.
- *
- * Some personalities (raid0, linear) use this. Personalities that
- * provide data have to be able to deal with loss of individual
- * disks, so they do their checking themselves.
- */
-int md_check_ordering (mddev_t *mddev)
-{
- int i, c;
- mdk_rdev_t *rdev;
- struct md_list_head *tmp;
-
- /*
- * First, all devices must be fully functional
- */
- ITERATE_RDEV(mddev,rdev,tmp) {
- if (rdev->faulty) {
- printk("md: md%d's device %s faulty, aborting.\n",
- mdidx(mddev), partition_name(rdev->dev));
- goto abort;
- }
- }
-
- c = 0;
- ITERATE_RDEV(mddev,rdev,tmp) {
- c++;
- }
- if (c != mddev->nb_dev) {
- MD_BUG();
- goto abort;
- }
- if (mddev->nb_dev != mddev->sb->raid_disks) {
- printk("md: md%d, array needs %d disks, has %d, aborting.\n",
- mdidx(mddev), mddev->sb->raid_disks, mddev->nb_dev);
- goto abort;
- }
- /*
- * Now the numbering check
- */
- for (i = 0; i < mddev->nb_dev; i++) {
- c = 0;
- ITERATE_RDEV(mddev,rdev,tmp) {
- if (rdev->desc_nr == i)
- c++;
- }
- if (!c) {
- printk("md: md%d, missing disk #%d, aborting.\n",
- mdidx(mddev), i);
- goto abort;
- }
- if (c > 1) {
- printk("md: md%d, too many disks #%d, aborting.\n",
- mdidx(mddev), i);
- goto abort;


- }
- }
- return 0;

-abort:


- return 1;
-}
-

-static void remove_descriptor (mdp_disk_t *disk, mdp_super_t *sb)
-{
- if (disk_active(disk)) {
- sb->working_disks--;
- } else {
- if (disk_spare(disk)) {
- sb->spare_disks--;
- sb->working_disks--;
- } else {
- sb->failed_disks--;
- }
- }
- sb->nr_disks--;
- disk->major = 0;
- disk->minor = 0;
- mark_disk_removed(disk);
-}
-
-#define BAD_MAGIC KERN_ERR \
-"md: invalid raid superblock magic on %s\n"
-
-#define BAD_MINOR KERN_ERR \
-"md: %s: invalid raid minor (%x)\n"
-
-#define OUT_OF_MEM KERN_ALERT \
-"md: out of memory.\n"
-
-#define NO_SB KERN_ERR \
-"md: disabled device %s, could not read superblock.\n"
-
-#define BAD_CSUM KERN_WARNING \
-"md: invalid superblock checksum on %s\n"
-
-static int alloc_array_sb (mddev_t * mddev)
-{
- if (mddev->sb) {


- MD_BUG();
- return 0;
- }
-

- mddev->sb = (mdp_super_t *) __get_free_page (GFP_KERNEL);
- if (!mddev->sb)
- return -ENOMEM;
- md_clear_page(mddev->sb);


- return 0;
-}
-

-static int alloc_disk_sb (mdk_rdev_t * rdev)
-{
- if (rdev->sb)
- MD_BUG();
-
- rdev->sb = (mdp_super_t *) __get_free_page(GFP_KERNEL);
- if (!rdev->sb) {
- printk (OUT_OF_MEM);
- return -EINVAL;
- }
- md_clear_page(rdev->sb);


-
- return 0;
-}
-

-static void free_disk_sb (mdk_rdev_t * rdev)
-{
- if (rdev->sb) {
- free_page((unsigned long) rdev->sb);
- rdev->sb = NULL;
- rdev->sb_offset = 0;
- rdev->size = 0;
- } else {
- if (!rdev->faulty)
- MD_BUG();
- }
-}
-
-static void mark_rdev_faulty (mdk_rdev_t * rdev)
-{
- if (!rdev) {


- MD_BUG();
- return;
- }

- free_disk_sb(rdev);
- rdev->faulty = 1;
-}
-
-static int read_disk_sb (mdk_rdev_t * rdev)
-{
- int ret = -EINVAL;
- struct buffer_head *bh = NULL;
- kdev_t dev = rdev->dev;
- mdp_super_t *sb;
- unsigned long sb_offset;
-
- if (!rdev->sb) {
- MD_BUG();
- goto abort;
- }
-
- /*
- * Calculate the position of the superblock,
- * it's at the end of the disk
- */
- sb_offset = calc_dev_sboffset(rdev->dev, rdev->mddev, 1);
- rdev->sb_offset = sb_offset;
- printk("(read) %s's sb offset: %ld", partition_name(dev), sb_offset);
- fsync_dev(dev);
- set_blocksize (dev, MD_SB_BYTES);
- bh = bread (dev, sb_offset / MD_SB_BLOCKS, MD_SB_BYTES);
-
- if (bh) {
- sb = (mdp_super_t *) bh->b_data;
- memcpy (rdev->sb, sb, MD_SB_BYTES);
- } else {
- printk (NO_SB,partition_name(rdev->dev));
- goto abort;
- }
- printk(" [events: %08lx]\n", (unsigned long)rdev->sb->events_lo);
- ret = 0;
-abort:
- if (bh)
- brelse (bh);


- return ret;
-}
-

-static unsigned int calc_sb_csum (mdp_super_t * sb)
-{
- unsigned int disk_csum, csum;
-
- disk_csum = sb->sb_csum;
- sb->sb_csum = 0;
- csum = csum_partial((void *)sb, MD_SB_BYTES, 0);
- sb->sb_csum = disk_csum;
- return csum;
-}
-
-/*
- * Check one RAID superblock for generic plausibility
- */
-
-static int check_disk_sb (mdk_rdev_t * rdev)
-{
- mdp_super_t *sb;
- int ret = -EINVAL;
-
- sb = rdev->sb;
- if (!sb) {
- MD_BUG();
- goto abort;
- }
-
- if (sb->md_magic != MD_SB_MAGIC) {
- printk (BAD_MAGIC, partition_name(rdev->dev));
- goto abort;
- }
-
- if (sb->md_minor >= MAX_MD_DEVS) {
- printk (BAD_MINOR, partition_name(rdev->dev),
- sb->md_minor);
- goto abort;
- }
-
- if (calc_sb_csum(sb) != sb->sb_csum)
- printk(BAD_CSUM, partition_name(rdev->dev));
- ret = 0;
-abort:


- return ret;
-}
-

-static kdev_t dev_unit(kdev_t dev)
-{
- unsigned int mask;
- struct gendisk *hd = find_gendisk(dev);
-
- if (!hd)
- return 0;
- mask = ~((1 << hd->minor_shift) - 1);
-
- return MKDEV(MAJOR(dev), MINOR(dev) & mask);
-}
-
-static mdk_rdev_t * match_dev_unit(mddev_t *mddev, kdev_t dev)
-{
- struct md_list_head *tmp;
- mdk_rdev_t *rdev;
-
- ITERATE_RDEV(mddev,rdev,tmp)
- if (dev_unit(rdev->dev) == dev_unit(dev))
- return rdev;
-


- return NULL;
-}
-

-static int match_mddev_units(mddev_t *mddev1, mddev_t *mddev2)
-{
- struct md_list_head *tmp;
- mdk_rdev_t *rdev;
-
- ITERATE_RDEV(mddev1,rdev,tmp)
- if (match_dev_unit(mddev2, rdev->dev))
- return 1;
-


- return 0;
-}
-

-static MD_LIST_HEAD(all_raid_disks);
-static MD_LIST_HEAD(pending_raid_disks);
-
-static void bind_rdev_to_array (mdk_rdev_t * rdev, mddev_t * mddev)
-{
- mdk_rdev_t *same_pdev;
-
- if (rdev->mddev) {


- MD_BUG();
- return;
- }

- same_pdev = match_dev_unit(mddev, rdev->dev);
- if (same_pdev)
- printk( KERN_WARNING
-"md%d: WARNING: %s appears to be on the same physical disk as %s. True\n"
-" protection against single-disk failure might be compromised.\n",
- mdidx(mddev), partition_name(rdev->dev),
- partition_name(same_pdev->dev));
-
- md_list_add(&rdev->same_set, &mddev->disks);
- rdev->mddev = mddev;
- mddev->nb_dev++;
- printk("bind<%s,%d>\n", partition_name(rdev->dev), mddev->nb_dev);
-}
-
-static void unbind_rdev_from_array (mdk_rdev_t * rdev)
-{
- if (!rdev->mddev) {


- MD_BUG();
- return;
- }

- md_list_del(&rdev->same_set);
- MD_INIT_LIST_HEAD(&rdev->same_set);
- rdev->mddev->nb_dev--;
- printk("unbind<%s,%d>\n", partition_name(rdev->dev),
- rdev->mddev->nb_dev);
- rdev->mddev = NULL;
-}
-
-/*
- * prevent the device from being mounted, repartitioned or
- * otherwise reused by a RAID array (or any other kernel
- * subsystem), by opening the device. [simply getting an
- * inode is not enough, the SCSI module usage code needs
- * an explicit open() on the device]
- */
-static int lock_rdev (mdk_rdev_t *rdev)
-{
- int err = 0;
-
- /*
- * First insert a dummy inode.
- */
- if (rdev->inode)
- MD_BUG();
- rdev->inode = get_empty_inode();
- if (!rdev->inode)
- return -ENOMEM;
- /*
- * we dont care about any other fields
- */
- rdev->inode->i_dev = rdev->inode->i_rdev = rdev->dev;
- insert_inode_hash(rdev->inode);
-
- memset(&rdev->filp, 0, sizeof(rdev->filp));
- rdev->filp.f_mode = 3; /* read write */


- return err;
-}
-

-static void unlock_rdev (mdk_rdev_t *rdev)
-{
- if (!rdev->inode)
- MD_BUG();
- iput(rdev->inode);
- rdev->inode = NULL;
-}
-
-static void export_rdev (mdk_rdev_t * rdev)
-{
- printk("export_rdev(%s)\n",partition_name(rdev->dev));
- if (rdev->mddev)
- MD_BUG();
- unlock_rdev(rdev);
- free_disk_sb(rdev);
- md_list_del(&rdev->all);
- MD_INIT_LIST_HEAD(&rdev->all);
- if (rdev->pending.next != &rdev->pending) {
- printk("(%s was pending)\n",partition_name(rdev->dev));
- md_list_del(&rdev->pending);
- MD_INIT_LIST_HEAD(&rdev->pending);
- }
- rdev->dev = 0;
- rdev->faulty = 0;
- kfree(rdev);
-}
-
-static void kick_rdev_from_array (mdk_rdev_t * rdev)
-{
- unbind_rdev_from_array(rdev);
- export_rdev(rdev);
-}
-
-static void export_array (mddev_t *mddev)
-{
- struct md_list_head *tmp;
- mdk_rdev_t *rdev;
- mdp_super_t *sb = mddev->sb;
-
- if (mddev->sb) {
- mddev->sb = NULL;
- free_page((unsigned long) sb);
- }
-
- ITERATE_RDEV(mddev,rdev,tmp) {
- if (!rdev->mddev) {
- MD_BUG();
- continue;
- }
- kick_rdev_from_array(rdev);
- }
- if (mddev->nb_dev)
- MD_BUG();
-}
-
-static void free_mddev (mddev_t *mddev)
-{
- if (!mddev) {


- MD_BUG();
- return;
- }
-

- export_array(mddev);
- md_size[mdidx(mddev)] = 0;
- md_hd_struct[mdidx(mddev)].nr_sects = 0;
-
- /*
- * Make sure nobody else is using this mddev
- * (careful, we rely on the global kernel lock here)
- */
- while (md_atomic_read(&mddev->resync_sem.count) != 1)
- schedule();
- while (md_atomic_read(&mddev->recovery_sem.count) != 1)
- schedule();
-
- del_mddev_mapping(mddev, MKDEV(MD_MAJOR, mdidx(mddev)));
- md_list_del(&mddev->all_mddevs);
- MD_INIT_LIST_HEAD(&mddev->all_mddevs);
- kfree(mddev);
- MOD_DEC_USE_COUNT;
-}
-
-#undef BAD_CSUM
-#undef BAD_MAGIC
-#undef OUT_OF_MEM
-#undef NO_SB
-
-static void print_desc(mdp_disk_t *desc)
-{
- printk(" DISK<N:%d,%s(%d,%d),R:%d,S:%d>\n", desc->number,
- partition_name(MKDEV(desc->major,desc->minor)),
- desc->major,desc->minor,desc->raid_disk,desc->state);
-}
-
-static void print_sb(mdp_super_t *sb)


-{
- int i;
-

- printk(" SB: (V:%d.%d.%d) ID:<%08x.%08x.%08x.%08x> CT:%08x\n",
- sb->major_version, sb->minor_version, sb->patch_version,
- sb->set_uuid0, sb->set_uuid1, sb->set_uuid2, sb->set_uuid3,
- sb->ctime);
- printk(" L%d S%08d ND:%d RD:%d md%d LO:%d CS:%d\n", sb->level,
- sb->size, sb->nr_disks, sb->raid_disks, sb->md_minor,
- sb->layout, sb->chunk_size);
- printk(" UT:%08x ST:%d AD:%d WD:%d FD:%d SD:%d CSUM:%08x E:%08lx\n",
- sb->utime, sb->state, sb->active_disks, sb->working_disks,
- sb->failed_disks, sb->spare_disks,
- sb->sb_csum, (unsigned long)sb->events_lo);
-
- for (i = 0; i < MD_SB_DISKS; i++) {
- mdp_disk_t *desc;
-
- desc = sb->disks + i;
- printk(" D %2d: ", i);
- print_desc(desc);
- }
- printk(" THIS: ");
- print_desc(&sb->this_disk);
-
-}
-
-static void print_rdev(mdk_rdev_t *rdev)
-{
- printk(" rdev %s: O:%s, SZ:%08ld F:%d DN:%d ",
- partition_name(rdev->dev), partition_name(rdev->old_dev),
- rdev->size, rdev->faulty, rdev->desc_nr);
- if (rdev->sb) {
- printk("rdev superblock:\n");
- print_sb(rdev->sb);
- } else
- printk("no rdev superblock!\n");
-}
-
-void md_print_devices (void)
-{
- struct md_list_head *tmp, *tmp2;
- mdk_rdev_t *rdev;
- mddev_t *mddev;
-
- printk("\n");
- printk(" **********************************\n");
- printk(" * <COMPLETE RAID STATE PRINTOUT> *\n");
- printk(" **********************************\n");
- ITERATE_MDDEV(mddev,tmp) {
- printk("md%d: ", mdidx(mddev));
-
- ITERATE_RDEV(mddev,rdev,tmp2)
- printk("<%s>", partition_name(rdev->dev));
-
- if (mddev->sb) {
- printk(" array superblock:\n");
- print_sb(mddev->sb);
- } else
- printk(" no array superblock.\n");
-
- ITERATE_RDEV(mddev,rdev,tmp2)
- print_rdev(rdev);
- }
- printk(" **********************************\n");
- printk("\n");
-}
-
-static int sb_equal ( mdp_super_t *sb1, mdp_super_t *sb2)
-{
- int ret;
- mdp_super_t *tmp1, *tmp2;
-
- tmp1 = kmalloc(sizeof(*tmp1),GFP_KERNEL);
- tmp2 = kmalloc(sizeof(*tmp2),GFP_KERNEL);
-
- if (!tmp1 || !tmp2) {
- ret = 0;
- goto abort;
- }
-
- *tmp1 = *sb1;
- *tmp2 = *sb2;
-
- /*
- * nr_disks is not constant
- */
- tmp1->nr_disks = 0;
- tmp2->nr_disks = 0;
-
- if (memcmp(tmp1, tmp2, MD_SB_GENERIC_CONSTANT_WORDS * 4))
- ret = 0;
- else


- ret = 1;
-

-abort:
- if (tmp1)
- kfree(tmp1);
- if (tmp2)
- kfree(tmp2);


-
- return ret;
-}
-

-static int uuid_equal(mdk_rdev_t *rdev1, mdk_rdev_t *rdev2)
-{
- if ( (rdev1->sb->set_uuid0 == rdev2->sb->set_uuid0) &&
- (rdev1->sb->set_uuid1 == rdev2->sb->set_uuid1) &&
- (rdev1->sb->set_uuid2 == rdev2->sb->set_uuid2) &&
- (rdev1->sb->set_uuid3 == rdev2->sb->set_uuid3))


-
- return 1;
-

- return 0;
-}
-

-static mdk_rdev_t * find_rdev_all (kdev_t dev)
-{
- struct md_list_head *tmp;
- mdk_rdev_t *rdev;
-
- tmp = all_raid_disks.next;
- while (tmp != &all_raid_disks) {
- rdev = md_list_entry(tmp, mdk_rdev_t, all);
- if (rdev->dev == dev)
- return rdev;
- tmp = tmp->next;
- }


- return NULL;
-}
-

-#define GETBLK_FAILED KERN_ERR \
-"md: getblk failed for device %s\n"
-
-static int write_disk_sb(mdk_rdev_t * rdev)
-{
- struct buffer_head *bh;
- kdev_t dev;
- unsigned long sb_offset, size;
- mdp_super_t *sb;
-
- if (!rdev->sb) {
- MD_BUG();
- return -1;
- }
- if (rdev->faulty) {
- MD_BUG();
- return -1;
- }
- if (rdev->sb->md_magic != MD_SB_MAGIC) {
- MD_BUG();


- return -1;
- }
-

- dev = rdev->dev;
- sb_offset = calc_dev_sboffset(dev, rdev->mddev, 1);
- if (rdev->sb_offset != sb_offset) {
- printk("%s's sb offset has changed from %ld to %ld, skipping\n", partition_name(dev), rdev->sb_offset, sb_offset);
- goto skip;
- }
- /*
- * If the disk went offline meanwhile and it's just a spare, then
- * it's size has changed to zero silently, and the MD code does
- * not yet know that it's faulty.
- */
- size = calc_dev_size(dev, rdev->mddev, 1);
- if (size != rdev->size) {
- printk("%s's size has changed from %ld to %ld since import, skipping\n", partition_name(dev), rdev->size, size);
- goto skip;
- }
-
- printk("(write) %s's sb offset: %ld\n", partition_name(dev), sb_offset);
- fsync_dev(dev);
- set_blocksize(dev, MD_SB_BYTES);
- bh = getblk(dev, sb_offset / MD_SB_BLOCKS, MD_SB_BYTES);
- if (!bh) {
- printk(GETBLK_FAILED, partition_name(dev));
- return 1;
- }
- memset(bh->b_data,0,bh->b_size);
- sb = (mdp_super_t *) bh->b_data;
- memcpy(sb, rdev->sb, MD_SB_BYTES);
-
- mark_buffer_uptodate(bh, 1);
- mark_buffer_dirty(bh);
- ll_rw_block(WRITE, 1, &bh);
- wait_on_buffer(bh);
- brelse(bh);
- fsync_dev(dev);
-skip:
- return 0;
-}
-#undef GETBLK_FAILED
-
-static void set_this_disk(mddev_t *mddev, mdk_rdev_t *rdev)
-{
- int i, ok = 0;
- mdp_disk_t *desc;
-
- for (i = 0; i < MD_SB_DISKS; i++) {
- desc = mddev->sb->disks + i;
-#if 0
- if (disk_faulty(desc)) {
- if (MKDEV(desc->major,desc->minor) == rdev->dev)
- ok = 1;
- continue;
- }
-#endif
- if (MKDEV(desc->major,desc->minor) == rdev->dev) {
- rdev->sb->this_disk = *desc;
- rdev->desc_nr = desc->number;
- ok = 1;


- break;
- }
- }
-

- if (!ok) {
- MD_BUG();
- }
-}
-
-static int sync_sbs(mddev_t * mddev)
-{
- mdk_rdev_t *rdev;
- mdp_super_t *sb;
- struct md_list_head *tmp;
-
- ITERATE_RDEV(mddev,rdev,tmp) {
- if (rdev->faulty)
- continue;
- sb = rdev->sb;
- *sb = *mddev->sb;
- set_this_disk(mddev, rdev);
- sb->sb_csum = calc_sb_csum(sb);


- }
- return 0;
-}
-

-int md_update_sb(mddev_t * mddev)
-{
- int first, err, count = 100;
- struct md_list_head *tmp;
- mdk_rdev_t *rdev;
-
-repeat:
- mddev->sb->utime = CURRENT_TIME;
- if ((++mddev->sb->events_lo)==0)
- ++mddev->sb->events_hi;
-
- if ((mddev->sb->events_lo|mddev->sb->events_hi)==0) {
- /*
- * oops, this 64-bit counter should never wrap.
- * Either we are in around ~1 trillion A.C., assuming
- * 1 reboot per second, or we have a bug:
- */
- MD_BUG();
- mddev->sb->events_lo = mddev->sb->events_hi = 0xffffffff;
- }
- sync_sbs(mddev);
-
- /*
- * do not write anything to disk if using
- * nonpersistent superblocks
- */
- if (mddev->sb->not_persistent)
- return 0;
-
- printk(KERN_INFO "md: updating md%d RAID superblock on device\n",
- mdidx(mddev));
-
- first = 1;
- err = 0;
- ITERATE_RDEV(mddev,rdev,tmp) {
- if (!first) {
- first = 0;
- printk(", ");
- }
- if (rdev->faulty)
- printk("(skipping faulty ");
- printk("%s ", partition_name(rdev->dev));
- if (!rdev->faulty) {
- printk("[events: %08lx]",
- (unsigned long)rdev->sb->events_lo);
- err += write_disk_sb(rdev);
- } else
- printk(")\n");
- }
- printk(".\n");
- if (err) {
- printk("errors occured during superblock update, repeating\n");
- if (--count)
- goto repeat;
- printk("excessive errors occured during superblock update, exiting\n");


- }
- return 0;
-}
-

-/*
- * Import a device. If 'on_disk', then sanity check the superblock
- *
- * mark the device faulty if:
- *
- * - the device is nonexistent (zero size)
- * - the device has no valid superblock
- *
- * a faulty rdev _never_ has rdev->sb set.
- */
-static int md_import_device (kdev_t newdev, int on_disk)
-{
- int err;
- mdk_rdev_t *rdev;
- unsigned int size;
-
- if (find_rdev_all(newdev))
- return -EEXIST;
-
- rdev = (mdk_rdev_t *) kmalloc(sizeof(*rdev), GFP_KERNEL);
- if (!rdev) {
- printk("could not alloc mem for %s!\n", partition_name(newdev));
- return -ENOMEM;
- }
- memset(rdev, 0, sizeof(*rdev));
-
- if (get_super(newdev)) {
- printk("md: can not import %s, has active inodes!\n",
- partition_name(newdev));
- err = -EBUSY;
- goto abort_free;
- }
-
- if ((err = alloc_disk_sb(rdev)))
- goto abort_free;
-
- rdev->dev = newdev;
- if (lock_rdev(rdev)) {
- printk("md: could not lock %s, zero-size? Marking faulty.\n",
- partition_name(newdev));
- err = -EINVAL;
- goto abort_free;
- }
- rdev->desc_nr = -1;
- rdev->faulty = 0;
-
- size = 0;
- if (blk_size[MAJOR(newdev)])
- size = blk_size[MAJOR(newdev)][MINOR(newdev)];
- if (!size) {
- printk("md: %s has zero size, marking faulty!\n",
- partition_name(newdev));
- err = -EINVAL;
- goto abort_free;
- }
-
- if (on_disk) {
- if ((err = read_disk_sb(rdev))) {
- printk("md: could not read %s's sb, not importing!\n",
- partition_name(newdev));
- goto abort_free;
- }
- if ((err = check_disk_sb(rdev))) {
- printk("md: %s has invalid sb, not importing!\n",
- partition_name(newdev));
- goto abort_free;
- }
-
- rdev->old_dev = MKDEV(rdev->sb->this_disk.major,
- rdev->sb->this_disk.minor);
- rdev->desc_nr = rdev->sb->this_disk.number;
- }
- md_list_add(&rdev->all, &all_raid_disks);
- MD_INIT_LIST_HEAD(&rdev->pending);
-
- if (rdev->faulty && rdev->sb)
- free_disk_sb(rdev);
- return 0;
-
-abort_free:
- if (rdev->sb) {
- if (rdev->inode)
- unlock_rdev(rdev);
- free_disk_sb(rdev);
- }
- kfree(rdev);


- return err;
-}
-

-/*
- * Check a full RAID array for plausibility
- */
-
-#define INCONSISTENT KERN_ERR \
-"md: fatal superblock inconsistency in %s -- removing from array\n"
-
-#define OUT_OF_DATE KERN_ERR \
-"md: superblock update time inconsistency -- using the most recent one\n"
-
-#define OLD_VERSION KERN_ALERT \
-"md: md%d: unsupported raid array version %d.%d.%d\n"
-
-#define NOT_CLEAN_IGNORE KERN_ERR \
-"md: md%d: raid array is not clean -- starting background reconstruction\n"
-
-#define UNKNOWN_LEVEL KERN_ERR \
-"md: md%d: unsupported raid level %d\n"
-
-static int analyze_sbs (mddev_t * mddev)
-{
- int out_of_date = 0, i;
- struct md_list_head *tmp, *tmp2;
- mdk_rdev_t *rdev, *rdev2, *freshest;
- mdp_super_t *sb;
-
- /*
- * Verify the RAID superblock on each real device
- */
- ITERATE_RDEV(mddev,rdev,tmp) {
- if (rdev->faulty) {
- MD_BUG();
- goto abort;
- }
- if (!rdev->sb) {
- MD_BUG();
- goto abort;
- }
- if (check_disk_sb(rdev))
- goto abort;
- }
-
- /*
- * The superblock constant part has to be the same
- * for all disks in the array.
- */
- sb = NULL;
-
- ITERATE_RDEV(mddev,rdev,tmp) {
- if (!sb) {
- sb = rdev->sb;
- continue;
- }
- if (!sb_equal(sb, rdev->sb)) {
- printk (INCONSISTENT, partition_name(rdev->dev));
- kick_rdev_from_array(rdev);
- continue;


- }
- }
-
- /*

- * OK, we have all disks and the array is ready to run. Let's
- * find the freshest superblock, that one will be the superblock
- * that represents the whole array.
- */
- if (!mddev->sb)
- if (alloc_array_sb(mddev))
- goto abort;
- sb = mddev->sb;
- freshest = NULL;
-
- ITERATE_RDEV(mddev,rdev,tmp) {
- __u64 ev1, ev2;
- /*
- * if the checksum is invalid, use the superblock
- * only as a last resort. (decrease it's age by
- * one event)
- */
- if (calc_sb_csum(rdev->sb) != rdev->sb->sb_csum) {
- if (rdev->sb->events_lo || rdev->sb->events_hi)
- if ((rdev->sb->events_lo--)==0)
- rdev->sb->events_hi--;
- }
-
- printk("%s's event counter: %08lx\n", partition_name(rdev->dev),
- (unsigned long)rdev->sb->events_lo);
- if (!freshest) {
- freshest = rdev;
- continue;
- }
- /*
- * Find the newest superblock version
- */
- ev1 = md_event(rdev->sb);
- ev2 = md_event(freshest->sb);
- if (ev1 != ev2) {
- out_of_date = 1;
- if (ev1 > ev2)
- freshest = rdev;
- }
- }
- if (out_of_date) {
- printk(OUT_OF_DATE);
- printk("freshest: %s\n", partition_name(freshest->dev));
- }
- memcpy (sb, freshest->sb, sizeof(*sb));
-
- /*
- * at this point we have picked the 'best' superblock
- * from all available superblocks.
- * now we validate this superblock and kick out possibly
- * failed disks.
- */
- ITERATE_RDEV(mddev,rdev,tmp) {
- /*
- * Kick all non-fresh devices faulty
- */
- __u64 ev1, ev2;
- ev1 = md_event(rdev->sb);
- ev2 = md_event(sb);
- ++ev1;
- if (ev1 < ev2) {
- printk("md: kicking non-fresh %s from array!\n",
- partition_name(rdev->dev));
- kick_rdev_from_array(rdev);
- continue;


- }
- }
-
- /*

- * Fix up changed device names ... but only if this disk has a
- * recent update time. Use faulty checksum ones too.
- */
- ITERATE_RDEV(mddev,rdev,tmp) {
- __u64 ev1, ev2, ev3;
- if (rdev->faulty) { /* REMOVEME */
- MD_BUG();
- goto abort;
- }
- ev1 = md_event(rdev->sb);
- ev2 = md_event(sb);
- ev3 = ev2;
- --ev3;
- if ((rdev->dev != rdev->old_dev) &&
- ((ev1 == ev2) || (ev1 == ev3))) {
- mdp_disk_t *desc;
-
- printk("md: device name has changed from %s to %s since last import!\n", partition_name(rdev->old_dev), partition_name(rdev->dev));
- if (rdev->desc_nr == -1) {
- MD_BUG();
- goto abort;
- }
- desc = &sb->disks[rdev->desc_nr];
- if (rdev->old_dev != MKDEV(desc->major, desc->minor)) {
- MD_BUG();
- goto abort;
- }
- desc->major = MAJOR(rdev->dev);
- desc->minor = MINOR(rdev->dev);
- desc = &rdev->sb->this_disk;
- desc->major = MAJOR(rdev->dev);
- desc->minor = MINOR(rdev->dev);


- }
- }
-
- /*

- * Remove unavailable and faulty devices ...
- *
- * note that if an array becomes completely unrunnable due to
- * missing devices, we do not write the superblock back, so the
- * administrator has a chance to fix things up. The removal thus
- * only happens if it's nonfatal to the contents of the array.
- */
- for (i = 0; i < MD_SB_DISKS; i++) {
- int found;
- mdp_disk_t *desc;
- kdev_t dev;
-
- desc = sb->disks + i;
- dev = MKDEV(desc->major, desc->minor);
-
- /*
- * We kick faulty devices/descriptors immediately.
- */
- if (disk_faulty(desc)) {
- found = 0;
- ITERATE_RDEV(mddev,rdev,tmp) {
- if (rdev->desc_nr != desc->number)
- continue;
- printk("md%d: kicking faulty %s!\n",
- mdidx(mddev),partition_name(rdev->dev));
- kick_rdev_from_array(rdev);
- found = 1;
- break;
- }
- if (!found) {
- if (dev == MKDEV(0,0))
- continue;
- printk("md%d: removing former faulty %s!\n",
- mdidx(mddev), partition_name(dev));
- }
- remove_descriptor(desc, sb);
- continue;
- }
-
- if (dev == MKDEV(0,0))
- continue;
- /*
- * Is this device present in the rdev ring?
- */
- found = 0;
- ITERATE_RDEV(mddev,rdev,tmp) {
- if (rdev->desc_nr == desc->number) {
- found = 1;
- break;
- }
- }
- if (found)
- continue;
-
- printk("md%d: former device %s is unavailable, removing from array!\n", mdidx(mddev), partition_name(dev));
- remove_descriptor(desc, sb);
- }
-
- /*
- * Double check wether all devices mentioned in the
- * superblock are in the rdev ring.
- */
- for (i = 0; i < MD_SB_DISKS; i++) {
- mdp_disk_t *desc;
- kdev_t dev;
-
- desc = sb->disks + i;
- dev = MKDEV(desc->major, desc->minor);
-
- if (dev == MKDEV(0,0))
- continue;
-
- if (disk_faulty(desc)) {
- MD_BUG();
- goto abort;
- }
-
- rdev = find_rdev(mddev, dev);
- if (!rdev) {
- MD_BUG();
- goto abort;


- }
- }
-
- /*

- * Do a final reality check.
- */
- ITERATE_RDEV(mddev,rdev,tmp) {
- if (rdev->desc_nr == -1) {
- MD_BUG();
- goto abort;
- }
- /*
- * is the desc_nr unique?
- */
- ITERATE_RDEV(mddev,rdev2,tmp2) {
- if ((rdev2 != rdev) &&
- (rdev2->desc_nr == rdev->desc_nr)) {
- MD_BUG();
- goto abort;
- }
- }
- /*
- * is the device unique?
- */
- ITERATE_RDEV(mddev,rdev2,tmp2) {
- if ((rdev2 != rdev) &&
- (rdev2->dev == rdev->dev)) {
- MD_BUG();
- goto abort;


- }
- }
- }
-
- /*

- * Check if we can support this RAID array
- */
- if (sb->major_version != MD_MAJOR_VERSION ||
- sb->minor_version > MD_MINOR_VERSION) {
-
- printk (OLD_VERSION, mdidx(mddev), sb->major_version,
- sb->minor_version, sb->patch_version);
- goto abort;
- }
-
- if ((sb->state != (1 << MD_SB_CLEAN)) && ((sb->level == 1) ||
- (sb->level == 4) || (sb->level == 5)))
- printk (NOT_CLEAN_IGNORE, mdidx(mddev));
-
- return 0;
-abort:


- return 1;
-}
-

-#undef INCONSISTENT
-#undef OUT_OF_DATE
-#undef OLD_VERSION
-#undef OLD_LEVEL
-
-static int device_size_calculation (mddev_t * mddev)
-{
- int data_disks = 0, persistent;
- unsigned int readahead;
- mdp_super_t *sb = mddev->sb;
- struct md_list_head *tmp;
- mdk_rdev_t *rdev;
-
- /*
- * Do device size calculation. Bail out if too small.
- * (we have to do this after having validated chunk_size,
- * because device size has to be modulo chunk_size)
- */
- persistent = !mddev->sb->not_persistent;
- ITERATE_RDEV(mddev,rdev,tmp) {
- if (rdev->faulty)
- continue;
- if (rdev->size) {
- MD_BUG();
- continue;
- }
- rdev->size = calc_dev_size(rdev->dev, mddev, persistent);
- if (rdev->size < sb->chunk_size / 1024) {
- printk (KERN_WARNING
- "Dev %s smaller than chunk_size: %ldk < %dk\n",
- partition_name(rdev->dev),
- rdev->size, sb->chunk_size / 1024);


- return -EINVAL;
- }
- }
-

- switch (sb->level) {
- case -3:
- data_disks = 1;
- break;
- case -2:
- data_disks = 1;
- break;
- case -1:
- zoned_raid_size(mddev);
- data_disks = 1;
- break;
- case 0:
- zoned_raid_size(mddev);
- data_disks = sb->raid_disks;
- break;
- case 1:
- data_disks = 1;
- break;
- case 4:
- case 5:
- data_disks = sb->raid_disks-1;
- break;
- default:
- printk (UNKNOWN_LEVEL, mdidx(mddev), sb->level);
- goto abort;
- }
- if (!md_size[mdidx(mddev)])
- md_size[mdidx(mddev)] = sb->size * data_disks;
-
- readahead = MD_READAHEAD;
- if ((sb->level == 0) || (sb->level == 4) || (sb->level == 5)) {
- readahead = (mddev->sb->chunk_size>>PAGE_SHIFT) * 4 * data_disks;
- if (readahead < data_disks * (MAX_SECTORS>>(PAGE_SHIFT-9))*2)
- readahead = data_disks * (MAX_SECTORS>>(PAGE_SHIFT-9))*2;
- } else {
- if (sb->level == -3)
- readahead = 0;
- }
- md_maxreadahead[mdidx(mddev)] = readahead;
-
- printk(KERN_INFO "md%d: max total readahead window set to %ldk\n",
- mdidx(mddev), readahead*(PAGE_SIZE/1024));
-
- printk(KERN_INFO
- "md%d: %d data-disks, max readahead per data-disk: %ldk\n",
- mdidx(mddev), data_disks, readahead/data_disks*(PAGE_SIZE/1024));
- return 0;
-abort:


- return 1;
-}
-

-
-#define TOO_BIG_CHUNKSIZE KERN_ERR \
-"too big chunk_size: %d > %d\n"
-
-#define TOO_SMALL_CHUNKSIZE KERN_ERR \
-"too small chunk_size: %d < %ld\n"
-
-#define BAD_CHUNKSIZE KERN_ERR \
-"no chunksize specified, see 'man raidtab'\n"
-
-static int do_md_run (mddev_t * mddev)
-{
- int pnum, err;
- int chunk_size;
- struct md_list_head *tmp;
- mdk_rdev_t *rdev;
-
-
- if (!mddev->nb_dev) {
- MD_BUG();


- return -EINVAL;
- }
-

- if (mddev->pers)


- return -EBUSY;
-
- /*

- * Resize disks to align partitions size on a given
- * chunk size.
- */
- md_size[mdidx(mddev)] = 0;
-
- /*
- * Analyze all RAID superblock(s)
- */
- if (analyze_sbs(mddev)) {
- MD_BUG();


- return -EINVAL;
- }
-

- chunk_size = mddev->sb->chunk_size;
- pnum = level_to_pers(mddev->sb->level);
-
- mddev->param.chunk_size = chunk_size;
- mddev->param.personality = pnum;
-
- if (chunk_size > MAX_CHUNK_SIZE) {
- printk(TOO_BIG_CHUNKSIZE, chunk_size, MAX_CHUNK_SIZE);


- return -EINVAL;
- }
- /*

- * chunk-size has to be a power of 2 and multiples of PAGE_SIZE
- */
- if ( (1 << ffz(~chunk_size)) != chunk_size) {
- MD_BUG();
- return -EINVAL;
- }
- if (chunk_size < PAGE_SIZE) {
- printk(TOO_SMALL_CHUNKSIZE, chunk_size, PAGE_SIZE);


- return -EINVAL;
- }
-

- if (pnum >= MAX_PERSONALITY) {
- MD_BUG();


- return -EINVAL;
- }
-

- if ((pnum != RAID1) && (pnum != LINEAR) && !chunk_size) {
- /*
- * 'default chunksize' in the old md code used to
- * be PAGE_SIZE, baaad.
- * we abort here to be on the safe side. We dont
- * want to continue the bad practice.
- */
- printk(BAD_CHUNKSIZE);


- return -EINVAL;
- }
-

- if (!pers[pnum])
- {
-#ifdef CONFIG_KMOD
- char module_name[80];
- sprintf (module_name, "md-personality-%d", pnum);
- request_module (module_name);
- if (!pers[pnum])
-#endif


- return -EINVAL;
- }
-

- if (device_size_calculation(mddev))


- return -EINVAL;
-
- /*

- * Drop all container device buffers, from now on
- * the only valid external interface is through the md
- * device.
- * Also find largest hardsector size
- */
- md_hardsect_sizes[mdidx(mddev)] = 512;
- ITERATE_RDEV(mddev,rdev,tmp) {
- if (rdev->faulty)
- continue;
- fsync_dev(rdev->dev);
- invalidate_buffers(rdev->dev);
- if (get_hardsect_size(rdev->dev)
- > md_hardsect_sizes[mdidx(mddev)])
- md_hardsect_sizes[mdidx(mddev)] =
- get_hardsect_size(rdev->dev);
- }
- md_blocksizes[mdidx(mddev)] = 1024;
- if (md_blocksizes[mdidx(mddev)] < md_hardsect_sizes[mdidx(mddev)])
- md_blocksizes[mdidx(mddev)] = md_hardsect_sizes[mdidx(mddev)];
- mddev->pers = pers[pnum];
-
- err = mddev->pers->run(mddev);
- if (err) {
- printk("pers->run() failed ...\n");
- mddev->pers = NULL;


- return -EINVAL;
- }
-

- mddev->sb->state &= ~(1 << MD_SB_CLEAN);
- md_update_sb(mddev);
-
- /*
- * md_size has units of 1K blocks, which are
- * twice as large as sectors.
- */
- md_hd_struct[mdidx(mddev)].start_sect = 0;
- md_hd_struct[mdidx(mddev)].nr_sects = md_size[mdidx(mddev)] << 1;
-
- read_ahead[MD_MAJOR] = 1024;
- return (0);
-}
-
-#undef TOO_BIG_CHUNKSIZE
-#undef BAD_CHUNKSIZE
-
-#define OUT(x) do { err = (x); goto out; } while (0)
-
-static int restart_array (mddev_t *mddev)
-{
- int err = 0;
-
- /*
- * Complain if it has no devices
- */
- if (!mddev->nb_dev)
- OUT(-ENXIO);
-
- if (mddev->pers) {
- if (!mddev->ro)
- OUT(-EBUSY);
-
- mddev->ro = 0;
- set_device_ro(mddev_to_kdev(mddev), 0);
-
- printk (KERN_INFO
- "md%d switched to read-write mode.\n", mdidx(mddev));
- /*
- * Kick recovery or resync if necessary
- */
- md_recover_arrays();
- if (mddev->pers->restart_resync)
- mddev->pers->restart_resync(mddev);
- } else
- err = -EINVAL;
-
-out:


- return err;
-}
-

-#define STILL_MOUNTED KERN_WARNING \
-"md: md%d still mounted.\n"
-
-static int do_md_stop (mddev_t * mddev, int ro)
-{
- int err = 0, resync_interrupted = 0;
- kdev_t dev = mddev_to_kdev(mddev);
-
- if (!ro && get_super(dev)) {
- printk (STILL_MOUNTED, mdidx(mddev));
- OUT(-EBUSY);
- }
-
- if (mddev->pers) {
- /*
- * It is safe to call stop here, it only frees private
- * data. Also, it tells us if a device is unstoppable
- * (eg. resyncing is in progress)
- */
- if (mddev->pers->stop_resync)
- if (mddev->pers->stop_resync(mddev))
- resync_interrupted = 1;
-
- if (mddev->recovery_running)
- md_interrupt_thread(md_recovery_thread);
-
- /*
- * This synchronizes with signal delivery to the
- * resync or reconstruction thread. It also nicely
- * hangs the process if some reconstruction has not
- * finished.
- */
- down(&mddev->recovery_sem);
- up(&mddev->recovery_sem);
-
- /*
- * sync and invalidate buffers because we cannot kill the
- * main thread with valid IO transfers still around.
- * the kernel lock protects us from new requests being
- * added after invalidate_buffers().
- */
- fsync_dev (mddev_to_kdev(mddev));
- fsync_dev (dev);
- invalidate_buffers (dev);
-
- if (ro) {
- if (mddev->ro)
- OUT(-ENXIO);
- mddev->ro = 1;
- } else {
- if (mddev->ro)
- set_device_ro(dev, 0);
- if (mddev->pers->stop(mddev)) {
- if (mddev->ro)
- set_device_ro(dev, 1);
- OUT(-EBUSY);
- }
- if (mddev->ro)
- mddev->ro = 0;
- }
- if (mddev->sb) {
- /*
- * mark it clean only if there was no resync
- * interrupted.
- */
- if (!mddev->recovery_running && !resync_interrupted) {
- printk("marking sb clean...\n");
- mddev->sb->state |= 1 << MD_SB_CLEAN;
- }
- md_update_sb(mddev);
- }
- if (ro)
- set_device_ro(dev, 1);
- }
-
- /*
- * Free resources if final stop
- */
- if (!ro) {
- printk (KERN_INFO "md%d stopped.\n", mdidx(mddev));
- free_mddev(mddev);
-
- } else
- printk (KERN_INFO
- "md%d switched to read-only mode.\n", mdidx(mddev));
-out:


- return err;
-}
-

-#undef OUT
-
-/*
- * We have to safely support old arrays too.
- */
-int detect_old_array (mdp_super_t *sb)
-{
- if (sb->major_version > 0)
- return 0;
- if (sb->minor_version >= 90)
- return 0;
-
- return -EINVAL;
-}
-
-
-static void autorun_array (mddev_t *mddev)
-{
- mdk_rdev_t *rdev;
- struct md_list_head *tmp;
- int err;
-
- if (mddev->disks.prev == &mddev->disks) {


- MD_BUG();
- return;
- }
-

- printk("running: ");
-
- ITERATE_RDEV(mddev,rdev,tmp) {
- printk("<%s>", partition_name(rdev->dev));
- }
- printk("\nnow!\n");
-
- err = do_md_run (mddev);
- if (err) {
- printk("do_md_run() returned %d\n", err);
- /*
- * prevent the writeback of an unrunnable array
- */
- mddev->sb_dirty = 0;
- do_md_stop (mddev, 0);
- }
-}
-
-/*
- * lets try to run arrays based on all disks that have arrived
- * until now. (those are in the ->pending list)
- *
- * the method: pick the first pending disk, collect all disks with
- * the same UUID, remove all from the pending list and put them into
- * the 'same_array' list. Then order this list based on superblock
- * update time (freshest comes first), kick out 'old' disks and
- * compare superblocks. If everything's fine then run it.
- */
-static void autorun_devices (void)
-{
- struct md_list_head candidates;
- struct md_list_head *tmp;
- mdk_rdev_t *rdev0, *rdev;
- mddev_t *mddev;
- kdev_t md_kdev;
-
-
- printk("autorun ...\n");
- while (pending_raid_disks.next != &pending_raid_disks) {
- rdev0 = md_list_entry(pending_raid_disks.next,
- mdk_rdev_t, pending);
-
- printk("considering %s ...\n", partition_name(rdev0->dev));
- MD_INIT_LIST_HEAD(&candidates);
- ITERATE_RDEV_PENDING(rdev,tmp) {
- if (uuid_equal(rdev0, rdev)) {
- if (!sb_equal(rdev0->sb, rdev->sb)) {
- printk("%s has same UUID as %s, but superblocks differ ...\n", partition_name(rdev->dev), partition_name(rdev0->dev));
- continue;
- }
- printk(" adding %s ...\n", partition_name(rdev->dev));
- md_list_del(&rdev->pending);
- md_list_add(&rdev->pending, &candidates);
- }
- }
- /*
- * now we have a set of devices, with all of them having
- * mostly sane superblocks. It's time to allocate the
- * mddev.
- */
- md_kdev = MKDEV(MD_MAJOR, rdev0->sb->md_minor);
- mddev = kdev_to_mddev(md_kdev);
- if (mddev) {
- printk("md%d already running, cannot run %s\n",
- mdidx(mddev), partition_name(rdev0->dev));
- ITERATE_RDEV_GENERIC(candidates,pending,rdev,tmp)
- export_rdev(rdev);
- continue;
- }
- mddev = alloc_mddev(md_kdev);
- printk("created md%d\n", mdidx(mddev));
- ITERATE_RDEV_GENERIC(candidates,pending,rdev,tmp) {
- bind_rdev_to_array(rdev, mddev);
- md_list_del(&rdev->pending);
- MD_INIT_LIST_HEAD(&rdev->pending);
- }
- autorun_array(mddev);
- }
- printk("... autorun DONE.\n");
-}
-
-/*
- * import RAID devices based on one partition
- * if possible, the array gets run as well.
- */
-
-#define BAD_VERSION KERN_ERR \
-"md: %s has RAID superblock version 0.%d, autodetect needs v0.90 or higher\n"
-
-#define OUT_OF_MEM KERN_ALERT \
-"md: out of memory.\n"
-
-#define NO_DEVICE KERN_ERR \
-"md: disabled device %s\n"
-
-#define AUTOADD_FAILED KERN_ERR \
-"md: auto-adding devices to md%d FAILED (error %d).\n"
-
-#define AUTOADD_FAILED_USED KERN_ERR \
-"md: cannot auto-add device %s to md%d, already used.\n"
-
-#define AUTORUN_FAILED KERN_ERR \
-"md: auto-running md%d FAILED (error %d).\n"
-
-#define MDDEV_BUSY KERN_ERR \
-"md: cannot auto-add to md%d, already running.\n"
-
-#define AUTOADDING KERN_INFO \
-"md: auto-adding devices to md%d, based on %s's superblock.\n"
-
-#define AUTORUNNING KERN_INFO \
-"md: auto-running md%d.\n"
-
-static int autostart_array (kdev_t startdev)
-{
- int err = -EINVAL, i;
- mdp_super_t *sb = NULL;
- mdk_rdev_t *start_rdev = NULL, *rdev;
-
- if (md_import_device(startdev, 1)) {
- printk("could not import %s!\n", partition_name(startdev));
- goto abort;
- }
-
- start_rdev = find_rdev_all(startdev);
- if (!start_rdev) {
- MD_BUG();
- goto abort;
- }
- if (start_rdev->faulty) {
- printk("can not autostart based on faulty %s!\n",
- partition_name(startdev));
- goto abort;
- }
- md_list_add(&start_rdev->pending, &pending_raid_disks);
-
- sb = start_rdev->sb;
-
- err = detect_old_array(sb);
- if (err) {
- printk("array version is too old to be autostarted, use raidtools 0.90 mkraid --upgrade\nto upgrade the array without data loss!\n");
- goto abort;
- }
-
- for (i = 0; i < MD_SB_DISKS; i++) {
- mdp_disk_t *desc;
- kdev_t dev;
-
- desc = sb->disks + i;
- dev = MKDEV(desc->major, desc->minor);
-
- if (dev == MKDEV(0,0))
- continue;
- if (dev == startdev)
- continue;
- if (md_import_device(dev, 1)) {
- printk("could not import %s, trying to run array nevertheless.\n", partition_name(dev));
- continue;
- }
- rdev = find_rdev_all(dev);
- if (!rdev) {
- MD_BUG();
- goto abort;
- }
- md_list_add(&rdev->pending, &pending_raid_disks);
- }
-
- /*
- * possibly return codes
- */
- autorun_devices();
- return 0;
-
-abort:
- if (start_rdev)
- export_rdev(start_rdev);


- return err;
-}
-

-#undef BAD_VERSION
-#undef OUT_OF_MEM
-#undef NO_DEVICE
-#undef AUTOADD_FAILED_USED
-#undef AUTOADD_FAILED
-#undef AUTORUN_FAILED
-#undef AUTOADDING
-#undef AUTORUNNING
-
-struct {
- int set;
- int noautodetect;
-
-} raid_setup_args md__initdata = { 0, 0 };
-
-void md_setup_drive(void) md__init;
-
-/*
- * Searches all registered partitions for autorun RAID arrays
- * at boot time.
- */
-#ifdef CONFIG_AUTODETECT_RAID
-static int detected_devices[128] md__initdata;
-static int dev_cnt=0;
-void md_autodetect_dev(kdev_t dev)
-{
- if (dev_cnt >= 0 && dev_cnt < 127)
- detected_devices[dev_cnt++] = dev;
-}
-#endif
-
-void md__init md_run_setup(void)
-{
-#ifdef CONFIG_AUTODETECT_RAID
- mdk_rdev_t *rdev;
- int i;
-
- if (raid_setup_args.noautodetect)
- printk(KERN_INFO "skipping autodetection of RAID arrays\n");
- else {
-
- printk(KERN_INFO "autodetecting RAID arrays\n");
-
- for (i=0; i<dev_cnt; i++) {
- kdev_t dev = detected_devices[i];
-
- if (md_import_device(dev,1)) {
- printk(KERN_ALERT "could not import %s!\n",
- partition_name(dev));
- continue;
- }
- /*
- * Sanity checks:
- */
- rdev = find_rdev_all(dev);
- if (!rdev) {
- MD_BUG();
- continue;
- }
- if (rdev->faulty) {
- MD_BUG();
- continue;
- }
- md_list_add(&rdev->pending, &pending_raid_disks);
- }
-
- autorun_devices();
- }
-
- dev_cnt = -1; /* make sure further calls to md_autodetect_dev are ignored */
-#endif
-#ifdef CONFIG_MD_BOOT
- md_setup_drive();
-#endif
-
-}
-
-static int get_version (void * arg)
-{
- mdu_version_t ver;
-
- ver.major = MD_MAJOR_VERSION;
- ver.minor = MD_MINOR_VERSION;
- ver.patchlevel = MD_PATCHLEVEL_VERSION;
-
- if (md_copy_to_user(arg, &ver, sizeof(ver)))


- return -EFAULT;
-
- return 0;
-}
-

-#define SET_FROM_SB(x) info.x = mddev->sb->x
-static int get_array_info (mddev_t * mddev, void * arg)
-{
- mdu_array_info_t info;
-
- if (!mddev->sb)
- return -EINVAL;
-
- SET_FROM_SB(major_version);
- SET_FROM_SB(minor_version);
- SET_FROM_SB(patch_version);
- SET_FROM_SB(ctime);
- SET_FROM_SB(level);
- SET_FROM_SB(size);
- SET_FROM_SB(nr_disks);
- SET_FROM_SB(raid_disks);
- SET_FROM_SB(md_minor);
- SET_FROM_SB(not_persistent);
-
- SET_FROM_SB(utime);
- SET_FROM_SB(state);
- SET_FROM_SB(active_disks);
- SET_FROM_SB(working_disks);
- SET_FROM_SB(failed_disks);
- SET_FROM_SB(spare_disks);
-
- SET_FROM_SB(layout);
- SET_FROM_SB(chunk_size);
-
- if (md_copy_to_user(arg, &info, sizeof(info)))


- return -EFAULT;
-
- return 0;
-}

-#undef SET_FROM_SB
-
-#define SET_FROM_SB(x) info.x = mddev->sb->disks[nr].x
-static int get_disk_info (mddev_t * mddev, void * arg)
-{
- mdu_disk_info_t info;
- unsigned int nr;
-
- if (!mddev->sb)
- return -EINVAL;
-
- if (md_copy_from_user(&info, arg, sizeof(info)))
- return -EFAULT;
-
- nr = info.number;
- if (nr >= mddev->sb->nr_disks)
- return -EINVAL;
-
- SET_FROM_SB(major);
- SET_FROM_SB(minor);
- SET_FROM_SB(raid_disk);
- SET_FROM_SB(state);
-
- if (md_copy_to_user(arg, &info, sizeof(info)))


- return -EFAULT;
-
- return 0;
-}

-#undef SET_FROM_SB
-
-#define SET_SB(x) mddev->sb->disks[nr].x = info->x
-
-static int add_new_disk (mddev_t * mddev, mdu_disk_info_t *info)
-{
- int err, size, persistent;
- mdk_rdev_t *rdev;
- unsigned int nr;
- kdev_t dev;
- dev = MKDEV(info->major,info->minor);
-
- if (find_rdev_all(dev)) {
- printk("device %s already used in a RAID array!\n",
- partition_name(dev));
- return -EBUSY;
- }
- if (!mddev->sb) {
- /* expecting a device which has a superblock */
- err = md_import_device(dev, 1);
- if (err) {
- printk("md error, md_import_device returned %d\n", err);
- return -EINVAL;
- }
- rdev = find_rdev_all(dev);
- if (!rdev) {
- MD_BUG();
- return -EINVAL;
- }
- if (mddev->nb_dev) {
- mdk_rdev_t *rdev0 = md_list_entry(mddev->disks.next,
- mdk_rdev_t, same_set);
- if (!uuid_equal(rdev0, rdev)) {
- printk("md: %s has different UUID to %s\n", partition_name(rdev->dev), partition_name(rdev0->dev));
- export_rdev(rdev);
- return -EINVAL;
- }
- if (!sb_equal(rdev0->sb, rdev->sb)) {
- printk("md: %s has same UUID but different superblock to %s\n", partition_name(rdev->dev), partition_name(rdev0->dev));
- export_rdev(rdev);


- return -EINVAL;
- }
- }

- bind_rdev_to_array(rdev, mddev);


- return 0;
- }
-

- nr = info->number;
- if (nr >= mddev->sb->nr_disks)
- return -EINVAL;
-
- SET_SB(number);
- SET_SB(major);
- SET_SB(minor);
- SET_SB(raid_disk);
- SET_SB(state);
-
- if ((info->state & (1<<MD_DISK_FAULTY))==0) {
- err = md_import_device (dev, 0);
- if (err) {
- printk("md: error, md_import_device() returned %d\n", err);
- return -EINVAL;
- }
- rdev = find_rdev_all(dev);
- if (!rdev) {
- MD_BUG();


- return -EINVAL;
- }
-

- rdev->old_dev = dev;
- rdev->desc_nr = info->number;
-
- bind_rdev_to_array(rdev, mddev);
-
- persistent = !mddev->sb->not_persistent;
- if (!persistent)
- printk("nonpersistent superblock ...\n");
- if (!mddev->sb->chunk_size)
- printk("no chunksize?\n");
-
- size = calc_dev_size(dev, mddev, persistent);
- rdev->sb_offset = calc_dev_sboffset(dev, mddev, persistent);
-
- if (!mddev->sb->size || (mddev->sb->size > size))
- mddev->sb->size = size;
- }
-
- /*
- * sync all other superblocks with the main superblock
- */
- sync_sbs(mddev);


-
- return 0;
-}

-#undef SET_SB
-
-static int hot_remove_disk (mddev_t * mddev, kdev_t dev)
-{
- int err;
- mdk_rdev_t *rdev;
- mdp_disk_t *disk;
-
- if (!mddev->pers)
- return -ENODEV;
-
- printk("trying to remove %s from md%d ... \n",
- partition_name(dev), mdidx(mddev));
-
- if (!mddev->pers->diskop) {
- printk("md%d: personality does not support diskops!\n",
- mdidx(mddev));


- return -EINVAL;
- }
-

- rdev = find_rdev(mddev, dev);
- if (!rdev)
- return -ENXIO;
-
- if (rdev->desc_nr == -1) {
- MD_BUG();
- return -EINVAL;
- }
- disk = &mddev->sb->disks[rdev->desc_nr];
- if (disk_active(disk))
- goto busy;
- if (disk_removed(disk)) {
- MD_BUG();


- return -EINVAL;
- }
-

- err = mddev->pers->diskop(mddev, &disk, DISKOP_HOT_REMOVE_DISK);
- if (err == -EBUSY)
- goto busy;
- if (err) {
- MD_BUG();


- return -EINVAL;
- }
-

- remove_descriptor(disk, mddev->sb);
- kick_rdev_from_array(rdev);
- mddev->sb_dirty = 1;
- md_update_sb(mddev);
-
- return 0;
-busy:
- printk("cannot remove active disk %s from md%d ... \n",
- partition_name(dev), mdidx(mddev));


- return -EBUSY;
-}
-

-static int hot_add_disk (mddev_t * mddev, kdev_t dev)
-{
- int i, err, persistent;
- unsigned int size;
- mdk_rdev_t *rdev;
- mdp_disk_t *disk;
-
- if (!mddev->pers)
- return -ENODEV;
-
- printk("trying to hot-add %s to md%d ... \n",
- partition_name(dev), mdidx(mddev));
-
- if (!mddev->pers->diskop) {
- printk("md%d: personality does not support diskops!\n",
- mdidx(mddev));


- return -EINVAL;
- }
-

- persistent = !mddev->sb->not_persistent;
- size = calc_dev_size(dev, mddev, persistent);
-
- if (size < mddev->sb->size) {
- printk("md%d: disk size %d blocks < array size %d\n",
- mdidx(mddev), size, mddev->sb->size);
- return -ENOSPC;
- }
-
- rdev = find_rdev(mddev, dev);
- if (rdev)
- return -EBUSY;
-
- err = md_import_device (dev, 0);
- if (err) {
- printk("md: error, md_import_device() returned %d\n", err);
- return -EINVAL;
- }
- rdev = find_rdev_all(dev);
- if (!rdev) {
- MD_BUG();
- return -EINVAL;
- }
- if (rdev->faulty) {
- printk("md: can not hot-add faulty %s disk to md%d!\n",
- partition_name(dev), mdidx(mddev));
- err = -EINVAL;
- goto abort_export;
- }
- bind_rdev_to_array(rdev, mddev);
-
- /*
- * The rest should better be atomic, we can have disk failures
- * noticed in interrupt contexts ...
- */
- rdev->old_dev = dev;
- rdev->size = size;
- rdev->sb_offset = calc_dev_sboffset(dev, mddev, persistent);
-
- disk = mddev->sb->disks + mddev->sb->raid_disks;
- for (i = mddev->sb->raid_disks; i < MD_SB_DISKS; i++) {
- disk = mddev->sb->disks + i;
-
- if (!disk->major && !disk->minor)
- break;
- if (disk_removed(disk))
- break;
- }
- if (i == MD_SB_DISKS) {
- printk("md%d: can not hot-add to full array!\n", mdidx(mddev));
- err = -EBUSY;
- goto abort_unbind_export;
- }
-
- if (disk_removed(disk)) {
- /*
- * reuse slot
- */
- if (disk->number != i) {
- MD_BUG();
- err = -EINVAL;
- goto abort_unbind_export;
- }
- } else {
- disk->number = i;
- }
-
- disk->raid_disk = disk->number;
- disk->major = MAJOR(dev);
- disk->minor = MINOR(dev);
-
- if (mddev->pers->diskop(mddev, &disk, DISKOP_HOT_ADD_DISK)) {
- MD_BUG();
- err = -EINVAL;
- goto abort_unbind_export;
- }
-
- mark_disk_spare(disk);
- mddev->sb->nr_disks++;
- mddev->sb->spare_disks++;
- mddev->sb->working_disks++;
-
- mddev->sb_dirty = 1;
-
- md_update_sb(mddev);
-
- /*
- * Kick recovery, maybe this spare has to be added to the
- * array immediately.
- */
- md_recover_arrays();


-
- return 0;
-

-abort_unbind_export:
- unbind_rdev_from_array(rdev);
-
-abort_export:
- export_rdev(rdev);


- return err;
-}
-

-#define SET_SB(x) mddev->sb->x = info->x
-static int set_array_info (mddev_t * mddev, mdu_array_info_t *info)
-{
-
- if (alloc_array_sb(mddev))
- return -ENOMEM;
-
- mddev->sb->major_version = MD_MAJOR_VERSION;
- mddev->sb->minor_version = MD_MINOR_VERSION;
- mddev->sb->patch_version = MD_PATCHLEVEL_VERSION;
- mddev->sb->ctime = CURRENT_TIME;
-
- SET_SB(level);
- SET_SB(size);
- SET_SB(nr_disks);
- SET_SB(raid_disks);
- SET_SB(md_minor);
- SET_SB(not_persistent);
-
- SET_SB(state);
- SET_SB(active_disks);
- SET_SB(working_disks);
- SET_SB(failed_disks);
- SET_SB(spare_disks);
-
- SET_SB(layout);
- SET_SB(chunk_size);
-
- mddev->sb->md_magic = MD_SB_MAGIC;
-
- /*
- * Generate a 128 bit UUID
- */
- get_random_bytes(&mddev->sb->set_uuid0, 4);
- get_random_bytes(&mddev->sb->set_uuid1, 4);
- get_random_bytes(&mddev->sb->set_uuid2, 4);
- get_random_bytes(&mddev->sb->set_uuid3, 4);


-
- return 0;
-}

-#undef SET_SB
-
-static int set_disk_info (mddev_t * mddev, void * arg)
-{
- printk("not yet");


- return -EINVAL;
-}
-

-static int clear_array (mddev_t * mddev)
-{
- printk("not yet");


- return -EINVAL;
-}
-

-static int write_raid_info (mddev_t * mddev)
-{
- printk("not yet");


- return -EINVAL;
-}
-

-static int protect_array (mddev_t * mddev)
-{
- printk("not yet");


- return -EINVAL;
-}
-

-static int unprotect_array (mddev_t * mddev)
-{
- printk("not yet");


- return -EINVAL;
-}
-

-static int set_disk_faulty (mddev_t *mddev, kdev_t dev)


-{
- int ret;
-

- fsync_dev(mddev_to_kdev(mddev));
- ret = md_error(mddev_to_kdev(mddev), dev);


- return ret;
-}
-

-static int md_ioctl (struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- unsigned int minor;
- int err = 0;
- struct hd_geometry *loc = (struct hd_geometry *) arg;
- mddev_t *mddev = NULL;
- kdev_t dev;
-
- if (!md_capable_admin())
- return -EACCES;
-
- dev = inode->i_rdev;
- minor = MINOR(dev);
- if (minor >= MAX_MD_DEVS)


- return -EINVAL;
-
- /*

- * Commands dealing with the RAID driver but not any
- * particular array:
- */
- switch (cmd)
- {
- case RAID_VERSION:
- err = get_version((void *)arg);
- goto done;
-
- case PRINT_RAID_DEBUG:
- err = 0;
- md_print_devices();
- goto done_unlock;
-
- case BLKGETSIZE: /* Return device size */
- if (!arg) {
- err = -EINVAL;
- goto abort;
- }
- err = md_put_user(md_hd_struct[minor].nr_sects,
- (long *) arg);
- goto done;
-
- case BLKFLSBUF:
- fsync_dev(dev);
- invalidate_buffers(dev);
- goto done;
-
- case BLKRASET:
- if (arg > 0xff) {
- err = -EINVAL;
- goto abort;
- }
- read_ahead[MAJOR(dev)] = arg;
- goto done;
-
- case BLKRAGET:
- if (!arg) {
- err = -EINVAL;
- goto abort;
- }
- err = md_put_user (read_ahead[
- MAJOR(dev)], (long *) arg);
- goto done;
- default:
- }
-
- /*
- * Commands creating/starting a new array:
- */
-
- mddev = kdev_to_mddev(dev);
-
- switch (cmd)
- {
- case SET_ARRAY_INFO:
- case START_ARRAY:
- if (mddev) {
- printk("array md%d already exists!\n",
- mdidx(mddev));
- err = -EEXIST;
- goto abort;
- }
- default:
- }
- switch (cmd)
- {
- case SET_ARRAY_INFO:
- mddev = alloc_mddev(dev);
- if (!mddev) {
- err = -ENOMEM;
- goto abort;
- }
- /*
- * alloc_mddev() should possibly self-lock.
- */
- err = lock_mddev(mddev);
- if (err) {
- printk("ioctl, reason %d, cmd %d\n", err, cmd);
- goto abort;
- }
-
- if (mddev->sb) {
- printk("array md%d already has a superblock!\n",
- mdidx(mddev));
- err = -EBUSY;
- goto abort_unlock;
- }
- if (arg) {
- mdu_array_info_t info;
- if (md_copy_from_user(&info, (void*)arg, sizeof(info))) {
- err = -EFAULT;
- goto abort_unlock;
- }
- err = set_array_info(mddev, &info);
- if (err) {
- printk("couldnt set array info. %d\n", err);
- goto abort_unlock;
- }
- }
- goto done_unlock;
-
- case START_ARRAY:
- /*
- * possibly make it lock the array ...
- */
- err = autostart_array((kdev_t)arg);
- if (err) {
- printk("autostart %s failed!\n",
- partition_name((kdev_t)arg));
- goto abort;
- }
- goto done;
-
- default:
- }
-
- /*
- * Commands querying/configuring an existing array:
- */
-
- if (!mddev) {
- err = -ENODEV;
- goto abort;
- }
- err = lock_mddev(mddev);
- if (err) {
- printk("ioctl lock interrupted, reason %d, cmd %d\n",err, cmd);
- goto abort;
- }
- /* if we don't have a superblock yet, only ADD_NEW_DISK or STOP_ARRAY is allowed */
- if (!mddev->sb && cmd != ADD_NEW_DISK && cmd != STOP_ARRAY && cmd != RUN_ARRAY) {
- err = -ENODEV;
- goto abort_unlock;
- }
-
- /*
- * Commands even a read-only array can execute:
- */
- switch (cmd)
- {
- case GET_ARRAY_INFO:
- err = get_array_info(mddev, (void *)arg);
- goto done_unlock;
-
- case GET_DISK_INFO:
- err = get_disk_info(mddev, (void *)arg);
- goto done_unlock;
-
- case RESTART_ARRAY_RW:
- err = restart_array(mddev);
- goto done_unlock;
-
- case STOP_ARRAY:
- if (!(err = do_md_stop (mddev, 0)))
- mddev = NULL;
- goto done_unlock;
-
- case STOP_ARRAY_RO:
- err = do_md_stop (mddev, 1);
- goto done_unlock;
-
- /*
- * We have a problem here : there is no easy way to give a CHS
- * virtual geometry. We currently pretend that we have a 2 heads
- * 4 sectors (with a BIG number of cylinders...). This drives
- * dosfs just mad... ;-)
- */
- case HDIO_GETGEO:
- if (!loc) {
- err = -EINVAL;
- goto abort_unlock;
- }
- err = md_put_user (2, (char *) &loc->heads);
- if (err)
- goto abort_unlock;
- err = md_put_user (4, (char *) &loc->sectors);
- if (err)
- goto abort_unlock;
- err = md_put_user (md_hd_struct[mdidx(mddev)].nr_sects/8,
- (short *) &loc->cylinders);
- if (err)
- goto abort_unlock;
- err = md_put_user (md_hd_struct[minor].start_sect,
- (long *) &loc->start);
- goto done_unlock;
- }
-
- /*
- * The remaining ioctls are changing the state of the
- * superblock, so we do not allow read-only arrays
- * here:
- */
- if (mddev->ro) {
- err = -EROFS;
- goto abort_unlock;
- }
-
- switch (cmd)
- {
- case CLEAR_ARRAY:
- err = clear_array(mddev);
- goto done_unlock;
-
- case ADD_NEW_DISK:
- {
- mdu_disk_info_t info;
- if (md_copy_from_user(&info, (void*)arg, sizeof(info)))
- err = -EFAULT;
- else
- err = add_new_disk(mddev, &info);
- goto done_unlock;
- }
- case HOT_REMOVE_DISK:
- err = hot_remove_disk(mddev, (kdev_t)arg);
- goto done_unlock;
-
- case HOT_ADD_DISK:
- err = hot_add_disk(mddev, (kdev_t)arg);
- goto done_unlock;
-
- case SET_DISK_INFO:
- err = set_disk_info(mddev, (void *)arg);
- goto done_unlock;
-
- case WRITE_RAID_INFO:
- err = write_raid_info(mddev);
- goto done_unlock;
-
- case UNPROTECT_ARRAY:
- err = unprotect_array(mddev);
- goto done_unlock;
-
- case PROTECT_ARRAY:
- err = protect_array(mddev);
- goto done_unlock;
-
- case SET_DISK_FAULTY:
- err = set_disk_faulty(mddev, (kdev_t)arg);
- goto done_unlock;
-
- case RUN_ARRAY:
- {
-/* The data is never used....
- mdu_param_t param;
- err = md_copy_from_user(&param, (mdu_param_t *)arg,
- sizeof(param));
- if (err)
- goto abort_unlock;
-*/
- err = do_md_run (mddev);
- /*
- * we have to clean up the mess if
- * the array cannot be run for some
- * reason ...
- */
- if (err) {
- mddev->sb_dirty = 0;
- if (!do_md_stop (mddev, 0))
- mddev = NULL;
- }
- goto done_unlock;
- }
-
- default:
- printk(KERN_WARNING "%s(pid %d) used obsolete MD ioctl, upgrade your software to use new ictls.\n", current->comm, current->pid);
- err = -EINVAL;
- goto abort_unlock;
- }
-
-done_unlock:
-abort_unlock:
- if (mddev)
- unlock_mddev(mddev);
-
- return err;
-done:
- if (err)
- printk("huh12?\n");
-abort:


- return err;
-}
-

-static int md_open (struct inode *inode, struct file *file)
-{
- /*
- * Always succeed
- */
- return (0);
-}
-
-static struct block_device_operations md_fops=
-{
- open: md_open,
- ioctl: md_ioctl,
-};
-
-
-int md_thread(void * arg)
-{
- mdk_thread_t *thread = arg;
-
- md_lock_kernel();
- exit_mm(current);
- exit_files(current);
- exit_fs(current);
-
- /*
- * Detach thread
- */
- daemonize();
- sprintf(current->comm, thread->name);
- md_init_signals();
- md_flush_signals();
- thread->tsk = current;
-
- /*
- * md_thread is a 'system-thread', it's priority should be very


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 042'
echo 'File patch-2.4.0-test9 is continued in part 043'
echo "043" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part043

#!/bin/sh -x
# this is part 043 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 043; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

- * high. We avoid resource deadlocks individually in each
- * raid personality. (RAID5 does preallocation) We also use RR and
- * the very same RT priority as kswapd, thus we will never get
- * into a priority inversion deadlock.
- *
- * we definitely have to have equal or higher priority than
- * bdflush, otherwise bdflush will deadlock if there are too
- * many dirty RAID5 blocks.
- */
- current->policy = SCHED_OTHER;
- current->nice = -20;
-// md_unlock_kernel();
-
- up(thread->sem);
-
- for (;;) {
- DECLARE_WAITQUEUE(wait, current);
-
- add_wait_queue(&thread->wqueue, &wait);
- set_task_state(current, TASK_INTERRUPTIBLE);
- if (!test_bit(THREAD_WAKEUP, &thread->flags)) {
- dprintk("thread %p went to sleep.\n", thread);
- schedule();
- dprintk("thread %p woke up.\n", thread);
- }
- current->state = TASK_RUNNING;
- remove_wait_queue(&thread->wqueue, &wait);
- clear_bit(THREAD_WAKEUP, &thread->flags);
-
- if (thread->run) {
- thread->run(thread->data);
- run_task_queue(&tq_disk);
- } else
- break;
- if (md_signal_pending(current)) {
- printk("%8s(%d) flushing signals.\n", current->comm,
- current->pid);
- md_flush_signals();
- }
- }
- up(thread->sem);


- return 0;
-}
-

-void md_wakeup_thread(mdk_thread_t *thread)
-{
- dprintk("waking up MD thread %p.\n", thread);
- set_bit(THREAD_WAKEUP, &thread->flags);
- wake_up(&thread->wqueue);
-}
-
-mdk_thread_t *md_register_thread (void (*run) (void *),
- void *data, const char *name)
-{
- mdk_thread_t *thread;
- int ret;
- DECLARE_MUTEX_LOCKED(sem);
-
- thread = (mdk_thread_t *) kmalloc
- (sizeof(mdk_thread_t), GFP_KERNEL);
- if (!thread)
- return NULL;
-
- memset(thread, 0, sizeof(mdk_thread_t));
- md_init_waitqueue_head(&thread->wqueue);
-
- thread->sem = &sem;
- thread->run = run;
- thread->data = data;
- thread->name = name;
- ret = kernel_thread(md_thread, thread, 0);
- if (ret < 0) {
- kfree(thread);
- return NULL;
- }
- down(&sem);
- return thread;
-}
-
-void md_interrupt_thread (mdk_thread_t *thread)
-{
- if (!thread->tsk) {


- MD_BUG();
- return;
- }

- printk("interrupting MD-thread pid %d\n", thread->tsk->pid);
- send_sig(SIGKILL, thread->tsk, 1);
-}
-
-void md_unregister_thread (mdk_thread_t *thread)
-{
- DECLARE_MUTEX_LOCKED(sem);
-
- thread->sem = &sem;
- thread->run = NULL;
- thread->name = NULL;
- if (!thread->tsk) {


- MD_BUG();
- return;
- }

- md_interrupt_thread(thread);
- down(&sem);
-}
-
-void md_recover_arrays (void)
-{
- if (!md_recovery_thread) {


- MD_BUG();
- return;
- }

- md_wakeup_thread(md_recovery_thread);
-}
-
-
-int md_error (kdev_t dev, kdev_t rdev)
-{
- mddev_t *mddev;
- mdk_rdev_t * rrdev;
- int rc;


-
- mddev = kdev_to_mddev(dev);

-/* printk("md_error dev:(%d:%d), rdev:(%d:%d), (caller: %p,%p,%p,%p).\n",MAJOR(dev),MINOR(dev),MAJOR(rdev),MINOR(rdev), __builtin_return_address(0),__builtin_return_address(1),__builtin_return_address(2),__builtin_return_address(3));
- */


- if (!mddev) {
- MD_BUG();

- return 0;
- }
- rrdev = find_rdev(mddev, rdev);
- mark_rdev_faulty(rrdev);
- /*
- * if recovery was running, stop it now.


- */
- if (mddev->pers->stop_resync)

- mddev->pers->stop_resync(mddev);


- if (mddev->recovery_running)
- md_interrupt_thread(md_recovery_thread);

- if (mddev->pers->error_handler) {
- rc = mddev->pers->error_handler(mddev, rdev);
- md_recover_arrays();
- return rc;


- }
- return 0;
-}
-

-static int status_unused (char * page)
-{
- int sz = 0, i = 0;


- mdk_rdev_t *rdev;
- struct md_list_head *tmp;
-

- sz += sprintf(page + sz, "unused devices: ");
-
- ITERATE_RDEV_ALL(rdev,tmp) {
- if (!rdev->same_set.next && !rdev->same_set.prev) {
- /*
- * The device is not yet used by any array.
- */
- i++;
- sz += sprintf(page + sz, "%s ",
- partition_name(rdev->dev));
- }
- }
- if (!i)
- sz += sprintf(page + sz, "<none>");
-
- sz += sprintf(page + sz, "\n");
- return sz;
-}
-
-
-static int status_resync (char * page, mddev_t * mddev)
-{


- int sz = 0;

- unsigned long max_blocks, resync, res, dt, db, rt;
-
- resync = mddev->curr_resync - atomic_read(&mddev->recovery_active);
- max_blocks = mddev->sb->size;
-
- /*
- * Should not happen.
- */
- if (!max_blocks) {


- MD_BUG();
- return 0;
- }

- res = (resync/1024)*1000/(max_blocks/1024 + 1);
- {
- int i, x = res/50, y = 20-x;
- sz += sprintf(page + sz, "[");
- for (i = 0; i < x; i++)
- sz += sprintf(page + sz, "=");
- sz += sprintf(page + sz, ">");
- for (i = 0; i < y; i++)
- sz += sprintf(page + sz, ".");
- sz += sprintf(page + sz, "] ");
- }
- if (!mddev->recovery_running)
- /*
- * true resync
- */
- sz += sprintf(page + sz, " resync =%3lu.%lu%% (%lu/%lu)",
- res/10, res % 10, resync, max_blocks);
- else
- /*
- * recovery ...
- */
- sz += sprintf(page + sz, " recovery =%3lu.%lu%% (%lu/%lu)",
- res/10, res % 10, resync, max_blocks);
-
- /*
- * We do not want to overflow, so the order of operands and
- * the * 100 / 100 trick are important. We do a +1 to be
- * safe against division by zero. We only estimate anyway.
- *
- * dt: time from mark until now
- * db: blocks written from mark until now
- * rt: remaining time
- */
- dt = ((jiffies - mddev->resync_mark) / HZ);
- if (!dt) dt++;
- db = resync - mddev->resync_mark_cnt;
- rt = (dt * ((max_blocks-resync) / (db/100+1)))/100;
-
- sz += sprintf(page + sz, " finish=%lu.%lumin", rt / 60, (rt % 60)/6);
-
- sz += sprintf(page + sz, " speed=%ldK/sec", db/dt);
-


- return sz;
-}
-

-static int md_status_read_proc(char *page, char **start, off_t off,
- int count, int *eof, void *data)
-{
- int sz = 0, j, size;


- struct md_list_head *tmp, *tmp2;
- mdk_rdev_t *rdev;
- mddev_t *mddev;
-

- sz += sprintf(page + sz, "Personalities : ");
- for (j = 0; j < MAX_PERSONALITY; j++)
- if (pers[j])
- sz += sprintf(page+sz, "[%s] ", pers[j]->name);
-
- sz += sprintf(page+sz, "\n");
-
-
- sz += sprintf(page+sz, "read_ahead ");
- if (read_ahead[MD_MAJOR] == INT_MAX)
- sz += sprintf(page+sz, "not set\n");
- else
- sz += sprintf(page+sz, "%d sectors\n", read_ahead[MD_MAJOR]);
-
- ITERATE_MDDEV(mddev,tmp) {
- sz += sprintf(page + sz, "md%d : %sactive", mdidx(mddev),
- mddev->pers ? "" : "in");
- if (mddev->pers) {
- if (mddev->ro)
- sz += sprintf(page + sz, " (read-only)");
- sz += sprintf(page + sz, " %s", mddev->pers->name);
- }


-
- size = 0;

- ITERATE_RDEV(mddev,rdev,tmp2) {
- sz += sprintf(page + sz, " %s[%d]",
- partition_name(rdev->dev), rdev->desc_nr);
- if (rdev->faulty) {
- sz += sprintf(page + sz, "(F)");
- continue;
- }
- size += rdev->size;
- }
-
- if (mddev->nb_dev) {
- if (mddev->pers)
- sz += sprintf(page + sz, "\n %d blocks",
- md_size[mdidx(mddev)]);
- else
- sz += sprintf(page + sz, "\n %d blocks", size);
- }
-
- if (!mddev->pers) {


- sz += sprintf(page+sz, "\n");

- continue;
- }
-
- sz += mddev->pers->status (page+sz, mddev);


-
- sz += sprintf(page+sz, "\n ");

- if (mddev->curr_resync) {
- sz += status_resync (page+sz, mddev);
- } else {
- if (md_atomic_read(&mddev->resync_sem.count) != 1)
- sz += sprintf(page + sz, " resync=DELAYED");
- }
- sz += sprintf(page + sz, "\n");
- }
- sz += status_unused (page + sz);
-


- return sz;
-}
-

-int register_md_personality (int pnum, mdk_personality_t *p)


-{
- if (pnum >= MAX_PERSONALITY)

- return -EINVAL;
-
- if (pers[pnum])
- return -EBUSY;
-
- pers[pnum] = p;
- printk(KERN_INFO "%s personality registered\n", p->name);


- return 0;
-}
-

-int unregister_md_personality (int pnum)


-{
- if (pnum >= MAX_PERSONALITY)

- return -EINVAL;
-
- printk(KERN_INFO "%s personality unregistered\n", pers[pnum]->name);
- pers[pnum] = NULL;


- return 0;
-}
-

-static mdp_disk_t *get_spare(mddev_t *mddev)
-{


- mdp_super_t *sb = mddev->sb;

- mdp_disk_t *disk;


- mdk_rdev_t *rdev;
- struct md_list_head *tmp;
-

- ITERATE_RDEV(mddev,rdev,tmp) {
- if (rdev->faulty)
- continue;

- if (!rdev->sb) {
- MD_BUG();

- continue;
- }
- disk = &sb->disks[rdev->desc_nr];
- if (disk_faulty(disk)) {


- MD_BUG();
- continue;
- }

- if (disk_active(disk))
- continue;
- return disk;


- }
- return NULL;
-}
-

-static unsigned int sync_io[DK_MAX_MAJOR][DK_MAX_DISK];
-void md_sync_acct(kdev_t dev, unsigned long nr_sectors)
-{
- unsigned int major = MAJOR(dev);
- unsigned int index;
-
- index = disk_index(dev);
- if ((index >= DK_MAX_DISK) || (major >= DK_MAX_MAJOR))
- return;
-
- sync_io[major][index] += nr_sectors;
-}
-
-static int is_mddev_idle (mddev_t *mddev)
-{


- mdk_rdev_t * rdev;
- struct md_list_head *tmp;

- int idle;
- unsigned long curr_events;
-
- idle = 1;
- ITERATE_RDEV(mddev,rdev,tmp) {
- int major = MAJOR(rdev->dev);
- int idx = disk_index(rdev->dev);
-
- if ((idx >= DK_MAX_DISK) || (major >= DK_MAX_MAJOR))
- continue;
-
- curr_events = kstat.dk_drive_rblk[major][idx] +
- kstat.dk_drive_wblk[major][idx] ;
- curr_events -= sync_io[major][idx];
-// printk("events(major: %d, idx: %d): %ld\n", major, idx, curr_events);
- if (curr_events != rdev->last_events) {
-// printk("!I(%ld)", curr_events - rdev->last_events);
- rdev->last_events = curr_events;
- idle = 0;
- }
- }
- return idle;
-}
-
-MD_DECLARE_WAIT_QUEUE_HEAD(resync_wait);
-
-void md_done_sync(mddev_t *mddev, int blocks, int ok)
-{
- /* another "blocks" (1K) blocks have been synced */
- atomic_sub(blocks, &mddev->recovery_active);
- wake_up(&mddev->recovery_wait);
- if (!ok) {
- // stop recovery, signal do_sync ....
- }
-}
-
-#define SYNC_MARKS 10
-#define SYNC_MARK_STEP (3*HZ)
-int md_do_sync(mddev_t *mddev, mdp_disk_t *spare)
-{
- mddev_t *mddev2;
- unsigned int max_blocks, currspeed,
- j, window, err, serialize;
- kdev_t read_disk = mddev_to_kdev(mddev);
- unsigned long mark[SYNC_MARKS];
- unsigned long mark_cnt[SYNC_MARKS];
- int last_mark,m;
- struct md_list_head *tmp;
- unsigned long last_check;
-
-
- err = down_interruptible(&mddev->resync_sem);
- if (err)
- goto out_nolock;
-
-recheck:
- serialize = 0;
- ITERATE_MDDEV(mddev2,tmp) {
- if (mddev2 == mddev)
- continue;
- if (mddev2->curr_resync && match_mddev_units(mddev,mddev2)) {
- printk(KERN_INFO "md: serializing resync, md%d has overlapping physical units with md%d!\n", mdidx(mddev), mdidx(mddev2));
- serialize = 1;
- break;
- }
- }
- if (serialize) {
- interruptible_sleep_on(&resync_wait);
- if (md_signal_pending(current)) {
- md_flush_signals();
- err = -EINTR;
- goto out;
- }
- goto recheck;
- }
-
- mddev->curr_resync = 1;
-
- max_blocks = mddev->sb->size;
-
- printk(KERN_INFO "md: syncing RAID array md%d\n", mdidx(mddev));
- printk(KERN_INFO "md: minimum _guaranteed_ reconstruction speed: %d KB/sec/disc.\n",
- sysctl_speed_limit_min);
- printk(KERN_INFO "md: using maximum available idle IO bandwith (but not more than %d KB/sec) for reconstruction.\n", sysctl_speed_limit_max);
-
- /*
- * Resync has low priority.
- */
- current->nice = 19;
-
- is_mddev_idle(mddev); /* this also initializes IO event counters */
- for (m = 0; m < SYNC_MARKS; m++) {
- mark[m] = jiffies;
- mark_cnt[m] = 0;
- }
- last_mark = 0;
- mddev->resync_mark = mark[last_mark];
- mddev->resync_mark_cnt = mark_cnt[last_mark];
-
- /*
- * Tune reconstruction:
- */
- window = MAX_READAHEAD*(PAGE_SIZE/1024);
- printk(KERN_INFO "md: using %dk window, over a total of %d blocks.\n",window,max_blocks);
-
- atomic_set(&mddev->recovery_active, 0);
- init_waitqueue_head(&mddev->recovery_wait);
- last_check = 0;
- for (j = 0; j < max_blocks;) {
- int blocks;
-
- blocks = mddev->pers->sync_request(mddev, j);
-
- if (blocks < 0) {
- err = blocks;
- goto out;
- }
- atomic_add(blocks, &mddev->recovery_active);
- j += blocks;
- mddev->curr_resync = j;
-
- if (last_check + window > j)
- continue;
-
- run_task_queue(&tq_disk); //??
-
- if (jiffies >= mark[last_mark] + SYNC_MARK_STEP ) {
- /* step marks */
- int next = (last_mark+1) % SYNC_MARKS;
-
- mddev->resync_mark = mark[next];
- mddev->resync_mark_cnt = mark_cnt[next];
- mark[next] = jiffies;
- mark_cnt[next] = j - atomic_read(&mddev->recovery_active);
- last_mark = next;
- }
-
-
- if (md_signal_pending(current)) {
- /*
- * got a signal, exit.
- */
- mddev->curr_resync = 0;
- printk("md_do_sync() got signal ... exiting\n");
- md_flush_signals();
- err = -EINTR;
- goto out;
- }
-
- /*
- * this loop exits only if either when we are slower than
- * the 'hard' speed limit, or the system was IO-idle for
- * a jiffy.
- * the system might be non-idle CPU-wise, but we only care
- * about not overloading the IO subsystem. (things like an
- * e2fsck being done on the RAID array should execute fast)
- */
-repeat:
- if (md_need_resched(current))
- schedule();
-
- currspeed = (j-mddev->resync_mark_cnt)/((jiffies-mddev->resync_mark)/HZ +1) +1;
-
- if (currspeed > sysctl_speed_limit_min) {
- current->nice = 19;
-
- if ((currspeed > sysctl_speed_limit_max) ||
- !is_mddev_idle(mddev)) {
- current->state = TASK_INTERRUPTIBLE;
- md_schedule_timeout(HZ/4);
- if (!md_signal_pending(current))
- goto repeat;
- }
- } else
- current->nice = -20;
- }
- fsync_dev(read_disk);
- printk(KERN_INFO "md: md%d: sync done.\n",mdidx(mddev));
- err = 0;
- /*
- * this also signals 'finished resyncing' to md_stop
- */
-out:
- wait_event(mddev->recovery_wait, atomic_read(&mddev->recovery_active)==0);
- up(&mddev->resync_sem);
-out_nolock:
- mddev->curr_resync = 0;
- wake_up(&resync_wait);


- return err;
-}
-
-

-/*
- * This is a kernel thread which syncs a spare disk with the active array
- *
- * the amount of foolproofing might seem to be a tad excessive, but an
- * early (not so error-safe) version of raid1syncd synced the first 0.5 gigs
- * of my root partition with the first 0.5 gigs of my /home partition ... so
- * i'm a bit nervous ;)
- */
-void md_do_recovery (void *data)
-{
- int err;
- mddev_t *mddev;
- mdp_super_t *sb;
- mdp_disk_t *spare;


- struct md_list_head *tmp;
-

- printk(KERN_INFO "md: recovery thread got woken up ...\n");
-restart:
- ITERATE_MDDEV(mddev,tmp) {


- sb = mddev->sb;

- if (!sb)
- continue;
- if (mddev->recovery_running)
- continue;
- if (sb->active_disks == sb->raid_disks)
- continue;
- if (!sb->spare_disks) {
- printk(KERN_ERR "md%d: no spare disk to reconstruct array! -- continuing in degraded mode\n", mdidx(mddev));


- continue;
- }
- /*

- * now here we get the spare and resync it.
- */
- if ((spare = get_spare(mddev)) == NULL)
- continue;
- printk(KERN_INFO "md%d: resyncing spare disk %s to replace failed disk\n", mdidx(mddev), partition_name(MKDEV(spare->major,spare->minor)));


- if (!mddev->pers->diskop)

- continue;
- if (mddev->pers->diskop(mddev, &spare, DISKOP_SPARE_WRITE))
- continue;
- down(&mddev->recovery_sem);
- mddev->recovery_running = 1;
- err = md_do_sync(mddev, spare);
- if (err == -EIO) {
- printk(KERN_INFO "md%d: spare disk %s failed, skipping to next spare.\n", mdidx(mddev), partition_name(MKDEV(spare->major,spare->minor)));
- if (!disk_faulty(spare)) {
- mddev->pers->diskop(mddev,&spare,DISKOP_SPARE_INACTIVE);
- mark_disk_faulty(spare);
- mark_disk_nonsync(spare);
- mark_disk_inactive(spare);


- sb->spare_disks--;
- sb->working_disks--;

- sb->failed_disks++;
- }
- } else
- if (disk_faulty(spare))
- mddev->pers->diskop(mddev, &spare,
- DISKOP_SPARE_INACTIVE);
- if (err == -EINTR || err == -ENOMEM) {
- /*
- * Recovery got interrupted, or ran out of mem ...
- * signal back that we have finished using the array.
- */
- mddev->pers->diskop(mddev, &spare,
- DISKOP_SPARE_INACTIVE);
- up(&mddev->recovery_sem);
- mddev->recovery_running = 0;
- continue;
- } else {
- mddev->recovery_running = 0;
- up(&mddev->recovery_sem);
- }
- if (!disk_faulty(spare)) {
- /*
- * the SPARE_ACTIVE diskop possibly changes the
- * pointer too
- */
- mddev->pers->diskop(mddev, &spare, DISKOP_SPARE_ACTIVE);
- mark_disk_sync(spare);
- mark_disk_active(spare);
- sb->active_disks++;
- sb->spare_disks--;


- }
- mddev->sb_dirty = 1;

- md_update_sb(mddev);
- goto restart;
- }
- printk(KERN_INFO "md: recovery thread finished ...\n");
-
-}
-
-int md_notify_reboot(struct notifier_block *this,
- unsigned long code, void *x)


-{
- struct md_list_head *tmp;

- mddev_t *mddev;
-
- if ((code == MD_SYS_DOWN) || (code == MD_SYS_HALT)
- || (code == MD_SYS_POWER_OFF)) {
-
- printk(KERN_INFO "stopping all md devices.\n");
-
- ITERATE_MDDEV(mddev,tmp)
- do_md_stop (mddev, 1);
- /*
- * certain more exotic SCSI devices are known to be
- * volatile wrt too early system reboots. While the
- * right place to handle this issue is the given
- * driver, we do want to have a safe RAID driver ...
- */
- md_mdelay(1000*1);
- }
- return NOTIFY_DONE;
-}
-
-struct notifier_block md_notifier = {
- md_notify_reboot,
- NULL,
- 0
-};
-#ifndef MODULE
-static int md__init raid_setup(char *str)
-{
- int len, pos;
-
- len = strlen(str) + 1;
- pos = 0;
-
- while (pos < len) {
- char *comma = strchr(str+pos, ',');
- int wlen;
- if (comma)
- wlen = (comma-str)-pos;
- else wlen = (len-1)-pos;
-
- if (strncmp(str, "noautodetect", wlen) == 0)
- raid_setup_args.noautodetect = 1;
- pos += wlen+1;
- }
- raid_setup_args.set = 1;
- return 1;
-}
-__setup("raid=", raid_setup);
-#endif
-static void md_geninit (void)


-{
- int i;
-

- for(i = 0; i < MAX_MD_DEVS; i++) {
- md_blocksizes[i] = 1024;
- md_size[i] = 0;
- md_hardsect_sizes[i] = 512;
- md_maxreadahead[i] = MD_READAHEAD;
- register_disk(&md_gendisk, MKDEV(MAJOR_NR,i), 1, &md_fops, 0);
- }
- blksize_size[MAJOR_NR] = md_blocksizes;
- blk_size[MAJOR_NR] = md_size;
- max_readahead[MAJOR_NR] = md_maxreadahead;
- hardsect_size[MAJOR_NR] = md_hardsect_sizes;
-
- printk("md.c: sizeof(mdp_super_t) = %d\n", (int)sizeof(mdp_super_t));
-
-#ifdef CONFIG_PROC_FS
- create_proc_read_entry("mdstat", 0, NULL, md_status_read_proc, NULL);
-#endif
-}
-void hsm_init (void);
-void translucent_init (void);
-void linear_init (void);
-void raid0_init (void);
-void raid1_init (void);
-void raid5_init (void);
-
-int md__init md_init (void)
-{
- static char * name = "mdrecoveryd";
-
- printk (KERN_INFO "md driver %d.%d.%d MAX_MD_DEVS=%d, MAX_REAL=%d\n",
- MD_MAJOR_VERSION, MD_MINOR_VERSION,
- MD_PATCHLEVEL_VERSION, MAX_MD_DEVS, MAX_REAL);
-
- if (devfs_register_blkdev (MAJOR_NR, "md", &md_fops))
- {
- printk (KERN_ALERT "Unable to get major %d for md\n", MAJOR_NR);
- return (-1);
- }
- devfs_handle = devfs_mk_dir (NULL, "md", NULL);
- devfs_register_series (devfs_handle, "%u",MAX_MD_DEVS,DEVFS_FL_DEFAULT,
- MAJOR_NR, 0, S_IFBLK | S_IRUSR | S_IWUSR,
- &md_fops, NULL);
-
- /* forward all md request to md_make_request */
- blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR), md_make_request);
-
-
- read_ahead[MAJOR_NR] = INT_MAX;
- md_gendisk.next = gendisk_head;
-
- gendisk_head = &md_gendisk;
-
- md_recovery_thread = md_register_thread(md_do_recovery, NULL, name);
- if (!md_recovery_thread)
- printk(KERN_ALERT "bug: couldn't allocate md_recovery_thread\n");
-
- md_register_reboot_notifier(&md_notifier);
- raid_table_header = register_sysctl_table(raid_root_table, 1);
-
-#ifdef CONFIG_MD_LINEAR
- linear_init ();
-#endif
-#ifdef CONFIG_MD_RAID0
- raid0_init ();
-#endif
-#ifdef CONFIG_MD_RAID1
- raid1_init ();
-#endif
-#ifdef CONFIG_MD_RAID5
- raid5_init ();
-#endif
- md_geninit();


- return (0);
-}
-

-#ifdef CONFIG_MD_BOOT
-#define MAX_MD_BOOT_DEVS 8
-struct {
- unsigned long set;
- int pers[MAX_MD_BOOT_DEVS];
- int chunk[MAX_MD_BOOT_DEVS];
- kdev_t devices[MAX_MD_BOOT_DEVS][MAX_REAL];
-} md_setup_args md__initdata;
-
-/*
- * Parse the command-line parameters given our kernel, but do not
- * actually try to invoke the MD device now; that is handled by
- * md_setup_drive after the low-level disk drivers have initialised.
- *
- * 27/11/1999: Fixed to work correctly with the 2.3 kernel (which
- * assigns the task of parsing integer arguments to the
- * invoked program now). Added ability to initialise all
- * the MD devices (by specifying multiple "md=" lines)
- * instead of just one. -- KTK
- * 18May2000: Added support for persistant-superblock arrays:
- * md=n,0,factor,fault,device-list uses RAID0 for device n
- * md=n,-1,factor,fault,device-list uses LINEAR for device n
- * md=n,device-list reads a RAID superblock from the devices
- * elements in device-list are read by name_to_kdev_t so can be
- * a hex number or something like /dev/hda1 /dev/sdb
- */
-extern kdev_t name_to_kdev_t(char *line) md__init;
-static int md__init md_setup(char *str)
-{
- int minor, level, factor, fault, i=0;
- kdev_t device;
- char *devnames, *pername = "";
-
- if(get_option(&str, &minor) != 2) { /* MD Number */
- printk("md: Too few arguments supplied to md=.\n");
- return 0;
- }
- if (minor >= MAX_MD_BOOT_DEVS) {
- printk ("md: Minor device number too high.\n");
- return 0;
- } else if (md_setup_args.set & (1 << minor)) {
- printk ("md: Warning - md=%d,... has been specified twice;\n"
- " will discard the first definition.\n", minor);
- }
- switch(get_option(&str, &level)) { /* RAID Personality */
- case 2: /* could be 0 or -1.. */
- if (level == 0 || level == -1) {
- if (get_option(&str, &factor) != 2 || /* Chunk Size */
- get_option(&str, &fault) != 2) {
- printk("md: Too few arguments supplied to md=.\n");
- return 0;
- }
- md_setup_args.pers[minor] = level;
- md_setup_args.chunk[minor] = 1 << (factor+12);
- switch(level) {
- case -1:
- level = LINEAR;
- pername = "linear";


- break;
- case 0:

- level = RAID0;
- pername = "raid0";
- break;
- default:
- printk ("md: The kernel has not been configured for raid%d"
- " support!\n", level);
- return 0;
- }
- md_setup_args.pers[minor] = level;
- break;
- }
- /* FALL THROUGH */
- case 1: /* the first device is numeric */
- md_setup_args.devices[minor][i++] = level;
- /* FALL THROUGH */
- case 0:
- md_setup_args.pers[minor] = 0;
- pername="super-block";
- }
- devnames = str;
- for (; i<MAX_REAL && str; i++) {
- if ((device = name_to_kdev_t(str))) {
- md_setup_args.devices[minor][i] = device;
- } else {
- printk ("md: Unknown device name, %s.\n", str);
- return 0;
- }
- if ((str = strchr(str, ',')) != NULL)
- str++;
- }
- if (!i) {
- printk ("md: No devices specified for md%d?\n", minor);


- return 0;
- }
-

- printk ("md: Will configure md%d (%s) from %s, below.\n",
- minor, pername, devnames);
- md_setup_args.devices[minor][i] = (kdev_t) 0;
- md_setup_args.set |= (1 << minor);


- return 1;
-}
-

-void md__init md_setup_drive(void)
-{
- int minor, i;
- kdev_t dev;
- mddev_t*mddev;
-
- for (minor = 0; minor < MAX_MD_BOOT_DEVS; minor++) {
- mdu_disk_info_t dinfo;
- int err=0;
- if (!(md_setup_args.set & (1 << minor)))
- continue;
- printk("md: Loading md%d.\n", minor);
- mddev = alloc_mddev(MKDEV(MD_MAJOR,minor));
- if (md_setup_args.pers[minor]) {
- /* non-persistent */
- mdu_array_info_t ainfo;
- ainfo.level = pers_to_level(md_setup_args.pers[minor]);
- ainfo.size = 0;
- ainfo.nr_disks =0;
- ainfo.raid_disks =0;
- ainfo.md_minor =minor;
- ainfo.not_persistent = 1;
-
- ainfo.state = MD_SB_CLEAN;
- ainfo.active_disks = 0;
- ainfo.working_disks = 0;
- ainfo.failed_disks = 0;
- ainfo.spare_disks = 0;
- ainfo.layout = 0;
- ainfo.chunk_size = md_setup_args.chunk[minor];
- err = set_array_info(mddev, &ainfo);
- for (i=0; !err && (dev = md_setup_args.devices[minor][i]); i++) {
- dinfo.number = i;
- dinfo.raid_disk = i;
- dinfo.state = (1<<MD_DISK_ACTIVE)|(1<<MD_DISK_SYNC);
- dinfo.major = MAJOR(dev);
- dinfo.minor = MINOR(dev);
- mddev->sb->nr_disks++;
- mddev->sb->raid_disks++;
- mddev->sb->active_disks++;
- mddev->sb->working_disks++;
- err = add_new_disk (mddev, &dinfo);
- }
- } else {
- /* persistent */
- for (i = 0; (dev = md_setup_args.devices[minor][i]); i++) {
- dinfo.major = MAJOR(dev);
- dinfo.minor = MINOR(dev);
- add_new_disk (mddev, &dinfo);
- }
- }
- if (!err)
- err = do_md_run(mddev);


- if (err) {
- mddev->sb_dirty = 0;

- do_md_stop(mddev, 0);
- printk("md: starting md%d failed\n", minor);
- }
- }
-}
-
-__setup("md=", md_setup);
-#endif
-
-#ifdef MODULE
-int init_module (void)
-{
- return md_init();
-}
-
-static void free_device_names(void)
-{
- while (device_names.next != &device_names) {
- struct list_head *tmp = device_names.next;
- list_del(tmp);
- kfree(tmp);
- }
-}


-
-
-void cleanup_module (void)
-{

- struct gendisk **gendisk_ptr;
-
- md_unregister_thread(md_recovery_thread);
- devfs_unregister(devfs_handle);
-
- devfs_unregister_blkdev(MAJOR_NR,"md");
- unregister_reboot_notifier(&md_notifier);
- unregister_sysctl_table(raid_table_header);
-#ifdef CONFIG_PROC_FS
- remove_proc_entry("mdstat", NULL);
-#endif
-
- gendisk_ptr = &gendisk_head;
- while (*gendisk_ptr) {
- if (*gendisk_ptr == &md_gendisk) {
- *gendisk_ptr = md_gendisk.next;
- break;
- }
- gendisk_ptr = & (*gendisk_ptr)->next;
- }
- blk_dev[MAJOR_NR].queue = NULL;


- blksize_size[MAJOR_NR] = NULL;
- blk_size[MAJOR_NR] = NULL;

- max_readahead[MAJOR_NR] = NULL;
- hardsect_size[MAJOR_NR] = NULL;
-
- free_device_names();
-
-}
-#endif
-
-MD_EXPORT_SYMBOL(md_size);
-MD_EXPORT_SYMBOL(register_md_personality);
-MD_EXPORT_SYMBOL(unregister_md_personality);
-MD_EXPORT_SYMBOL(partition_name);
-MD_EXPORT_SYMBOL(md_error);
-MD_EXPORT_SYMBOL(md_do_sync);
-MD_EXPORT_SYMBOL(md_sync_acct);
-MD_EXPORT_SYMBOL(md_done_sync);
-MD_EXPORT_SYMBOL(md_recover_arrays);
-MD_EXPORT_SYMBOL(md_register_thread);
-MD_EXPORT_SYMBOL(md_unregister_thread);
-MD_EXPORT_SYMBOL(md_update_sb);
-MD_EXPORT_SYMBOL(md_wakeup_thread);
-MD_EXPORT_SYMBOL(md_print_devices);
-MD_EXPORT_SYMBOL(find_rdev_nr);
-MD_EXPORT_SYMBOL(md_interrupt_thread);
-MD_EXPORT_SYMBOL(mddev_map);
-MD_EXPORT_SYMBOL(md_check_ordering);
-
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/block/paride/paride.h linux/drivers/block/paride/paride.h
--- v2.4.0-test8/linux/drivers/block/paride/paride.h Wed May 12 13:27:37 1999
+++ linux/drivers/block/paride/paride.h Fri Sep 22 14:21:16 2000
@@ -1,3 +1,6 @@
+#ifndef __DRIVERS_PARIDE_H__
+#define __DRIVERS_PARIDE_H__
+
X /*
X paride.h (c) 1997-8 Grant R. Guenther <gr...@torque.net>
X Under the terms of the GPL.
@@ -161,4 +164,5 @@
X extern int pi_register( PIP * );
X extern void pi_unregister ( PIP * );
X
+#endif /* __DRIVERS_PARIDE_H__ */
X /* end of paride.h */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/block/raid0.c linux/drivers/block/raid0.c
--- v2.4.0-test8/linux/drivers/block/raid0.c Thu Aug 10 12:35:50 2000
+++ linux/drivers/block/raid0.c Wed Dec 31 16:00:00 1969
@@ -1,356 +0,0 @@
-/*
- raid0.c : Multiple Devices driver for Linux


- Copyright (C) 1994-96 Marc ZYNGIER
- <zyn...@ufr-info-p7.ibp.fr> or
- <m...@gloups.fdn.fr>

- Copyright (C) 1999, 2000 Ingo Molnar, Red Hat
-
-
- RAID-0 management functions.


-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- You should have received a copy of the GNU General Public License
- (for example /usr/src/linux/COPYING); if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <linux/module.h>

-#include <linux/raid/raid0.h>


-
-#define MAJOR_NR MD_MAJOR
-#define MD_DRIVER

-#define MD_PERSONALITY
-
-static int create_strip_zones (mddev_t *mddev)
-{
- int i, c, j, j1, j2;
- unsigned long current_offset, curr_zone_offset;
- raid0_conf_t *conf = mddev_to_conf(mddev);
- mdk_rdev_t *smallest, *rdev1, *rdev2, *rdev;
-
- /*
- * The number of 'same size groups'
- */
- conf->nr_strip_zones = 0;
-
- ITERATE_RDEV_ORDERED(mddev,rdev1,j1) {
- printk("raid0: looking at %s\n", partition_name(rdev1->dev));
- c = 0;
- ITERATE_RDEV_ORDERED(mddev,rdev2,j2) {
- printk("raid0: comparing %s(%ld) with %s(%ld)\n", partition_name(rdev1->dev), rdev1->size, partition_name(rdev2->dev), rdev2->size);
- if (rdev2 == rdev1) {
- printk("raid0: END\n");
- break;
- }
- if (rdev2->size == rdev1->size)
- {
- /*
- * Not unique, dont count it as a new
- * group
- */
- printk("raid0: EQUAL\n");
- c = 1;
- break;
- }
- printk("raid0: NOT EQUAL\n");
- }
- if (!c) {
- printk("raid0: ==> UNIQUE\n");
- conf->nr_strip_zones++;
- printk("raid0: %d zones\n", conf->nr_strip_zones);
- }
- }
- printk("raid0: FINAL %d zones\n", conf->nr_strip_zones);
-
- conf->strip_zone = vmalloc(sizeof(struct strip_zone)*
- conf->nr_strip_zones);
- if (!conf->strip_zone)


- return 1;
-
-

- conf->smallest = NULL;

- current_offset = 0;
- curr_zone_offset = 0;
-
- for (i = 0; i < conf->nr_strip_zones; i++)
- {
- struct strip_zone *zone = conf->strip_zone + i;
-
- printk("zone %d\n", i);
- zone->dev_offset = current_offset;
- smallest = NULL;


- c = 0;
-

- ITERATE_RDEV_ORDERED(mddev,rdev,j) {
-
- printk(" checking %s ...", partition_name(rdev->dev));
- if (rdev->size > current_offset)
- {
- printk(" contained as device %d\n", c);
- zone->dev[c] = rdev;
- c++;
- if (!smallest || (rdev->size <smallest->size)) {
- smallest = rdev;
- printk(" (%ld) is smallest!.\n", rdev->size);
- }
- } else
- printk(" nope.\n");
- }
-
- zone->nb_dev = c;
- zone->size = (smallest->size - current_offset) * c;
- printk(" zone->nb_dev: %d, size: %ld\n",zone->nb_dev,zone->size);
-
- if (!conf->smallest || (zone->size < conf->smallest->size))
- conf->smallest = zone;
-
- zone->zone_offset = curr_zone_offset;
- curr_zone_offset += zone->size;
-
- current_offset = smallest->size;
- printk("current zone offset: %ld\n", current_offset);
- }
- printk("done.\n");


- return 0;
-}
-

-static int raid0_run (mddev_t *mddev)
-{
- unsigned long cur=0, i=0, size, zone0_size, nb_zone;
- raid0_conf_t *conf;
-
- MOD_INC_USE_COUNT;
-
- conf = vmalloc(sizeof (raid0_conf_t));


- if (!conf)
- goto out;

- mddev->private = (void *)conf;
-
- if (md_check_ordering(mddev)) {
- printk("raid0: disks are not ordered, aborting!\n");
- goto out_free_conf;
- }
-
- if (create_strip_zones (mddev))
- goto out_free_conf;
-
- printk("raid0 : md_size is %d blocks.\n", md_size[mdidx(mddev)]);
- printk("raid0 : conf->smallest->size is %ld blocks.\n", conf->smallest->size);
- nb_zone = md_size[mdidx(mddev)]/conf->smallest->size +
- (md_size[mdidx(mddev)] % conf->smallest->size ? 1 : 0);
- printk("raid0 : nb_zone is %ld.\n", nb_zone);
- conf->nr_zones = nb_zone;
-
- printk("raid0 : Allocating %ld bytes for hash.\n",
- nb_zone*sizeof(struct raid0_hash));
-
- conf->hash_table = vmalloc (sizeof (struct raid0_hash)*nb_zone);
- if (!conf->hash_table)
- goto out_free_zone_conf;
- size = conf->strip_zone[cur].size;
-
- i = 0;
- while (cur < conf->nr_strip_zones) {
- conf->hash_table[i].zone0 = conf->strip_zone + cur;
-
- /*
- * If we completely fill the slot
- */
- if (size >= conf->smallest->size) {
- conf->hash_table[i++].zone1 = NULL;


- size -= conf->smallest->size;
-

- if (!size) {
- if (++cur == conf->nr_strip_zones)
- continue;
- size = conf->strip_zone[cur].size;
- }
- continue;
- }
- if (++cur == conf->nr_strip_zones) {
- /*
- * Last dev, set unit1 as NULL
- */
- conf->hash_table[i].zone1=NULL;
- continue;
- }
-
- /*
- * Here we use a 2nd dev to fill the slot
- */
- zone0_size = size;
- size = conf->strip_zone[cur].size;
- conf->hash_table[i++].zone1 = conf->strip_zone + cur;
- size -= (conf->smallest->size - zone0_size);


- }
- return 0;
-

-out_free_zone_conf:
- vfree(conf->strip_zone);
- conf->strip_zone = NULL;
-
-out_free_conf:
- vfree(conf);
- mddev->private = NULL;
-out:
- MOD_DEC_USE_COUNT;


- return 1;
-}
-

-static int raid0_stop (mddev_t *mddev)
-{
- raid0_conf_t *conf = mddev_to_conf(mddev);
-
- vfree (conf->hash_table);
- conf->hash_table = NULL;
- vfree (conf->strip_zone);
- conf->strip_zone = NULL;
- vfree (conf);
- mddev->private = NULL;
-
- MOD_DEC_USE_COUNT;


- return 0;
-}
-
-/*

- * FIXME - We assume some things here :
- * - requested buffers NEVER bigger than chunk size,
- * - requested buffers NEVER cross stripes limits.
- * Of course, those facts may not be valid anymore (and surely won't...)
- * Hey guys, there's some work out there ;-)
- */
-static int raid0_make_request (mddev_t *mddev,
- int rw, struct buffer_head * bh)
-{
- unsigned int sect_in_chunk, chunksize_bits, chunk_size;
- raid0_conf_t *conf = mddev_to_conf(mddev);
- struct raid0_hash *hash;
- struct strip_zone *zone;
- mdk_rdev_t *tmp_dev;
- unsigned long chunk, block, rsect;
-
- chunk_size = mddev->param.chunk_size >> 10;
- chunksize_bits = ffz(~chunk_size);


- block = bh->b_rsector >> 1;

- hash = conf->hash_table + block / conf->smallest->size;
-
- /* Sanity check */
- if (chunk_size < (block % chunk_size) + (bh->b_size >> 10))
- goto bad_map;
-
- if (!hash)
- goto bad_hash;
-
- if (!hash->zone0)
- goto bad_zone0;
-
- if (block >= (hash->zone0->size + hash->zone0->zone_offset)) {
- if (!hash->zone1)
- goto bad_zone1;
- zone = hash->zone1;
- } else
- zone = hash->zone0;
-
- sect_in_chunk = bh->b_rsector & ((chunk_size<<1) -1);
- chunk = (block - zone->zone_offset) / (zone->nb_dev << chunksize_bits);
- tmp_dev = zone->dev[(block >> chunksize_bits) % zone->nb_dev];
- rsect = (((chunk << chunksize_bits) + zone->dev_offset)<<1)
- + sect_in_chunk;
-
- /*
- * The new BH_Lock semantics in ll_rw_blk.c guarantee that this
- * is the only IO operation happening on this bh.
- */


- bh->b_rdev = tmp_dev->dev;

- bh->b_rsector = rsect;
-
- /*
- * Let the main block layer submit the IO and resolve recursion:
- */
- return 1;
-
-bad_map:
- printk ("raid0_make_request bug: can't convert block across chunks or bigger than %dk %ld %d\n", chunk_size, bh->b_rsector, bh->b_size >> 10);
- return -1;
-bad_hash:
- printk("raid0_make_request bug: hash==NULL for block %ld\n", block);
- return -1;
-bad_zone0:
- printk ("raid0_make_request bug: hash->zone0==NULL for block %ld\n", block);
- return -1;
-bad_zone1:
- printk ("raid0_make_request bug: hash->zone1==NULL for block %ld\n", block);


- return -1;
-}
-

-static int raid0_status (char *page, mddev_t *mddev)


-{
- int sz = 0;

-#undef MD_DEBUG
-#ifdef MD_DEBUG
- int j, k;
- raid0_conf_t *conf = mddev_to_conf(mddev);


-
- sz += sprintf(page + sz, " ");

- for (j = 0; j < conf->nr_zones; j++) {
- sz += sprintf(page + sz, "[z%d",
- conf->hash_table[j].zone0 - conf->strip_zone);
- if (conf->hash_table[j].zone1)
- sz += sprintf(page+sz, "/z%d] ",
- conf->hash_table[j].zone1 - conf->strip_zone);
- else
- sz += sprintf(page+sz, "] ");
- }
-
- sz += sprintf(page + sz, "\n");
-
- for (j = 0; j < conf->nr_strip_zones; j++) {
- sz += sprintf(page + sz, " z%d=[", j);
- for (k = 0; k < conf->strip_zone[j].nb_dev; k++)
- sz += sprintf (page+sz, "%s/", partition_name(
- conf->strip_zone[j].dev[k]->dev));
- sz--;
- sz += sprintf (page+sz, "] zo=%d do=%d s=%d\n",
- conf->strip_zone[j].zone_offset,
- conf->strip_zone[j].dev_offset,
- conf->strip_zone[j].size);
- }
-#endif
- sz += sprintf(page + sz, " %dk chunks", mddev->param.chunk_size/1024);


- return sz;
-}
-

-static mdk_personality_t raid0_personality=
-{
- name: "raid0",
- make_request: raid0_make_request,
- run: raid0_run,
- stop: raid0_stop,
- status: raid0_status,


-};
-
-#ifndef MODULE
-

-void raid0_init (void)
-{
- register_md_personality (RAID0, &raid0_personality);


-}
-
-#else
-
-int init_module (void)
-{

- return (register_md_personality (RAID0, &raid0_personality));


-}
-
-void cleanup_module (void)
-{

- unregister_md_personality (RAID0);
-}
-
-#endif
-
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/block/raid1.c linux/drivers/block/raid1.c
--- v2.4.0-test8/linux/drivers/block/raid1.c Mon Aug 14 08:26:34 2000
+++ linux/drivers/block/raid1.c Wed Dec 31 16:00:00 1969
@@ -1,1897 +0,0 @@
-/*
- * raid1.c : Multiple Devices driver for Linux
- *
- * Copyright (C) 1999, 2000 Ingo Molnar, Red Hat
- *
- * Copyright (C) 1996, 1997, 1998 Ingo Molnar, Miguel de Icaza, Gadi Oxman
- *
- * RAID-1 management functions.
- *
- * Better read-balancing code written by Mika Kuoppala <mi...@iki.fi>, 2000
- *
- * Fixes to reconstruction by Jakob Řstergaard" <ja...@ostenfeld.dk>
- * Various fixes by Neil Brown <ne...@cse.unsw.edu.au>
- *
- * This program is free software; you can redistribute it and/or modify


- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *

- * You should have received a copy of the GNU General Public License
- * (for example /usr/src/linux/COPYING); if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.


- */
-
-#include <linux/module.h>

-#include <linux/malloc.h>
-#include <linux/raid/raid1.h>
-#include <asm/atomic.h>


-
-#define MAJOR_NR MD_MAJOR
-#define MD_DRIVER

-#define MD_PERSONALITY
-
-#define MAX_WORK_PER_DISK 128
-
-/*
- * The following can be used to debug the driver
- */
-#define RAID1_DEBUG 0
-
-#if RAID1_DEBUG
-#define PRINTK(x...) printk(x)
-#define inline
-#define __inline__
-#else
-#define PRINTK(x...) do { } while (0)
-#endif
-
-
-static mdk_personality_t raid1_personality;
-static md_spinlock_t retry_list_lock = MD_SPIN_LOCK_UNLOCKED;
-struct raid1_bh *raid1_retry_list = NULL, **raid1_retry_tail;
-
-static struct buffer_head *raid1_alloc_bh(raid1_conf_t *conf, int cnt)
-{
- /* return a linked list of "cnt" struct buffer_heads.
- * don't take any off the free list unless we know we can
- * get all we need, otherwise we could deadlock
- */
- struct buffer_head *bh=NULL;
-
- while(cnt) {
- struct buffer_head *t;
- md_spin_lock_irq(&conf->device_lock);
- if (conf->freebh_cnt >= cnt)
- while (cnt) {
- t = conf->freebh;
- conf->freebh = t->b_next;
- t->b_next = bh;
- bh = t;
- t->b_state = 0;
- conf->freebh_cnt--;
- cnt--;
- }
- md_spin_unlock_irq(&conf->device_lock);
- if (cnt == 0)
- break;
- t = (struct buffer_head *)kmalloc(sizeof(struct buffer_head), GFP_BUFFER);
- if (t) {
- memset(t, 0, sizeof(*t));
- t->b_next = bh;
- bh = t;
- cnt--;
- } else {
- PRINTK("waiting for %d bh\n", cnt);
- wait_event(conf->wait_buffer, conf->freebh_cnt >= cnt);
- }
- }
- return bh;
-}
-
-static inline void raid1_free_bh(raid1_conf_t *conf, struct buffer_head *bh)
-{
- md_spin_lock_irq(&conf->device_lock);
- while (bh) {
- struct buffer_head *t = bh;
- bh=bh->b_next;
- if (t->b_pprev == NULL)
- kfree(t);
- else {
- t->b_next= conf->freebh;
- conf->freebh = t;
- conf->freebh_cnt++;
- }
- }
- md_spin_unlock_irq(&conf->device_lock);
- wake_up(&conf->wait_buffer);
-}
-
-static int raid1_grow_bh(raid1_conf_t *conf, int cnt)
-{
- /* allocate cnt buffer_heads, possibly less if kalloc fails */


- int i = 0;
-

- while (i < cnt) {
- struct buffer_head *bh;
- bh = kmalloc(sizeof(*bh), GFP_KERNEL);
- if (!bh) break;
- memset(bh, 0, sizeof(*bh));
-
- md_spin_lock_irq(&conf->device_lock);
- bh->b_pprev = &conf->freebh;
- bh->b_next = conf->freebh;
- conf->freebh = bh;
- conf->freebh_cnt++;
- md_spin_unlock_irq(&conf->device_lock);
-
- i++;
- }
- return i;
-}
-
-static int raid1_shrink_bh(raid1_conf_t *conf, int cnt)
-{
- /* discard cnt buffer_heads, if we can find them */


- int i = 0;
-

- md_spin_lock_irq(&conf->device_lock);
- while ((i < cnt) && conf->freebh) {
- struct buffer_head *bh = conf->freebh;
- conf->freebh = bh->b_next;
- kfree(bh);
- i++;
- conf->freebh_cnt--;
- }
- md_spin_unlock_irq(&conf->device_lock);
- return i;
-}
-
-
-static struct raid1_bh *raid1_alloc_r1bh(raid1_conf_t *conf)
-{
- struct raid1_bh *r1_bh = NULL;
-
- do {
- md_spin_lock_irq(&conf->device_lock);
- if (conf->freer1) {
- r1_bh = conf->freer1;
- conf->freer1 = r1_bh->next_r1;
- r1_bh->next_r1 = NULL;
- r1_bh->state = 0;
- r1_bh->bh_req.b_state = 0;
- }
- md_spin_unlock_irq(&conf->device_lock);
- if (r1_bh)
- return r1_bh;
- r1_bh = (struct raid1_bh *) kmalloc(sizeof(struct raid1_bh),
- GFP_BUFFER);
- if (r1_bh) {
- memset(r1_bh, 0, sizeof(*r1_bh));
- return r1_bh;
- }
- wait_event(conf->wait_buffer, conf->freer1);
- } while (1);
-}
-
-static inline void raid1_free_r1bh(struct raid1_bh *r1_bh)
-{
- struct buffer_head *bh = r1_bh->mirror_bh_list;
- raid1_conf_t *conf = mddev_to_conf(r1_bh->mddev);
-
- r1_bh->mirror_bh_list = NULL;
-
- if (test_bit(R1BH_PreAlloc, &r1_bh->state)) {
- md_spin_lock_irq(&conf->device_lock);
- r1_bh->next_r1 = conf->freer1;
- conf->freer1 = r1_bh;
- md_spin_unlock_irq(&conf->device_lock);
- } else {
- kfree(r1_bh);
- }
- raid1_free_bh(conf, bh);
-}
-
-static int raid1_grow_r1bh (raid1_conf_t *conf, int cnt)


-{
- int i = 0;
-

- while (i < cnt) {
- struct raid1_bh *r1_bh;
- r1_bh = (struct raid1_bh*)kmalloc(sizeof(*r1_bh), GFP_KERNEL);
- if (!r1_bh)
- break;
- memset(r1_bh, 0, sizeof(*r1_bh));
-
- md_spin_lock_irq(&conf->device_lock);
- set_bit(R1BH_PreAlloc, &r1_bh->state);
- r1_bh->next_r1 = conf->freer1;
- conf->freer1 = r1_bh;
- md_spin_unlock_irq(&conf->device_lock);
-
- i++;
- }
- return i;
-}
-
-static void raid1_shrink_r1bh(raid1_conf_t *conf)
-{
- md_spin_lock_irq(&conf->device_lock);
- while (conf->freer1) {
- struct raid1_bh *r1_bh = conf->freer1;
- conf->freer1 = r1_bh->next_r1;
- kfree(r1_bh);
- }
- md_spin_unlock_irq(&conf->device_lock);
-}
-
-
-
-static inline void raid1_free_buf(struct raid1_bh *r1_bh)
-{
- struct buffer_head *bh = r1_bh->mirror_bh_list;
- raid1_conf_t *conf = mddev_to_conf(r1_bh->mddev);
- r1_bh->mirror_bh_list = NULL;
-
- md_spin_lock_irq(&conf->device_lock);
- r1_bh->next_r1 = conf->freebuf;
- conf->freebuf = r1_bh;
- md_spin_unlock_irq(&conf->device_lock);
- raid1_free_bh(conf, bh);
-}
-
-static struct raid1_bh *raid1_alloc_buf(raid1_conf_t *conf)
-{
- struct raid1_bh *r1_bh;
-
- md_spin_lock_irq(&conf->device_lock);
- wait_event_lock_irq(conf->wait_buffer, conf->freebuf, conf->device_lock);
- r1_bh = conf->freebuf;
- conf->freebuf = r1_bh->next_r1;
- r1_bh->next_r1= NULL;
- md_spin_unlock_irq(&conf->device_lock);
-
- return r1_bh;
-}
-
-static int raid1_grow_buffers (raid1_conf_t *conf, int cnt)


-{
- int i = 0;
-

- md_spin_lock_irq(&conf->device_lock);
- while (i < cnt) {
- struct raid1_bh *r1_bh;
- struct page *page;
-


- page = alloc_page(GFP_KERNEL);
- if (!page)

- break;
-
- r1_bh = (struct raid1_bh *) kmalloc(sizeof(*r1_bh), GFP_KERNEL);
- if (!r1_bh) {
- __free_page(page);
- break;
- }
- memset(r1_bh, 0, sizeof(*r1_bh));
- r1_bh->bh_req.b_page = page;
- r1_bh->bh_req.b_data = page_address(page);
- r1_bh->next_r1 = conf->freebuf;
- conf->freebuf = r1_bh;
- i++;
- }
- md_spin_unlock_irq(&conf->device_lock);
- return i;
-}
-
-static void raid1_shrink_buffers (raid1_conf_t *conf)
-{
- md_spin_lock_irq(&conf->device_lock);
- while (conf->freebuf) {
- struct raid1_bh *r1_bh = conf->freebuf;
- conf->freebuf = r1_bh->next_r1;
- __free_page(r1_bh->bh_req.b_page);
- kfree(r1_bh);
- }
- md_spin_unlock_irq(&conf->device_lock);
-}
-
-static int raid1_map (mddev_t *mddev, kdev_t *rdev, unsigned long size)
-{
- raid1_conf_t *conf = mddev_to_conf(mddev);
- int i, disks = MD_SB_DISKS;
-
- /*
- * Later we do read balancing on the read side
- * now we use the first available disk.
- */
-
- for (i = 0; i < disks; i++) {
- if (conf->mirrors[i].operational) {
- *rdev = conf->mirrors[i].dev;


- return (0);
- }
- }
-

- printk (KERN_ERR "raid1_map(): huh, no more operational devices?\n");
- return (-1);
-}
-
-static void raid1_reschedule_retry (struct raid1_bh *r1_bh)
-{
- unsigned long flags;
- mddev_t *mddev = r1_bh->mddev;
- raid1_conf_t *conf = mddev_to_conf(mddev);
-
- md_spin_lock_irqsave(&retry_list_lock, flags);
- if (raid1_retry_list == NULL)
- raid1_retry_tail = &raid1_retry_list;
- *raid1_retry_tail = r1_bh;
- raid1_retry_tail = &r1_bh->next_r1;
- r1_bh->next_r1 = NULL;
- md_spin_unlock_irqrestore(&retry_list_lock, flags);
- md_wakeup_thread(conf->thread);
-}
-
-
-static void inline io_request_done(unsigned long sector, raid1_conf_t *conf, int phase)
-{
- unsigned long flags;
- spin_lock_irqsave(&conf->segment_lock, flags);
- if (sector < conf->start_active)
- conf->cnt_done--;
- else if (sector >= conf->start_future && conf->phase == phase)
- conf->cnt_future--;
- else if (!--conf->cnt_pending)
- wake_up(&conf->wait_ready);
-
- spin_unlock_irqrestore(&conf->segment_lock, flags);
-}
-
-static void inline sync_request_done (unsigned long sector, raid1_conf_t *conf)
-{
- unsigned long flags;
- spin_lock_irqsave(&conf->segment_lock, flags);
- if (sector >= conf->start_ready)
- --conf->cnt_ready;
- else if (sector >= conf->start_active) {
- if (!--conf->cnt_active) {
- conf->start_active = conf->start_ready;
- wake_up(&conf->wait_done);
- }
- }
- spin_unlock_irqrestore(&conf->segment_lock, flags);
-}
-
-/*
- * raid1_end_bh_io() is called when we have finished servicing a mirrored
- * operation and are ready to return a success/failure code to the buffer
- * cache layer.
- */
-static void raid1_end_bh_io (struct raid1_bh *r1_bh, int uptodate)
-{
- struct buffer_head *bh = r1_bh->master_bh;
-
- io_request_done(bh->b_rsector, mddev_to_conf(r1_bh->mddev),
- test_bit(R1BH_SyncPhase, &r1_bh->state));
-
- bh->b_end_io(bh, uptodate);
- raid1_free_r1bh(r1_bh);
-}
-void raid1_end_request (struct buffer_head *bh, int uptodate)
-{
- struct raid1_bh * r1_bh = (struct raid1_bh *)(bh->b_private);
-
- /*
- * this branch is our 'one mirror IO has finished' event handler:
- */
- if (!uptodate)
- md_error (mddev_to_kdev(r1_bh->mddev), bh->b_dev);
- else
- /*
- * Set R1BH_Uptodate in our master buffer_head, so that
- * we will return a good error code for to the higher
- * levels even if IO on some other mirrored buffer fails.
- *
- * The 'master' represents the complex operation to
- * user-side. So if something waits for IO, then it will
- * wait for the 'master' buffer_head.
- */
- set_bit (R1BH_Uptodate, &r1_bh->state);
-
- /*
- * We split up the read and write side, imho they are
- * conceptually different.
- */
-
- if ( (r1_bh->cmd == READ) || (r1_bh->cmd == READA) ) {
- /*
- * we have only one buffer_head on the read side
- */
-
- if (uptodate) {
- raid1_end_bh_io(r1_bh, uptodate);
- return;
- }
- /*
- * oops, read error:
- */
- printk(KERN_ERR "raid1: %s: rescheduling block %lu\n",
- partition_name(bh->b_dev), bh->b_blocknr);
- raid1_reschedule_retry(r1_bh);
- return;
- }
-
- /*
- * WRITE:
- *
- * Let's see if all mirrored write operations have finished
- * already.
- */
-
- if (atomic_dec_and_test(&r1_bh->remaining))
- raid1_end_bh_io(r1_bh, test_bit(R1BH_Uptodate, &r1_bh->state));
-}
-
-/*
- * This routine returns the disk from which the requested read should
- * be done. It bookkeeps the last read position for every disk
- * in array and when new read requests come, the disk which last
- * position is nearest to the request, is chosen.
- *
- * TODO: now if there are 2 mirrors in the same 2 devices, performance
- * degrades dramatically because position is mirror, not device based.
- * This should be changed to be device based. Also atomic sequential
- * reads should be somehow balanced.
- */
-
-static int raid1_read_balance (raid1_conf_t *conf, struct buffer_head *bh)
-{
- int new_disk = conf->last_used;
- const int sectors = bh->b_size >> 9;
- const unsigned long this_sector = bh->b_rsector;
- int disk = new_disk;
- unsigned long new_distance;
- unsigned long current_distance;
-
- /*
- * Check if it is sane at all to balance
- */
-
- if (conf->resync_mirrors)
- goto rb_out;
-
- if (conf->working_disks < 2) {


- int i = 0;
-

- while( !conf->mirrors[new_disk].operational &&
- (i < MD_SB_DISKS) ) {
- new_disk = conf->mirrors[new_disk].next;
- i++;
- }
-
- if (i >= MD_SB_DISKS) {
- /*
- * This means no working disk was found
- * Nothing much to do, lets not change anything
- * and hope for the best...
- */
-
- new_disk = conf->last_used;
- }
-
- goto rb_out;
- }
-
- /*
- * Don't touch anything for sequential reads.
- */
-
- if (this_sector == conf->mirrors[new_disk].head_position)
- goto rb_out;
-
- /*
- * If reads have been done only on a single disk
- * for a time, lets give another disk a change.
- * This is for kicking those idling disks so that
- * they would find work near some hotspot.
- */
-
- if (conf->sect_count >= conf->mirrors[new_disk].sect_limit) {
- conf->sect_count = 0;
-
- while( new_disk != conf->mirrors[new_disk].next ) {
- if ((conf->mirrors[new_disk].write_only) ||
- (!conf->mirrors[new_disk].operational) )
- continue;
-
- new_disk = conf->mirrors[new_disk].next;
- break;
- }
-
- goto rb_out;
- }
-
- current_distance = abs(this_sector -
- conf->mirrors[disk].head_position);
-
- /* Find the disk which is closest */
-
- while( conf->mirrors[disk].next != conf->last_used ) {
- disk = conf->mirrors[disk].next;
-
- if ((conf->mirrors[disk].write_only) ||
- (!conf->mirrors[disk].operational))
- continue;
-
- new_distance = abs(this_sector -
- conf->mirrors[disk].head_position);
-
- if (new_distance < current_distance) {
- conf->sect_count = 0;
- current_distance = new_distance;
- new_disk = disk;
- }
- }
-
-rb_out:
- conf->mirrors[new_disk].head_position = this_sector + sectors;
-
- conf->last_used = new_disk;
- conf->sect_count += sectors;
-
- return new_disk;
-}
-
-static int raid1_make_request (mddev_t *mddev, int rw,
- struct buffer_head * bh)
-{
- raid1_conf_t *conf = mddev_to_conf(mddev);
- struct buffer_head *bh_req, *bhl;
- struct raid1_bh * r1_bh;
- int disks = MD_SB_DISKS;
- int i, sum_bhs = 0, sectors;
- struct mirror_info *mirror;
-
- if (!buffer_locked(bh))
- BUG();
-
-/*
- * make_request() can abort the operation when READA is being
- * used and no empty request is available.
- *
- * Currently, just replace the command with READ/WRITE.
- */
- if (rw == READA)
- rw = READ;
-
- r1_bh = raid1_alloc_r1bh (conf);
-
- spin_lock_irq(&conf->segment_lock);
- wait_event_lock_irq(conf->wait_done,
- bh->b_rsector < conf->start_active ||
- bh->b_rsector >= conf->start_future,
- conf->segment_lock);
- if (bh->b_rsector < conf->start_active)
- conf->cnt_done++;
- else {
- conf->cnt_future++;
- if (conf->phase)
- set_bit(R1BH_SyncPhase, &r1_bh->state);
- }
- spin_unlock_irq(&conf->segment_lock);
-
- /*
- * i think the read and write branch should be separated completely,
- * since we want to do read balancing on the read side for example.
- * Alternative implementations? :) --mingo
- */
-
- r1_bh->master_bh = bh;
- r1_bh->mddev = mddev;
- r1_bh->cmd = rw;
-
- sectors = bh->b_size >> 9;
- if (rw == READ) {
- /*
- * read balancing logic:
- */
- mirror = conf->mirrors + raid1_read_balance(conf, bh);
-
- bh_req = &r1_bh->bh_req;
- memcpy(bh_req, bh, sizeof(*bh));
- bh_req->b_blocknr = bh->b_rsector * sectors;
- bh_req->b_dev = mirror->dev;
- bh_req->b_rdev = mirror->dev;
- /* bh_req->b_rsector = bh->n_rsector; */
- bh_req->b_end_io = raid1_end_request;
- bh_req->b_private = r1_bh;
- generic_make_request (rw, bh_req);


- return 0;
- }
-

- /*
- * WRITE:
- */
-
- bhl = raid1_alloc_bh(conf, conf->raid_disks);
- for (i = 0; i < disks; i++) {
- struct buffer_head *mbh;
- if (!conf->mirrors[i].operational)

- continue;
-
- /*

- * We should use a private pool (size depending on NR_REQUEST),
- * to avoid writes filling up the memory with bhs
- *
- * Such pools are much faster than kmalloc anyways (so we waste
- * almost nothing by not using the master bh when writing and
- * win alot of cleanness) but for now we are cool enough. --mingo
- *
- * It's safe to sleep here, buffer heads cannot be used in a shared
- * manner in the write branch. Look how we lock the buffer at the
- * beginning of this function to grok the difference ;)
- */
- mbh = bhl;
- if (mbh == NULL) {
- MD_BUG();
- break;
- }
- bhl = mbh->b_next;
- mbh->b_next = NULL;
- mbh->b_this_page = (struct buffer_head *)1;
-
- /*
- * prepare mirrored mbh (fields ordered for max mem throughput):
- */
- mbh->b_blocknr = bh->b_rsector * sectors;
- mbh->b_dev = conf->mirrors[i].dev;
- mbh->b_rdev = conf->mirrors[i].dev;
- mbh->b_rsector = bh->b_rsector;
- mbh->b_state = (1<<BH_Req) | (1<<BH_Dirty) |
- (1<<BH_Mapped) | (1<<BH_Lock);
-
- atomic_set(&mbh->b_count, 1);
- mbh->b_size = bh->b_size;
- mbh->b_page = bh->b_page;
- mbh->b_data = bh->b_data;
- mbh->b_list = BUF_LOCKED;
- mbh->b_end_io = raid1_end_request;
- mbh->b_private = r1_bh;
-
- mbh->b_next = r1_bh->mirror_bh_list;
- r1_bh->mirror_bh_list = mbh;
- sum_bhs++;
- }
- if (bhl) raid1_free_bh(conf,bhl);
- md_atomic_set(&r1_bh->remaining, sum_bhs);
-
- /*
- * We have to be a bit careful about the semaphore above, thats
- * why we start the requests separately. Since kmalloc() could
- * fail, sleep and make_request() can sleep too, this is the
- * safer solution. Imagine, end_request decreasing the semaphore
- * before we could have set it up ... We could play tricks with
- * the semaphore (presetting it and correcting at the end if
- * sum_bhs is not 'n' but we have to do end_request by hand if
- * all requests finish until we had a chance to set up the
- * semaphore correctly ... lots of races).
- */
- bh = r1_bh->mirror_bh_list;
- while(bh) {
- struct buffer_head *bh2 = bh;
- bh = bh->b_next;
- generic_make_request(rw, bh2);
- }


- return (0);
-}
-

-static int raid1_status (char *page, mddev_t *mddev)
-{
- raid1_conf_t *conf = mddev_to_conf(mddev);
- int sz = 0, i;
-
- sz += sprintf (page+sz, " [%d/%d] [", conf->raid_disks,
- conf->working_disks);
- for (i = 0; i < conf->raid_disks; i++)
- sz += sprintf (page+sz, "%s",
- conf->mirrors[i].operational ? "U" : "_");
- sz += sprintf (page+sz, "]");


- return sz;
-}
-

-static void unlink_disk (raid1_conf_t *conf, int target)
-{
- int disks = MD_SB_DISKS;
- int i;
-
- for (i = 0; i < disks; i++)
- if (conf->mirrors[i].next == target)
- conf->mirrors[i].next = conf->mirrors[target].next;
-}
-
-#define LAST_DISK KERN_ALERT \
-"raid1: only one disk left and IO error.\n"
-
-#define NO_SPARE_DISK KERN_ALERT \
-"raid1: no spare disk left, degrading mirror level by one.\n"
-
-#define DISK_FAILED KERN_ALERT \
-"raid1: Disk failure on %s, disabling device. \n" \
-" Operation continuing on %d devices\n"
-
-#define START_SYNCING KERN_ALERT \
-"raid1: start syncing spare disk.\n"
-
-#define ALREADY_SYNCING KERN_INFO \
-"raid1: syncing already in progress.\n"
-
-static void mark_disk_bad (mddev_t *mddev, int failed)
-{
- raid1_conf_t *conf = mddev_to_conf(mddev);
- struct mirror_info *mirror = conf->mirrors+failed;


- mdp_super_t *sb = mddev->sb;
-

- mirror->operational = 0;
- unlink_disk(conf, failed);
- mark_disk_faulty(sb->disks+mirror->number);
- mark_disk_nonsync(sb->disks+mirror->number);
- mark_disk_inactive(sb->disks+mirror->number);
- sb->active_disks--;
- sb->working_disks--;
- sb->failed_disks++;


- mddev->sb_dirty = 1;

- md_wakeup_thread(conf->thread);
- conf->working_disks--;
- printk (DISK_FAILED, partition_name (mirror->dev),
- conf->working_disks);
-}
-
-static int raid1_error (mddev_t *mddev, kdev_t dev)
-{
- raid1_conf_t *conf = mddev_to_conf(mddev);
- struct mirror_info * mirrors = conf->mirrors;
- int disks = MD_SB_DISKS;
- int i;
-
- if (conf->working_disks == 1) {
- /*
- * Uh oh, we can do nothing if this is our last disk, but
- * first check if this is a queued request for a device
- * which has just failed.
- */
- for (i = 0; i < disks; i++) {
- if (mirrors[i].dev==dev && !mirrors[i].operational)
- return 0;
- }
- printk (LAST_DISK);
- } else {
- /*
- * Mark disk as unusable
- */
- for (i = 0; i < disks; i++) {
- if (mirrors[i].dev==dev && mirrors[i].operational) {
- mark_disk_bad(mddev, i);


- break;
- }
- }
- }

- return 0;
-}
-
-#undef LAST_DISK
-#undef NO_SPARE_DISK
-#undef DISK_FAILED
-#undef START_SYNCING
-
-/*
- * Insert the spare disk into the drive-ring
- */
-static void link_disk(raid1_conf_t *conf, struct mirror_info *mirror)
-{
- int j, next;
- int disks = MD_SB_DISKS;
- struct mirror_info *p = conf->mirrors;
-
- for (j = 0; j < disks; j++, p++)
- if (p->operational && !p->write_only) {
- next = p->next;
- p->next = mirror->raid_disk;
- mirror->next = next;
- return;
- }
-
- printk("raid1: bug: no read-operational devices\n");
-}
-
-static void print_raid1_conf (raid1_conf_t *conf)
-{
- int i;
- struct mirror_info *tmp;
-
- printk("RAID1 conf printout:\n");
- if (!conf) {
- printk("(conf==NULL)\n");
- return;
- }
- printk(" --- wd:%d rd:%d nd:%d\n", conf->working_disks,
- conf->raid_disks, conf->nr_disks);


-
- for (i = 0; i < MD_SB_DISKS; i++) {

- tmp = conf->mirrors + i;
- printk(" disk %d, s:%d, o:%d, n:%d rd:%d us:%d dev:%s\n",
- i, tmp->spare,tmp->operational,
- tmp->number,tmp->raid_disk,tmp->used_slot,
- partition_name(tmp->dev));
- }
-}
-
-static int raid1_diskop(mddev_t *mddev, mdp_disk_t **d, int state)


-{
- int err = 0;

- int i, failed_disk=-1, spare_disk=-1, removed_disk=-1, added_disk=-1;
- raid1_conf_t *conf = mddev->private;
- struct mirror_info *tmp, *sdisk, *fdisk, *rdisk, *adisk;


- mdp_super_t *sb = mddev->sb;

- mdp_disk_t *failed_desc, *spare_desc, *added_desc;
-
- print_raid1_conf(conf);
- md_spin_lock_irq(&conf->device_lock);


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 043'
echo 'File patch-2.4.0-test9 is continued in part 044'
echo "044" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part044

#!/bin/sh -x
# this is part 044 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 044; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

- /*
- * find the disk ...
- */
- switch (state) {
-
- case DISKOP_SPARE_ACTIVE:
-
- /*
- * Find the failed disk within the RAID1 configuration ...
- * (this can only be in the first conf->working_disks part)
- */
- for (i = 0; i < conf->raid_disks; i++) {


- tmp = conf->mirrors + i;

- if ((!tmp->operational && !tmp->spare) ||
- !tmp->used_slot) {
- failed_disk = i;
- break;
- }
- }
- /*
- * When we activate a spare disk we _must_ have a disk in
- * the lower (active) part of the array to replace.
- */
- if ((failed_disk == -1) || (failed_disk >= conf->raid_disks)) {
- MD_BUG();
- err = 1;
- goto abort;
- }
- /* fall through */
-
- case DISKOP_SPARE_WRITE:
- case DISKOP_SPARE_INACTIVE:
-
- /*
- * Find the spare disk ... (can only be in the 'high'
- * area of the array)
- */
- for (i = conf->raid_disks; i < MD_SB_DISKS; i++) {


- tmp = conf->mirrors + i;

- if (tmp->spare && tmp->number == (*d)->number) {
- spare_disk = i;
- break;
- }
- }
- if (spare_disk == -1) {
- MD_BUG();
- err = 1;
- goto abort;
- }
- break;
-
- case DISKOP_HOT_REMOVE_DISK:


-
- for (i = 0; i < MD_SB_DISKS; i++) {
- tmp = conf->mirrors + i;

- if (tmp->used_slot && (tmp->number == (*d)->number)) {
- if (tmp->operational) {
- err = -EBUSY;
- goto abort;
- }
- removed_disk = i;
- break;
- }
- }
- if (removed_disk == -1) {
- MD_BUG();
- err = 1;
- goto abort;
- }
- break;
-
- case DISKOP_HOT_ADD_DISK:
-
- for (i = conf->raid_disks; i < MD_SB_DISKS; i++) {


- tmp = conf->mirrors + i;

- if (!tmp->used_slot) {
- added_disk = i;
- break;
- }
- }
- if (added_disk == -1) {
- MD_BUG();
- err = 1;
- goto abort;
- }
- break;
- }
-
- switch (state) {
- /*
- * Switch the spare disk to write-only mode:
- */
- case DISKOP_SPARE_WRITE:
- sdisk = conf->mirrors + spare_disk;
- sdisk->operational = 1;
- sdisk->write_only = 1;
- break;
- /*
- * Deactivate a spare disk:
- */
- case DISKOP_SPARE_INACTIVE:
- sdisk = conf->mirrors + spare_disk;
- sdisk->operational = 0;
- sdisk->write_only = 0;
- break;
- /*
- * Activate (mark read-write) the (now sync) spare disk,
- * which means we switch it's 'raid position' (->raid_disk)
- * with the failed disk. (only the first 'conf->nr_disks'
- * slots are used for 'real' disks and we must preserve this
- * property)
- */
- case DISKOP_SPARE_ACTIVE:
-
- sdisk = conf->mirrors + spare_disk;
- fdisk = conf->mirrors + failed_disk;
-
- spare_desc = &sb->disks[sdisk->number];
- failed_desc = &sb->disks[fdisk->number];
-
- if (spare_desc != *d) {
- MD_BUG();
- err = 1;


- goto abort;
- }
-

- if (spare_desc->raid_disk != sdisk->raid_disk) {
- MD_BUG();
- err = 1;


- goto abort;
- }
-

- if (sdisk->raid_disk != spare_disk) {
- MD_BUG();
- err = 1;


- goto abort;
- }
-

- if (failed_desc->raid_disk != fdisk->raid_disk) {
- MD_BUG();
- err = 1;


- goto abort;
- }
-

- if (fdisk->raid_disk != failed_disk) {
- MD_BUG();
- err = 1;
- goto abort;
- }
-
- /*
- * do the switch finally
- */
- xchg_values(*spare_desc, *failed_desc);
- xchg_values(*fdisk, *sdisk);
-
- /*
- * (careful, 'failed' and 'spare' are switched from now on)
- *
- * we want to preserve linear numbering and we want to
- * give the proper raid_disk number to the now activated
- * disk. (this means we switch back these values)
- */
-
- xchg_values(spare_desc->raid_disk, failed_desc->raid_disk);
- xchg_values(sdisk->raid_disk, fdisk->raid_disk);
- xchg_values(spare_desc->number, failed_desc->number);
- xchg_values(sdisk->number, fdisk->number);
-
- *d = failed_desc;
-
- if (sdisk->dev == MKDEV(0,0))
- sdisk->used_slot = 0;
- /*
- * this really activates the spare.
- */
- fdisk->spare = 0;
- fdisk->write_only = 0;
- link_disk(conf, fdisk);
-
- /*
- * if we activate a spare, we definitely replace a
- * non-operational disk slot in the 'low' area of
- * the disk array.
- */
-
- conf->working_disks++;
-
- break;
-
- case DISKOP_HOT_REMOVE_DISK:
- rdisk = conf->mirrors + removed_disk;
-
- if (rdisk->spare && (removed_disk < conf->raid_disks)) {
- MD_BUG();
- err = 1;
- goto abort;
- }
- rdisk->dev = MKDEV(0,0);
- rdisk->used_slot = 0;
- conf->nr_disks--;
- break;
-
- case DISKOP_HOT_ADD_DISK:
- adisk = conf->mirrors + added_disk;
- added_desc = *d;
-
- if (added_disk != added_desc->number) {
- MD_BUG();
- err = 1;


- goto abort;
- }
-

- adisk->number = added_desc->number;
- adisk->raid_disk = added_desc->raid_disk;
- adisk->dev = MKDEV(added_desc->major,added_desc->minor);
-
- adisk->operational = 0;
- adisk->write_only = 0;
- adisk->spare = 1;
- adisk->used_slot = 1;
- adisk->head_position = 0;
- conf->nr_disks++;
-


- break;
-
- default:

- MD_BUG();
- err = 1;
- goto abort;
- }
-abort:
- md_spin_unlock_irq(&conf->device_lock);
- if (state == DISKOP_SPARE_ACTIVE || state == DISKOP_SPARE_INACTIVE)
- /* should move to "END_REBUILD" when such exists */
- raid1_shrink_buffers(conf);
-
- print_raid1_conf(conf);


- return err;
-}
-
-

-#define IO_ERROR KERN_ALERT \
-"raid1: %s: unrecoverable I/O read error for block %lu\n"
-
-#define REDIRECT_SECTOR KERN_ERR \
-"raid1: %s: redirecting sector %lu to another mirror\n"
-
-/*
- * This is a kernel thread which:
- *
- * 1. Retries failed read operations on working mirrors.
- * 2. Updates the raid superblock when problems encounter.
- * 3. Performs writes following reads for array syncronising.
- */
-static void end_sync_write(struct buffer_head *bh, int uptodate);
-static void end_sync_read(struct buffer_head *bh, int uptodate);
-
-static void raid1d (void *data)


-{
- struct raid1_bh *r1_bh;

- struct buffer_head *bh;
- unsigned long flags;
- mddev_t *mddev;
- kdev_t dev;
-


-
- for (;;) {

- md_spin_lock_irqsave(&retry_list_lock, flags);
- r1_bh = raid1_retry_list;


- if (!r1_bh)
- break;

- raid1_retry_list = r1_bh->next_r1;
- md_spin_unlock_irqrestore(&retry_list_lock, flags);
-
- mddev = r1_bh->mddev;
- if (mddev->sb_dirty) {
- printk(KERN_INFO "dirty sb detected, updating.\n");


- mddev->sb_dirty = 0;

- md_update_sb(mddev);
- }
- bh = &r1_bh->bh_req;
- switch(r1_bh->cmd) {
- case SPECIAL:
- /* have to allocate lots of bh structures and
- * schedule writes
- */
- if (test_bit(R1BH_Uptodate, &r1_bh->state)) {
- int i, sum_bhs = 0;


- int disks = MD_SB_DISKS;

- struct buffer_head *bhl, *mbh;
- raid1_conf_t *conf;
- int sectors = bh->b_size >> 9;
-
- conf = mddev_to_conf(mddev);
- bhl = raid1_alloc_bh(conf, conf->raid_disks); /* don't really need this many */


- for (i = 0; i < disks ; i++) {

- if (!conf->mirrors[i].operational)
- continue;

- if (i==conf->last_used)
- /* we read from here, no need to write */
- continue;
- if (i < conf->raid_disks
- && !conf->resync_mirrors)
- /* don't need to write this,
- * we are just rebuilding */
- continue;
- mbh = bhl;
- if (!mbh) {


- MD_BUG();
- break;
- }
- bhl = mbh->b_next;

- mbh->b_this_page = (struct buffer_head *)1;
-
-
- /*

- * prepare mirrored bh (fields ordered for max mem throughput):
- */
- mbh->b_blocknr = bh->b_blocknr;


- mbh->b_dev = conf->mirrors[i].dev;
- mbh->b_rdev = conf->mirrors[i].dev;

- mbh->b_rsector = bh->b_blocknr * sectors;


- mbh->b_state = (1<<BH_Req) | (1<<BH_Dirty) |
- (1<<BH_Mapped) | (1<<BH_Lock);
- atomic_set(&mbh->b_count, 1);
- mbh->b_size = bh->b_size;
- mbh->b_page = bh->b_page;
- mbh->b_data = bh->b_data;
- mbh->b_list = BUF_LOCKED;

- mbh->b_end_io = end_sync_write;


- mbh->b_private = r1_bh;
-
- mbh->b_next = r1_bh->mirror_bh_list;
- r1_bh->mirror_bh_list = mbh;
-

- sum_bhs++;
- }
- md_atomic_set(&r1_bh->remaining, sum_bhs);
- if (bhl) raid1_free_bh(conf, bhl);
- mbh = r1_bh->mirror_bh_list;
- while (mbh) {
- struct buffer_head *bh1 = mbh;
- mbh = mbh->b_next;
- generic_make_request(WRITE, bh1);
- md_sync_acct(bh1->b_rdev, bh1->b_size/512);
- }
- } else {
- dev = bh->b_dev;
- raid1_map (mddev, &bh->b_dev, bh->b_size >> 9);
- if (bh->b_dev == dev) {
- printk (IO_ERROR, partition_name(bh->b_dev), bh->b_blocknr);
- md_done_sync(mddev, bh->b_size>>10, 0);
- } else {
- printk (REDIRECT_SECTOR,


- partition_name(bh->b_dev), bh->b_blocknr);

- bh->b_rdev = bh->b_dev;
- generic_make_request(READ, bh);
- }
- }
-
- break;
- case READ:
- case READA:
- dev = bh->b_dev;
-
- raid1_map (mddev, &bh->b_dev, bh->b_size >> 9);
- if (bh->b_dev == dev) {
- printk (IO_ERROR, partition_name(bh->b_dev), bh->b_blocknr);
- raid1_end_bh_io(r1_bh, 0);
- } else {
- printk (REDIRECT_SECTOR,


- partition_name(bh->b_dev), bh->b_blocknr);

- bh->b_rdev = bh->b_dev;
- generic_make_request (r1_bh->cmd, bh);
- }
- break;
- }
- }
- md_spin_unlock_irqrestore(&retry_list_lock, flags);
-}
-#undef IO_ERROR
-#undef REDIRECT_SECTOR
-
-/*
- * Private kernel thread to reconstruct mirrors after an unclean
- * shutdown.
- */
-static void raid1syncd (void *data)
-{
- raid1_conf_t *conf = data;
- mddev_t *mddev = conf->mddev;
-
- if (!conf->resync_mirrors)
- return;
- if (conf->resync_mirrors == 2)
- return;
- down(&mddev->recovery_sem);
- if (!md_do_sync(mddev, NULL)) {
- /*
- * Only if everything went Ok.
- */
- conf->resync_mirrors = 0;
- }
-
- /* If reconstruction was interrupted, we need to close the "active" and "pending"
- * holes.
- * we know that there are no active rebuild requests, os cnt_active == cnt_ready ==0
- */
- /* this is really needed when recovery stops too... */
- spin_lock_irq(&conf->segment_lock);
- conf->start_active = conf->start_pending;
- conf->start_ready = conf->start_pending;
- wait_event_lock_irq(conf->wait_ready, !conf->cnt_pending, conf->segment_lock);
- conf->start_active =conf->start_ready = conf->start_pending = conf->start_future;
- conf->start_future = mddev->sb->size+1;
- conf->cnt_pending = conf->cnt_future;
- conf->cnt_future = 0;
- conf->phase = conf->phase ^1;
- wait_event_lock_irq(conf->wait_ready, !conf->cnt_pending, conf->segment_lock);
- conf->start_active = conf->start_ready = conf->start_pending = conf->start_future = 0;
- conf->phase = 0;
- conf->cnt_future = conf->cnt_done;;
- conf->cnt_done = 0;
- spin_unlock_irq(&conf->segment_lock);
- wake_up(&conf->wait_done);
-
- up(&mddev->recovery_sem);
- raid1_shrink_buffers(conf);
-}
-
-/*
- * perform a "sync" on one "block"
- *
- * We need to make sure that no normal I/O request - particularly write
- * requests - conflict with active sync requests.
- * This is achieved by conceptually dividing the device space into a
- * number of sections:
- * DONE: 0 .. a-1 These blocks are in-sync
- * ACTIVE: a.. b-1 These blocks may have active sync requests, but
- * no normal IO requests
- * READY: b .. c-1 These blocks have no normal IO requests - sync
- * request may be happening
- * PENDING: c .. d-1 These blocks may have IO requests, but no new
- * ones will be added
- * FUTURE: d .. end These blocks are not to be considered yet. IO may
- * be happening, but not sync
- *
- * We keep a
- * phase which flips (0 or 1) each time d moves and
- * a count of:
- * z = active io requests in FUTURE since d moved - marked with
- * current phase
- * y = active io requests in FUTURE before d moved, or PENDING -
- * marked with previous phase
- * x = active sync requests in READY
- * w = active sync requests in ACTIVE
- * v = active io requests in DONE
- *
- * Normally, a=b=c=d=0 and z= active io requests
- * or a=b=c=d=END and v= active io requests
- * Allowed changes to a,b,c,d:
- * A: c==d && y==0 -> d+=window, y=z, z=0, phase=!phase
- * B: y==0 -> c=d
- * C: b=c, w+=x, x=0
- * D: w==0 -> a=b
- * E: a==b==c==d==end -> a=b=c=d=0, z=v, v=0
- *
- * At start of sync we apply A.
- * When y reaches 0, we apply B then A then being sync requests
- * When sync point reaches c-1, we wait for y==0, and W==0, and
- * then apply apply B then A then D then C.
- * Finally, we apply E
- *
- * The sync request simply issues a "read" against a working drive
- * This is marked so that on completion the raid1d thread is woken to
- * issue suitable write requests
- */
-
-static int raid1_sync_request (mddev_t *mddev, unsigned long block_nr)


-{
- raid1_conf_t *conf = mddev_to_conf(mddev);

- struct mirror_info *mirror;
- struct raid1_bh *r1_bh;
- struct buffer_head *bh;
- int bsize;
-
- spin_lock_irq(&conf->segment_lock);
- if (!block_nr) {
- /* initialize ...*/
- int buffs;
- conf->start_active = 0;
- conf->start_ready = 0;
- conf->start_pending = 0;
- conf->start_future = 0;
- conf->phase = 0;
- /* we want enough buffers to hold twice the window of 128*/
- buffs = 128 *2 / (PAGE_SIZE>>9);
- buffs = raid1_grow_buffers(conf, buffs);
- if (buffs < 2)
- goto nomem;
-
- conf->window = buffs*(PAGE_SIZE>>9)/2;
- conf->cnt_future += conf->cnt_done+conf->cnt_pending;
- conf->cnt_done = conf->cnt_pending = 0;
- if (conf->cnt_ready || conf->cnt_active)
- MD_BUG();
- }
- while ((block_nr<<1) >= conf->start_pending) {
- PRINTK("wait .. sect=%lu start_active=%d ready=%d pending=%d future=%d, cnt_done=%d active=%d ready=%d pending=%d future=%d\n",
- block_nr<<1, conf->start_active, conf->start_ready, conf->start_pending, conf->start_future,
- conf->cnt_done, conf->cnt_active, conf->cnt_ready, conf->cnt_pending, conf->cnt_future);
- wait_event_lock_irq(conf->wait_done,
- !conf->cnt_active,
- conf->segment_lock);
- wait_event_lock_irq(conf->wait_ready,
- !conf->cnt_pending,
- conf->segment_lock);


- conf->start_active = conf->start_ready;

- conf->start_ready = conf->start_pending;
- conf->start_pending = conf->start_future;
- conf->start_future = conf->start_future+conf->window;
- // Note: falling off the end is not a problem
- conf->phase = conf->phase ^1;
- conf->cnt_active = conf->cnt_ready;
- conf->cnt_ready = 0;
- conf->cnt_pending = conf->cnt_future;
- conf->cnt_future = 0;
- wake_up(&conf->wait_done);
- }
- conf->cnt_ready++;


- spin_unlock_irq(&conf->segment_lock);
-
-

- /* If reconstructing, and >1 working disc,
- * could dedicate one to rebuild and others to
- * service read requests ..
- */
- mirror = conf->mirrors+conf->last_used;
-
- r1_bh = raid1_alloc_buf (conf);
- r1_bh->master_bh = NULL;


- r1_bh->mddev = mddev;

- r1_bh->cmd = SPECIAL;
- bh = &r1_bh->bh_req;
-
- bh->b_blocknr = block_nr;
- bsize = 1024;
- while (!(bh->b_blocknr & 1) && bsize < PAGE_SIZE
- && (bh->b_blocknr+2)*(bsize>>10) < mddev->sb->size) {
- bh->b_blocknr >>= 1;
- bsize <<= 1;
- }
- bh->b_size = bsize;
- bh->b_list = BUF_LOCKED;
- bh->b_dev = mirror->dev;
- bh->b_rdev = mirror->dev;
- bh->b_state = (1<<BH_Req) | (1<<BH_Mapped);
- if (!bh->b_page)
- BUG();
- if (!bh->b_data)
- BUG();
- if (bh->b_data != page_address(bh->b_page))
- BUG();
- bh->b_end_io = end_sync_read;
- bh->b_private = r1_bh;
- bh->b_rsector = block_nr<<1;
- init_waitqueue_head(&bh->b_wait);
-
- generic_make_request(READ, bh);
- md_sync_acct(bh->b_rdev, bh->b_size/512);
-
- return (bsize >> 10);
-
-nomem:
- raid1_shrink_buffers(conf);
- spin_unlock_irq(&conf->segment_lock);


- return -ENOMEM;
-}
-

-static void end_sync_read(struct buffer_head *bh, int uptodate)


-{
- struct raid1_bh * r1_bh = (struct raid1_bh *)(bh->b_private);
-

- /* we have read a block, now it needs to be re-written,
- * or re-read if the read failed.
- * We don't do much here, just schedule handling by raid1d


- */
- if (!uptodate)
- md_error (mddev_to_kdev(r1_bh->mddev), bh->b_dev);
- else

- set_bit(R1BH_Uptodate, &r1_bh->state);
- raid1_reschedule_retry(r1_bh);
-}
-
-static void end_sync_write(struct buffer_head *bh, int uptodate)


-{
- struct raid1_bh * r1_bh = (struct raid1_bh *)(bh->b_private);
-

- if (!uptodate)
- md_error (mddev_to_kdev(r1_bh->mddev), bh->b_dev);

- if (atomic_dec_and_test(&r1_bh->remaining)) {


- mddev_t *mddev = r1_bh->mddev;

- unsigned long sect = bh->b_blocknr * (bh->b_size>>9);
- int size = bh->b_size;
- raid1_free_buf(r1_bh);
- sync_request_done(sect, mddev_to_conf(mddev));
- md_done_sync(mddev,size>>10, uptodate);
- }
-}
-
-/*
- * This will catch the scenario in which one of the mirrors was
- * mounted as a normal device rather than as a part of a raid set.
- *
- * check_consistency is very personality-dependent, eg. RAID5 cannot
- * do this check, it uses another method.
- */
-static int __check_consistency (mddev_t *mddev, int row)


-{
- raid1_conf_t *conf = mddev_to_conf(mddev);

- int disks = MD_SB_DISKS;
- kdev_t dev;
- struct buffer_head *bh = NULL;
- int i, rc = 0;
- char *buffer = NULL;


-
- for (i = 0; i < disks; i++) {

- printk("(checking disk %d)\n",i);


- if (!conf->mirrors[i].operational)
- continue;

- printk("(really checking disk %d)\n",i);
- dev = conf->mirrors[i].dev;
- set_blocksize(dev, 4096);
- if ((bh = bread(dev, row / 4, 4096)) == NULL)
- break;
- if (!buffer) {
- buffer = (char *) __get_free_page(GFP_KERNEL);
- if (!buffer)
- break;
- memcpy(buffer, bh->b_data, 4096);
- } else if (memcmp(buffer, bh->b_data, 4096)) {
- rc = 1;
- break;
- }
- bforget(bh);
- fsync_dev(dev);
- invalidate_buffers(dev);
- bh = NULL;
- }
- if (buffer)
- free_page((unsigned long) buffer);
- if (bh) {
- dev = bh->b_dev;
- bforget(bh);


- fsync_dev(dev);
- invalidate_buffers(dev);
- }

- return rc;
-}
-

-static int check_consistency (mddev_t *mddev)
-{
- if (__check_consistency(mddev, 0))
-/*
- * we do not do this currently, as it's perfectly possible to
- * have an inconsistent array when it's freshly created. Only
- * newly written data has to be consistent.
- */
- return 0;
-


- return 0;
-}
-

-#define INVALID_LEVEL KERN_WARNING \
-"raid1: md%d: raid level not set to mirroring (%d)\n"
-
-#define NO_SB KERN_ERR \
-"raid1: disabled mirror %s (couldn't access raid superblock)\n"
-
-#define ERRORS KERN_ERR \
-"raid1: disabled mirror %s (errors detected)\n"
-
-#define NOT_IN_SYNC KERN_ERR \
-"raid1: disabled mirror %s (not in sync)\n"
-
-#define INCONSISTENT KERN_ERR \
-"raid1: disabled mirror %s (inconsistent descriptor)\n"
-
-#define ALREADY_RUNNING KERN_ERR \
-"raid1: disabled mirror %s (mirror %d already operational)\n"
-
-#define OPERATIONAL KERN_INFO \
-"raid1: device %s operational as mirror %d\n"
-
-#define MEM_ERROR KERN_ERR \
-"raid1: couldn't allocate memory for md%d\n"
-
-#define SPARE KERN_INFO \
-"raid1: spare disk %s\n"
-
-#define NONE_OPERATIONAL KERN_ERR \
-"raid1: no operational mirrors for md%d\n"
-
-#define RUNNING_CKRAID KERN_ERR \
-"raid1: detected mirror differences -- running resync\n"
-
-#define ARRAY_IS_ACTIVE KERN_INFO \
-"raid1: raid set md%d active with %d out of %d mirrors\n"
-
-#define THREAD_ERROR KERN_ERR \
-"raid1: couldn't allocate thread for md%d\n"
-
-#define START_RESYNC KERN_WARNING \
-"raid1: raid set md%d not clean; reconstructing mirrors\n"
-
-static int raid1_run (mddev_t *mddev)
-{
- raid1_conf_t *conf;
- int i, j, disk_idx;
- struct mirror_info *disk;


- mdp_super_t *sb = mddev->sb;

- mdp_disk_t *descriptor;


- mdk_rdev_t *rdev;
- struct md_list_head *tmp;

- int start_recovery = 0;
-
- MOD_INC_USE_COUNT;
-
- if (sb->level != 1) {
- printk(INVALID_LEVEL, mdidx(mddev), sb->level);
- goto out;
- }
- /*
- * copy the already verified devices into our private RAID1
- * bookkeeping area. [whatever we allocate in raid1_run(),
- * should be freed in raid1_stop()]
- */
-
- conf = kmalloc(sizeof(raid1_conf_t), GFP_KERNEL);


- mddev->private = conf;

- if (!conf) {
- printk(MEM_ERROR, mdidx(mddev));
- goto out;
- }
- memset(conf, 0, sizeof(*conf));


-
- ITERATE_RDEV(mddev,rdev,tmp) {
- if (rdev->faulty) {

- printk(ERRORS, partition_name(rdev->dev));
- } else {


- if (!rdev->sb) {
- MD_BUG();
- continue;
- }
- }

- if (rdev->desc_nr == -1) {

- MD_BUG();
- continue;
- }

- descriptor = &sb->disks[rdev->desc_nr];
- disk_idx = descriptor->raid_disk;
- disk = conf->mirrors + disk_idx;
-
- if (disk_faulty(descriptor)) {
- disk->number = descriptor->number;
- disk->raid_disk = disk_idx;
- disk->dev = rdev->dev;
- disk->sect_limit = MAX_WORK_PER_DISK;
- disk->operational = 0;
- disk->write_only = 0;
- disk->spare = 0;
- disk->used_slot = 1;
- disk->head_position = 0;
- continue;
- }
- if (disk_active(descriptor)) {
- if (!disk_sync(descriptor)) {
- printk(NOT_IN_SYNC,
- partition_name(rdev->dev));
- continue;
- }
- if ((descriptor->number > MD_SB_DISKS) ||
- (disk_idx > sb->raid_disks)) {
-
- printk(INCONSISTENT,
- partition_name(rdev->dev));
- continue;
- }
- if (disk->operational) {
- printk(ALREADY_RUNNING,
- partition_name(rdev->dev),
- disk_idx);
- continue;
- }
- printk(OPERATIONAL, partition_name(rdev->dev),
- disk_idx);
- disk->number = descriptor->number;
- disk->raid_disk = disk_idx;
- disk->dev = rdev->dev;
- disk->sect_limit = MAX_WORK_PER_DISK;
- disk->operational = 1;
- disk->write_only = 0;
- disk->spare = 0;
- disk->used_slot = 1;
- disk->head_position = 0;
- conf->working_disks++;
- } else {
- /*
- * Must be a spare disk ..
- */
- printk(SPARE, partition_name(rdev->dev));
- disk->number = descriptor->number;
- disk->raid_disk = disk_idx;
- disk->dev = rdev->dev;
- disk->sect_limit = MAX_WORK_PER_DISK;
- disk->operational = 0;
- disk->write_only = 0;
- disk->spare = 1;
- disk->used_slot = 1;
- disk->head_position = 0;
- }
- }
- conf->raid_disks = sb->raid_disks;
- conf->nr_disks = sb->nr_disks;
- conf->mddev = mddev;
- conf->device_lock = MD_SPIN_LOCK_UNLOCKED;
-
- conf->segment_lock = MD_SPIN_LOCK_UNLOCKED;
- init_waitqueue_head(&conf->wait_buffer);
- init_waitqueue_head(&conf->wait_done);
- init_waitqueue_head(&conf->wait_ready);
-
- if (!conf->working_disks) {
- printk(NONE_OPERATIONAL, mdidx(mddev));


- goto out_free_conf;
- }
-
-

- /* pre-allocate some buffer_head structures.
- * As a minimum, 1 r1bh and raid_disks buffer_heads
- * would probably get us by in tight memory situations,
- * but a few more is probably a good idea.
- * For now, try 16 r1bh and 16*raid_disks bufferheads
- * This will allow at least 16 concurrent reads or writes
- * even if kmalloc starts failing
- */
- if (raid1_grow_r1bh(conf, 16) < 16 ||
- raid1_grow_bh(conf, 16*conf->raid_disks)< 16*conf->raid_disks) {
- printk(MEM_ERROR, mdidx(mddev));


- goto out_free_conf;
- }
-

- for (i = 0; i < MD_SB_DISKS; i++) {
-

- descriptor = sb->disks+i;
- disk_idx = descriptor->raid_disk;
- disk = conf->mirrors + disk_idx;
-
- if (disk_faulty(descriptor) && (disk_idx < conf->raid_disks) &&
- !disk->used_slot) {
-
- disk->number = descriptor->number;
- disk->raid_disk = disk_idx;
- disk->dev = MKDEV(0,0);
-
- disk->operational = 0;
- disk->write_only = 0;
- disk->spare = 0;
- disk->used_slot = 1;
- disk->head_position = 0;
- }
- }
-
- /*
- * find the first working one and use it as a starting point
- * to read balancing.
- */
- for (j = 0; !conf->mirrors[j].operational; j++)
- /* nothing */;
- conf->last_used = j;
-
- /*
- * initialize the 'working disks' list.
- */
- for (i = conf->raid_disks - 1; i >= 0; i--) {


- if (conf->mirrors[i].operational) {

- conf->mirrors[i].next = j;
- j = i;
- }
- }
-
- if (conf->working_disks != sb->raid_disks) {
- printk(KERN_ALERT "raid1: md%d, not all disks are operational -- trying to recover array\n", mdidx(mddev));
- start_recovery = 1;
- }
-
- if (!start_recovery && (sb->state & (1 << MD_SB_CLEAN))) {
- /*
- * we do sanity checks even if the device says
- * it's clean ...
- */
- if (check_consistency(mddev)) {
- printk(RUNNING_CKRAID);
- sb->state &= ~(1 << MD_SB_CLEAN);
- }
- }
-
- {
- const char * name = "raid1d";
-
- conf->thread = md_register_thread(raid1d, conf, name);
- if (!conf->thread) {
- printk(THREAD_ERROR, mdidx(mddev));


- goto out_free_conf;
- }
- }
-

- if (!start_recovery && !(sb->state & (1 << MD_SB_CLEAN))) {
- const char * name = "raid1syncd";
-
- conf->resync_thread = md_register_thread(raid1syncd, conf,name);
- if (!conf->resync_thread) {
- printk(THREAD_ERROR, mdidx(mddev));


- goto out_free_conf;
- }
-

- printk(START_RESYNC, mdidx(mddev));
- conf->resync_mirrors = 1;
- md_wakeup_thread(conf->resync_thread);
- }
-
- /*
- * Regenerate the "device is in sync with the raid set" bit for
- * each device.
- */
- for (i = 0; i < MD_SB_DISKS; i++) {
- mark_disk_nonsync(sb->disks+i);
- for (j = 0; j < sb->raid_disks; j++) {
- if (!conf->mirrors[j].operational)
- continue;
- if (sb->disks[i].number == conf->mirrors[j].number)
- mark_disk_sync(sb->disks+i);
- }
- }
- sb->active_disks = conf->working_disks;
-
- if (start_recovery)
- md_recover_arrays();
-
-
- printk(ARRAY_IS_ACTIVE, mdidx(mddev), sb->active_disks, sb->raid_disks);
- /*
- * Ok, everything is just fine now
- */
- return 0;
-
-out_free_conf:
- raid1_shrink_r1bh(conf);
- raid1_shrink_bh(conf, conf->freebh_cnt);
- raid1_shrink_buffers(conf);
- kfree(conf);


- mddev->private = NULL;
-out:
- MOD_DEC_USE_COUNT;

- return -EIO;
-}
-
-#undef INVALID_LEVEL
-#undef NO_SB
-#undef ERRORS
-#undef NOT_IN_SYNC
-#undef INCONSISTENT
-#undef ALREADY_RUNNING
-#undef OPERATIONAL
-#undef SPARE
-#undef NONE_OPERATIONAL
-#undef RUNNING_CKRAID
-#undef ARRAY_IS_ACTIVE
-
-static int raid1_stop_resync (mddev_t *mddev)


-{
- raid1_conf_t *conf = mddev_to_conf(mddev);
-

- if (conf->resync_thread) {
- if (conf->resync_mirrors) {
- conf->resync_mirrors = 2;
- md_interrupt_thread(conf->resync_thread);
-
- printk(KERN_INFO "raid1: mirror resync was not fully finished, restarting next time.\n");
- return 1;
- }
- return 0;


- }
- return 0;
-}
-

-static int raid1_restart_resync (mddev_t *mddev)


-{
- raid1_conf_t *conf = mddev_to_conf(mddev);
-

- if (conf->resync_mirrors) {
- if (!conf->resync_thread) {


- MD_BUG();
- return 0;
- }

- conf->resync_mirrors = 1;
- md_wakeup_thread(conf->resync_thread);
- return 1;
- }


- return 0;
-}
-

-static int raid1_stop (mddev_t *mddev)


-{
- raid1_conf_t *conf = mddev_to_conf(mddev);
-

- md_unregister_thread(conf->thread);
- if (conf->resync_thread)
- md_unregister_thread(conf->resync_thread);
- raid1_shrink_r1bh(conf);
- raid1_shrink_bh(conf, conf->freebh_cnt);
- raid1_shrink_buffers(conf);
- kfree(conf);


- mddev->private = NULL;
- MOD_DEC_USE_COUNT;
- return 0;
-}
-

-static mdk_personality_t raid1_personality=
-{
- name: "raid1",
- make_request: raid1_make_request,
- run: raid1_run,
- stop: raid1_stop,
- status: raid1_status,
- error_handler: raid1_error,
- diskop: raid1_diskop,
- stop_resync: raid1_stop_resync,
- restart_resync: raid1_restart_resync,
- sync_request: raid1_sync_request
-};
-
-int raid1_init (void)
-{
- return register_md_personality (RAID1, &raid1_personality);
-}


-
-#ifdef MODULE
-int init_module (void)
-{

- return raid1_init();


-}
-
-void cleanup_module (void)
-{

- unregister_md_personality (RAID1);
-}
-#endif
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/block/raid5.c linux/drivers/block/raid5.c
--- v2.4.0-test8/linux/drivers/block/raid5.c Mon Aug 14 08:26:34 2000
+++ linux/drivers/block/raid5.c Wed Dec 31 16:00:00 1969
@@ -1,2371 +0,0 @@
-/*
- * raid5.c : Multiple Devices driver for Linux
- * Copyright (C) 1996, 1997 Ingo Molnar, Miguel de Icaza, Gadi Oxman
- * Copyright (C) 1999, 2000 Ingo Molnar
- *
- * RAID-5 management functions.
- *


- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * You should have received a copy of the GNU General Public License
- * (for example /usr/src/linux/COPYING); if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-

-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/locks.h>
-#include <linux/malloc.h>
-#include <linux/raid/raid5.h>
-#include <asm/bitops.h>
-#include <asm/atomic.h>
-
-static mdk_personality_t raid5_personality;
-
-/*
- * Stripe cache
- */
-
-#define NR_STRIPES 128
-#define HASH_PAGES 1
-#define HASH_PAGES_ORDER 0
-#define NR_HASH (HASH_PAGES * PAGE_SIZE / sizeof(struct stripe_head *))
-#define HASH_MASK (NR_HASH - 1)
-#define stripe_hash(conf, sect, size) ((conf)->stripe_hashtbl[((sect) / (size >> 9)) & HASH_MASK])


-
-/*
- * The following can be used to debug the driver
- */

-#define RAID5_DEBUG 0
-#define RAID5_PARANOIA 1
-#if RAID5_PARANOIA && CONFIG_SMP
-# define CHECK_DEVLOCK() if (!spin_is_locked(&conf->device_lock)) BUG()
-# define CHECK_SHLOCK(sh) if (!stripe_locked(sh)) BUG()
-#else
-# define CHECK_DEVLOCK()
-# define CHECK_SHLOCK(unused)
-#endif
-
-#if RAID5_DEBUG


-#define PRINTK(x...) printk(x)
-#define inline
-#define __inline__
-#else
-#define PRINTK(x...) do { } while (0)
-#endif
-

-static void print_raid5_conf (raid5_conf_t *conf);
-
-static inline int stripe_locked(struct stripe_head *sh)
-{
- return test_bit(STRIPE_LOCKED, &sh->state);
-}
-
-static void __unlock_stripe(struct stripe_head *sh)
-{
- if (!md_test_and_clear_bit(STRIPE_LOCKED, &sh->state))
- BUG();
- PRINTK("unlocking stripe %lu\n", sh->sector);
- wake_up(&sh->wait);
-}
-
-static void finish_unlock_stripe(struct stripe_head *sh)
-{
- raid5_conf_t *conf = sh->raid_conf;
- sh->cmd = STRIPE_NONE;
- sh->phase = PHASE_COMPLETE;
- atomic_dec(&conf->nr_pending_stripes);
- atomic_inc(&conf->nr_cached_stripes);
- __unlock_stripe(sh);
- atomic_dec(&sh->count);
- wake_up(&conf->wait_for_stripe);
-}
-
-static void remove_hash(raid5_conf_t *conf, struct stripe_head *sh)
-{
- PRINTK("remove_hash(), stripe %lu\n", sh->sector);
-
- CHECK_DEVLOCK();
- CHECK_SHLOCK(sh);
- if (sh->hash_pprev) {
- if (sh->hash_next)
- sh->hash_next->hash_pprev = sh->hash_pprev;
- *sh->hash_pprev = sh->hash_next;
- sh->hash_pprev = NULL;
- atomic_dec(&conf->nr_hashed_stripes);
- }
-}
-
-static void lock_get_bh (struct buffer_head *bh)
-{
- while (md_test_and_set_bit(BH_Lock, &bh->b_state))
- __wait_on_buffer(bh);
- atomic_inc(&bh->b_count);
-}
-
-static __inline__ void insert_hash(raid5_conf_t *conf, struct stripe_head *sh)
-{
- struct stripe_head **shp = &stripe_hash(conf, sh->sector, sh->size);
-
- PRINTK("insert_hash(), stripe %lu, nr_hashed_stripes %d\n",
- sh->sector, atomic_read(&conf->nr_hashed_stripes));
-
- CHECK_DEVLOCK();
- CHECK_SHLOCK(sh);
- if ((sh->hash_next = *shp) != NULL)
- (*shp)->hash_pprev = &sh->hash_next;
- *shp = sh;
- sh->hash_pprev = shp;
- atomic_inc(&conf->nr_hashed_stripes);
-}
-
-static struct buffer_head *get_free_buffer(struct stripe_head *sh, int b_size)
-{
- struct buffer_head *bh;


- unsigned long flags;
-

- CHECK_SHLOCK(sh);
- md_spin_lock_irqsave(&sh->stripe_lock, flags);
- bh = sh->buffer_pool;
- if (!bh)
- goto out_unlock;
- sh->buffer_pool = bh->b_next;
- bh->b_size = b_size;
- if (atomic_read(&bh->b_count))
- BUG();
-out_unlock:
- md_spin_unlock_irqrestore(&sh->stripe_lock, flags);


-
- return bh;
-}
-

-static struct buffer_head *get_free_bh(struct stripe_head *sh)
-{
- struct buffer_head *bh;


- unsigned long flags;
-

- CHECK_SHLOCK(sh);
- md_spin_lock_irqsave(&sh->stripe_lock, flags);
- bh = sh->bh_pool;
- if (!bh)
- goto out_unlock;
- sh->bh_pool = bh->b_next;
- if (atomic_read(&bh->b_count))
- BUG();
-out_unlock:
- md_spin_unlock_irqrestore(&sh->stripe_lock, flags);


-
- return bh;
-}
-

-static void put_free_buffer(struct stripe_head *sh, struct buffer_head *bh)
-{
- unsigned long flags;
-
- if (atomic_read(&bh->b_count))
- BUG();
- CHECK_SHLOCK(sh);
- md_spin_lock_irqsave(&sh->stripe_lock, flags);
- bh->b_next = sh->buffer_pool;
- sh->buffer_pool = bh;
- md_spin_unlock_irqrestore(&sh->stripe_lock, flags);
-}
-
-static void put_free_bh(struct stripe_head *sh, struct buffer_head *bh)
-{
- unsigned long flags;
-
- if (atomic_read(&bh->b_count))
- BUG();
- CHECK_SHLOCK(sh);
- md_spin_lock_irqsave(&sh->stripe_lock, flags);
- bh->b_next = sh->bh_pool;
- sh->bh_pool = bh;
- md_spin_unlock_irqrestore(&sh->stripe_lock, flags);
-}
-
-static struct stripe_head *get_free_stripe(raid5_conf_t *conf)
-{
- struct stripe_head *sh;
-
- md_spin_lock_irq(&conf->device_lock);
- sh = conf->free_sh_list;
- if (!sh)
- goto out;
- conf->free_sh_list = sh->free_next;
- atomic_dec(&conf->nr_free_sh);
- if (!atomic_read(&conf->nr_free_sh) && conf->free_sh_list)
- BUG();
- if (sh->hash_pprev || md_atomic_read(&sh->nr_pending) ||
- atomic_read(&sh->count))
- BUG();
-out:
- md_spin_unlock_irq(&conf->device_lock);
- return sh;
-}
-
-static void __put_free_stripe (raid5_conf_t *conf, struct stripe_head *sh)
-{
- if (atomic_read(&sh->count) != 0)
- BUG();
- CHECK_DEVLOCK();
- CHECK_SHLOCK(sh);
- clear_bit(STRIPE_LOCKED, &sh->state);
- sh->free_next = conf->free_sh_list;
- conf->free_sh_list = sh;
- atomic_inc(&conf->nr_free_sh);
-}
-
-static void shrink_buffers(struct stripe_head *sh, int num)
-{
- struct buffer_head *bh;
-
- while (num--) {
- bh = get_free_buffer(sh, -1);
- if (!bh)
- return;
- free_page((unsigned long) bh->b_data);
- kfree(bh);
- }
-}
-
-static void shrink_bh(struct stripe_head *sh, int num)
-{
- struct buffer_head *bh;
-
- while (num--) {
- bh = get_free_bh(sh);
- if (!bh)
- return;
- kfree(bh);
- }
-}
-
-static int grow_raid5_buffers(struct stripe_head *sh, int num, int b_size, int priority)
-{
- struct buffer_head *bh;
-
- while (num--) {
- struct page *page;
- bh = kmalloc(sizeof(struct buffer_head), priority);
- if (!bh)
- return 1;
- memset(bh, 0, sizeof (struct buffer_head));
- init_waitqueue_head(&bh->b_wait);
- page = alloc_page(priority);
- bh->b_data = page_address(page);
- if (!bh->b_data) {
- kfree(bh);
- return 1;
- }
- bh->b_size = b_size;
- atomic_set(&bh->b_count, 0);
- bh->b_page = page;
- put_free_buffer(sh, bh);


- }
- return 0;
-}
-

-static int grow_bh(struct stripe_head *sh, int num, int priority)
-{
- struct buffer_head *bh;
-
- while (num--) {
- bh = kmalloc(sizeof(struct buffer_head), priority);
- if (!bh)
- return 1;
- memset(bh, 0, sizeof (struct buffer_head));
- init_waitqueue_head(&bh->b_wait);
- put_free_bh(sh, bh);


- }
- return 0;
-}
-

-static void raid5_free_buffer(struct stripe_head *sh, struct buffer_head *bh)
-{
- put_free_buffer(sh, bh);
-}
-
-static void raid5_free_bh(struct stripe_head *sh, struct buffer_head *bh)
-{
- put_free_bh(sh, bh);
-}
-
-static void raid5_free_old_bh(struct stripe_head *sh, int i)
-{
- CHECK_SHLOCK(sh);
- if (!sh->bh_old[i])
- BUG();
- raid5_free_buffer(sh, sh->bh_old[i]);
- sh->bh_old[i] = NULL;
-}
-
-static void raid5_update_old_bh(struct stripe_head *sh, int i)
-{
- CHECK_SHLOCK(sh);
- PRINTK("stripe %lu, idx %d, updating cache copy\n", sh->sector, i);
- if (!sh->bh_copy[i])
- BUG();
- if (sh->bh_old[i])
- raid5_free_old_bh(sh, i);
- sh->bh_old[i] = sh->bh_copy[i];
- sh->bh_copy[i] = NULL;
-}
-
-static void free_stripe(struct stripe_head *sh)
-{
- raid5_conf_t *conf = sh->raid_conf;
- int disks = conf->raid_disks, j;
-
- if (atomic_read(&sh->count) != 0)
- BUG();
- CHECK_DEVLOCK();
- CHECK_SHLOCK(sh);
- PRINTK("free_stripe called, stripe %lu\n", sh->sector);
- if (sh->phase != PHASE_COMPLETE || atomic_read(&sh->count)) {
- PRINTK("raid5: free_stripe(), sector %lu, phase %d, count %d\n", sh->sector, sh->phase, atomic_read(&sh->count));
- return;
- }
- for (j = 0; j < disks; j++) {
- if (sh->bh_old[j])
- raid5_free_old_bh(sh, j);
- if (sh->bh_new[j] || sh->bh_copy[j])
- BUG();
- }
- remove_hash(conf, sh);
- __put_free_stripe(conf, sh);
-}
-
-static int shrink_stripe_cache(raid5_conf_t *conf, int nr)
-{
- struct stripe_head *sh;
- int i, count = 0;
-
- PRINTK("shrink_stripe_cache called, %d/%d, clock %d\n", nr, atomic_read(&conf->nr_hashed_stripes), conf->clock);
- md_spin_lock_irq(&conf->device_lock);
- for (i = 0; i < NR_HASH; i++) {
- sh = conf->stripe_hashtbl[(i + conf->clock) & HASH_MASK];
- for (; sh; sh = sh->hash_next) {
- if (sh->phase != PHASE_COMPLETE)
- continue;
- if (atomic_read(&sh->count))
- continue;
- /*
- * Try to lock this stripe:
- */
- if (md_test_and_set_bit(STRIPE_LOCKED, &sh->state))
- continue;
- free_stripe(sh);
- if (++count == nr) {
- conf->clock = (i + conf->clock) & HASH_MASK;


- goto out;
- }
- }
- }

-out:
- md_spin_unlock_irq(&conf->device_lock);
- PRINTK("shrink completed, nr_hashed_stripes %d, nr_pending_strips %d\n",
- atomic_read(&conf->nr_hashed_stripes),
- atomic_read(&conf->nr_pending_stripes));
- return count;
-}
-
-void __wait_lock_stripe(struct stripe_head *sh)
-{
- MD_DECLARE_WAITQUEUE(wait, current);
-
- PRINTK("wait_lock_stripe %lu\n", sh->sector);
- if (!atomic_read(&sh->count))
- BUG();
- add_wait_queue(&sh->wait, &wait);
-repeat:
- set_current_state(TASK_UNINTERRUPTIBLE);
- if (md_test_and_set_bit(STRIPE_LOCKED, &sh->state)) {
- schedule();
- goto repeat;
- }
- PRINTK("wait_lock_stripe %lu done\n", sh->sector);
- remove_wait_queue(&sh->wait, &wait);


- current->state = TASK_RUNNING;
-}

-
-static struct stripe_head *__find_stripe(raid5_conf_t *conf, unsigned long sector, int size)
-{
- struct stripe_head *sh;
-
- PRINTK("__find_stripe, sector %lu\n", sector);
- for (sh = stripe_hash(conf, sector, size); sh; sh = sh->hash_next) {
- if (sh->sector == sector && sh->raid_conf == conf) {
- if (sh->size != size)
- BUG();
- return sh;
- }
- }
- PRINTK("__stripe %lu not in cache\n", sector);


- return NULL;
-}
-

-static inline struct stripe_head *alloc_stripe(raid5_conf_t *conf, unsigned long sector, int size)
-{
- struct stripe_head *sh;
- struct buffer_head *buffer_pool, *bh_pool;
- MD_DECLARE_WAITQUEUE(wait, current);
-
- PRINTK("alloc_stripe called\n");
-
-
- while ((sh = get_free_stripe(conf)) == NULL) {
- int cnt;
- add_wait_queue(&conf->wait_for_stripe, &wait);
- set_current_state(TASK_UNINTERRUPTIBLE);
- cnt = shrink_stripe_cache(conf, conf->max_nr_stripes / 8);
- sh = get_free_stripe(conf);
- if (!sh && cnt < (conf->max_nr_stripes/8)) {
- md_wakeup_thread(conf->thread);
- PRINTK("waiting for some stripes to complete - %d %d\n", cnt, conf->max_nr_stripes/8);
- schedule();
- }
- remove_wait_queue(&conf->wait_for_stripe, &wait);


- current->state = TASK_RUNNING;

- if (sh)
- break;
- }
-
- buffer_pool = sh->buffer_pool;
- bh_pool = sh->bh_pool;
- memset(sh, 0, sizeof(*sh));
- sh->stripe_lock = MD_SPIN_LOCK_UNLOCKED;
- md_init_waitqueue_head(&sh->wait);
- sh->buffer_pool = buffer_pool;
- sh->bh_pool = bh_pool;
- sh->phase = PHASE_COMPLETE;
- sh->cmd = STRIPE_NONE;
- sh->raid_conf = conf;
- sh->sector = sector;
- sh->size = size;
- atomic_inc(&conf->nr_cached_stripes);
-
- return sh;
-}
-
-static struct stripe_head *get_lock_stripe(raid5_conf_t *conf, unsigned long sector, int size)
-{
- struct stripe_head *sh, *new = NULL;
-
- PRINTK("get_stripe, sector %lu\n", sector);
-
- /*
- * Do this in set_blocksize()!
- */
- if (conf->buffer_size != size) {
- PRINTK("switching size, %d --> %d\n", conf->buffer_size, size);
- shrink_stripe_cache(conf, conf->max_nr_stripes);
- conf->buffer_size = size;
- }
-
-repeat:
- md_spin_lock_irq(&conf->device_lock);
- sh = __find_stripe(conf, sector, size);
- if (!sh) {
- if (!new) {
- md_spin_unlock_irq(&conf->device_lock);
- new = alloc_stripe(conf, sector, size);
- goto repeat;
- }
- sh = new;
- new = NULL;
- if (md_test_and_set_bit(STRIPE_LOCKED, &sh->state))
- BUG();
- insert_hash(conf, sh);
- atomic_inc(&sh->count);


- md_spin_unlock_irq(&conf->device_lock);
- } else {

- atomic_inc(&sh->count);
- if (new) {
- if (md_test_and_set_bit(STRIPE_LOCKED, &new->state))
- BUG();
- __put_free_stripe(conf, new);
- }
- md_spin_unlock_irq(&conf->device_lock);
- PRINTK("get_stripe, waiting, sector %lu\n", sector);
- if (md_test_and_set_bit(STRIPE_LOCKED, &sh->state))
- __wait_lock_stripe(sh);
- }
- return sh;
-}
-
-static int grow_stripes(raid5_conf_t *conf, int num, int priority)
-{
- struct stripe_head *sh;
-
- while (num--) {
- sh = kmalloc(sizeof(struct stripe_head), priority);
- if (!sh)
- return 1;
- memset(sh, 0, sizeof(*sh));
- sh->raid_conf = conf;
- sh->stripe_lock = MD_SPIN_LOCK_UNLOCKED;
- md_init_waitqueue_head(&sh->wait);
-
- if (md_test_and_set_bit(STRIPE_LOCKED, &sh->state))
- BUG();
- if (grow_raid5_buffers(sh, 2 * conf->raid_disks, PAGE_SIZE, priority)) {
- shrink_buffers(sh, 2 * conf->raid_disks);
- kfree(sh);
- return 1;
- }
- if (grow_bh(sh, conf->raid_disks, priority)) {
- shrink_buffers(sh, 2 * conf->raid_disks);
- shrink_bh(sh, conf->raid_disks);
- kfree(sh);
- return 1;
- }
- md_spin_lock_irq(&conf->device_lock);
- __put_free_stripe(conf, sh);
- atomic_inc(&conf->nr_stripes);
- md_spin_unlock_irq(&conf->device_lock);
- }


- return 0;
-}
-

-static void shrink_stripes(raid5_conf_t *conf, int num)
-{
- struct stripe_head *sh;
-
- while (num--) {
- sh = get_free_stripe(conf);
- if (!sh)
- break;
- if (md_test_and_set_bit(STRIPE_LOCKED, &sh->state))
- BUG();
- shrink_buffers(sh, conf->raid_disks * 2);
- shrink_bh(sh, conf->raid_disks);
- kfree(sh);
- atomic_dec(&conf->nr_stripes);
- }
-}
-
-
-static struct buffer_head *raid5_alloc_buffer(struct stripe_head *sh, int b_size)
-{
- struct buffer_head *bh;
-
- bh = get_free_buffer(sh, b_size);
- if (!bh)
- BUG();


- return bh;
-}
-

-static struct buffer_head *raid5_alloc_bh(struct stripe_head *sh)
-{
- struct buffer_head *bh;
-
- bh = get_free_bh(sh);
- if (!bh)
- BUG();


- return bh;
-}
-

-static void raid5_end_buffer_io (struct stripe_head *sh, int i, int uptodate)
-{
- struct buffer_head *bh = sh->bh_new[i];
-
- PRINTK("raid5_end_buffer_io %lu, uptodate: %d.\n", bh->b_blocknr, uptodate);
- sh->bh_new[i] = NULL;
- raid5_free_bh(sh, sh->bh_req[i]);
- sh->bh_req[i] = NULL;
- PRINTK("calling %p->end_io: %p.\n", bh, bh->b_end_io);
- bh->b_end_io(bh, uptodate);
- if (!uptodate)
- printk(KERN_ALERT "raid5: %s: unrecoverable I/O error for "
- "block %lu\n",
- partition_name(mddev_to_kdev(sh->raid_conf->mddev)),
- bh->b_blocknr);
-}
-
-static inline void raid5_mark_buffer_uptodate (struct buffer_head *bh, int uptodate)
-{
- if (uptodate)
- set_bit(BH_Uptodate, &bh->b_state);
- else
- clear_bit(BH_Uptodate, &bh->b_state);
-}
-
-static void raid5_end_request (struct buffer_head * bh, int uptodate)
-{
- struct stripe_head *sh = bh->b_private;
- raid5_conf_t *conf = sh->raid_conf;
- int disks = conf->raid_disks, i;


- unsigned long flags;
-

- PRINTK("end_request %lu, nr_pending %d, uptodate: %d, (caller: %p,%p,%p,%p).\n", sh->sector, atomic_read(&sh->nr_pending), uptodate, __builtin_return_address(0),__builtin_return_address(1),__builtin_return_address(2), __builtin_return_address(3));
- md_spin_lock_irqsave(&sh->stripe_lock, flags);
- raid5_mark_buffer_uptodate(bh, uptodate);
- if (!uptodate)
- md_error(mddev_to_kdev(conf->mddev), bh->b_dev);
- if (conf->failed_disks) {


- for (i = 0; i < disks; i++) {

- if (conf->disks[i].operational)
- continue;
- if (bh != sh->bh_old[i] && bh != sh->bh_req[i] && bh != sh->bh_copy[i])
- continue;
- if (bh->b_dev != conf->disks[i].dev)
- continue;
- set_bit(STRIPE_ERROR, &sh->state);
- }
- }
- md_spin_unlock_irqrestore(&sh->stripe_lock, flags);
-
- if (atomic_dec_and_test(&sh->nr_pending)) {
- atomic_inc(&conf->nr_handle);


- md_wakeup_thread(conf->thread);
- }
-}
-

-static void raid5_build_block (struct stripe_head *sh, struct buffer_head *bh, int i)
-{
- raid5_conf_t *conf = sh->raid_conf;
- char *b_data;
- struct page *b_page;
- unsigned long block = sh->sector / (sh->size >> 9);
-
- b_data = bh->b_data;
- b_page = bh->b_page;
- memset (bh, 0, sizeof (struct buffer_head));
- init_waitqueue_head(&bh->b_wait);
- init_buffer(bh, raid5_end_request, sh);
- bh->b_dev = conf->disks[i].dev;
- bh->b_blocknr = block;
-
- bh->b_data = b_data;
- bh->b_page = b_page;
-
- bh->b_rdev = conf->disks[i].dev;
- bh->b_rsector = sh->sector;
-
- bh->b_state = (1 << BH_Req) | (1 << BH_Mapped);
- bh->b_size = sh->size;
- bh->b_list = BUF_LOCKED;
-}
-
-static int raid5_error (mddev_t *mddev, kdev_t dev)
-{
- raid5_conf_t *conf = (raid5_conf_t *) mddev->private;


- mdp_super_t *sb = mddev->sb;

- struct disk_info *disk;
- int i;
-
- PRINTK("raid5_error called\n");
- conf->resync_parity = 0;
- for (i = 0, disk = conf->disks; i < conf->raid_disks; i++, disk++) {
- if (disk->dev == dev && disk->operational) {
- disk->operational = 0;
- mark_disk_faulty(sb->disks+disk->number);
- mark_disk_nonsync(sb->disks+disk->number);
- mark_disk_inactive(sb->disks+disk->number);


- sb->active_disks--;
- sb->working_disks--;
- sb->failed_disks++;
- mddev->sb_dirty = 1;

- conf->working_disks--;
- conf->failed_disks++;
- md_wakeup_thread(conf->thread);
- printk (KERN_ALERT
- "raid5: Disk failure on %s, disabling device."
- " Operation continuing on %d devices\n",
- partition_name (dev), conf->working_disks);


- return 0;
- }
- }
- /*

- * handle errors in spares (during reconstruction)
- */
- if (conf->spare) {
- disk = conf->spare;
- if (disk->dev == dev) {
- printk (KERN_ALERT
- "raid5: Disk failure on spare %s\n",
- partition_name (dev));
- if (!conf->spare->operational) {
- MD_BUG();
- return -EIO;
- }
- disk->operational = 0;
- disk->write_only = 0;
- conf->spare = NULL;
- mark_disk_faulty(sb->disks+disk->number);
- mark_disk_nonsync(sb->disks+disk->number);
- mark_disk_inactive(sb->disks+disk->number);


- sb->spare_disks--;
- sb->working_disks--;
- sb->failed_disks++;
-

- return 0;
- }
- }

- MD_BUG();
- return -EIO;
-}
-
-/*
- * Input: a 'big' sector number,
- * Output: index of the data and parity disk, and the sector # in them.
- */
-static unsigned long raid5_compute_sector(unsigned long r_sector, unsigned int raid_disks,
- unsigned int data_disks, unsigned int * dd_idx,
- unsigned int * pd_idx, raid5_conf_t *conf)
-{
- unsigned long stripe;
- unsigned long chunk_number;
- unsigned int chunk_offset;
- unsigned long new_sector;
- int sectors_per_chunk = conf->chunk_size >> 9;
-
- /* First compute the information on this sector */
-
- /*
- * Compute the chunk number and the sector offset inside the chunk
- */
- chunk_number = r_sector / sectors_per_chunk;
- chunk_offset = r_sector % sectors_per_chunk;
-
- /*
- * Compute the stripe number
- */
- stripe = chunk_number / data_disks;
-
- /*
- * Compute the data disk and parity disk indexes inside the stripe
- */
- *dd_idx = chunk_number % data_disks;
-
- /*
- * Select the parity disk based on the user selected algorithm.
- */
- if (conf->level == 4)
- *pd_idx = data_disks;
- else switch (conf->algorithm) {
- case ALGORITHM_LEFT_ASYMMETRIC:
- *pd_idx = data_disks - stripe % raid_disks;
- if (*dd_idx >= *pd_idx)
- (*dd_idx)++;
- break;
- case ALGORITHM_RIGHT_ASYMMETRIC:
- *pd_idx = stripe % raid_disks;
- if (*dd_idx >= *pd_idx)
- (*dd_idx)++;
- break;
- case ALGORITHM_LEFT_SYMMETRIC:
- *pd_idx = data_disks - stripe % raid_disks;
- *dd_idx = (*pd_idx + 1 + *dd_idx) % raid_disks;
- break;
- case ALGORITHM_RIGHT_SYMMETRIC:
- *pd_idx = stripe % raid_disks;
- *dd_idx = (*pd_idx + 1 + *dd_idx) % raid_disks;
- break;
- default:
- printk ("raid5: unsupported algorithm %d\n", conf->algorithm);
- }
-
- /*
- * Finally, compute the new sector number
- */
- new_sector = stripe * sectors_per_chunk + chunk_offset;
- return new_sector;
-}
-
-static unsigned long compute_blocknr(struct stripe_head *sh, int i)
-{
- raid5_conf_t *conf = sh->raid_conf;
- int raid_disks = conf->raid_disks, data_disks = raid_disks - 1;
- unsigned long new_sector = sh->sector, check;
- int sectors_per_chunk = conf->chunk_size >> 9;
- unsigned long stripe = new_sector / sectors_per_chunk;
- int chunk_offset = new_sector % sectors_per_chunk;
- int chunk_number, dummy1, dummy2, dd_idx = i;
- unsigned long r_sector, blocknr;
-
- switch (conf->algorithm) {
- case ALGORITHM_LEFT_ASYMMETRIC:
- case ALGORITHM_RIGHT_ASYMMETRIC:
- if (i > sh->pd_idx)
- i--;
- break;
- case ALGORITHM_LEFT_SYMMETRIC:
- case ALGORITHM_RIGHT_SYMMETRIC:
- if (i < sh->pd_idx)
- i += raid_disks;
- i -= (sh->pd_idx + 1);
- break;
- default:
- printk ("raid5: unsupported algorithm %d\n", conf->algorithm);
- }
-
- chunk_number = stripe * data_disks + i;
- r_sector = chunk_number * sectors_per_chunk + chunk_offset;
- blocknr = r_sector / (sh->size >> 9);
-
- check = raid5_compute_sector (r_sector, raid_disks, data_disks, &dummy1, &dummy2, conf);
- if (check != sh->sector || dummy1 != dd_idx || dummy2 != sh->pd_idx) {
- printk("compute_blocknr: map not correct\n");
- return 0;
- }
- return blocknr;
-}
-
-static void compute_block(struct stripe_head *sh, int dd_idx)
-{
- raid5_conf_t *conf = sh->raid_conf;
- int i, count, disks = conf->raid_disks;
- struct buffer_head *bh_ptr[MAX_XOR_BLOCKS];
-
- PRINTK("compute_block, stripe %lu, idx %d\n", sh->sector, dd_idx);
-
- if (sh->bh_old[dd_idx] == NULL)
- sh->bh_old[dd_idx] = raid5_alloc_buffer(sh, sh->size);
- raid5_build_block(sh, sh->bh_old[dd_idx], dd_idx);
-
- memset(sh->bh_old[dd_idx]->b_data, 0, sh->size);
- bh_ptr[0] = sh->bh_old[dd_idx];
- count = 1;


- for (i = 0; i < disks; i++) {

- if (i == dd_idx)
- continue;
- if (sh->bh_old[i]) {
- bh_ptr[count++] = sh->bh_old[i];
- } else {
- printk("compute_block() %d, stripe %lu, %d not present\n", dd_idx, sh->sector, i);
- }
- if (count == MAX_XOR_BLOCKS) {
- xor_block(count, &bh_ptr[0]);
- count = 1;
- }
- }
- if (count != 1)
- xor_block(count, &bh_ptr[0]);
- raid5_mark_buffer_uptodate(sh->bh_old[dd_idx], 1);
-}
-
-static void compute_parity(struct stripe_head *sh, int method)
-{
- raid5_conf_t *conf = sh->raid_conf;
- int i, pd_idx = sh->pd_idx, disks = conf->raid_disks, count;
- struct buffer_head *bh_ptr[MAX_XOR_BLOCKS];
-
- PRINTK("compute_parity, stripe %lu, method %d\n", sh->sector, method);


- for (i = 0; i < disks; i++) {

- if (i == pd_idx || !sh->bh_new[i])
- continue;
- if (!sh->bh_copy[i])
- sh->bh_copy[i] = raid5_alloc_buffer(sh, sh->size);
- raid5_build_block(sh, sh->bh_copy[i], i);
- atomic_set_buffer_dirty(sh->bh_copy[i]);
- memcpy(sh->bh_copy[i]->b_data, sh->bh_new[i]->b_data, sh->size);
- }
- if (sh->bh_copy[pd_idx] == NULL) {
- sh->bh_copy[pd_idx] = raid5_alloc_buffer(sh, sh->size);
- atomic_set_buffer_dirty(sh->bh_copy[pd_idx]);
- }
- raid5_build_block(sh, sh->bh_copy[pd_idx], sh->pd_idx);
-
- if (method == RECONSTRUCT_WRITE) {
- memset(sh->bh_copy[pd_idx]->b_data, 0, sh->size);
- bh_ptr[0] = sh->bh_copy[pd_idx];
- count = 1;


- for (i = 0; i < disks; i++) {

- if (i == sh->pd_idx)
- continue;
- if (sh->bh_new[i]) {
- bh_ptr[count++] = sh->bh_copy[i];
- } else if (sh->bh_old[i]) {
- bh_ptr[count++] = sh->bh_old[i];
- }
- if (count == MAX_XOR_BLOCKS) {
- xor_block(count, &bh_ptr[0]);
- count = 1;
- }
- }
- if (count != 1) {
- xor_block(count, &bh_ptr[0]);
- }
- } else if (method == READ_MODIFY_WRITE) {
- memcpy(sh->bh_copy[pd_idx]->b_data, sh->bh_old[pd_idx]->b_data, sh->size);
- bh_ptr[0] = sh->bh_copy[pd_idx];
- count = 1;


- for (i = 0; i < disks; i++) {

- if (i == sh->pd_idx)
- continue;
- if (sh->bh_new[i] && sh->bh_old[i]) {
- bh_ptr[count++] = sh->bh_copy[i];
- bh_ptr[count++] = sh->bh_old[i];
- }
- if (count >= (MAX_XOR_BLOCKS - 1)) {
- xor_block(count, &bh_ptr[0]);
- count = 1;
- }
- }
- if (count != 1) {
- xor_block(count, &bh_ptr[0]);
- }
- }
- raid5_mark_buffer_uptodate(sh->bh_copy[pd_idx], 1);
-}
-
-static void add_stripe_bh (struct stripe_head *sh, struct buffer_head *bh, int dd_idx, int rw)
-{
- raid5_conf_t *conf = sh->raid_conf;
- struct buffer_head *bh_req;
-
- PRINTK("adding bh b#%lu to stripe s#%lu\n", bh->b_blocknr, sh->sector);
- CHECK_SHLOCK(sh);
- if (sh->bh_new[dd_idx])
- BUG();
-
- bh_req = raid5_alloc_bh(sh);
- raid5_build_block(sh, bh_req, dd_idx);
- bh_req->b_data = bh->b_data;
- bh_req->b_page = bh->b_page;
-
- md_spin_lock_irq(&conf->device_lock);
- if (sh->phase == PHASE_COMPLETE && sh->cmd == STRIPE_NONE) {
- PRINTK("stripe s#%lu => PHASE_BEGIN (%s)\n", sh->sector, rw == READ ? "read" : "write");
- sh->phase = PHASE_BEGIN;
- sh->cmd = (rw == READ) ? STRIPE_READ : STRIPE_WRITE;
- atomic_inc(&conf->nr_pending_stripes);
- atomic_inc(&conf->nr_handle);
- PRINTK("# of pending stripes: %u, # of handle: %u\n", atomic_read(&conf->nr_pending_stripes), atomic_read(&conf->nr_handle));
- }
- sh->bh_new[dd_idx] = bh;
- sh->bh_req[dd_idx] = bh_req;
- sh->cmd_new[dd_idx] = rw;
- sh->new[dd_idx] = 1;
- md_spin_unlock_irq(&conf->device_lock);
-
- PRINTK("added bh b#%lu to stripe s#%lu, disk %d.\n", bh->b_blocknr, sh->sector, dd_idx);
-}
-
-static void complete_stripe(struct stripe_head *sh)
-{
- raid5_conf_t *conf = sh->raid_conf;
- int disks = conf->raid_disks;
- int i, new = 0;
-
- PRINTK("complete_stripe %lu\n", sh->sector);


- for (i = 0; i < disks; i++) {

- if (sh->cmd == STRIPE_SYNC && sh->bh_copy[i])
- raid5_update_old_bh(sh, i);
- if (sh->cmd == STRIPE_WRITE && i == sh->pd_idx)
- raid5_update_old_bh(sh, i);
- if (sh->bh_new[i]) {
- PRINTK("stripe %lu finishes new bh, sh->new == %d\n", sh->sector, sh->new[i]);
- if (!sh->new[i]) {
-#if 0
- if (sh->cmd == STRIPE_WRITE) {
- if (memcmp(sh->bh_new[i]->b_data, sh->bh_copy[i]->b_data, sh->size)) {
- printk("copy differs, %s, sector %lu ",
- test_bit(BH_Dirty, &sh->bh_new[i]->b_state) ? "dirty" : "clean",
- sh->sector);
- } else if (test_bit(BH_Dirty, &sh->bh_new[i]->b_state))
- printk("sector %lu dirty\n", sh->sector);
- }
-#endif
- if (sh->cmd == STRIPE_WRITE)
- raid5_update_old_bh(sh, i);
- raid5_end_buffer_io(sh, i, 1);
- continue;
- } else
- new++;
- }
- if (new && sh->cmd == STRIPE_WRITE)
- printk("raid5: bug, completed STRIPE_WRITE with new == %d\n", new);
- }
- if (sh->cmd == STRIPE_SYNC)
- md_done_sync(conf->mddev, (sh->size>>10) - sh->sync_redone,1);
- if (!new)
- finish_unlock_stripe(sh);
- else {
- PRINTK("stripe %lu, new == %d\n", sh->sector, new);
- sh->phase = PHASE_BEGIN;
- }
-}
-
-
-static void handle_stripe_write (mddev_t *mddev , raid5_conf_t *conf,
- struct stripe_head *sh, int nr_write, int * operational, int disks,
- int parity, int parity_failed, int nr_cache, int nr_cache_other,
- int nr_failed_other, int nr_cache_overwrite, int nr_failed_overwrite)
-{
- int i;
- unsigned int block;
- struct buffer_head *bh;
- int method1 = INT_MAX, method2 = INT_MAX;
-
- /*
- * Attempt to add entries :-)
- */
- if (nr_write != disks - 1) {


- for (i = 0; i < disks; i++) {

- if (i == sh->pd_idx)
- continue;
- if (sh->bh_new[i])
- continue;
- block = (int) compute_blocknr(sh, i);
- bh = get_hash_table(mddev_to_kdev(mddev), block, sh->size);
- if (!bh)
- continue;
- if (buffer_dirty(bh) && !md_test_and_set_bit(BH_Lock, &bh->b_state)) {
- PRINTK("Whee.. sector %lu, index %d (%d) found in the buffer cache!\n", sh->sector, i, block);
- add_stripe_bh(sh, bh, i, WRITE);
- sh->new[i] = 0;
- nr_write++;
- if (sh->bh_old[i]) {
- nr_cache_overwrite++;
- nr_cache_other--;
- } else
- if (!operational[i]) {
- nr_failed_overwrite++;
- nr_failed_other--;
- }
- }
- atomic_dec(&bh->b_count);
- }
- }
- PRINTK("handle_stripe() -- begin writing, stripe %lu\n", sh->sector);
- /*
- * Writing, need to update parity buffer.
- *
- * Compute the number of I/O requests in the "reconstruct
- * write" and "read modify write" methods.
- */
- if (!nr_failed_other)
- method1 = (disks - 1) - (nr_write + nr_cache_other);
- if (!nr_failed_overwrite && !parity_failed)
- method2 = nr_write - nr_cache_overwrite + (1 - parity);
-
- if (method1 == INT_MAX && method2 == INT_MAX)
- BUG();
- PRINTK("handle_stripe(), sector %lu, nr_write %d, method1 %d, method2 %d\n", sh->sector, nr_write, method1, method2);
-
- if (!method1 || !method2) {
- sh->phase = PHASE_WRITE;
- compute_parity(sh, method1 <= method2 ? RECONSTRUCT_WRITE : READ_MODIFY_WRITE);


-
- for (i = 0; i < disks; i++) {

- if (!operational[i] && !conf->spare && !conf->resync_parity)
- continue;
- bh = sh->bh_copy[i];
- if (i != sh->pd_idx && ((bh == NULL) ^ (sh->bh_new[i] == NULL)))
- printk("raid5: bug: bh == %p, bh_new[%d] == %p\n", bh, i, sh->bh_new[i]);
- if (i == sh->pd_idx && !bh)
- printk("raid5: bug: bh == NULL, i == pd_idx == %d\n", i);
- if (bh) {
- PRINTK("making request for buffer %d\n", i);
- lock_get_bh(bh);
- if (!operational[i] && !conf->resync_parity) {
- PRINTK("writing spare %d\n", i);
- atomic_inc(&sh->nr_pending);
- bh->b_dev = bh->b_rdev = conf->spare->dev;
- generic_make_request(WRITE, bh);
- } else {
- atomic_inc(&sh->nr_pending);
- bh->b_dev = bh->b_rdev = conf->disks[i].dev;
- generic_make_request(WRITE, bh);
- }
- atomic_dec(&bh->b_count);
- }
- }
- PRINTK("handle_stripe() %lu, writing back %d buffers\n", sh->sector, md_atomic_read(&sh->nr_pending));
- return;
- }
-
- if (method1 < method2) {
- sh->write_method = RECONSTRUCT_WRITE;


- for (i = 0; i < disks; i++) {

- if (i == sh->pd_idx)
- continue;
- if (sh->bh_new[i] || sh->bh_old[i])
- continue;
- sh->bh_old[i] = raid5_alloc_buffer(sh, sh->size);
- raid5_build_block(sh, sh->bh_old[i], i);
- }
- } else {
- sh->write_method = READ_MODIFY_WRITE;


- for (i = 0; i < disks; i++) {

- if (sh->bh_old[i])
- continue;
- if (!sh->bh_new[i] && i != sh->pd_idx)
- continue;
- sh->bh_old[i] = raid5_alloc_buffer(sh, sh->size);
- raid5_build_block(sh, sh->bh_old[i], i);


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 044'
echo 'File patch-2.4.0-test9 is continued in part 045'
echo "045" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part045

#!/bin/sh -x
# this is part 045 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 045; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&
- }

- }
- sh->phase = PHASE_READ_OLD;


- for (i = 0; i < disks; i++) {

- if (!sh->bh_old[i])

- continue;
- if (test_bit(BH_Uptodate, &sh->bh_old[i]->b_state))
- continue;
- lock_get_bh(sh->bh_old[i]);
- atomic_inc(&sh->nr_pending);
- sh->bh_old[i]->b_dev = sh->bh_old[i]->b_rdev = conf->disks[i].dev;
- generic_make_request(READ, sh->bh_old[i]);
- atomic_dec(&sh->bh_old[i]->b_count);
- }
- PRINTK("handle_stripe() %lu, reading %d old buffers\n", sh->sector, md_atomic_read(&sh->nr_pending));
-}
-
-/*
- * Reading
- */
-static void handle_stripe_read (mddev_t *mddev , raid5_conf_t *conf,
- struct stripe_head *sh, int nr_read, int * operational, int disks,


- int parity, int parity_failed, int nr_cache, int nr_cache_other,
- int nr_failed_other, int nr_cache_overwrite, int nr_failed_overwrite)
-{
- int i;

- int method1 = INT_MAX;
-
- method1 = nr_read - nr_cache_overwrite;
-
- PRINTK("handle_stripe(), sector %lu, nr_read %d, nr_cache %d, method1 %d\n", sh->sector, nr_read, nr_cache, method1);
-
- if (!method1 || (method1 == 1 && nr_cache == disks - 1)) {
- PRINTK("read %lu completed from cache\n", sh->sector);


- for (i = 0; i < disks; i++) {

- if (!sh->bh_new[i])
- continue;
- if (!sh->bh_old[i])
- compute_block(sh, i);
- memcpy(sh->bh_new[i]->b_data, sh->bh_old[i]->b_data, sh->size);
- }
- complete_stripe(sh);
- return;
- }
- if (nr_failed_overwrite) {
- sh->phase = PHASE_READ_OLD;


- for (i = 0; i < disks; i++) {
- if (sh->bh_old[i])
- continue;

- if (!operational[i])


- continue;
- sh->bh_old[i] = raid5_alloc_buffer(sh, sh->size);
- raid5_build_block(sh, sh->bh_old[i], i);

- lock_get_bh(sh->bh_old[i]);
- atomic_inc(&sh->nr_pending);
- sh->bh_old[i]->b_dev = sh->bh_old[i]->b_rdev = conf->disks[i].dev;
- generic_make_request(READ, sh->bh_old[i]);
- atomic_dec(&sh->bh_old[i]->b_count);
- }
- PRINTK("handle_stripe() %lu, phase READ_OLD, pending %d buffers\n", sh->sector, md_atomic_read(&sh->nr_pending));
- return;
- }
- sh->phase = PHASE_READ;


- for (i = 0; i < disks; i++) {

- if (!sh->bh_new[i])
- continue;


- if (sh->bh_old[i]) {

- memcpy(sh->bh_new[i]->b_data, sh->bh_old[i]->b_data, sh->size);
- continue;
- }
-#if RAID5_PARANOIA
- if (sh->bh_req[i] == NULL || test_bit(BH_Lock, &sh->bh_req[i]->b_state)) {
- int j;
- printk("req %d is NULL! or locked \n", i);
- for (j=0; j<disks; j++) {
- printk("%d: new=%p old=%p req=%p new=%d cmd=%d\n",
- j, sh->bh_new[j], sh->bh_old[j], sh->bh_req[j],
- sh->new[j], sh->cmd_new[j]);
- }
-
- }
-#endif
- lock_get_bh(sh->bh_req[i]);
- atomic_inc(&sh->nr_pending);
- sh->bh_req[i]->b_dev = sh->bh_req[i]->b_rdev = conf->disks[i].dev;
- generic_make_request(READ, sh->bh_req[i]);
- atomic_dec(&sh->bh_req[i]->b_count);
- }
- PRINTK("handle_stripe() %lu, phase READ, pending %d\n", sh->sector, md_atomic_read(&sh->nr_pending));
-}
-
-/*
- * Syncing
- */
-static void handle_stripe_sync (mddev_t *mddev , raid5_conf_t *conf,
- struct stripe_head *sh, int * operational, int disks,


- int parity, int parity_failed, int nr_cache, int nr_cache_other,
- int nr_failed_other, int nr_cache_overwrite, int nr_failed_overwrite)
-{

- struct buffer_head *bh;
- int i, pd_idx;
-
- /* firstly, we want to have data from all non-failed drives
- * in bh_old
- */
- PRINTK("handle_stripe_sync: sec=%lu disks=%d nr_cache=%d\n", sh->sector, disks, nr_cache);
- if ((nr_cache < disks-1) || ((nr_cache == disks-1) && !(parity_failed+nr_failed_other+nr_failed_overwrite))
- ) {
- sh->phase = PHASE_READ_OLD;


- for (i = 0; i < disks; i++) {
- if (sh->bh_old[i])
- continue;

- if (!conf->disks[i].operational)
- continue;
-
- bh = raid5_alloc_buffer(sh, sh->size);
- sh->bh_old[i] = bh;
- raid5_build_block(sh, bh, i);
- lock_get_bh(bh);


- atomic_inc(&sh->nr_pending);
- bh->b_dev = bh->b_rdev = conf->disks[i].dev;

- generic_make_request(READ, bh);
- md_sync_acct(bh->b_rdev, bh->b_size/512);

- atomic_dec(&sh->bh_old[i]->b_count);
- }
- PRINTK("handle_stripe_sync() %lu, phase READ_OLD, pending %d buffers\n", sh->sector, md_atomic_read(&sh->nr_pending));
-
- return;
- }
- /* now, if there is a failed drive, rebuild and write to spare */
- if (nr_cache == disks-1) {


- sh->phase = PHASE_WRITE;

- /* we can generate the missing block, which will be on the failed drive */
- for (i=0; i<disks; i++) {
- if (operational[i])
- continue;
- compute_block(sh, i);
- if (conf->spare) {


- bh = sh->bh_copy[i];

- if (bh) {
- memcpy(bh->b_data, sh->bh_old[i]->b_data, sh->size);


- set_bit(BH_Uptodate, &bh->b_state);
- } else {

- bh = sh->bh_old[i];


- sh->bh_old[i] = NULL;

- sh->bh_copy[i] = bh;
- }
- atomic_inc(&sh->nr_pending);
- lock_get_bh(bh);


- bh->b_dev = bh->b_rdev = conf->spare->dev;
- generic_make_request(WRITE, bh);

- md_sync_acct(bh->b_rdev, bh->b_size/512);

- atomic_dec(&bh->b_count);
- PRINTK("handle_stripe_sync() %lu, phase WRITE, pending %d buffers\n", sh->sector, md_atomic_read(&sh->nr_pending));
- }
- break;
- }
- return;
- }
-
- /* nr_cache == disks:
- * check parity and compute/write if needed
- */
-
- compute_parity(sh, RECONSTRUCT_WRITE);
- pd_idx = sh->pd_idx;
- if (!memcmp(sh->bh_copy[pd_idx]->b_data, sh->bh_old[pd_idx]->b_data, sh->size)) {
- /* the parity is correct - Yay! */
- complete_stripe(sh);
- } else {


- sh->phase = PHASE_WRITE;

- bh = sh->bh_copy[pd_idx];
- atomic_set_buffer_dirty(bh);
- lock_get_bh(bh);
- atomic_inc(&sh->nr_pending);
- bh->b_dev = bh->b_rdev = conf->disks[pd_idx].dev;
- generic_make_request(WRITE, bh);


- md_sync_acct(bh->b_rdev, bh->b_size/512);

- atomic_dec(&bh->b_count);
- PRINTK("handle_stripe_sync() %lu phase WRITE, pending %d buffers\n",
- sh->sector, md_atomic_read(&sh->nr_pending));
- }
-}
-
-/*
- * handle_stripe() is our main logic routine. Note that:
- *
- * 1. lock_stripe() should be used whenever we can't accept additonal
- * buffers, either during short sleeping in handle_stripe() or
- * during io operations.
- *
- * 2. We should be careful to set sh->nr_pending whenever we sleep,
- * to prevent re-entry of handle_stripe() for the same sh.
- *
- * 3. conf->failed_disks and disk->operational can be changed
- * from an interrupt. This complicates things a bit, but it allows
- * us to stop issuing requests for a failed drive as soon as possible.
- */
-static void handle_stripe(struct stripe_head *sh)


-{
- raid5_conf_t *conf = sh->raid_conf;

- mddev_t *mddev = conf->mddev;

- int disks = conf->raid_disks;

- int i, nr_read = 0, nr_write = 0, parity = 0;
- int nr_cache = 0, nr_cache_other = 0, nr_cache_overwrite = 0;
- int nr_failed_other = 0, nr_failed_overwrite = 0, parity_failed = 0;
- int operational[MD_SB_DISKS], failed_disks = conf->failed_disks;
-
- PRINTK("handle_stripe(), stripe %lu\n", sh->sector);
- if (!stripe_locked(sh))
- BUG();
- if (md_atomic_read(&sh->nr_pending))
- BUG();
- if (sh->phase == PHASE_COMPLETE)
- BUG();
-
- atomic_dec(&conf->nr_handle);
-
- if (md_test_and_clear_bit(STRIPE_ERROR, &sh->state)) {
- printk("raid5: restarting stripe %lu\n", sh->sector);


- sh->phase = PHASE_BEGIN;
- }
-

- if ((sh->cmd == STRIPE_WRITE && sh->phase == PHASE_WRITE) ||
- (sh->cmd == STRIPE_READ && sh->phase == PHASE_READ) ||
- (sh->cmd == STRIPE_SYNC && sh->phase == PHASE_WRITE)
- ) {
- /*
- * Completed
- */
- complete_stripe(sh);
- if (sh->phase == PHASE_COMPLETE)
- return;
- }
-
- md_spin_lock_irq(&conf->device_lock);
- for (i = 0; i < disks; i++) {
- operational[i] = conf->disks[i].operational;
- if (i == sh->pd_idx && conf->resync_parity)
- operational[i] = 0;
- }
- failed_disks = conf->failed_disks;
- md_spin_unlock_irq(&conf->device_lock);
-
- /*
- * Make this one more graceful?
- */
- if (failed_disks > 1) {


- for (i = 0; i < disks; i++) {

- if (sh->bh_new[i]) {

- raid5_end_buffer_io(sh, i, 0);
- continue;
- }
- }


- if (sh->cmd == STRIPE_SYNC)
- md_done_sync(conf->mddev, (sh->size>>10) - sh->sync_redone,1);

- finish_unlock_stripe(sh);
- return;
- }
-
- PRINTK("=== stripe index START ===\n");


- for (i = 0; i < disks; i++) {

- PRINTK("disk %d, ", i);


- if (sh->bh_old[i]) {

- nr_cache++;
- PRINTK(" (old cached, %d)", nr_cache);
- }


- if (i == sh->pd_idx) {

- PRINTK(" PARITY.");


- if (sh->bh_old[i]) {

- PRINTK(" CACHED.");
- parity = 1;
- } else {
- PRINTK(" UNCACHED.");


- if (!operational[i]) {

- PRINTK(" FAILED.");
- parity_failed = 1;
- }
- }
- PRINTK("\n");
- continue;
- }
- if (!sh->bh_new[i]) {
- PRINTK(" (no new data block) ");


- if (sh->bh_old[i]) {

- PRINTK(" (but old block cached) ");
- nr_cache_other++;


- } else {
- if (!operational[i]) {

- PRINTK(" (because failed disk) ");
- nr_failed_other++;
- } else
- PRINTK(" (no old block either) ");
- }
- PRINTK("\n");
- continue;
- }


- sh->new[i] = 0;

- if (sh->cmd_new[i] == READ) {
- nr_read++;
- PRINTK(" (new READ %d)", nr_read);
- }
- if (sh->cmd_new[i] == WRITE) {
- nr_write++;
- PRINTK(" (new WRITE %d)", nr_write);
- }


- if (sh->bh_old[i]) {
- nr_cache_overwrite++;

- PRINTK(" (overwriting old %d)", nr_cache_overwrite);


- } else {
- if (!operational[i]) {
- nr_failed_overwrite++;

- PRINTK(" (overwriting failed %d)", nr_failed_overwrite);
- }
- }
- PRINTK("\n");
- }
- PRINTK("=== stripe index END ===\n");
-
- if (nr_write && nr_read)
- BUG();
-
- if (nr_write)
- handle_stripe_write(
- mddev, conf, sh, nr_write, operational, disks,
- parity, parity_failed, nr_cache, nr_cache_other,
- nr_failed_other, nr_cache_overwrite,
- nr_failed_overwrite
- );
- else if (nr_read)
- handle_stripe_read(
- mddev, conf, sh, nr_read, operational, disks,
- parity, parity_failed, nr_cache, nr_cache_other,
- nr_failed_other, nr_cache_overwrite,
- nr_failed_overwrite
- );
- else if (sh->cmd == STRIPE_SYNC)
- handle_stripe_sync(
- mddev, conf, sh, operational, disks,
- parity, parity_failed, nr_cache, nr_cache_other,
- nr_failed_other, nr_cache_overwrite, nr_failed_overwrite
- );
-}
-
-
-static int raid5_make_request (mddev_t *mddev, int rw, struct buffer_head * bh)


-{
- raid5_conf_t *conf = (raid5_conf_t *) mddev->private;

- const unsigned int raid_disks = conf->raid_disks;
- const unsigned int data_disks = raid_disks - 1;
- unsigned int dd_idx, pd_idx;


- unsigned long new_sector;
-

- struct stripe_head *sh;
-

- if (rw == READA)
- rw = READ;
-

- new_sector = raid5_compute_sector(bh->b_rsector,
- raid_disks, data_disks, &dd_idx, &pd_idx, conf);
-
- PRINTK("raid5_make_request, sector %lu\n", new_sector);
- sh = get_lock_stripe(conf, new_sector, bh->b_size);
-#if 0
- if ((rw == READ && sh->cmd == STRIPE_WRITE) || (rw == WRITE && sh->cmd == STRIPE_READ)) {
- PRINTK("raid5: lock contention, rw == %d, sh->cmd == %d\n", rw, sh->cmd);
- lock_stripe(sh);
- if (!md_atomic_read(&sh->nr_pending))
- handle_stripe(sh);
- goto repeat;
- }
-#endif
- sh->pd_idx = pd_idx;
- if (sh->phase != PHASE_COMPLETE && sh->phase != PHASE_BEGIN)
- PRINTK("stripe %lu catching the bus!\n", sh->sector);


- if (sh->bh_new[dd_idx])
- BUG();

- add_stripe_bh(sh, bh, dd_idx, rw);
-
- md_wakeup_thread(conf->thread);


- return 0;
-}
-

-/*
- * Determine correct block size for this device.
- */
-unsigned int device_bsize (kdev_t dev)
-{
- unsigned int i, correct_size;
-
- correct_size = BLOCK_SIZE;
- if (blksize_size[MAJOR(dev)]) {
- i = blksize_size[MAJOR(dev)][MINOR(dev)];
- if (i)
- correct_size = i;
- }
-
- return correct_size;
-}
-
-static int raid5_sync_request (mddev_t *mddev, unsigned long block_nr)
-{


- raid5_conf_t *conf = (raid5_conf_t *) mddev->private;

- struct stripe_head *sh;


- int sectors_per_chunk = conf->chunk_size >> 9;

- unsigned long stripe = (block_nr<<2)/sectors_per_chunk;
- int chunk_offset = (block_nr<<2) % sectors_per_chunk;
- int dd_idx, pd_idx;
- unsigned long first_sector;
- int raid_disks = conf->raid_disks;
- int data_disks = raid_disks-1;
- int redone = 0;
- int bufsize;
-
- if (!conf->buffer_size)
- conf->buffer_size = /* device_bsize(mddev_to_kdev(mddev))*/ PAGE_SIZE;
- bufsize = conf->buffer_size;
- /* Hmm... race on buffer_size ?? */
- redone = block_nr% (bufsize>>10);
- block_nr -= redone;
- sh = get_lock_stripe(conf, block_nr<<1, bufsize);
- first_sector = raid5_compute_sector(stripe*data_disks*sectors_per_chunk
- + chunk_offset, raid_disks, data_disks, &dd_idx, &pd_idx, conf);
- sh->pd_idx = pd_idx;
- sh->cmd = STRIPE_SYNC;


- sh->phase = PHASE_BEGIN;

- sh->sync_redone = redone;


- atomic_inc(&conf->nr_pending_stripes);
- atomic_inc(&conf->nr_handle);

- md_wakeup_thread(conf->thread);
- return (bufsize>>10)-redone;
-}
-
-/*
- * This is our raid5 kernel thread.
- *
- * We scan the hash table for stripes which can be handled now.
- * During the scan, completed stripes are saved for us by the interrupt
- * handler, so that they will not have to wait for our next wakeup.
- */
-static void raid5d (void *data)
-{
- struct stripe_head *sh;
- raid5_conf_t *conf = data;


- mddev_t *mddev = conf->mddev;

- int i, handled;
-
- PRINTK("+++ raid5d active\n");
-
- handled = 0;
- md_spin_lock_irq(&conf->device_lock);
- clear_bit(THREAD_WAKEUP, &conf->thread->flags);
-repeat_pass:
- if (mddev->sb_dirty) {
- md_spin_unlock_irq(&conf->device_lock);


- mddev->sb_dirty = 0;
- md_update_sb(mddev);

- md_spin_lock_irq(&conf->device_lock);
- }
- for (i = 0; i < NR_HASH; i++) {
-repeat:
- sh = conf->stripe_hashtbl[i];


- for (; sh; sh = sh->hash_next) {

- if (sh->raid_conf != conf)
- continue;
- if (sh->phase == PHASE_COMPLETE)
- continue;
- if (md_atomic_read(&sh->nr_pending))
- continue;
- md_spin_unlock_irq(&conf->device_lock);


- if (!atomic_read(&sh->count))
- BUG();
-

- handled++;
- handle_stripe(sh);
- md_spin_lock_irq(&conf->device_lock);


- goto repeat;
- }
- }

- if (conf) {
- PRINTK("%d stripes handled, nr_handle %d\n", handled, md_atomic_read(&conf->nr_handle));
- if (test_and_clear_bit(THREAD_WAKEUP, &conf->thread->flags) &&
- md_atomic_read(&conf->nr_handle))
- goto repeat_pass;


- }
- md_spin_unlock_irq(&conf->device_lock);
-

- PRINTK("--- raid5d inactive\n");
-}
-
-/*
- * Private kernel thread for parity reconstruction after an unclean
- * shutdown. Reconstruction on spare drives in case of a failed drive
- * is done by the generic mdsyncd.
- */
-static void raid5syncd (void *data)
-{
- raid5_conf_t *conf = data;


- mddev_t *mddev = conf->mddev;
-

- if (!conf->resync_parity)
- return;
- if (conf->resync_parity == 2)


- return;
- down(&mddev->recovery_sem);

- if (md_do_sync(mddev,NULL)) {
- up(&mddev->recovery_sem);
- printk("raid5: resync aborted!\n");
- return;
- }


- conf->resync_parity = 0;

- up(&mddev->recovery_sem);
- printk("raid5: resync finished.\n");
-}
-


-static int __check_consistency (mddev_t *mddev, int row)
-{

- raid5_conf_t *conf = mddev->private;
- kdev_t dev;
- struct buffer_head *bh[MD_SB_DISKS], *tmp = NULL;
- int i, ret = 0, nr = 0, count;


- struct buffer_head *bh_ptr[MAX_XOR_BLOCKS];
-

- if (conf->working_disks != conf->raid_disks)
- goto out;
- tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
- tmp->b_size = 4096;
- tmp->b_page = alloc_page(GFP_KERNEL);
- tmp->b_data = page_address(tmp->b_page);
- if (!tmp->b_data)
- goto out;
- md_clear_page(tmp->b_data);
- memset(bh, 0, MD_SB_DISKS * sizeof(struct buffer_head *));


- for (i = 0; i < conf->raid_disks; i++) {

- dev = conf->disks[i].dev;
- set_blocksize(dev, 4096);
- bh[i] = bread(dev, row / 4, 4096);
- if (!bh[i])
- break;
- nr++;
- }
- if (nr == conf->raid_disks) {
- bh_ptr[0] = tmp;
- count = 1;
- for (i = 1; i < nr; i++) {
- bh_ptr[count++] = bh[i];


- if (count == MAX_XOR_BLOCKS) {
- xor_block(count, &bh_ptr[0]);
- count = 1;
- }
- }
- if (count != 1) {
- xor_block(count, &bh_ptr[0]);
- }

- if (memcmp(tmp->b_data, bh[0]->b_data, 4096))
- ret = 1;
- }
- for (i = 0; i < conf->raid_disks; i++) {
- dev = conf->disks[i].dev;
- if (bh[i]) {
- bforget(bh[i]);
- bh[i] = NULL;
- }


- fsync_dev(dev);
- invalidate_buffers(dev);
- }

- free_page((unsigned long) tmp->b_data);
-out:
- if (tmp)
- kfree(tmp);
- return ret;


-}
-
-static int check_consistency (mddev_t *mddev)
-{
- if (__check_consistency(mddev, 0))
-/*

- * We are not checking this currently, as it's legitimate to have
- * an inconsistent array, at creation time.


- */
- return 0;
-
- return 0;
-}
-

-static int raid5_run (mddev_t *mddev)
-{
- raid5_conf_t *conf;
- int i, j, raid_disk, memory;


- mdp_super_t *sb = mddev->sb;

- mdp_disk_t *desc;
- mdk_rdev_t *rdev;
- struct disk_info *disk;


- struct md_list_head *tmp;
- int start_recovery = 0;
-
- MOD_INC_USE_COUNT;
-

- if (sb->level != 5 && sb->level != 4) {
- printk("raid5: md%d: raid level not set to 4/5 (%d)\n", mdidx(mddev), sb->level);


- MOD_DEC_USE_COUNT;
- return -EIO;
- }
-

- mddev->private = kmalloc (sizeof (raid5_conf_t), GFP_KERNEL);
- if ((conf = mddev->private) == NULL)
- goto abort;
- memset (conf, 0, sizeof (*conf));


- conf->mddev = mddev;
-

- if ((conf->stripe_hashtbl = (struct stripe_head **) md__get_free_pages(GFP_ATOMIC, HASH_PAGES_ORDER)) == NULL)
- goto abort;
- memset(conf->stripe_hashtbl, 0, HASH_PAGES * PAGE_SIZE);
-


- conf->device_lock = MD_SPIN_LOCK_UNLOCKED;

- md_init_waitqueue_head(&conf->wait_for_stripe);
- PRINTK("raid5_run(md%d) called.\n", mdidx(mddev));
-
- ITERATE_RDEV(mddev,rdev,tmp) {
- /*
- * This is important -- we are using the descriptor on
- * the disk only to get a pointer to the descriptor on
- * the main superblock, which might be more recent.
- */
- desc = sb->disks + rdev->desc_nr;
- raid_disk = desc->raid_disk;
- disk = conf->disks + raid_disk;
-
- if (disk_faulty(desc)) {
- printk(KERN_ERR "raid5: disabled device %s (errors detected)\n", partition_name(rdev->dev));
- if (!rdev->faulty) {
- MD_BUG();
- goto abort;
- }
- disk->number = desc->number;
- disk->raid_disk = raid_disk;


- disk->dev = rdev->dev;
-

- disk->operational = 0;
- disk->write_only = 0;
- disk->spare = 0;
- disk->used_slot = 1;

- continue;
- }
- if (disk_active(desc)) {
- if (!disk_sync(desc)) {
- printk(KERN_ERR "raid5: disabled device %s (not in sync)\n", partition_name(rdev->dev));
- MD_BUG();
- goto abort;
- }
- if (raid_disk > sb->raid_disks) {
- printk(KERN_ERR "raid5: disabled device %s (inconsistent descriptor)\n", partition_name(rdev->dev));


- continue;
- }
- if (disk->operational) {

- printk(KERN_ERR "raid5: disabled device %s (device %d already operational)\n", partition_name(rdev->dev), raid_disk);
- continue;
- }
- printk(KERN_INFO "raid5: device %s operational as raid disk %d\n", partition_name(rdev->dev), raid_disk);
-
- disk->number = desc->number;
- disk->raid_disk = raid_disk;


- disk->dev = rdev->dev;

- disk->operational = 1;

- disk->used_slot = 1;
-
- conf->working_disks++;


- } else {
- /*
- * Must be a spare disk ..
- */

- printk(KERN_INFO "raid5: spare disk %s\n", partition_name(rdev->dev));
- disk->number = desc->number;
- disk->raid_disk = raid_disk;


- disk->dev = rdev->dev;
-

- disk->operational = 0;
- disk->write_only = 0;
- disk->spare = 1;
- disk->used_slot = 1;
- }

- }
-
- for (i = 0; i < MD_SB_DISKS; i++) {

- desc = sb->disks + i;

- raid_disk = desc->raid_disk;
- disk = conf->disks + raid_disk;
-
- if (disk_faulty(desc) && (raid_disk < sb->raid_disks) &&
- !conf->disks[raid_disk].used_slot) {
-
- disk->number = desc->number;
- disk->raid_disk = raid_disk;


- disk->dev = MKDEV(0,0);
-
- disk->operational = 0;
- disk->write_only = 0;
- disk->spare = 0;
- disk->used_slot = 1;
- }

- }
-
- conf->raid_disks = sb->raid_disks;

- /*
- * 0 for a fully functional array, 1 for a degraded array.
- */
- conf->failed_disks = conf->raid_disks - conf->working_disks;


- conf->mddev = mddev;

- conf->chunk_size = sb->chunk_size;
- conf->level = sb->level;
- conf->algorithm = sb->layout;
- conf->max_nr_stripes = NR_STRIPES;
-
-#if 0


- for (i = 0; i < conf->raid_disks; i++) {

- if (!conf->disks[i].used_slot) {
- MD_BUG();


- goto abort;
- }
- }

-#endif
- if (!conf->chunk_size || conf->chunk_size % 4) {
- printk(KERN_ERR "raid5: invalid chunk size %d for md%d\n", conf->chunk_size, mdidx(mddev));
- goto abort;
- }
- if (conf->algorithm > ALGORITHM_RIGHT_SYMMETRIC) {
- printk(KERN_ERR "raid5: unsupported parity algorithm %d for md%d\n", conf->algorithm, mdidx(mddev));
- goto abort;
- }
- if (conf->failed_disks > 1) {
- printk(KERN_ERR "raid5: not enough operational devices for md%d (%d/%d failed)\n", mdidx(mddev), conf->failed_disks, conf->raid_disks);


- goto abort;
- }
-

- if (conf->working_disks != sb->raid_disks) {

- printk(KERN_ALERT "raid5: md%d, not all disks are operational -- trying to recover array\n", mdidx(mddev));


- start_recovery = 1;
- }
-

- if (!start_recovery && (sb->state & (1 << MD_SB_CLEAN)) &&
- check_consistency(mddev)) {
- printk(KERN_ERR "raid5: detected raid-5 superblock xor inconsistency -- running resync\n");


- sb->state &= ~(1 << MD_SB_CLEAN);
- }
-
- {

- const char * name = "raid5d";
-
- conf->thread = md_register_thread(raid5d, conf, name);
- if (!conf->thread) {
- printk(KERN_ERR "raid5: couldn't allocate thread for md%d\n", mdidx(mddev));


- goto abort;
- }
- }
-

- memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
- conf->raid_disks * (sizeof(struct buffer_head) +
- 2 * (sizeof(struct buffer_head) + PAGE_SIZE))) / 1024;
- if (grow_stripes(conf, conf->max_nr_stripes, GFP_KERNEL)) {
- printk(KERN_ERR "raid5: couldn't allocate %dkB for buffers\n", memory);
- shrink_stripes(conf, conf->max_nr_stripes);
- goto abort;
- } else
- printk(KERN_INFO "raid5: allocated %dkB for md%d\n", memory, mdidx(mddev));


-
- /*
- * Regenerate the "device is in sync with the raid set" bit for
- * each device.
- */
- for (i = 0; i < MD_SB_DISKS ; i++) {
- mark_disk_nonsync(sb->disks + i);
- for (j = 0; j < sb->raid_disks; j++) {

- if (!conf->disks[j].operational)
- continue;
- if (sb->disks[i].number == conf->disks[j].number)
- mark_disk_sync(sb->disks + i);


- }
- }
- sb->active_disks = conf->working_disks;
-

- if (sb->active_disks == sb->raid_disks)

- printk("raid5: raid level %d set md%d active with %d out of %d devices, algorithm %d\n", conf->level, mdidx(mddev), sb->active_disks, sb->raid_disks, conf->algorithm);
- else
- printk(KERN_ALERT "raid5: raid level %d set md%d active with %d out of %d devices, algorithm %d\n", conf->level, mdidx(mddev), sb->active_disks, sb->raid_disks, conf->algorithm);


-
- if (!start_recovery && !(sb->state & (1 << MD_SB_CLEAN))) {

- const char * name = "raid5syncd";
-
- conf->resync_thread = md_register_thread(raid5syncd, conf,name);
- if (!conf->resync_thread) {
- printk(KERN_ERR "raid5: couldn't allocate thread for md%d\n", mdidx(mddev));


- goto abort;
- }
-

- printk("raid5: raid set md%d not clean; reconstructing parity\n", mdidx(mddev));
- conf->resync_parity = 1;


- md_wakeup_thread(conf->resync_thread);
- }
-

- print_raid5_conf(conf);


- if (start_recovery)
- md_recover_arrays();

- print_raid5_conf(conf);
-
- /* Ok, everything is just fine now */
- return (0);
-abort:
- if (conf) {
- print_raid5_conf(conf);
- if (conf->stripe_hashtbl)
- free_pages((unsigned long) conf->stripe_hashtbl,
- HASH_PAGES_ORDER);
- kfree(conf);
- }


- mddev->private = NULL;

- printk(KERN_ALERT "raid5: failed to run raid set md%d\n", mdidx(mddev));


- MOD_DEC_USE_COUNT;
- return -EIO;
-}
-

-static int raid5_stop_resync (mddev_t *mddev)
-{
- raid5_conf_t *conf = mddev_to_conf(mddev);
- mdk_thread_t *thread = conf->resync_thread;
-
- if (thread) {
- if (conf->resync_parity) {
- conf->resync_parity = 2;
- md_interrupt_thread(thread);
- printk(KERN_INFO "raid5: parity resync was not fully finished, restarting next time.\n");


- return 1;
- }
- return 0;
- }
- return 0;
-}
-

-static int raid5_restart_resync (mddev_t *mddev)
-{
- raid5_conf_t *conf = mddev_to_conf(mddev);
-
- if (conf->resync_parity) {


- if (!conf->resync_thread) {
- MD_BUG();
- return 0;
- }

- printk("raid5: waking up raid5resync.\n");
- conf->resync_parity = 1;


- md_wakeup_thread(conf->resync_thread);
- return 1;

- } else
- printk("raid5: no restart-resync needed.\n");


- return 0;
-}
-

-
-static int raid5_stop (mddev_t *mddev)


-{
- raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
-

- shrink_stripe_cache(conf, conf->max_nr_stripes);
- shrink_stripes(conf, conf->max_nr_stripes);


- md_unregister_thread(conf->thread);
- if (conf->resync_thread)
- md_unregister_thread(conf->resync_thread);

- free_pages((unsigned long) conf->stripe_hashtbl, HASH_PAGES_ORDER);


- kfree(conf);
- mddev->private = NULL;
- MOD_DEC_USE_COUNT;
- return 0;
-}
-

-#if RAID5_DEBUG
-static void print_sh (struct stripe_head *sh)


-{
- int i;
-

- printk("sh %lu, phase %d, size %d, pd_idx %d, state %ld, cmd %d.\n", sh->sector, sh->phase, sh->size, sh->pd_idx, sh->state, sh->cmd);
- printk("sh %lu, write_method %d, nr_pending %d, count %d.\n", sh->sector, sh->write_method, atomic_read(&sh->nr_pending), atomic_read(&sh->count));
- printk("sh %lu, ", sh->sector);
- for (i = 0; i < MD_SB_DISKS; i++) {


- if (sh->bh_old[i])

- printk("(old%d: %p) ", i, sh->bh_old[i]);


- if (sh->bh_new[i])

- printk("(new%d: %p) ", i, sh->bh_new[i]);
- if (sh->bh_copy[i])
- printk("(copy%d: %p) ", i, sh->bh_copy[i]);
- if (sh->bh_req[i])
- printk("(req%d: %p) ", i, sh->bh_req[i]);
- }
- printk("\n");


- for (i = 0; i < MD_SB_DISKS; i++)

- printk("%d(%d/%d) ", i, sh->cmd_new[i], sh->new[i]);
- printk("\n");
-}
-
-static void printall (raid5_conf_t *conf)


-{
- struct stripe_head *sh;

- int i;
-
- md_spin_lock_irq(&conf->device_lock);


- for (i = 0; i < NR_HASH; i++) {

- sh = conf->stripe_hashtbl[i];


- for (; sh; sh = sh->hash_next) {

- if (sh->raid_conf != conf)
- continue;
- print_sh(sh);
- }


- }
- md_spin_unlock_irq(&conf->device_lock);
-

- PRINTK("--- raid5d inactive\n");
-}
-#endif
-
-static int raid5_status (char *page, mddev_t *mddev)


-{
- raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
- mdp_super_t *sb = mddev->sb;

- int sz = 0, i;
-

- sz += sprintf (page+sz, " level %d, %dk chunk, algorithm %d", sb->level, sb->chunk_size >> 10, sb->layout);
- sz += sprintf (page+sz, " [%d/%d] [", conf->raid_disks, conf->working_disks);


- for (i = 0; i < conf->raid_disks; i++)

- sz += sprintf (page+sz, "%s", conf->disks[i].operational ? "U" : "_");


- sz += sprintf (page+sz, "]");

-#if RAID5_DEBUG
-#define D(x) \
- sz += sprintf (page+sz, "<"#x":%d>", atomic_read(&conf->x))
- D(nr_handle);
- D(nr_stripes);
- D(nr_hashed_stripes);
- D(nr_locked_stripes);
- D(nr_pending_stripes);
- D(nr_cached_stripes);
- D(nr_free_sh);
- printall(conf);
-#endif
- return sz;
-}


-
-static void print_raid5_conf (raid5_conf_t *conf)

-{
- int i;
- struct disk_info *tmp;
-
- printk("RAID5 conf printout:\n");


- if (!conf) {
- printk("(conf==NULL)\n");
- return;
- }

- printk(" --- rd:%d wd:%d fd:%d\n", conf->raid_disks,
- conf->working_disks, conf->failed_disks);


-
- for (i = 0; i < MD_SB_DISKS; i++) {

- tmp = conf->disks + i;


- printk(" disk %d, s:%d, o:%d, n:%d rd:%d us:%d dev:%s\n",
- i, tmp->spare,tmp->operational,
- tmp->number,tmp->raid_disk,tmp->used_slot,
- partition_name(tmp->dev));

- }
-}
-
-static int raid5_diskop(mddev_t *mddev, mdp_disk_t **d, int state)


-{
- int err = 0;
- int i, failed_disk=-1, spare_disk=-1, removed_disk=-1, added_disk=-1;

- raid5_conf_t *conf = mddev->private;
- struct disk_info *tmp, *sdisk, *fdisk, *rdisk, *adisk;


- mdp_super_t *sb = mddev->sb;

- mdp_disk_t *failed_desc, *spare_desc, *added_desc;
-

- print_raid5_conf(conf);
- md_spin_lock_irq(&conf->device_lock);


- /*
- * find the disk ...
- */
- switch (state) {
-
- case DISKOP_SPARE_ACTIVE:
-
- /*

- * Find the failed disk within the RAID5 configuration ...
- * (this can only be in the first conf->raid_disks part)


- */
- for (i = 0; i < conf->raid_disks; i++) {

- tmp = conf->disks + i;

- tmp = conf->disks + i;


- if (tmp->spare && tmp->number == (*d)->number) {
- spare_disk = i;
- break;
- }
- }
- if (spare_disk == -1) {
- MD_BUG();
- err = 1;
- goto abort;
- }
- break;
-
- case DISKOP_HOT_REMOVE_DISK:
-
- for (i = 0; i < MD_SB_DISKS; i++) {

- tmp = conf->disks + i;


- if (tmp->used_slot && (tmp->number == (*d)->number)) {
- if (tmp->operational) {
- err = -EBUSY;
- goto abort;
- }
- removed_disk = i;
- break;
- }
- }
- if (removed_disk == -1) {
- MD_BUG();
- err = 1;
- goto abort;
- }
- break;
-
- case DISKOP_HOT_ADD_DISK:
-
- for (i = conf->raid_disks; i < MD_SB_DISKS; i++) {

- tmp = conf->disks + i;


- if (!tmp->used_slot) {
- added_disk = i;
- break;
- }
- }
- if (added_disk == -1) {
- MD_BUG();
- err = 1;
- goto abort;
- }
- break;
- }
-
- switch (state) {
- /*
- * Switch the spare disk to write-only mode:
- */
- case DISKOP_SPARE_WRITE:

- if (conf->spare) {


- MD_BUG();
- err = 1;
- goto abort;
- }

- sdisk = conf->disks + spare_disk;


- sdisk->operational = 1;
- sdisk->write_only = 1;

- conf->spare = sdisk;


- break;
- /*
- * Deactivate a spare disk:
- */
- case DISKOP_SPARE_INACTIVE:

- sdisk = conf->disks + spare_disk;


- sdisk->operational = 0;
- sdisk->write_only = 0;

- /*
- * Was the spare being resynced?
- */
- if (conf->spare == sdisk)


- conf->spare = NULL;

- break;
- /*
- * Activate (mark read-write) the (now sync) spare disk,
- * which means we switch it's 'raid position' (->raid_disk)

- * with the failed disk. (only the first 'conf->raid_disks'


- * slots are used for 'real' disks and we must preserve this
- * property)
- */
- case DISKOP_SPARE_ACTIVE:

- if (!conf->spare) {


- MD_BUG();
- err = 1;
- goto abort;
- }

- sdisk = conf->disks + spare_disk;
- fdisk = conf->disks + failed_disk;

- /*
- * if we activate a spare, we definitely replace a
- * non-operational disk slot in the 'low' area of
- * the disk array.
- */

- conf->failed_disks--;
- conf->working_disks++;


- conf->spare = NULL;
-

- break;
-
- case DISKOP_HOT_REMOVE_DISK:

- rdisk = conf->disks + removed_disk;


-
- if (rdisk->spare && (removed_disk < conf->raid_disks)) {
- MD_BUG();
- err = 1;
- goto abort;
- }
- rdisk->dev = MKDEV(0,0);
- rdisk->used_slot = 0;
-

- break;
-
- case DISKOP_HOT_ADD_DISK:

- adisk = conf->disks + added_disk;


- added_desc = *d;
-
- if (added_disk != added_desc->number) {
- MD_BUG();
- err = 1;
- goto abort;
- }
-
- adisk->number = added_desc->number;
- adisk->raid_disk = added_desc->raid_disk;
- adisk->dev = MKDEV(added_desc->major,added_desc->minor);
-
- adisk->operational = 0;
- adisk->write_only = 0;
- adisk->spare = 1;
- adisk->used_slot = 1;
-

-
- break;
-
- default:
- MD_BUG();
- err = 1;
- goto abort;
- }
-abort:
- md_spin_unlock_irq(&conf->device_lock);

- print_raid5_conf(conf);


- return err;
-}
-

-static mdk_personality_t raid5_personality=
-{
- name: "raid5",
- make_request: raid5_make_request,
- run: raid5_run,
- stop: raid5_stop,
- status: raid5_status,
- error_handler: raid5_error,
- diskop: raid5_diskop,
- stop_resync: raid5_stop_resync,
- restart_resync: raid5_restart_resync,
- sync_request: raid5_sync_request
-};
-
-int raid5_init (void)


-{
- int err;
-

- err = register_md_personality (RAID5, &raid5_personality);
- if (err)
- return err;
-
- /*
- * pick a XOR routine, runtime.
- */
- calibrate_xor_block();


-
- return 0;
-}
-

-#ifdef MODULE
-int init_module (void)
-{

- return raid5_init();


-}
-
-void cleanup_module (void)
-{

- unregister_md_personality (RAID5);
-}
-#endif
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/block/swim3.c linux/drivers/block/swim3.c
--- v2.4.0-test8/linux/drivers/block/swim3.c Tue Jun 20 07:24:52 2000
+++ linux/drivers/block/swim3.c Tue Sep 19 08:31:53 2000
@@ -16,6 +16,7 @@
X * handle GCR disks
X */
X
+#include <linux/config.h>
X #include <linux/stddef.h>
X #include <linux/kernel.h>
X #include <linux/sched.h>
@@ -245,6 +246,13 @@
X static int floppy_revalidate(kdev_t dev);
X static int swim3_add_device(struct device_node *swims);
X int swim3_init(void);
+
+#ifndef CONFIG_PMAC_PBOOK
+static inline int check_media_bay(struct device_node *which_bay, int what)
+{
+ return 1;
+}
+#endif
X
X static void swim3_select(struct floppy_state *fs, int sel)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/block/xd.c linux/drivers/block/xd.c
--- v2.4.0-test8/linux/drivers/block/xd.c Thu Jun 29 18:25:49 2000
+++ linux/drivers/block/xd.c Mon Oct 2 14:22:40 2000
@@ -116,7 +116,7 @@
X };
X
X static struct hd_struct xd_struct[XD_MAXDRIVES << 6];
-static int xd_sizes[XD_MAXDRIVES << 6], xd_access[XD_MAXDRIVES] = { 0, 0 };
+static int xd_sizes[XD_MAXDRIVES << 6], xd_access[XD_MAXDRIVES];
X static int xd_blocksizes[XD_MAXDRIVES << 6];
X
X extern struct block_device_operations xd_fops;
@@ -141,12 +141,12 @@
X static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int);
X static DECLARE_WAIT_QUEUE_HEAD(xd_wait_open);
X static u_char xd_valid[XD_MAXDRIVES] = { 0,0 };
-static u_char xd_drives = 0, xd_irq = 5, xd_dma = 3, xd_maxsectors;
-static u_char xd_override __initdata = 0, xd_type = 0;
+static u_char xd_drives, xd_irq = 5, xd_dma = 3, xd_maxsectors;
+static u_char xd_override __initdata, xd_type __initdata;
X static u_short xd_iobase = 0x320;
-static int xd_geo[XD_MAXDRIVES*3] __initdata = { 0,0,0,0,0,0 };
+static int xd_geo[XD_MAXDRIVES*3] __initdata;
X
-static volatile int xdc_busy = 0;
+static volatile int xdc_busy;
X static DECLARE_WAIT_QUEUE_HEAD(xdc_wait);
X
X static struct timer_list xd_timer, xd_watchdog_int;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/block/xor.c linux/drivers/block/xor.c
--- v2.4.0-test8/linux/drivers/block/xor.c Mon Aug 28 21:21:57 2000
+++ linux/drivers/block/xor.c Wed Dec 31 16:00:00 1969
@@ -1,2728 +0,0 @@
-/*
- * xor.c : Multiple Devices driver for Linux
- *
- * Copyright (C) 1996, 1997, 1998, 1999 Ingo Molnar, Matti Aarnio, Jakub Jelinek
- *
- *
- * optimized RAID-5 checksumming functions.


- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * You should have received a copy of the GNU General Public License
- * (for example /usr/src/linux/COPYING); if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */

-#include <linux/config.h>
-#define BH_TRACE 0
-#include <linux/module.h>
-#include <linux/raid/md.h>
-#ifdef __sparc_v9__
-#include <asm/head.h>
-#include <asm/asi.h>
-#include <asm/visasm.h>
-#endif
-
-/*
- * we use the 'XOR function template' to register multiple xor
- * functions runtime. The kernel measures their speed upon bootup
- * and decides which one to use. (compile-time registration is
- * not enough as certain CPU features like MMX can only be detected
- * runtime)
- *
- * this architecture makes it pretty easy to add new routines
- * that are faster on certain CPUs, without killing other CPU's
- * 'native' routine. Although the current routines are belived
- * to be the physically fastest ones on all CPUs tested, but
- * feel free to prove me wrong and add yet another routine =B-)
- * --mingo
- */
-
-#define MAX_XOR_BLOCKS 5
-
-#define XOR_ARGS (unsigned int count, struct buffer_head **bh_ptr)
-
-typedef void (*xor_block_t) XOR_ARGS;
-xor_block_t xor_block = NULL;
-
-#ifndef __sparc_v9__
-
-struct xor_block_template;
-
-struct xor_block_template {
- char * name;
- xor_block_t xor_block;
- int speed;
- struct xor_block_template * next;
-};
-
-struct xor_block_template * xor_functions = NULL;
-
-#define XORBLOCK_TEMPLATE(x) \
-static void xor_block_##x XOR_ARGS; \
-static struct xor_block_template t_xor_block_##x = \
- { #x, xor_block_##x, 0, NULL }; \
-static void xor_block_##x XOR_ARGS
-
-#ifdef __i386__
-
-#ifdef CONFIG_X86_XMM
-/*
- * Cache avoiding checksumming functions utilizing KNI instructions
- * Copyright (C) 1999 Zach Brown (with obvious credit due Ingo)
- */
-
-XORBLOCK_TEMPLATE(pIII_kni)
-{
- char xmm_save[16*4];
- int cr0;
- int lines = (bh_ptr[0]->b_size>>8);
-
- __asm__ __volatile__ (
- "movl %%cr0,%0 ;\n\t"
- "clts ;\n\t"
- "movups %%xmm0,(%1) ;\n\t"
- "movups %%xmm1,0x10(%1) ;\n\t"
- "movups %%xmm2,0x20(%1) ;\n\t"
- "movups %%xmm3,0x30(%1) ;\n\t"
- : "=r" (cr0)
- : "r" (xmm_save)
- : "memory" );
-
-#define OFFS(x) "8*("#x"*2)"
-#define PF0(x) \
- " prefetcht0 "OFFS(x)"(%1) ;\n"
-#define LD(x,y) \
- " movaps "OFFS(x)"(%1), %%xmm"#y" ;\n"
-#define ST(x,y) \
- " movaps %%xmm"#y", "OFFS(x)"(%1) ;\n"
-#define PF1(x) \
- " prefetchnta "OFFS(x)"(%2) ;\n"
-#define PF2(x) \
- " prefetchnta "OFFS(x)"(%3) ;\n"
-#define PF3(x) \
- " prefetchnta "OFFS(x)"(%4) ;\n"
-#define PF4(x) \
- " prefetchnta "OFFS(x)"(%5) ;\n"
-#define PF5(x) \
- " prefetchnta "OFFS(x)"(%6) ;\n"
-#define XO1(x,y) \
- " xorps "OFFS(x)"(%2), %%xmm"#y" ;\n"
-#define XO2(x,y) \
- " xorps "OFFS(x)"(%3), %%xmm"#y" ;\n"
-#define XO3(x,y) \
- " xorps "OFFS(x)"(%4), %%xmm"#y" ;\n"
-#define XO4(x,y) \
- " xorps "OFFS(x)"(%5), %%xmm"#y" ;\n"
-#define XO5(x,y) \
- " xorps "OFFS(x)"(%6), %%xmm"#y" ;\n"
-
- switch(count) {
- case 2:
- __asm__ __volatile__ (
-#undef BLOCK
-#define BLOCK(i) \
- LD(i,0) \
- LD(i+1,1) \
- PF1(i) \
- PF1(i+2) \
- LD(i+2,2) \
- LD(i+3,3) \
- PF0(i+4) \
- PF0(i+6) \
- XO1(i,0) \
- XO1(i+1,1) \
- XO1(i+2,2) \
- XO1(i+3,3) \
- ST(i,0) \
- ST(i+1,1) \
- ST(i+2,2) \
- ST(i+3,3) \
-
-
- PF0(0)
- PF0(2)
-
- " .align 32,0x90 ;\n"
- " 1: ;\n"
-
- BLOCK(0)
- BLOCK(4)
- BLOCK(8)
- BLOCK(12)
-
- " addl $256, %1 ;\n"
- " addl $256, %2 ;\n"
- " decl %0 ;\n"
- " jnz 1b ;\n"
-
- :
- : "r" (lines),
- "r" (bh_ptr[0]->b_data),
- "r" (bh_ptr[1]->b_data)
- : "memory" );
- break;
- case 3:
- __asm__ __volatile__ (
-#undef BLOCK
-#define BLOCK(i) \
- PF1(i) \
- PF1(i+2) \
- LD(i,0) \
- LD(i+1,1) \
- LD(i+2,2) \
- LD(i+3,3) \
- PF2(i) \
- PF2(i+2) \
- PF0(i+4) \
- PF0(i+6) \
- XO1(i,0) \
- XO1(i+1,1) \
- XO1(i+2,2) \
- XO1(i+3,3) \
- XO2(i,0) \
- XO2(i+1,1) \
- XO2(i+2,2) \
- XO2(i+3,3) \
- ST(i,0) \
- ST(i+1,1) \
- ST(i+2,2) \
- ST(i+3,3) \
-
-
- PF0(0)
- PF0(2)
-
- " .align 32,0x90 ;\n"
- " 1: ;\n"
-
- BLOCK(0)
- BLOCK(4)
- BLOCK(8)
- BLOCK(12)
-
- " addl $256, %1 ;\n"
- " addl $256, %2 ;\n"
- " addl $256, %3 ;\n"
- " decl %0 ;\n"
- " jnz 1b ;\n"
- :
- : "r" (lines),
- "r" (bh_ptr[0]->b_data),
- "r" (bh_ptr[1]->b_data),
- "r" (bh_ptr[2]->b_data)
- : "memory" );


- break;
- case 4:

- __asm__ __volatile__ (
-#undef BLOCK
-#define BLOCK(i) \
- PF1(i) \
- PF1(i+2) \
- LD(i,0) \
- LD(i+1,1) \
- LD(i+2,2) \
- LD(i+3,3) \
- PF2(i) \
- PF2(i+2) \
- XO1(i,0) \
- XO1(i+1,1) \
- XO1(i+2,2) \
- XO1(i+3,3) \
- PF3(i) \
- PF3(i+2) \
- PF0(i+4) \
- PF0(i+6) \
- XO2(i,0) \
- XO2(i+1,1) \
- XO2(i+2,2) \
- XO2(i+3,3) \
- XO3(i,0) \
- XO3(i+1,1) \
- XO3(i+2,2) \
- XO3(i+3,3) \
- ST(i,0) \
- ST(i+1,1) \
- ST(i+2,2) \
- ST(i+3,3) \
-
-
- PF0(0)
- PF0(2)
-
- " .align 32,0x90 ;\n"
- " 1: ;\n"
-
- BLOCK(0)
- BLOCK(4)
- BLOCK(8)
- BLOCK(12)
-
- " addl $256, %1 ;\n"
- " addl $256, %2 ;\n"
- " addl $256, %3 ;\n"
- " addl $256, %4 ;\n"
- " decl %0 ;\n"
- " jnz 1b ;\n"
-
- :
- : "r" (lines),
- "r" (bh_ptr[0]->b_data),
- "r" (bh_ptr[1]->b_data),
- "r" (bh_ptr[2]->b_data),
- "r" (bh_ptr[3]->b_data)
- : "memory" );
- break;
- case 5:
- __asm__ __volatile__ (
-#undef BLOCK
-#define BLOCK(i) \
- PF1(i) \
- PF1(i+2) \
- LD(i,0) \
- LD(i+1,1) \
- LD(i+2,2) \
- LD(i+3,3) \
- PF2(i) \
- PF2(i+2) \
- XO1(i,0) \
- XO1(i+1,1) \
- XO1(i+2,2) \
- XO1(i+3,3) \
- PF3(i) \
- PF3(i+2) \
- XO2(i,0) \
- XO2(i+1,1) \
- XO2(i+2,2) \
- XO2(i+3,3) \
- PF4(i) \
- PF4(i+2) \
- PF0(i+4) \
- PF0(i+6) \
- XO3(i,0) \
- XO3(i+1,1) \
- XO3(i+2,2) \
- XO3(i+3,3) \
- XO4(i,0) \
- XO4(i+1,1) \
- XO4(i+2,2) \
- XO4(i+3,3) \
- ST(i,0) \
- ST(i+1,1) \
- ST(i+2,2) \
- ST(i+3,3) \
-
-
- PF0(0)
- PF0(2)
-
- " .align 32,0x90 ;\n"
- " 1: ;\n"
-
- BLOCK(0)
- BLOCK(4)
- BLOCK(8)
- BLOCK(12)
-
- " addl $256, %1 ;\n"
- " addl $256, %2 ;\n"
- " addl $256, %3 ;\n"
- " addl $256, %4 ;\n"
- " addl $256, %5 ;\n"
- " decl %0 ;\n"
- " jnz 1b ;\n"
-
- :
- : "r" (lines),
- "r" (bh_ptr[0]->b_data),
- "r" (bh_ptr[1]->b_data),
- "r" (bh_ptr[2]->b_data),
- "r" (bh_ptr[3]->b_data),
- "r" (bh_ptr[4]->b_data)
- : "memory");
- break;
- }
-
- __asm__ __volatile__ (
- "sfence ;\n\t"
- "movups (%1),%%xmm0 ;\n\t"
- "movups 0x10(%1),%%xmm1 ;\n\t"
- "movups 0x20(%1),%%xmm2 ;\n\t"
- "movups 0x30(%1),%%xmm3 ;\n\t"
- "movl %0,%%cr0 ;\n\t"
- :
- : "r" (cr0), "r" (xmm_save)
- : "memory" );
-}
-
-#undef OFFS
-#undef LD
-#undef ST
-#undef PF0
-#undef PF1
-#undef PF2
-#undef PF3
-#undef PF4
-#undef PF5
-#undef XO1
-#undef XO2
-#undef XO3
-#undef XO4
-#undef XO5
-#undef BLOCK
-
-#endif /* CONFIG_X86_XMM */
-
-/*
- * high-speed RAID5 checksumming functions utilizing MMX instructions
- * Copyright (C) 1998 Ingo Molnar
- */
-XORBLOCK_TEMPLATE(pII_mmx)
-{
- char fpu_save[108];
- int lines = (bh_ptr[0]->b_size>>7);
-
- if (!(current->flags & PF_USEDFPU))
- __asm__ __volatile__ ( " clts;\n");
-
- __asm__ __volatile__ ( " fsave %0; fwait\n"::"m"(fpu_save[0]) );
-
-#define LD(x,y) \
- " movq 8*("#x")(%1), %%mm"#y" ;\n"
-#define ST(x,y) \
- " movq %%mm"#y", 8*("#x")(%1) ;\n"
-#define XO1(x,y) \
- " pxor 8*("#x")(%2), %%mm"#y" ;\n"
-#define XO2(x,y) \
- " pxor 8*("#x")(%3), %%mm"#y" ;\n"
-#define XO3(x,y) \
- " pxor 8*("#x")(%4), %%mm"#y" ;\n"
-#define XO4(x,y) \
- " pxor 8*("#x")(%5), %%mm"#y" ;\n"
-
- switch(count) {
- case 2:
- __asm__ __volatile__ (
-#undef BLOCK
-#define BLOCK(i) \
- LD(i,0) \
- LD(i+1,1) \
- LD(i+2,2) \
- LD(i+3,3) \
- XO1(i,0) \
- ST(i,0) \
- XO1(i+1,1) \
- ST(i+1,1) \
- XO1(i+2,2) \
- ST(i+2,2) \
- XO1(i+3,3) \
- ST(i+3,3)
-
- " .align 32,0x90 ;\n"
- " 1: ;\n"
-
- BLOCK(0)
- BLOCK(4)
- BLOCK(8)
- BLOCK(12)
-
- " addl $128, %1 ;\n"
- " addl $128, %2 ;\n"
- " decl %0 ;\n"
- " jnz 1b ;\n"
- :
- : "r" (lines),
- "r" (bh_ptr[0]->b_data),
- "r" (bh_ptr[1]->b_data)
- : "memory");
- break;
- case 3:
- __asm__ __volatile__ (
-#undef BLOCK
-#define BLOCK(i) \
- LD(i,0) \
- LD(i+1,1) \
- LD(i+2,2) \
- LD(i+3,3) \
- XO1(i,0) \
- XO1(i+1,1) \
- XO1(i+2,2) \
- XO1(i+3,3) \
- XO2(i,0) \
- ST(i,0) \
- XO2(i+1,1) \
- ST(i+1,1) \
- XO2(i+2,2) \
- ST(i+2,2) \
- XO2(i+3,3) \
- ST(i+3,3)
-
- " .align 32,0x90 ;\n"
- " 1: ;\n"
-
- BLOCK(0)
- BLOCK(4)
- BLOCK(8)
- BLOCK(12)
-
- " addl $128, %1 ;\n"
- " addl $128, %2 ;\n"
- " addl $128, %3 ;\n"
- " decl %0 ;\n"
- " jnz 1b ;\n"
- :
- : "r" (lines),
- "r" (bh_ptr[0]->b_data),
- "r" (bh_ptr[1]->b_data),
- "r" (bh_ptr[2]->b_data)
- : "memory");


- break;
- case 4:

- __asm__ __volatile__ (
-#undef BLOCK
-#define BLOCK(i) \
- LD(i,0) \
- LD(i+1,1) \
- LD(i+2,2) \
- LD(i+3,3) \
- XO1(i,0) \
- XO1(i+1,1) \
- XO1(i+2,2) \
- XO1(i+3,3) \
- XO2(i,0) \
- XO2(i+1,1) \
- XO2(i+2,2) \
- XO2(i+3,3) \
- XO3(i,0) \
- ST(i,0) \
- XO3(i+1,1) \
- ST(i+1,1) \
- XO3(i+2,2) \
- ST(i+2,2) \
- XO3(i+3,3) \
- ST(i+3,3)
-
- " .align 32,0x90 ;\n"
- " 1: ;\n"
-
- BLOCK(0)
- BLOCK(4)
- BLOCK(8)
- BLOCK(12)
-
- " addl $128, %1 ;\n"
- " addl $128, %2 ;\n"
- " addl $128, %3 ;\n"
- " addl $128, %4 ;\n"
- " decl %0 ;\n"
- " jnz 1b ;\n"
- :
- : "r" (lines),
- "r" (bh_ptr[0]->b_data),
- "r" (bh_ptr[1]->b_data),
- "r" (bh_ptr[2]->b_data),
- "r" (bh_ptr[3]->b_data)
- : "memory");
- break;
- case 5:
- __asm__ __volatile__ (
-#undef BLOCK
-#define BLOCK(i) \
- LD(i,0) \
- LD(i+1,1) \
- LD(i+2,2) \
- LD(i+3,3) \
- XO1(i,0) \
- XO1(i+1,1) \
- XO1(i+2,2) \
- XO1(i+3,3) \
- XO2(i,0) \
- XO2(i+1,1) \
- XO2(i+2,2) \
- XO2(i+3,3) \
- XO3(i,0) \
- XO3(i+1,1) \
- XO3(i+2,2) \
- XO3(i+3,3) \
- XO4(i,0) \
- ST(i,0) \
- XO4(i+1,1) \
- ST(i+1,1) \
- XO4(i+2,2) \
- ST(i+2,2) \
- XO4(i+3,3) \
- ST(i+3,3)
-
- " .align 32,0x90 ;\n"
- " 1: ;\n"
-
- BLOCK(0)
- BLOCK(4)
- BLOCK(8)
- BLOCK(12)
-
- " addl $128, %1 ;\n"
- " addl $128, %2 ;\n"
- " addl $128, %3 ;\n"
- " addl $128, %4 ;\n"
- " addl $128, %5 ;\n"
- " decl %0 ;\n"
- " jnz 1b ;\n"
- :
- : "g" (lines),
- "r" (bh_ptr[0]->b_data),
- "r" (bh_ptr[1]->b_data),
- "r" (bh_ptr[2]->b_data),
- "r" (bh_ptr[3]->b_data),
- "r" (bh_ptr[4]->b_data)
- : "memory");
- break;
- }
-
- __asm__ __volatile__ ( " frstor %0;\n"::"m"(fpu_save[0]) );
-
- if (!(current->flags & PF_USEDFPU))
- stts();
-}
-
-#undef LD
-#undef XO1
-#undef XO2
-#undef XO3
-#undef XO4
-#undef ST
-#undef BLOCK
-
-XORBLOCK_TEMPLATE(p5_mmx)
-{
- char fpu_save[108];
- int lines = (bh_ptr[0]->b_size>>6);
-
- if (!(current->flags & PF_USEDFPU))
- __asm__ __volatile__ ( " clts;\n");
-
- __asm__ __volatile__ ( " fsave %0; fwait\n"::"m"(fpu_save[0]) );
-
- switch(count) {
- case 2:
- __asm__ __volatile__ (
-
- " .align 32,0x90 ;\n"
- " 1: ;\n"
- " movq (%1), %%mm0 ;\n"
- " movq 8(%1), %%mm1 ;\n"
- " pxor (%2), %%mm0 ;\n"
- " movq 16(%1), %%mm2 ;\n"
- " movq %%mm0, (%1) ;\n"
- " pxor 8(%2), %%mm1 ;\n"
- " movq 24(%1), %%mm3 ;\n"
- " movq %%mm1, 8(%1) ;\n"
- " pxor 16(%2), %%mm2 ;\n"
- " movq 32(%1), %%mm4 ;\n"
- " movq %%mm2, 16(%1) ;\n"
- " pxor 24(%2), %%mm3 ;\n"
- " movq 40(%1), %%mm5 ;\n"
- " movq %%mm3, 24(%1) ;\n"
- " pxor 32(%2), %%mm4 ;\n"
- " movq 48(%1), %%mm6 ;\n"
- " movq %%mm4, 32(%1) ;\n"
- " pxor 40(%2), %%mm5 ;\n"
- " movq 56(%1), %%mm7 ;\n"
- " movq %%mm5, 40(%1) ;\n"
- " pxor 48(%2), %%mm6 ;\n"
- " pxor 56(%2), %%mm7 ;\n"
- " movq %%mm6, 48(%1) ;\n"
- " movq %%mm7, 56(%1) ;\n"
-
- " addl $64, %1 ;\n"
- " addl $64, %2 ;\n"
- " decl %0 ;\n"
- " jnz 1b ;\n"
-
- :
- : "r" (lines),
- "r" (bh_ptr[0]->b_data),
- "r" (bh_ptr[1]->b_data)
- : "memory" );
- break;
- case 3:
- __asm__ __volatile__ (
-
- " .align 32,0x90 ;\n"
- " 1: ;\n"
- " movq (%1), %%mm0 ;\n"
- " movq 8(%1), %%mm1 ;\n"
- " pxor (%2), %%mm0 ;\n"
- " movq 16(%1), %%mm2 ;\n"
- " pxor 8(%2), %%mm1 ;\n"
- " pxor (%3), %%mm0 ;\n"
- " pxor 16(%2), %%mm2 ;\n"
- " movq %%mm0, (%1) ;\n"
- " pxor 8(%3), %%mm1 ;\n"
- " pxor 16(%3), %%mm2 ;\n"
- " movq 24(%1), %%mm3 ;\n"
- " movq %%mm1, 8(%1) ;\n"
- " movq 32(%1), %%mm4 ;\n"
- " movq 40(%1), %%mm5 ;\n"
- " pxor 24(%2), %%mm3 ;\n"
- " movq %%mm2, 16(%1) ;\n"
- " pxor 32(%2), %%mm4 ;\n"
- " pxor 24(%3), %%mm3 ;\n"
- " pxor 40(%2), %%mm5 ;\n"
- " movq %%mm3, 24(%1) ;\n"
- " pxor 32(%3), %%mm4 ;\n"
- " pxor 40(%3), %%mm5 ;\n"
- " movq 48(%1), %%mm6 ;\n"
- " movq %%mm4, 32(%1) ;\n"
- " movq 56(%1), %%mm7 ;\n"
- " pxor 48(%2), %%mm6 ;\n"
- " movq %%mm5, 40(%1) ;\n"
- " pxor 56(%2), %%mm7 ;\n"
- " pxor 48(%3), %%mm6 ;\n"
- " pxor 56(%3), %%mm7 ;\n"
- " movq %%mm6, 48(%1) ;\n"
- " movq %%mm7, 56(%1) ;\n"
-
- " addl $64, %1 ;\n"
- " addl $64, %2 ;\n"
- " addl $64, %3 ;\n"
- " decl %0 ;\n"
- " jnz 1b ;\n"
-
- :
- : "r" (lines),
- "r" (bh_ptr[0]->b_data),
- "r" (bh_ptr[1]->b_data),
- "r" (bh_ptr[2]->b_data)
- : "memory" );


- break;
- case 4:

- __asm__ __volatile__ (
-
- " .align 32,0x90 ;\n"
- " 1: ;\n"
- " movq (%1), %%mm0 ;\n"
- " movq 8(%1), %%mm1 ;\n"
- " pxor (%2), %%mm0 ;\n"
- " movq 16(%1), %%mm2 ;\n"
- " pxor 8(%2), %%mm1 ;\n"
- " pxor (%3), %%mm0 ;\n"
- " pxor 16(%2), %%mm2 ;\n"
- " pxor 8(%3), %%mm1 ;\n"
- " pxor (%4), %%mm0 ;\n"
- " movq 24(%1), %%mm3 ;\n"
- " pxor 16(%3), %%mm2 ;\n"
- " pxor 8(%4), %%mm1 ;\n"
- " movq %%mm0, (%1) ;\n"
- " movq 32(%1), %%mm4 ;\n"
- " pxor 24(%2), %%mm3 ;\n"
- " pxor 16(%4), %%mm2 ;\n"
- " movq %%mm1, 8(%1) ;\n"
- " movq 40(%1), %%mm5 ;\n"
- " pxor 32(%2), %%mm4 ;\n"
- " pxor 24(%3), %%mm3 ;\n"
- " movq %%mm2, 16(%1) ;\n"
- " pxor 40(%2), %%mm5 ;\n"
- " pxor 32(%3), %%mm4 ;\n"
- " pxor 24(%4), %%mm3 ;\n"
- " movq %%mm3, 24(%1) ;\n"
- " movq 56(%1), %%mm7 ;\n"
- " movq 48(%1), %%mm6 ;\n"
- " pxor 40(%3), %%mm5 ;\n"
- " pxor 32(%4), %%mm4 ;\n"
- " pxor 48(%2), %%mm6 ;\n"
- " movq %%mm4, 32(%1) ;\n"
- " pxor 56(%2), %%mm7 ;\n"
- " pxor 40(%4), %%mm5 ;\n"
- " pxor 48(%3), %%mm6 ;\n"
- " pxor 56(%3), %%mm7 ;\n"
- " movq %%mm5, 40(%1) ;\n"
- " pxor 48(%4), %%mm6 ;\n"
- " pxor 56(%4), %%mm7 ;\n"
- " movq %%mm6, 48(%1) ;\n"
- " movq %%mm7, 56(%1) ;\n"
-
- " addl $64, %1 ;\n"
- " addl $64, %2 ;\n"
- " addl $64, %3 ;\n"
- " addl $64, %4 ;\n"
- " decl %0 ;\n"
- " jnz 1b ;\n"
-
- :
- : "r" (lines),
- "r" (bh_ptr[0]->b_data),
- "r" (bh_ptr[1]->b_data),
- "r" (bh_ptr[2]->b_data),
- "r" (bh_ptr[3]->b_data)
- : "memory" );
- break;
- case 5:
- __asm__ __volatile__ (
-
- " .align 32,0x90 ;\n"
- " 1: ;\n"
- " movq (%1), %%mm0 ;\n"
- " movq 8(%1), %%mm1 ;\n"
- " pxor (%2), %%mm0 ;\n"
- " pxor 8(%2), %%mm1 ;\n"
- " movq 16(%1), %%mm2 ;\n"
- " pxor (%3), %%mm0 ;\n"
- " pxor 8(%3), %%mm1 ;\n"
- " pxor 16(%2), %%mm2 ;\n"
- " pxor (%4), %%mm0 ;\n"
- " pxor 8(%4), %%mm1 ;\n"
- " pxor 16(%3), %%mm2 ;\n"
- " movq 24(%1), %%mm3 ;\n"
- " pxor (%5), %%mm0 ;\n"
- " pxor 8(%5), %%mm1 ;\n"
- " movq %%mm0, (%1) ;\n"
- " pxor 16(%4), %%mm2 ;\n"
- " pxor 24(%2), %%mm3 ;\n"
- " movq %%mm1, 8(%1) ;\n"
- " pxor 16(%5), %%mm2 ;\n"
- " pxor 24(%3), %%mm3 ;\n"
- " movq 32(%1), %%mm4 ;\n"
- " movq %%mm2, 16(%1) ;\n"
- " pxor 24(%4), %%mm3 ;\n"
- " pxor 32(%2), %%mm4 ;\n"
- " movq 40(%1), %%mm5 ;\n"
- " pxor 24(%5), %%mm3 ;\n"
- " pxor 32(%3), %%mm4 ;\n"
- " pxor 40(%2), %%mm5 ;\n"
- " movq %%mm3, 24(%1) ;\n"
- " pxor 32(%4), %%mm4 ;\n"
- " pxor 40(%3), %%mm5 ;\n"
- " movq 48(%1), %%mm6 ;\n"
- " movq 56(%1), %%mm7 ;\n"
- " pxor 32(%5), %%mm4 ;\n"
- " pxor 40(%4), %%mm5 ;\n"
- " pxor 48(%2), %%mm6 ;\n"
- " pxor 56(%2), %%mm7 ;\n"
- " movq %%mm4, 32(%1) ;\n"
- " pxor 48(%3), %%mm6 ;\n"
- " pxor 56(%3), %%mm7 ;\n"
- " pxor 40(%5), %%mm5 ;\n"
- " pxor 48(%4), %%mm6 ;\n"
- " pxor 56(%4), %%mm7 ;\n"
- " movq %%mm5, 40(%1) ;\n"
- " pxor 48(%5), %%mm6 ;\n"
- " pxor 56(%5), %%mm7 ;\n"
- " movq %%mm6, 48(%1) ;\n"
- " movq %%mm7, 56(%1) ;\n"
-
- " addl $64, %1 ;\n"


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 045'
echo 'File patch-2.4.0-test9 is continued in part 046'
echo "046" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part046

#!/bin/sh -x
# this is part 046 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 046; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

- " addl $64, %2 ;\n"
- " addl $64, %3 ;\n"
- " addl $64, %4 ;\n"

- " addl $64, %5 ;\n"


- " decl %0 ;\n"
- " jnz 1b ;\n"
-
- :

- : "g" (lines),
- "r" (bh_ptr[0]->b_data),
- "r" (bh_ptr[1]->b_data),
- "r" (bh_ptr[2]->b_data),
- "r" (bh_ptr[3]->b_data),
- "r" (bh_ptr[4]->b_data)
- : "memory" );
- break;
- }
-
- __asm__ __volatile__ ( " frstor %0;\n"::"m"(fpu_save[0]) );
-
- if (!(current->flags & PF_USEDFPU))
- stts();
-}

-#endif /* __i386__ */
-#endif /* !__sparc_v9__ */
-
-#ifdef __sparc_v9__
-/*
- * High speed xor_block operation for RAID4/5 utilizing the
- * UltraSparc Visual Instruction Set.
- *
- * Copyright (C) 1997, 1999 Jakub Jelinek (j...@ultra.linux.cz)
- *
- * Requirements:
- * !(((long)dest | (long)sourceN) & (64 - 1)) &&
- * !(len & 127) && len >= 256
- *
- * It is done in pure assembly, as otherwise gcc makes it
- * a non-leaf function, which is not what we want.
- * Also, we don't measure the speeds as on other architectures,
- * as the measuring routine does not take into account cold caches
- * and the fact that xor_block_VIS bypasses the caches.
- * xor_block_32regs might be 5% faster for count 2 if caches are hot
- * and things just right (for count 3 VIS is about as fast as 32regs for
- * hot caches and for count 4 and 5 VIS is faster by good margin always),
- * but I think it is better not to pollute the caches.
- * Actually, if I'd just fight for speed for hot caches, I could
- * write a hybrid VIS/integer routine, which would do always two
- * 64B blocks in VIS and two in IEUs, but I really care more about
- * caches.
- */
-extern void *VISenter(void);
-extern void xor_block_VIS XOR_ARGS;
-
-void __xor_block_VIS(void)
-{
-__asm__ ("
- .globl xor_block_VIS
-xor_block_VIS:
- ldx [%%o1 + 0], %%o4
- ldx [%%o1 + 8], %%o3
- ldx [%%o4 + %1], %%g5
- ldx [%%o4 + %0], %%o4
- ldx [%%o3 + %0], %%o3
- rd %%fprs, %%o5
- andcc %%o5, %2, %%g0
- be,pt %%icc, 297f
- sethi %%hi(%5), %%g1
- jmpl %%g1 + %%lo(%5), %%g7
- add %%g7, 8, %%g7
-297: wr %%g0, %4, %%fprs
- membar #LoadStore|#StoreLoad|#StoreStore
- sub %%g5, 64, %%g5
- ldda [%%o4] %3, %%f0
- ldda [%%o3] %3, %%f16
- cmp %%o0, 4
- bgeu,pt %%xcc, 10f
- cmp %%o0, 3
- be,pn %%xcc, 13f
- mov -64, %%g1
- sub %%g5, 64, %%g5
- rd %%asi, %%g1
- wr %%g0, %3, %%asi
-
-2: ldda [%%o4 + 64] %%asi, %%f32
- fxor %%f0, %%f16, %%f16
- fxor %%f2, %%f18, %%f18
- fxor %%f4, %%f20, %%f20
- fxor %%f6, %%f22, %%f22
- fxor %%f8, %%f24, %%f24
- fxor %%f10, %%f26, %%f26
- fxor %%f12, %%f28, %%f28
- fxor %%f14, %%f30, %%f30
- stda %%f16, [%%o4] %3
- ldda [%%o3 + 64] %%asi, %%f48
- ldda [%%o4 + 128] %%asi, %%f0
- fxor %%f32, %%f48, %%f48
- fxor %%f34, %%f50, %%f50
- add %%o4, 128, %%o4
- fxor %%f36, %%f52, %%f52
- add %%o3, 128, %%o3
- fxor %%f38, %%f54, %%f54
- subcc %%g5, 128, %%g5
- fxor %%f40, %%f56, %%f56
- fxor %%f42, %%f58, %%f58
- fxor %%f44, %%f60, %%f60
- fxor %%f46, %%f62, %%f62
- stda %%f48, [%%o4 - 64] %%asi
- bne,pt %%xcc, 2b
- ldda [%%o3] %3, %%f16
-
- ldda [%%o4 + 64] %%asi, %%f32
- fxor %%f0, %%f16, %%f16
- fxor %%f2, %%f18, %%f18
- fxor %%f4, %%f20, %%f20
- fxor %%f6, %%f22, %%f22
- fxor %%f8, %%f24, %%f24
- fxor %%f10, %%f26, %%f26
- fxor %%f12, %%f28, %%f28
- fxor %%f14, %%f30, %%f30
- stda %%f16, [%%o4] %3
- ldda [%%o3 + 64] %%asi, %%f48
- membar #Sync
- fxor %%f32, %%f48, %%f48
- fxor %%f34, %%f50, %%f50
- fxor %%f36, %%f52, %%f52
- fxor %%f38, %%f54, %%f54
- fxor %%f40, %%f56, %%f56
- fxor %%f42, %%f58, %%f58
- fxor %%f44, %%f60, %%f60
- fxor %%f46, %%f62, %%f62
- stda %%f48, [%%o4 + 64] %%asi
- membar #Sync|#StoreStore|#StoreLoad
- wr %%g0, 0, %%fprs
- retl
- wr %%g1, %%g0, %%asi
-
-13: ldx [%%o1 + 16], %%o2
- ldx [%%o2 + %0], %%o2
-
-3: ldda [%%o2] %3, %%f32
- fxor %%f0, %%f16, %%f48
- fxor %%f2, %%f18, %%f50
- add %%o4, 64, %%o4
- fxor %%f4, %%f20, %%f52
- fxor %%f6, %%f22, %%f54
- add %%o3, 64, %%o3
- fxor %%f8, %%f24, %%f56
- fxor %%f10, %%f26, %%f58
- fxor %%f12, %%f28, %%f60
- fxor %%f14, %%f30, %%f62
- ldda [%%o4] %3, %%f0
- fxor %%f48, %%f32, %%f48
- fxor %%f50, %%f34, %%f50
- fxor %%f52, %%f36, %%f52
- fxor %%f54, %%f38, %%f54
- add %%o2, 64, %%o2
- fxor %%f56, %%f40, %%f56
- fxor %%f58, %%f42, %%f58
- subcc %%g5, 64, %%g5
- fxor %%f60, %%f44, %%f60
- fxor %%f62, %%f46, %%f62
- stda %%f48, [%%o4 + %%g1] %3
- bne,pt %%xcc, 3b
- ldda [%%o3] %3, %%f16
-
- ldda [%%o2] %3, %%f32
- fxor %%f0, %%f16, %%f48
- fxor %%f2, %%f18, %%f50
- fxor %%f4, %%f20, %%f52
- fxor %%f6, %%f22, %%f54
- fxor %%f8, %%f24, %%f56
- fxor %%f10, %%f26, %%f58
- fxor %%f12, %%f28, %%f60
- fxor %%f14, %%f30, %%f62
- membar #Sync
- fxor %%f48, %%f32, %%f48
- fxor %%f50, %%f34, %%f50
- fxor %%f52, %%f36, %%f52
- fxor %%f54, %%f38, %%f54
- fxor %%f56, %%f40, %%f56
- fxor %%f58, %%f42, %%f58
- fxor %%f60, %%f44, %%f60
- fxor %%f62, %%f46, %%f62
- stda %%f48, [%%o4] %3
- membar #Sync|#StoreStore|#StoreLoad
- retl
- wr %%g0, 0, %%fprs
-
-10: cmp %%o0, 5
- be,pt %%xcc, 15f
- mov -64, %%g1
-
-14: ldx [%%o1 + 16], %%o2
- ldx [%%o1 + 24], %%o0
- ldx [%%o2 + %0], %%o2
- ldx [%%o0 + %0], %%o0
-
-4: ldda [%%o2] %3, %%f32
- fxor %%f0, %%f16, %%f16
- fxor %%f2, %%f18, %%f18
- add %%o4, 64, %%o4
- fxor %%f4, %%f20, %%f20
- fxor %%f6, %%f22, %%f22
- add %%o3, 64, %%o3
- fxor %%f8, %%f24, %%f24
- fxor %%f10, %%f26, %%f26
- fxor %%f12, %%f28, %%f28
- fxor %%f14, %%f30, %%f30
- ldda [%%o0] %3, %%f48
- fxor %%f16, %%f32, %%f32
- fxor %%f18, %%f34, %%f34
- fxor %%f20, %%f36, %%f36
- fxor %%f22, %%f38, %%f38
- add %%o2, 64, %%o2
- fxor %%f24, %%f40, %%f40
- fxor %%f26, %%f42, %%f42
- fxor %%f28, %%f44, %%f44
- fxor %%f30, %%f46, %%f46
- ldda [%%o4] %3, %%f0
- fxor %%f32, %%f48, %%f48
- fxor %%f34, %%f50, %%f50
- fxor %%f36, %%f52, %%f52
- add %%o0, 64, %%o0
- fxor %%f38, %%f54, %%f54
- fxor %%f40, %%f56, %%f56
- fxor %%f42, %%f58, %%f58
- subcc %%g5, 64, %%g5
- fxor %%f44, %%f60, %%f60
- fxor %%f46, %%f62, %%f62
- stda %%f48, [%%o4 + %%g1] %3
- bne,pt %%xcc, 4b
- ldda [%%o3] %3, %%f16
-
- ldda [%%o2] %3, %%f32
- fxor %%f0, %%f16, %%f16
- fxor %%f2, %%f18, %%f18
- fxor %%f4, %%f20, %%f20
- fxor %%f6, %%f22, %%f22
- fxor %%f8, %%f24, %%f24
- fxor %%f10, %%f26, %%f26
- fxor %%f12, %%f28, %%f28
- fxor %%f14, %%f30, %%f30
- ldda [%%o0] %3, %%f48
- fxor %%f16, %%f32, %%f32
- fxor %%f18, %%f34, %%f34
- fxor %%f20, %%f36, %%f36
- fxor %%f22, %%f38, %%f38
- fxor %%f24, %%f40, %%f40
- fxor %%f26, %%f42, %%f42
- fxor %%f28, %%f44, %%f44
- fxor %%f30, %%f46, %%f46
- membar #Sync
- fxor %%f32, %%f48, %%f48
- fxor %%f34, %%f50, %%f50
- fxor %%f36, %%f52, %%f52
- fxor %%f38, %%f54, %%f54
- fxor %%f40, %%f56, %%f56
- fxor %%f42, %%f58, %%f58
- fxor %%f44, %%f60, %%f60
- fxor %%f46, %%f62, %%f62
- stda %%f48, [%%o4] %3
- membar #Sync|#StoreStore|#StoreLoad
- retl
- wr %%g0, 0, %%fprs
-
-15: ldx [%%o1 + 16], %%o2
- ldx [%%o1 + 24], %%o0
- ldx [%%o1 + 32], %%o1
- ldx [%%o2 + %0], %%o2
- ldx [%%o0 + %0], %%o0
- ldx [%%o1 + %0], %%o1
-
-5: ldda [%%o2] %3, %%f32
- fxor %%f0, %%f16, %%f48
- fxor %%f2, %%f18, %%f50
- add %%o4, 64, %%o4
- fxor %%f4, %%f20, %%f52
- fxor %%f6, %%f22, %%f54
- add %%o3, 64, %%o3
- fxor %%f8, %%f24, %%f56
- fxor %%f10, %%f26, %%f58
- fxor %%f12, %%f28, %%f60
- fxor %%f14, %%f30, %%f62
- ldda [%%o0] %3, %%f16
- fxor %%f48, %%f32, %%f48
- fxor %%f50, %%f34, %%f50
- fxor %%f52, %%f36, %%f52
- fxor %%f54, %%f38, %%f54
- add %%o2, 64, %%o2
- fxor %%f56, %%f40, %%f56
- fxor %%f58, %%f42, %%f58
- fxor %%f60, %%f44, %%f60
- fxor %%f62, %%f46, %%f62
- ldda [%%o1] %3, %%f32
- fxor %%f48, %%f16, %%f48
- fxor %%f50, %%f18, %%f50
- add %%o0, 64, %%o0
- fxor %%f52, %%f20, %%f52
- fxor %%f54, %%f22, %%f54
- add %%o1, 64, %%o1
- fxor %%f56, %%f24, %%f56
- fxor %%f58, %%f26, %%f58
- fxor %%f60, %%f28, %%f60
- fxor %%f62, %%f30, %%f62
- ldda [%%o4] %3, %%f0
- fxor %%f48, %%f32, %%f48
- fxor %%f50, %%f34, %%f50
- fxor %%f52, %%f36, %%f52
- fxor %%f54, %%f38, %%f54
- fxor %%f56, %%f40, %%f56
- fxor %%f58, %%f42, %%f58
- subcc %%g5, 64, %%g5
- fxor %%f60, %%f44, %%f60
- fxor %%f62, %%f46, %%f62
- stda %%f48, [%%o4 + %%g1] %3
- bne,pt %%xcc, 5b
- ldda [%%o3] %3, %%f16
-
- ldda [%%o2] %3, %%f32
- fxor %%f0, %%f16, %%f48
- fxor %%f2, %%f18, %%f50
- fxor %%f4, %%f20, %%f52
- fxor %%f6, %%f22, %%f54
- fxor %%f8, %%f24, %%f56
- fxor %%f10, %%f26, %%f58
- fxor %%f12, %%f28, %%f60
- fxor %%f14, %%f30, %%f62
- ldda [%%o0] %3, %%f16
- fxor %%f48, %%f32, %%f48
- fxor %%f50, %%f34, %%f50
- fxor %%f52, %%f36, %%f52
- fxor %%f54, %%f38, %%f54
- fxor %%f56, %%f40, %%f56
- fxor %%f58, %%f42, %%f58
- fxor %%f60, %%f44, %%f60
- fxor %%f62, %%f46, %%f62
- ldda [%%o1] %3, %%f32
- fxor %%f48, %%f16, %%f48
- fxor %%f50, %%f18, %%f50
- fxor %%f52, %%f20, %%f52
- fxor %%f54, %%f22, %%f54
- fxor %%f56, %%f24, %%f56
- fxor %%f58, %%f26, %%f58
- fxor %%f60, %%f28, %%f60
- fxor %%f62, %%f30, %%f62
- membar #Sync
- fxor %%f48, %%f32, %%f48
- fxor %%f50, %%f34, %%f50
- fxor %%f52, %%f36, %%f52
- fxor %%f54, %%f38, %%f54
- fxor %%f56, %%f40, %%f56
- fxor %%f58, %%f42, %%f58
- fxor %%f60, %%f44, %%f60
- fxor %%f62, %%f46, %%f62
- stda %%f48, [%%o4] %3
- membar #Sync|#StoreStore|#StoreLoad
- retl
- wr %%g0, 0, %%fprs
- " : :
- "i" (&((struct buffer_head *)0)->b_data),
- "i" (&((struct buffer_head *)0)->b_size),
- "i" (FPRS_FEF|FPRS_DU), "i" (ASI_BLK_P),
- "i" (FPRS_FEF), "i" (VISenter));
-}
-#endif /* __sparc_v9__ */
-
-#if defined(__sparc__) && !defined(__sparc_v9__)
-/*
- * High speed xor_block operation for RAID4/5 utilizing the
- * ldd/std SPARC instructions.
- *
- * Copyright (C) 1999 Jakub Jelinek (j...@ultra.linux.cz)


- *
- */
-

-XORBLOCK_TEMPLATE(SPARC)
-{
- int size = bh_ptr[0]->b_size;
- int lines = size / (sizeof (long)) / 8, i;
- long *destp = (long *) bh_ptr[0]->b_data;
- long *source1 = (long *) bh_ptr[1]->b_data;
- long *source2, *source3, *source4;
-
- switch (count) {
- case 2:
- for (i = lines; i > 0; i--) {
- __asm__ __volatile__("
- ldd [%0 + 0x00], %%g2
- ldd [%0 + 0x08], %%g4
- ldd [%0 + 0x10], %%o0
- ldd [%0 + 0x18], %%o2
- ldd [%1 + 0x00], %%o4
- ldd [%1 + 0x08], %%l0
- ldd [%1 + 0x10], %%l2
- ldd [%1 + 0x18], %%l4
- xor %%g2, %%o4, %%g2
- xor %%g3, %%o5, %%g3
- xor %%g4, %%l0, %%g4
- xor %%g5, %%l1, %%g5
- xor %%o0, %%l2, %%o0
- xor %%o1, %%l3, %%o1
- xor %%o2, %%l4, %%o2
- xor %%o3, %%l5, %%o3
- std %%g2, [%0 + 0x00]
- std %%g4, [%0 + 0x08]
- std %%o0, [%0 + 0x10]
- std %%o2, [%0 + 0x18]
- " : : "r" (destp), "r" (source1) : "g2", "g3", "g4", "g5", "o0",
- "o1", "o2", "o3", "o4", "o5", "l0", "l1", "l2", "l3", "l4", "l5");
- destp += 8;
- source1 += 8;
- }


- break;
- case 3:

- source2 = (long *) bh_ptr[2]->b_data;
- for (i = lines; i > 0; i--) {
- __asm__ __volatile__("
- ldd [%0 + 0x00], %%g2
- ldd [%0 + 0x08], %%g4
- ldd [%0 + 0x10], %%o0
- ldd [%0 + 0x18], %%o2
- ldd [%1 + 0x00], %%o4
- ldd [%1 + 0x08], %%l0
- ldd [%1 + 0x10], %%l2
- ldd [%1 + 0x18], %%l4
- xor %%g2, %%o4, %%g2
- xor %%g3, %%o5, %%g3
- ldd [%2 + 0x00], %%o4
- xor %%g4, %%l0, %%g4
- xor %%g5, %%l1, %%g5
- ldd [%2 + 0x08], %%l0
- xor %%o0, %%l2, %%o0
- xor %%o1, %%l3, %%o1
- ldd [%2 + 0x10], %%l2
- xor %%o2, %%l4, %%o2
- xor %%o3, %%l5, %%o3
- ldd [%2 + 0x18], %%l4
- xor %%g2, %%o4, %%g2
- xor %%g3, %%o5, %%g3
- xor %%g4, %%l0, %%g4
- xor %%g5, %%l1, %%g5
- xor %%o0, %%l2, %%o0
- xor %%o1, %%l3, %%o1
- xor %%o2, %%l4, %%o2
- xor %%o3, %%l5, %%o3
- std %%g2, [%0 + 0x00]
- std %%g4, [%0 + 0x08]
- std %%o0, [%0 + 0x10]
- std %%o2, [%0 + 0x18]
- " : : "r" (destp), "r" (source1), "r" (source2)
- : "g2", "g3", "g4", "g5", "o0", "o1", "o2", "o3", "o4", "o5",
- "l0", "l1", "l2", "l3", "l4", "l5");
- destp += 8;
- source1 += 8;
- source2 += 8;
- }


- break;
- case 4:

- source2 = (long *) bh_ptr[2]->b_data;
- source3 = (long *) bh_ptr[3]->b_data;
- for (i = lines; i > 0; i--) {
- __asm__ __volatile__("
- ldd [%0 + 0x00], %%g2
- ldd [%0 + 0x08], %%g4
- ldd [%0 + 0x10], %%o0
- ldd [%0 + 0x18], %%o2
- ldd [%1 + 0x00], %%o4
- ldd [%1 + 0x08], %%l0
- ldd [%1 + 0x10], %%l2
- ldd [%1 + 0x18], %%l4
- xor %%g2, %%o4, %%g2
- xor %%g3, %%o5, %%g3
- ldd [%2 + 0x00], %%o4
- xor %%g4, %%l0, %%g4
- xor %%g5, %%l1, %%g5
- ldd [%2 + 0x08], %%l0
- xor %%o0, %%l2, %%o0
- xor %%o1, %%l3, %%o1
- ldd [%2 + 0x10], %%l2
- xor %%o2, %%l4, %%o2
- xor %%o3, %%l5, %%o3
- ldd [%2 + 0x18], %%l4
- xor %%g2, %%o4, %%g2
- xor %%g3, %%o5, %%g3
- ldd [%3 + 0x00], %%o4
- xor %%g4, %%l0, %%g4
- xor %%g5, %%l1, %%g5
- ldd [%3 + 0x08], %%l0
- xor %%o0, %%l2, %%o0
- xor %%o1, %%l3, %%o1
- ldd [%3 + 0x10], %%l2
- xor %%o2, %%l4, %%o2
- xor %%o3, %%l5, %%o3
- ldd [%3 + 0x18], %%l4
- xor %%g2, %%o4, %%g2
- xor %%g3, %%o5, %%g3
- xor %%g4, %%l0, %%g4
- xor %%g5, %%l1, %%g5
- xor %%o0, %%l2, %%o0
- xor %%o1, %%l3, %%o1
- xor %%o2, %%l4, %%o2
- xor %%o3, %%l5, %%o3
- std %%g2, [%0 + 0x00]
- std %%g4, [%0 + 0x08]
- std %%o0, [%0 + 0x10]
- std %%o2, [%0 + 0x18]
- " : : "r" (destp), "r" (source1), "r" (source2), "r" (source3)
- : "g2", "g3", "g4", "g5", "o0", "o1", "o2", "o3", "o4", "o5",
- "l0", "l1", "l2", "l3", "l4", "l5");
- destp += 8;
- source1 += 8;
- source2 += 8;
- source3 += 8;
- }


- break;
- case 5:

- source2 = (long *) bh_ptr[2]->b_data;
- source3 = (long *) bh_ptr[3]->b_data;
- source4 = (long *) bh_ptr[4]->b_data;
- for (i = lines; i > 0; i--) {
- __asm__ __volatile__("
- ldd [%0 + 0x00], %%g2
- ldd [%0 + 0x08], %%g4
- ldd [%0 + 0x10], %%o0
- ldd [%0 + 0x18], %%o2
- ldd [%1 + 0x00], %%o4
- ldd [%1 + 0x08], %%l0
- ldd [%1 + 0x10], %%l2
- ldd [%1 + 0x18], %%l4
- xor %%g2, %%o4, %%g2
- xor %%g3, %%o5, %%g3
- ldd [%2 + 0x00], %%o4
- xor %%g4, %%l0, %%g4
- xor %%g5, %%l1, %%g5
- ldd [%2 + 0x08], %%l0
- xor %%o0, %%l2, %%o0
- xor %%o1, %%l3, %%o1
- ldd [%2 + 0x10], %%l2
- xor %%o2, %%l4, %%o2
- xor %%o3, %%l5, %%o3
- ldd [%2 + 0x18], %%l4
- xor %%g2, %%o4, %%g2
- xor %%g3, %%o5, %%g3
- ldd [%3 + 0x00], %%o4
- xor %%g4, %%l0, %%g4
- xor %%g5, %%l1, %%g5
- ldd [%3 + 0x08], %%l0
- xor %%o0, %%l2, %%o0
- xor %%o1, %%l3, %%o1
- ldd [%3 + 0x10], %%l2
- xor %%o2, %%l4, %%o2
- xor %%o3, %%l5, %%o3
- ldd [%3 + 0x18], %%l4
- xor %%g2, %%o4, %%g2
- xor %%g3, %%o5, %%g3
- ldd [%4 + 0x00], %%o4
- xor %%g4, %%l0, %%g4
- xor %%g5, %%l1, %%g5
- ldd [%4 + 0x08], %%l0
- xor %%o0, %%l2, %%o0
- xor %%o1, %%l3, %%o1
- ldd [%4 + 0x10], %%l2
- xor %%o2, %%l4, %%o2
- xor %%o3, %%l5, %%o3
- ldd [%4 + 0x18], %%l4
- xor %%g2, %%o4, %%g2
- xor %%g3, %%o5, %%g3
- xor %%g4, %%l0, %%g4
- xor %%g5, %%l1, %%g5
- xor %%o0, %%l2, %%o0
- xor %%o1, %%l3, %%o1
- xor %%o2, %%l4, %%o2
- xor %%o3, %%l5, %%o3
- std %%g2, [%0 + 0x00]
- std %%g4, [%0 + 0x08]
- std %%o0, [%0 + 0x10]
- std %%o2, [%0 + 0x18]
- " : : "r" (destp), "r" (source1), "r" (source2), "r" (source3), "r" (source4)
- : "g2", "g3", "g4", "g5", "o0", "o1", "o2", "o3", "o4", "o5",
- "l0", "l1", "l2", "l3", "l4", "l5");
- destp += 8;
- source1 += 8;
- source2 += 8;
- source3 += 8;
- source4 += 8;


- }
- break;
- }
-}

-#endif /* __sparc_v[78]__ */
-
-#ifdef __alpha__
-/*
- * High speed xor_block operation for RAID4/5 pipelined for Alpha EV5.
- * There is a second version using EV6 prefetch instructions.
- *
- * Copyright (C) 2000 Richard Henderson (r...@redhat.com)
- */
-
-XORBLOCK_TEMPLATE(alpha)
-{
- long lines = bh_ptr[0]->b_size / sizeof (long) / 8;
- long *d = (long *) bh_ptr[0]->b_data;
- long *s1 = (long *) bh_ptr[1]->b_data;
- long *s2, *s3, *s4;
-
- if (count == 2) goto two_blocks;
-
- s2 = (long *) bh_ptr[2]->b_data;
- if (count == 3) goto three_blocks;
-
- s3 = (long *) bh_ptr[3]->b_data;
- if (count == 4) goto four_blocks;
-
- s4 = (long *) bh_ptr[4]->b_data;
- goto five_blocks;
-
-two_blocks:
-asm volatile ("
- .align 4
-2:
- ldq $0,0(%0)
- ldq $1,0(%1)
- ldq $2,8(%0)
- ldq $3,8(%1)
-
- ldq $4,16(%0)
- ldq $5,16(%1)
- ldq $6,24(%0)
- ldq $7,24(%1)
-
- ldq $16,32(%0)
- ldq $17,32(%1)
- ldq $18,40(%0)
- ldq $19,40(%1)
-
- ldq $20,48(%0)
- ldq $21,48(%1)
- ldq $22,56(%0)
- xor $0,$1,$0 # 7 cycles from $1 load
-
- ldq $23,56(%1)
- xor $2,$3,$2
- stq $0,0(%0)
- xor $4,$5,$4
-
- stq $2,8(%0)
- xor $6,$7,$6
- stq $4,16(%0)
- xor $16,$17,$16
-
- stq $6,24(%0)
- xor $18,$19,$18
- stq $16,32(%0)
- xor $20,$21,$20
-
- stq $18,40(%0)
- xor $22,$23,$22
- stq $20,48(%0)
- subq %2,1,%2
-
- stq $22,56(%0)
- addq %0,64,%0
- addq %1,64,%1
- bgt %2,2b"
- : "=r"(d), "=r"(s1), "=r"(lines)
- : "0"(d), "1"(s1), "2"(lines)
- : "memory", "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
- "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23");
- return;
-
-three_blocks:
-asm volatile ("
- .align 4
-3:
- ldq $0,0(%0)
- ldq $1,0(%1)
- ldq $2,0(%2)
- ldq $3,8(%0)
-
- ldq $4,8(%1)
- ldq $6,16(%0)
- ldq $7,16(%1)
- ldq $17,24(%0)
-
- ldq $18,24(%1)
- ldq $20,32(%0)
- ldq $21,32(%1)
- ldq $5,8(%2)
-
- ldq $16,16(%2)
- ldq $19,24(%2)
- ldq $22,32(%2)
- nop
-
- xor $0,$1,$1 # 8 cycles from $0 load
- xor $3,$4,$4 # 6 cycles from $4 load
- xor $6,$7,$7 # 6 cycles from $7 load
- xor $17,$18,$18 # 5 cycles from $18 load
-
- xor $1,$2,$2 # 9 cycles from $2 load
- xor $20,$21,$21 # 5 cycles from $21 load
- stq $2,0(%0)
- xor $4,$5,$5 # 6 cycles from $5 load
-
- stq $5,8(%0)
- xor $7,$16,$16 # 7 cycles from $16 load
- stq $16,16(%0)
- xor $18,$19,$19 # 7 cycles from $19 load
-
- stq $19,24(%0)
- xor $21,$22,$22 # 7 cycles from $22 load
- stq $22,32(%0)
- nop
-
- ldq $0,40(%0)
- ldq $1,40(%1)
- ldq $3,48(%0)
- ldq $4,48(%1)
-
- ldq $6,56(%0)
- ldq $7,56(%1)
- ldq $2,40(%2)
- ldq $5,48(%2)
-
- ldq $16,56(%2)
- xor $0,$1,$1 # 4 cycles from $1 load
- xor $3,$4,$4 # 5 cycles from $4 load
- xor $6,$7,$7 # 5 cycles from $7 load
-
- xor $1,$2,$2 # 4 cycles from $2 load
- xor $4,$5,$5 # 5 cycles from $5 load
- stq $2,40(%0)
- xor $7,$16,$16 # 4 cycles from $16 load
-
- stq $5,48(%0)
- subq %3,1,%3
- stq $16,56(%0)
- addq %2,64,%2
-
- addq %1,64,%1
- addq %0,64,%0
- bgt %3,3b"
- : "=r"(d), "=r"(s1), "=r"(s2), "=r"(lines)
- : "0"(d), "1"(s1), "2"(s2), "3"(lines)
- : "memory", "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
- "$16", "$17", "$18", "$19", "$20", "$21", "$22");
- return;
-
-four_blocks:
-asm volatile ("
- .align 4
-4:
- ldq $0,0(%0)
- ldq $1,0(%1)
- ldq $2,0(%2)
- ldq $3,0(%3)
-
- ldq $4,8(%0)
- ldq $5,8(%1)
- ldq $6,8(%2)
- ldq $7,8(%3)
-
- ldq $16,16(%0)
- ldq $17,16(%1)
- ldq $18,16(%2)
- ldq $19,16(%3)
-
- ldq $20,24(%0)
- xor $0,$1,$1 # 6 cycles from $1 load
- ldq $21,24(%1)
- xor $2,$3,$3 # 6 cycles from $3 load
-
- ldq $0,24(%2)
- xor $1,$3,$3
- ldq $1,24(%3)
- xor $4,$5,$5 # 7 cycles from $5 load
-
- stq $3,0(%0)
- xor $6,$7,$7
- xor $16,$17,$17 # 7 cycles from $17 load
- xor $5,$7,$7
-
- stq $7,8(%0)
- xor $18,$19,$19 # 7 cycles from $19 load
- ldq $2,32(%0)
- xor $17,$19,$19
-
- ldq $3,32(%1)
- ldq $4,32(%2)
- ldq $5,32(%3)
- xor $20,$21,$21 # 8 cycles from $21 load
-
- ldq $6,40(%0)
- ldq $7,40(%1)
- ldq $16,40(%2)
- ldq $17,40(%3)
-
- stq $19,16(%0)
- xor $0,$1,$1 # 9 cycles from $1 load
- xor $2,$3,$3 # 5 cycles from $3 load
- xor $21,$1,$1
-
- ldq $18,48(%0)
- xor $4,$5,$5 # 5 cycles from $5 load
- ldq $19,48(%1)
- xor $3,$5,$5
-
- ldq $20,48(%2)
- ldq $21,48(%3)
- ldq $0,56(%0)
- ldq $1,56(%1)
-
- ldq $2,56(%2)
- xor $6,$7,$7 # 8 cycles from $6 load
- ldq $3,56(%3)
- xor $16,$17,$17 # 8 cycles from $17 load
-
- xor $7,$17,$17
- xor $18,$19,$19 # 5 cycles from $19 load
- xor $20,$21,$21 # 5 cycles from $21 load
- xor $19,$21,$21
-
- stq $1,24(%0)
- xor $0,$1,$1 # 5 cycles from $1 load
- stq $5,32(%0)
- xor $2,$3,$3 # 4 cycles from $3 load
-
- stq $17,40(%0)
- xor $1,$3,$3
- stq $21,48(%0)
- subq %4,1,%4
-
- stq $3,56(%0)
- addq %3,64,%3
- addq %2,64,%2
- addq %1,64,%1
-
- addq %0,64,%0
- bgt %4,4b"
- : "=r"(d), "=r"(s1), "=r"(s2), "=r"(s3), "=r"(lines)
- : "0"(d), "1"(s1), "2"(s2), "3"(s3), "4"(lines)
- : "memory", "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
- "$16", "$17", "$18", "$19", "$20", "$21");
- return;
-
-five_blocks:
-asm volatile ("
- ldq %0,0(%6)
- ldq %1,8(%6)
- ldq %2,16(%6)
- ldq %3,24(%6)
- ldq %4,32(%6)
- ldq %0,%7(%0)
- ldq %1,%7(%1)
- ldq %2,%7(%2)
- ldq %3,%7(%3)
- ldq %4,%7(%4)
- .align 4
-5:
- ldq $0,0(%0)
- ldq $1,0(%1)
- ldq $2,0(%2)
- ldq $3,0(%3)
-
- ldq $4,0(%4)
- ldq $5,8(%0)
- ldq $6,8(%1)
- ldq $7,8(%2)
-
- ldq $16,8(%3)
- ldq $17,8(%4)
- ldq $18,16(%0)
- ldq $19,16(%1)
-
- ldq $20,16(%2)
- xor $0,$1,$1 # 6 cycles from $1 load
- ldq $21,16(%3)
- xor $2,$3,$3 # 6 cycles from $3 load
-
- ldq $0,16(%4)
- xor $1,$3,$3
- ldq $1,24(%0)
- xor $3,$4,$4 # 7 cycles from $4 load
-
- stq $4,0(%0)
- xor $5,$6,$6 # 7 cycles from $6 load
- xor $7,$16,$16 # 7 cycles from $16 load
- xor $6,$17,$17 # 7 cycles from $17 load
-
- ldq $2,24(%1)
- xor $16,$17,$17
- ldq $3,24(%2)
- xor $18,$19,$19 # 8 cycles from $19 load
-
- stq $17,8(%0)
- xor $19,$20,$20 # 8 cycles from $20 load
- ldq $4,24(%3)
- xor $21,$0,$0 # 7 cycles from $0 load
-
- ldq $5,24(%4)
- xor $20,$0,$0
- ldq $6,32(%0)
- ldq $7,32(%1)
-
- stq $0,16(%0)
- xor $1,$2,$2 # 6 cycles from $2 load
- ldq $16,32(%2)
- xor $3,$4,$4 # 4 cycles from $4 load
-
- ldq $17,32(%3)
- xor $2,$4,$4
- ldq $18,32(%4)
- ldq $19,40(%0)
-
- ldq $20,40(%1)
- ldq $21,40(%2)
- ldq $0,40(%3)
- xor $4,$5,$5 # 7 cycles from $5 load
-
- stq $5,24(%0)
- xor $6,$7,$7 # 7 cycles from $7 load
- ldq $1,40(%4)
- ldq $2,48(%0)
-
- ldq $3,48(%1)
- xor $7,$16,$16 # 7 cycles from $16 load
- ldq $4,48(%2)
- xor $17,$18,$18 # 6 cycles from $18 load
-
- ldq $5,48(%3)
- xor $16,$18,$18
- ldq $6,48(%4)
- xor $19,$20,$20 # 7 cycles from $20 load
-
- stq $18,32(%0)
- xor $20,$21,$21 # 8 cycles from $21 load
- ldq $7,56(%0)
- xor $0,$1,$1 # 6 cycles from $1 load
-
- ldq $16,56(%1)
- ldq $17,56(%2)
- ldq $18,56(%3)
- ldq $19,56(%4)
-
- xor $21,$1,$1
- xor $2,$3,$3 # 9 cycles from $3 load
- xor $3,$4,$4 # 9 cycles from $4 load
- xor $5,$6,$6 # 8 cycles from $6 load
-
- unop
- xor $4,$6,$6
- xor $7,$16,$16 # 7 cycles from $16 load
- xor $17,$18,$18 # 6 cycles from $18 load
-
- stq $6,48(%0)
- xor $16,$18,$18
- subq %5,1,%5
- xor $18,$19,$19 # 8 cycles from $19 load
-
- stq $19,56(%0)
- addq %4,64,%4
- addq %3,64,%3
- addq %2,64,%2
-
- addq %1,64,%1
- addq %0,64,%0
- bgt %5,5b"
- : "=&r"(d), "=&r"(s1), "=&r"(s2), "=&r"(s3), "=r"(s4), "=r"(lines)
- /* ARG! We've run out of asm arguments! We've got to reload
- all those pointers we just loaded. */
- : "r"(bh_ptr), "i" (&((struct buffer_head *)0)->b_data), "5"(lines)
- : "memory", "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
- "$16", "$17", "$18", "$19", "$20", "$21");
- return;
-}
-
-#define prefetch(base, ofs) \
- asm("ldq $31,%2(%0)" : "=r"(base) : "0"(base), "i"(ofs))
-
-XORBLOCK_TEMPLATE(alpha_prefetch)
-{
- long lines = bh_ptr[0]->b_size / sizeof (long) / 8;
- long *d = (long *) bh_ptr[0]->b_data;
- long *s1 = (long *) bh_ptr[1]->b_data;
- long *s2, *s3, *s4;
- long p;
-
- p = count == 2;
- prefetch(d, 0);
- prefetch(s1, 0);
- prefetch(d, 64);
- prefetch(s1, 64);
- prefetch(d, 128);
- prefetch(s1, 128);
- prefetch(d, 192);
- prefetch(s1, 192);
- if (p) goto two_blocks;
-
- s2 = (long *) bh_ptr[2]->b_data;
- p = count == 3;
- prefetch(s2, 0);
- prefetch(s2, 64);
- prefetch(s2, 128);
- prefetch(s2, 192);
- if (p) goto three_blocks;
-
- s3 = (long *) bh_ptr[3]->b_data;
- p = count == 4;
- prefetch(s3, 0);
- prefetch(s3, 64);
- prefetch(s3, 128);
- prefetch(s3, 192);
- if (p) goto four_blocks;
-
- s4 = (long *) bh_ptr[4]->b_data;
- prefetch(s4, 0);
- prefetch(s4, 64);
- prefetch(s4, 128);
- prefetch(s4, 192);
- goto five_blocks;
-
-two_blocks:
-asm volatile ("
- .align 4
-2:
- ldq $0,0(%0)
- ldq $1,0(%1)
- ldq $2,8(%0)
- ldq $3,8(%1)
-
- ldq $4,16(%0)
- ldq $5,16(%1)
- ldq $6,24(%0)
- ldq $7,24(%1)
-
- ldq $16,32(%0)
- ldq $17,32(%1)
- ldq $18,40(%0)
- ldq $19,40(%1)
-
- ldq $20,48(%0)
- ldq $21,48(%1)
- ldq $22,56(%0)
- ldq $23,56(%1)
-
- ldq $31,256(%0)
- xor $0,$1,$0 # 8 cycles from $1 load
- ldq $31,256(%1)
- xor $2,$3,$2
-
- stq $0,0(%0)
- xor $4,$5,$4
- stq $2,8(%0)
- xor $6,$7,$6
-
- stq $4,16(%0)
- xor $16,$17,$16
- stq $6,24(%0)
- xor $18,$19,$18
-
- stq $16,32(%0)
- xor $20,$21,$20
- stq $18,40(%0)
- xor $22,$23,$22
-
- stq $20,48(%0)
- subq %2,1,%2
- stq $22,56(%0)
- addq %0,64,%0
-
- addq %1,64,%1
- bgt %2,2b"
- : "=r"(d), "=r"(s1), "=r"(lines)
- : "0"(d), "1"(s1), "2"(lines)
- : "memory", "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
- "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23");
- return;
-
-three_blocks:
-asm volatile ("
- .align 4
-3:
- ldq $0,0(%0)
- ldq $1,0(%1)
- ldq $2,0(%2)
- ldq $3,8(%0)
-
- ldq $4,8(%1)
- ldq $6,16(%0)
- ldq $7,16(%1)
- ldq $17,24(%0)
-
- ldq $18,24(%1)
- ldq $20,32(%0)
- ldq $21,32(%1)
- ldq $5,8(%2)
-
- ldq $16,16(%2)
- ldq $19,24(%2)
- ldq $22,32(%2)
- nop
-
- xor $0,$1,$1 # 8 cycles from $0 load
- xor $3,$4,$4 # 7 cycles from $4 load
- xor $6,$7,$7 # 6 cycles from $7 load
- xor $17,$18,$18 # 5 cycles from $18 load
-
- xor $1,$2,$2 # 9 cycles from $2 load
- xor $20,$21,$21 # 5 cycles from $21 load
- stq $2,0(%0)
- xor $4,$5,$5 # 6 cycles from $5 load
-
- stq $5,8(%0)
- xor $7,$16,$16 # 7 cycles from $16 load
- stq $16,16(%0)
- xor $18,$19,$19 # 7 cycles from $19 load
-
- stq $19,24(%0)
- xor $21,$22,$22 # 7 cycles from $22 load
- stq $22,32(%0)
- nop
-
- ldq $0,40(%0)
- ldq $1,40(%1)
- ldq $3,48(%0)
- ldq $4,48(%1)
-
- ldq $6,56(%0)
- ldq $7,56(%1)
- ldq $2,40(%2)
- ldq $5,48(%2)
-
- ldq $16,56(%2)
- ldq $31,256(%0)
- ldq $31,256(%1)
- ldq $31,256(%2)
-
- xor $0,$1,$1 # 6 cycles from $1 load
- xor $3,$4,$4 # 5 cycles from $4 load
- xor $6,$7,$7 # 5 cycles from $7 load
- xor $1,$2,$2 # 4 cycles from $2 load
-
- xor $4,$5,$5 # 5 cycles from $5 load
- xor $7,$16,$16 # 4 cycles from $16 load
- stq $2,40(%0)
- subq %3,1,%3
-
- stq $5,48(%0)
- addq %2,64,%2
- stq $16,56(%0)
- addq %1,64,%1
-
- addq %0,64,%0
- bgt %3,3b"
- : "=r"(d), "=r"(s1), "=r"(s2), "=r"(lines)
- : "0"(d), "1"(s1), "2"(s2), "3"(lines)
- : "memory", "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
- "$16", "$17", "$18", "$19", "$20", "$21", "$22");
- return;
-
-four_blocks:
-asm volatile ("
- .align 4
-4:
- ldq $0,0(%0)
- ldq $1,0(%1)
- ldq $2,0(%2)
- ldq $3,0(%3)
-
- ldq $4,8(%0)
- ldq $5,8(%1)
- ldq $6,8(%2)
- ldq $7,8(%3)
-
- ldq $16,16(%0)
- ldq $17,16(%1)
- ldq $18,16(%2)
- ldq $19,16(%3)
-
- ldq $20,24(%0)
- xor $0,$1,$1 # 6 cycles from $1 load
- ldq $21,24(%1)
- xor $2,$3,$3 # 6 cycles from $3 load
-
- ldq $0,24(%2)
- xor $1,$3,$3
- ldq $1,24(%3)
- xor $4,$5,$5 # 7 cycles from $5 load
-
- stq $3,0(%0)
- xor $6,$7,$7
- xor $16,$17,$17 # 7 cycles from $17 load
- xor $5,$7,$7
-
- stq $7,8(%0)
- xor $18,$19,$19 # 7 cycles from $19 load
- ldq $2,32(%0)
- xor $17,$19,$19
-
- ldq $3,32(%1)
- ldq $4,32(%2)
- ldq $5,32(%3)
- xor $20,$21,$21 # 8 cycles from $21 load
-
- ldq $6,40(%0)
- ldq $7,40(%1)
- ldq $16,40(%2)
- ldq $17,40(%3)
-
- stq $19,16(%0)
- xor $0,$1,$1 # 9 cycles from $1 load
- xor $2,$3,$3 # 5 cycles from $3 load
- xor $21,$1,$1
-
- ldq $18,48(%0)
- xor $4,$5,$5 # 5 cycles from $5 load
- ldq $19,48(%1)
- xor $3,$5,$5
-
- ldq $20,48(%2)
- ldq $21,48(%3)
- ldq $0,56(%0)
- ldq $1,56(%1)
-
- ldq $2,56(%2)
- xor $6,$7,$7 # 8 cycles from $6 load
- ldq $3,56(%3)
- xor $16,$17,$17 # 8 cycles from $17 load
-
- ldq $31,256(%0)
- xor $7,$17,$17
- ldq $31,256(%1)
- xor $18,$19,$19 # 6 cycles from $19 load
-
- ldq $31,256(%2)
- xor $20,$21,$21 # 6 cycles from $21 load
- ldq $31,256(%3)
- xor $19,$21,$21
-
- stq $1,24(%0)
- xor $0,$1,$1 # 7 cycles from $1 load
- stq $5,32(%0)
- xor $2,$3,$3 # 6 cycles from $3 load
-
- stq $17,40(%0)
- xor $1,$3,$3
- stq $21,48(%0)
- subq %4,1,%4
-
- stq $3,56(%0)
- addq %3,64,%3
- addq %2,64,%2
- addq %1,64,%1
-
- addq %0,64,%0
- bgt %4,4b"
- : "=r"(d), "=r"(s1), "=r"(s2), "=r"(s3), "=r"(lines)
- : "0"(d), "1"(s1), "2"(s2), "3"(s3), "4"(lines)
- : "memory", "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
- "$16", "$17", "$18", "$19", "$20", "$21");
- return;
-
-five_blocks:
-asm volatile ("
- ldq %0,0(%6)
- ldq %1,8(%6)
- ldq %2,16(%6)
- ldq %3,24(%6)
- ldq %4,32(%6)
- ldq %0,%7(%0)
- ldq %1,%7(%1)
- ldq %2,%7(%2)
- ldq %3,%7(%3)
- ldq %4,%7(%4)
- .align 4
-5:
- ldq $0,0(%0)
- ldq $1,0(%1)
- ldq $2,0(%2)
- ldq $3,0(%3)
-
- ldq $4,0(%4)
- ldq $5,8(%0)
- ldq $6,8(%1)
- ldq $7,8(%2)
-
- ldq $16,8(%3)
- ldq $17,8(%4)
- ldq $18,16(%0)
- ldq $19,16(%1)
-
- ldq $20,16(%2)
- xor $0,$1,$1 # 6 cycles from $1 load
- ldq $21,16(%3)
- xor $2,$3,$3 # 6 cycles from $3 load
-
- ldq $0,16(%4)
- xor $1,$3,$3
- ldq $1,24(%0)
- xor $3,$4,$4 # 7 cycles from $4 load
-
- stq $4,0(%0)
- xor $5,$6,$6 # 7 cycles from $6 load
- xor $7,$16,$16 # 7 cycles from $16 load
- xor $6,$17,$17 # 7 cycles from $17 load
-
- ldq $2,24(%1)
- xor $16,$17,$17
- ldq $3,24(%2)
- xor $18,$19,$19 # 8 cycles from $19 load
-
- stq $17,8(%0)
- xor $19,$20,$20 # 8 cycles from $20 load
- ldq $4,24(%3)
- xor $21,$0,$0 # 7 cycles from $0 load
-
- ldq $5,24(%4)
- xor $20,$0,$0
- ldq $6,32(%0)
- ldq $7,32(%1)
-
- stq $0,16(%0)
- xor $1,$2,$2 # 6 cycles from $2 load
- ldq $16,32(%2)
- xor $3,$4,$4 # 4 cycles from $4 load
-
- ldq $17,32(%3)
- xor $2,$4,$4
- ldq $18,32(%4)
- ldq $19,40(%0)
-
- ldq $20,40(%1)
- ldq $21,40(%2)
- ldq $0,40(%3)
- xor $4,$5,$5 # 7 cycles from $5 load
-
- stq $5,24(%0)
- xor $6,$7,$7 # 7 cycles from $7 load
- ldq $1,40(%4)
- ldq $2,48(%0)
-
- ldq $3,48(%1)
- xor $7,$16,$16 # 7 cycles from $16 load
- ldq $4,48(%2)
- xor $17,$18,$18 # 6 cycles from $18 load
-
- ldq $5,48(%3)
- xor $16,$18,$18
- ldq $6,48(%4)
- xor $19,$20,$20 # 7 cycles from $20 load
-
- stq $18,32(%0)
- xor $20,$21,$21 # 8 cycles from $21 load
- ldq $7,56(%0)
- xor $0,$1,$1 # 6 cycles from $1 load
-
- ldq $16,56(%1)
- ldq $17,56(%2)
- ldq $18,56(%3)
- ldq $19,56(%4)
-
- ldq $31,256(%0)
- xor $21,$1,$1
- ldq $31,256(%1)
- xor $2,$3,$3 # 9 cycles from $3 load
-
- ldq $31,256(%2)
- xor $3,$4,$4 # 9 cycles from $4 load
- ldq $31,256(%3)
- xor $5,$6,$6 # 8 cycles from $6 load
-
- ldq $31,256(%4)
- xor $4,$6,$6
- xor $7,$16,$16 # 7 cycles from $16 load
- xor $17,$18,$18 # 6 cycles from $18 load
-
- stq $6,48(%0)
- xor $16,$18,$18
- subq %5,1,%5
- xor $18,$19,$19 # 8 cycles from $19 load
-
- stq $19,56(%0)
- addq %4,64,%4
- addq %3,64,%3
- addq %2,64,%2
-
- addq %1,64,%1
- addq %0,64,%0
- bgt %5,5b"
- : "=&r"(d), "=&r"(s1), "=&r"(s2), "=&r"(s3), "=r"(s4), "=r"(lines)
- /* ARG! We've run out of asm arguments! We've got to reload
- all those pointers we just loaded. */
- : "r"(bh_ptr), "i" (&((struct buffer_head *)0)->b_data), "5"(lines)
- : "memory", "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
- "$16", "$17", "$18", "$19", "$20", "$21");
- return;
-}
-
-#undef prefetch
-
-#endif /* __alpha__ */
-
-#ifndef __sparc_v9__
-
-/*
- * this one works reasonably on any x86 CPU
- * (send me an assembly version for inclusion if you can make it faster)
- *
- * this one is just as fast as written in pure assembly on x86.
- * the reason for this separate version is that the
- * fast open-coded xor routine "32reg" produces suboptimal code
- * on x86, due to lack of registers.
- */
-XORBLOCK_TEMPLATE(8regs)
-{
- int len = bh_ptr[0]->b_size;
- long *destp = (long *) bh_ptr[0]->b_data;
- long *source1, *source2, *source3, *source4;
- long lines = len / (sizeof (long)) / 8, i;


-
- switch(count) {
- case 2:

- source1 = (long *) bh_ptr[1]->b_data;
- for (i = lines; i > 0; i--) {
- *(destp + 0) ^= *(source1 + 0);
- *(destp + 1) ^= *(source1 + 1);
- *(destp + 2) ^= *(source1 + 2);
- *(destp + 3) ^= *(source1 + 3);
- *(destp + 4) ^= *(source1 + 4);
- *(destp + 5) ^= *(source1 + 5);
- *(destp + 6) ^= *(source1 + 6);
- *(destp + 7) ^= *(source1 + 7);
- source1 += 8;
- destp += 8;
- }


- break;
- case 3:

- source2 = (long *) bh_ptr[2]->b_data;
- source1 = (long *) bh_ptr[1]->b_data;
- for (i = lines; i > 0; i--) {
- *(destp + 0) ^= *(source1 + 0);
- *(destp + 0) ^= *(source2 + 0);
- *(destp + 1) ^= *(source1 + 1);
- *(destp + 1) ^= *(source2 + 1);
- *(destp + 2) ^= *(source1 + 2);
- *(destp + 2) ^= *(source2 + 2);
- *(destp + 3) ^= *(source1 + 3);
- *(destp + 3) ^= *(source2 + 3);
- *(destp + 4) ^= *(source1 + 4);
- *(destp + 4) ^= *(source2 + 4);
- *(destp + 5) ^= *(source1 + 5);
- *(destp + 5) ^= *(source2 + 5);
- *(destp + 6) ^= *(source1 + 6);
- *(destp + 6) ^= *(source2 + 6);
- *(destp + 7) ^= *(source1 + 7);
- *(destp + 7) ^= *(source2 + 7);
- source1 += 8;
- source2 += 8;
- destp += 8;
- }


- break;
- case 4:

- source3 = (long *) bh_ptr[3]->b_data;
- source2 = (long *) bh_ptr[2]->b_data;
- source1 = (long *) bh_ptr[1]->b_data;
- for (i = lines; i > 0; i--) {
- *(destp + 0) ^= *(source1 + 0);
- *(destp + 0) ^= *(source2 + 0);
- *(destp + 0) ^= *(source3 + 0);
- *(destp + 1) ^= *(source1 + 1);
- *(destp + 1) ^= *(source2 + 1);
- *(destp + 1) ^= *(source3 + 1);
- *(destp + 2) ^= *(source1 + 2);
- *(destp + 2) ^= *(source2 + 2);
- *(destp + 2) ^= *(source3 + 2);
- *(destp + 3) ^= *(source1 + 3);
- *(destp + 3) ^= *(source2 + 3);
- *(destp + 3) ^= *(source3 + 3);
- *(destp + 4) ^= *(source1 + 4);
- *(destp + 4) ^= *(source2 + 4);
- *(destp + 4) ^= *(source3 + 4);
- *(destp + 5) ^= *(source1 + 5);
- *(destp + 5) ^= *(source2 + 5);
- *(destp + 5) ^= *(source3 + 5);
- *(destp + 6) ^= *(source1 + 6);
- *(destp + 6) ^= *(source2 + 6);
- *(destp + 6) ^= *(source3 + 6);
- *(destp + 7) ^= *(source1 + 7);
- *(destp + 7) ^= *(source2 + 7);
- *(destp + 7) ^= *(source3 + 7);
- source1 += 8;
- source2 += 8;
- source3 += 8;
- destp += 8;
- }


- break;
- case 5:

- source4 = (long *) bh_ptr[4]->b_data;
- source3 = (long *) bh_ptr[3]->b_data;
- source2 = (long *) bh_ptr[2]->b_data;
- source1 = (long *) bh_ptr[1]->b_data;
- for (i = lines; i > 0; i--) {
- *(destp + 0) ^= *(source1 + 0);
- *(destp + 0) ^= *(source2 + 0);
- *(destp + 0) ^= *(source3 + 0);
- *(destp + 0) ^= *(source4 + 0);
- *(destp + 1) ^= *(source1 + 1);
- *(destp + 1) ^= *(source2 + 1);
- *(destp + 1) ^= *(source3 + 1);
- *(destp + 1) ^= *(source4 + 1);
- *(destp + 2) ^= *(source1 + 2);
- *(destp + 2) ^= *(source2 + 2);
- *(destp + 2) ^= *(source3 + 2);
- *(destp + 2) ^= *(source4 + 2);
- *(destp + 3) ^= *(source1 + 3);
- *(destp + 3) ^= *(source2 + 3);
- *(destp + 3) ^= *(source3 + 3);
- *(destp + 3) ^= *(source4 + 3);
- *(destp + 4) ^= *(source1 + 4);
- *(destp + 4) ^= *(source2 + 4);
- *(destp + 4) ^= *(source3 + 4);
- *(destp + 4) ^= *(source4 + 4);
- *(destp + 5) ^= *(source1 + 5);
- *(destp + 5) ^= *(source2 + 5);
- *(destp + 5) ^= *(source3 + 5);
- *(destp + 5) ^= *(source4 + 5);
- *(destp + 6) ^= *(source1 + 6);
- *(destp + 6) ^= *(source2 + 6);
- *(destp + 6) ^= *(source3 + 6);
- *(destp + 6) ^= *(source4 + 6);
- *(destp + 7) ^= *(source1 + 7);
- *(destp + 7) ^= *(source2 + 7);
- *(destp + 7) ^= *(source3 + 7);
- *(destp + 7) ^= *(source4 + 7);
- source1 += 8;
- source2 += 8;
- source3 += 8;
- source4 += 8;
- destp += 8;


- }
- break;
- }
-}
-

-/*
- * platform independent RAID5 checksum calculation, this should
- * be very fast on any platform that has a decent amount of
- * registers. (32 or more)
- */
-XORBLOCK_TEMPLATE(32regs)
-{
- int size = bh_ptr[0]->b_size;
- int lines = size / (sizeof (long)) / 8, i;
- long *destp = (long *) bh_ptr[0]->b_data;
- long *source1, *source2, *source3, *source4;
-
- /* LOTS of registers available...
- We do explicite loop-unrolling here for code which
- favours RISC machines. In fact this is almoast direct
- RISC assembly on Alpha and SPARC :-) */
-


-
- switch(count) {
- case 2:

- source1 = (long *) bh_ptr[1]->b_data;
- for (i = lines; i > 0; i--) {
- register long d0, d1, d2, d3, d4, d5, d6, d7;
- d0 = destp[0]; /* Pull the stuff into registers */
- d1 = destp[1]; /* ... in bursts, if possible. */
- d2 = destp[2];
- d3 = destp[3];
- d4 = destp[4];
- d5 = destp[5];
- d6 = destp[6];
- d7 = destp[7];
- d0 ^= source1[0];
- d1 ^= source1[1];
- d2 ^= source1[2];
- d3 ^= source1[3];
- d4 ^= source1[4];
- d5 ^= source1[5];
- d6 ^= source1[6];
- d7 ^= source1[7];
- destp[0] = d0; /* Store the result (in burts) */
- destp[1] = d1;
- destp[2] = d2;
- destp[3] = d3;
- destp[4] = d4; /* Store the result (in burts) */
- destp[5] = d5;
- destp[6] = d6;
- destp[7] = d7;
- source1 += 8;
- destp += 8;
- }


- break;
- case 3:

- source2 = (long *) bh_ptr[2]->b_data;
- source1 = (long *) bh_ptr[1]->b_data;
- for (i = lines; i > 0; i--) {
- register long d0, d1, d2, d3, d4, d5, d6, d7;
- d0 = destp[0]; /* Pull the stuff into registers */
- d1 = destp[1]; /* ... in bursts, if possible. */
- d2 = destp[2];
- d3 = destp[3];
- d4 = destp[4];
- d5 = destp[5];
- d6 = destp[6];
- d7 = destp[7];
- d0 ^= source1[0];
- d1 ^= source1[1];
- d2 ^= source1[2];
- d3 ^= source1[3];
- d4 ^= source1[4];
- d5 ^= source1[5];
- d6 ^= source1[6];
- d7 ^= source1[7];
- d0 ^= source2[0];
- d1 ^= source2[1];
- d2 ^= source2[2];
- d3 ^= source2[3];
- d4 ^= source2[4];
- d5 ^= source2[5];
- d6 ^= source2[6];
- d7 ^= source2[7];
- destp[0] = d0; /* Store the result (in burts) */
- destp[1] = d1;
- destp[2] = d2;
- destp[3] = d3;
- destp[4] = d4; /* Store the result (in burts) */
- destp[5] = d5;
- destp[6] = d6;
- destp[7] = d7;
- source1 += 8;
- source2 += 8;
- destp += 8;
- }


- break;
- case 4:

- source3 = (long *) bh_ptr[3]->b_data;
- source2 = (long *) bh_ptr[2]->b_data;
- source1 = (long *) bh_ptr[1]->b_data;
- for (i = lines; i > 0; i--) {
- register long d0, d1, d2, d3, d4, d5, d6, d7;
- d0 = destp[0]; /* Pull the stuff into registers */
- d1 = destp[1]; /* ... in bursts, if possible. */
- d2 = destp[2];
- d3 = destp[3];
- d4 = destp[4];
- d5 = destp[5];
- d6 = destp[6];
- d7 = destp[7];
- d0 ^= source1[0];
- d1 ^= source1[1];
- d2 ^= source1[2];
- d3 ^= source1[3];
- d4 ^= source1[4];
- d5 ^= source1[5];
- d6 ^= source1[6];
- d7 ^= source1[7];
- d0 ^= source2[0];
- d1 ^= source2[1];
- d2 ^= source2[2];
- d3 ^= source2[3];
- d4 ^= source2[4];
- d5 ^= source2[5];
- d6 ^= source2[6];
- d7 ^= source2[7];
- d0 ^= source3[0];
- d1 ^= source3[1];
- d2 ^= source3[2];
- d3 ^= source3[3];
- d4 ^= source3[4];
- d5 ^= source3[5];
- d6 ^= source3[6];
- d7 ^= source3[7];
- destp[0] = d0; /* Store the result (in burts) */
- destp[1] = d1;
- destp[2] = d2;
- destp[3] = d3;
- destp[4] = d4; /* Store the result (in burts) */
- destp[5] = d5;
- destp[6] = d6;
- destp[7] = d7;
- source1 += 8;
- source2 += 8;
- source3 += 8;
- destp += 8;
- }


- break;
- case 5:

- source4 = (long *) bh_ptr[4]->b_data;
- source3 = (long *) bh_ptr[3]->b_data;
- source2 = (long *) bh_ptr[2]->b_data;
- source1 = (long *) bh_ptr[1]->b_data;
- for (i = lines; i > 0; i--) {
- register long d0, d1, d2, d3, d4, d5, d6, d7;
- d0 = destp[0]; /* Pull the stuff into registers */
- d1 = destp[1]; /* ... in bursts, if possible. */
- d2 = destp[2];
- d3 = destp[3];
- d4 = destp[4];
- d5 = destp[5];
- d6 = destp[6];
- d7 = destp[7];
- d0 ^= source1[0];
- d1 ^= source1[1];
- d2 ^= source1[2];
- d3 ^= source1[3];
- d4 ^= source1[4];
- d5 ^= source1[5];
- d6 ^= source1[6];
- d7 ^= source1[7];
- d0 ^= source2[0];
- d1 ^= source2[1];
- d2 ^= source2[2];
- d3 ^= source2[3];
- d4 ^= source2[4];
- d5 ^= source2[5];
- d6 ^= source2[6];
- d7 ^= source2[7];
- d0 ^= source3[0];
- d1 ^= source3[1];
- d2 ^= source3[2];
- d3 ^= source3[3];
- d4 ^= source3[4];
- d5 ^= source3[5];
- d6 ^= source3[6];
- d7 ^= source3[7];
- d0 ^= source4[0];
- d1 ^= source4[1];
- d2 ^= source4[2];
- d3 ^= source4[3];
- d4 ^= source4[4];
- d5 ^= source4[5];
- d6 ^= source4[6];
- d7 ^= source4[7];
- destp[0] = d0; /* Store the result (in burts) */
- destp[1] = d1;
- destp[2] = d2;
- destp[3] = d3;
- destp[4] = d4; /* Store the result (in burts) */
- destp[5] = d5;
- destp[6] = d6;
- destp[7] = d7;
- source1 += 8;
- source2 += 8;
- source3 += 8;
- source4 += 8;
- destp += 8;


- }
- break;
- }
-}
-

-/*
- * (the -6*32 shift factor colors the cache)
- */
-#define SIZE (PAGE_SIZE-6*32)
-
-static void xor_speed ( struct xor_block_template * func,
- struct buffer_head *b1, struct buffer_head *b2)
-{
- int speed;
- unsigned long now;
- int i, count, max;
- struct buffer_head *bh_ptr[6];
-
- func->next = xor_functions;
- xor_functions = func;
- bh_ptr[0] = b1;
- bh_ptr[1] = b2;
-
- /*
- * count the number of XORs done during a whole jiffy.
- * calculate the speed of checksumming from this.
- * (we use a 2-page allocation to have guaranteed
- * color L1-cache layout)
- */
- max = 0;
- for (i = 0; i < 5; i++) {
- now = jiffies;
- count = 0;
- while (jiffies == now) {
- mb();
- func->xor_block(2,bh_ptr);
- mb();
- count++;
- mb();
- }
- if (count > max)
- max = count;
- }
-
- speed = max * (HZ*SIZE/1024);
- func->speed = speed;
-
- printk( " %-10s: %5d.%03d MB/sec\n", func->name,
- speed / 1000, speed % 1000);
-}
-
-static inline void pick_fastest_function(void)
-{
- struct xor_block_template *f, *fastest;
-
- fastest = xor_functions;
- for (f = fastest; f; f = f->next) {
- if (f->speed > fastest->speed)
- fastest = f;
- }
-#ifdef CONFIG_X86_XMM
- if (cpu_has_xmm) {
- /* we force the use of the KNI xor block because it
- can write around l2. we may also be able
- to load into the l1 only depending on how
- the cpu deals with a load to a line that is
- being prefetched.
- */
- fastest = &t_xor_block_pIII_kni;
- }
-#endif
-#ifdef __alpha__
- if (implver() == IMPLVER_EV6) {
- /* Force the use of alpha_prefetch if EV6, as it
- is significantly faster in the cold cache case. */
- fastest = &t_xor_block_alpha_prefetch;
- }
-#endif
- xor_block = fastest->xor_block;
- printk( "using fastest function: %s (%d.%03d MB/sec)\n", fastest->name,
- fastest->speed / 1000, fastest->speed % 1000);
-}
-
-static struct buffer_head b1, b2;
-
-void calibrate_xor_block(void)
-{
- if (xor_block)
- return;
- memset(&b1,0,sizeof(b1));
- b2 = b1;
-
- b1.b_data = (char *) md__get_free_pages(GFP_KERNEL,2);
- if (!b1.b_data) {
- pick_fastest_function();
- return;
- }
- b2.b_data = b1.b_data + 2*PAGE_SIZE + SIZE;
-
- b1.b_size = SIZE;
-
- printk(KERN_INFO "raid5: measuring checksumming speed\n");
-
- sti(); /* should be safe */
-
-#if defined(__sparc__) && !defined(__sparc_v9__)
- printk(KERN_INFO "raid5: trying high-speed SPARC checksum routine\n");
- xor_speed(&t_xor_block_SPARC,&b1,&b2);
-#endif
-
-#ifdef CONFIG_X86_XMM
- if (cpu_has_xmm) {
- printk(KERN_INFO
- "raid5: KNI detected, trying cache-avoiding KNI checksum routine\n");
- xor_speed(&t_xor_block_pIII_kni,&b1,&b2);


- }
-#endif /* CONFIG_X86_XMM */
-

-#ifdef __i386__
- if (md_cpu_has_mmx()) {
- printk(KERN_INFO
- "raid5: MMX detected, trying high-speed MMX checksum routines\n");
- xor_speed(&t_xor_block_pII_mmx,&b1,&b2);
- xor_speed(&t_xor_block_p5_mmx,&b1,&b2);
- }
-#endif /* __i386__ */
-
-#ifdef __alpha__
- xor_speed(&t_xor_block_alpha,&b1,&b2);
- xor_speed(&t_xor_block_alpha_prefetch,&b1,&b2);
-#endif
-
- xor_speed(&t_xor_block_8regs,&b1,&b2);
- xor_speed(&t_xor_block_32regs,&b1,&b2);
-
- free_pages((unsigned long)b1.b_data,2);
- pick_fastest_function();
-}
-
-#else /* __sparc_v9__ */
-
-void calibrate_xor_block(void)
-{
- if (xor_block)
- return;
- printk(KERN_INFO "raid5: using high-speed VIS checksum routine\n");
- xor_block = xor_block_VIS;
-}
-
-#endif /* __sparc_v9__ */
-
-MD_EXPORT_SYMBOL(xor_block);
-MD_EXPORT_SYMBOL(calibrate_xor_block);
-
-#ifdef MODULE
-int init_module(void)
-{
- calibrate_xor_block();
- return 0;
-}
-#endif
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/cdrom/cdrom.c linux/drivers/cdrom/cdrom.c
--- v2.4.0-test8/linux/drivers/cdrom/cdrom.c Tue Sep 5 13:46:15 2000
+++ linux/drivers/cdrom/cdrom.c Mon Sep 25 17:05:01 2000
@@ -1118,6 +1118,7 @@
X cdinfo(CD_DVD, "entering DVD_LU_SEND_RPC_STATE\n");
X setup_report_key(&cgc, 0, 8);
X memset(&rpc_state, 0, sizeof(rpc_state_t));
+ cgc.buffer = (char *) &rpc_state;
X
X if ((ret = cdo->generic_packet(cdi, &cgc)))
X return ret;
@@ -2571,8 +2572,9 @@
X return;
X
X cdrom_sysctl_header = register_sysctl_table(cdrom_root_table, 1);
+#ifdef CONFIG_PROC_FS
X cdrom_root_table->child->de->owner = THIS_MODULE;
-
+#endif /* CONFIG_PROC_FS */
X /* set the defaults */
X cdrom_sysctl_settings.autoclose = autoclose;
X cdrom_sysctl_settings.autoeject = autoeject;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/cdrom/mcd.c linux/drivers/cdrom/mcd.c
--- v2.4.0-test8/linux/drivers/cdrom/mcd.c Wed Jul 26 09:09:39 2000
+++ linux/drivers/cdrom/mcd.c Sun Sep 17 09:45:06 2000
@@ -275,7 +275,7 @@
X static int
X statusCmd(void)
X {
- int st, retry;
+ int st = -1, retry;
X
X for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
X {
@@ -297,7 +297,7 @@
X static int
X mcdPlay(struct mcd_Play_msf *arg)
X {
- int retry, st;
+ int retry, st = -1;
X
X for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/cdrom/sonycd535.c linux/drivers/cdrom/sonycd535.c
--- v2.4.0-test8/linux/drivers/cdrom/sonycd535.c Tue Jul 18 16:09:27 2000
+++ linux/drivers/cdrom/sonycd535.c Sun Oct 1 20:35:15 2000
@@ -217,16 +217,16 @@
X static unsigned short read_status_reg;
X static unsigned short data_reg;
X
-static int initialized = 0; /* Has the drive been initialized? */
+static int initialized; /* Has the drive been initialized? */
X static int sony_disc_changed = 1; /* Has the disk been changed
X since the last check? */
-static int sony_toc_read = 0; /* Has the table of contents been
+static int sony_toc_read; /* Has the table of contents been
X read? */
X static unsigned int sony_buffer_size; /* Size in bytes of the read-ahead
X buffer. */
X static unsigned int sony_buffer_sectors; /* Size (in 2048 byte records) of
X the read-ahead buffer. */
-static unsigned int sony_usage = 0; /* How many processes have the
+static unsigned int sony_usage; /* How many processes have the
X drive open. */
X
X static int sony_first_block = -1; /* First OS block (512 byte) in
@@ -242,7 +242,7 @@
X static Byte **sony_buffer; /* Points to the pointers
X to the sector buffers */
X
-static int sony_inuse = 0; /* is the drive in use? Only one
+static int sony_inuse; /* is the drive in use? Only one
X open at a time allowed */
X
X /*
@@ -260,8 +260,8 @@
X * I just kept the CDU-31A driver behavior rather than using the PAUSE
X * command on the CDU-535.
X */
-static Byte cur_pos_msf[3] = {0, 0, 0};
-static Byte final_pos_msf[3] = {0, 0, 0};
+static Byte cur_pos_msf[3];
+static Byte final_pos_msf[3];
X
X /* What IRQ is the drive using? 0 if none. */
X static int sony535_irq_used = CDU535_INTERRUPT;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/Config.in linux/drivers/char/Config.in
--- v2.4.0-test8/linux/drivers/char/Config.in Tue Aug 22 11:29:02 2000
+++ linux/drivers/char/Config.in Sun Oct 1 20:33:28 2000
@@ -16,7 +16,7 @@
X tristate ' Dual serial port support' CONFIG_DUALSP_SERIAL
X fi
X fi
-bool 'Extended dumb serial driver options' CONFIG_SERIAL_EXTENDED
+dep_bool 'Extended dumb serial driver options' CONFIG_SERIAL_EXTENDED $CONFIG_SERIAL
X if [ "$CONFIG_SERIAL_EXTENDED" = "y" ]; then
X bool ' Support more than 4 serial ports' CONFIG_SERIAL_MANY_PORTS
X bool ' Support for sharing serial interrupts' CONFIG_SERIAL_SHARE_IRQ
@@ -90,8 +90,8 @@
X dep_tristate ' ATIXL busmouse support' CONFIG_ATIXL_BUSMOUSE $CONFIG_BUSMOUSE
X dep_tristate ' Logitech busmouse support' CONFIG_LOGIBUSMOUSE $CONFIG_BUSMOUSE
X dep_tristate ' Microsoft busmouse support' CONFIG_MS_BUSMOUSE $CONFIG_BUSMOUSE
- if [ "$CONFIG_ADB" = "y" ]; then
- dep_tristate ' Apple Desktop Bus mouse support' CONFIG_ADBMOUSE $CONFIG_BUSMOUSE
+ if [ "$CONFIG_ADB" = "y" -a "$CONFIG_ADB_KEYBOARD" = "y" ]; then
+ dep_tristate ' Apple Desktop Bus mouse support (old driver)' CONFIG_ADBMOUSE $CONFIG_BUSMOUSE
X fi
X fi
X
@@ -122,6 +122,7 @@
X bool 'Watchdog Timer Support' CONFIG_WATCHDOG
X if [ "$CONFIG_WATCHDOG" != "n" ]; then
X bool ' Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT
+ tristate ' Software Watchdog' CONFIG_SOFT_WATCHDOG
X tristate ' WDT Watchdog timer' CONFIG_WDT
X tristate ' WDT PCI Watchdog timer' CONFIG_WDTPCI
X if [ "$CONFIG_WDT" != "n" ]; then
@@ -130,7 +131,6 @@
X bool ' Fan Tachometer' CONFIG_WDT_501_FAN
X fi
X fi
- tristate ' Software Watchdog' CONFIG_SOFT_WATCHDOG
X tristate ' Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG
X tristate ' Acquire SBC Watchdog Timer' CONFIG_ACQUIRE_WDT
X tristate ' SBC-60XX Watchdog Timer' CONFIG_60XX_WDT
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/Makefile linux/drivers/char/Makefile
--- v2.4.0-test8/linux/drivers/char/Makefile Tue Aug 22 11:41:14 2000
+++ linux/drivers/char/Makefile Sun Oct 1 19:45:29 2000
@@ -101,6 +101,8 @@
X obj-$(CONFIG_VT) += vt.o vc_screen.o consolemap.o consolemap_deftbl.o $(CONSOLE) selection.o
X obj-$(CONFIG_SERIAL) += $(SERIAL)
X obj-$(CONFIG_SERIAL_21285) += serial_21285.o
+obj-$(CONFIG_SERIAL_SA1100) += serial_sa1100.o
+obj-$(CONFIG_SERIAL_AMBA) += serial_amba.o
X
X ifndef CONFIG_SUN_KEYBOARD
X obj-$(CONFIG_VT) += keyboard.o $(KEYMAP) $(KEYBD)
@@ -158,26 +160,16 @@
X obj-$(CONFIG_APPLICOM) += applicom.o
X obj-$(CONFIG_MS_BUSMOUSE) += msbusmouse.o
X obj-$(CONFIG_82C710_MOUSE) += qpmouse.o
-obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
-obj-$(CONFIG_PCWATCHDOG) += pcwd.o
-obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
-obj-$(CONFIG_MIXCOMWD) += mixcomwd.o
-obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o
X obj-$(CONFIG_AMIGAMOUSE) += amigamouse.o
X obj-$(CONFIG_ATARIMOUSE) += atarimouse.o
X obj-$(CONFIG_ADBMOUSE) += adbmouse.o
X obj-$(CONFIG_PC110_PAD) += pc110pad.o
-obj-$(CONFIG_WDT) += wdt.o
-obj-$(CONFIG_WDTPCI) += wdt_pci.o
X obj-$(CONFIG_RTC) += rtc.o
X obj-$(CONFIG_EFI_RTC) += efirtc.o
X ifeq ($(CONFIG_PPC),)
X obj-$(CONFIG_NVRAM) += nvram.o
X endif
-
-obj-$(CONFIG_21285_WATCHDOG) += wdt285.o
-obj-$(CONFIG_977_WATCHDOG) += wdt977.o
-obj-$(CONFIG_I810_TCO) += i810-tco.o
+obj-$(CONFIG_TOSHIBA) += toshiba.o
X obj-$(CONFIG_DS1620) += ds1620.o
X obj-$(CONFIG_INTEL_RNG) += i810_rng.o
X
@@ -227,6 +219,23 @@
X MOD_SUB_DIRS += agp
X endif
X endif
+
+# Only one watchdog can succeed. We probe the hardware watchdog
+# drivers first, then the softdog driver. This means if your hardware
+# watchdog dies or is 'borrowed' for some reason the software watchdog
+# still gives you some cover.
+
+obj-$(CONFIG_PCWATCHDOG) += pcwd.o
+obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
+obj-$(CONFIG_MIXCOMWD) += mixcomwd.o
+obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o
+obj-$(CONFIG_WDT) += wdt.o
+obj-$(CONFIG_WDTPCI) += wdt_pci.o
+obj-$(CONFIG_21285_WATCHDOG) += wdt285.o
+obj-$(CONFIG_977_WATCHDOG) += wdt977.o
+obj-$(CONFIG_I810_TCO) += i810-tco.o
+obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
+
X
X # Extract lists of the multi-part drivers.
X # The 'int-*' lists are the intermediate files used to build the multi's.
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/acquirewdt.c linux/drivers/char/acquirewdt.c
--- v2.4.0-test8/linux/drivers/char/acquirewdt.c Wed Jul 12 21:58:42 2000
+++ linux/drivers/char/acquirewdt.c Sun Oct 1 19:45:29 2000
@@ -204,21 +204,7 @@
X 0
X };
X
-#ifdef MODULE
-
-#define acq_init init_module
-
-void cleanup_module(void)
-{
- misc_deregister(&acq_miscdev);
- unregister_reboot_notifier(&acq_notifier);
- release_region(WDT_STOP,1);
- release_region(WDT_START,1);
-}
-
-#endif
-
-int __init acq_init(void)
+static int __init acq_init(void)
X {
X printk("WDT driver for Acquire single board computer initialising.\n");
X
@@ -229,4 +215,14 @@
X register_reboot_notifier(&acq_notifier);
X return 0;
X }
+
+static void __exit acq_exit(void)
+{
+ misc_deregister(&acq_miscdev);
+ unregister_reboot_notifier(&acq_notifier);
+ release_region(WDT_STOP,1);
+ release_region(WDT_START,1);
+}
X
+module_init(acq_init);
+module_exit(acq_exit);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/drm/dma.c linux/drivers/char/drm/dma.c
--- v2.4.0-test8/linux/drivers/char/drm/dma.c Tue Aug 29 14:09:15 2000
+++ linux/drivers/char/drm/dma.c Sun Oct 1 19:59:59 2000
@@ -397,10 +397,10 @@
X
X atomic_inc(&q->use_count);
X if (atomic_read(&q->block_write)) {


- current->state = TASK_INTERRUPTIBLE;

X add_wait_queue(&q->write_queue, &entry);
X atomic_inc(&q->block_count);
X for (;;) {
+ current->state = TASK_INTERRUPTIBLE;
X if (!atomic_read(&q->block_write)) break;
X schedule();
X if (signal_pending(current)) {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/drm/drm.h linux/drivers/char/drm/drm.h
--- v2.4.0-test8/linux/drivers/char/drm/drm.h Fri Jul 21 12:56:44 2000
+++ linux/drivers/char/drm/drm.h Sun Oct 1 19:59:59 2000
@@ -35,7 +35,13 @@
X #ifndef _DRM_H_
X #define _DRM_H_
X
+#if defined(__linux__)
X #include <asm/ioctl.h> /* For _IO* macros */
+#define DRM_IOCTL_NR(n) _IOC_NR(n)
+#elif defined(__FreeBSD__)
+#include <sys/ioccom.h>
+#define DRM_IOCTL_NR(n) ((n) & 0xff)
+#endif
X
X #define DRM_PROC_DEVICES "/proc/devices"
X #define DRM_PROC_MISC "/proc/misc"
@@ -289,7 +295,6 @@
X } drm_agp_info_t;
X
X #define DRM_IOCTL_BASE 'd'
-#define DRM_IOCTL_NR(n) _IOC_NR(n)
X #define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
X #define DRM_IOR(nr,size) _IOR(DRM_IOCTL_BASE,nr,size)
X #define DRM_IOW(nr,size) _IOW(DRM_IOCTL_BASE,nr,size)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/drm/drmP.h linux/drivers/char/drm/drmP.h
--- v2.4.0-test8/linux/drivers/char/drm/drmP.h Fri Sep 8 12:52:45 2000
+++ linux/drivers/char/drm/drmP.h Mon Oct 2 12:07:56 2000
@@ -33,6 +33,12 @@
X #define _DRM_P_H_
X
X #ifdef __KERNEL__
+#ifdef __alpha__
+/* add include of current.h so that "current" is defined
+ * before static inline funcs in wait.h. Doing this so we
+ * can build the DRM (part of PI DRI). 4/21/2000 S + B */
+#include <asm/current.h>
+#endif /* __alpha__ */
X #include <linux/config.h>
X #include <linux/module.h>
X #include <linux/kernel.h>
@@ -47,6 +53,9 @@
X #include <linux/sched.h>
X #include <linux/smp_lock.h> /* For (un)lock_kernel */
X #include <linux/mm.h>
+#ifdef __alpha__
+#include <asm/pgtable.h> /* For pte_wrprotect */
+#endif
X #include <asm/io.h>
X #include <asm/mman.h>
X #include <asm/uaccess.h>
@@ -147,6 +156,71 @@
X #ifndef __HAVE_ARCH_CMPXCHG
X /* Include this here so that driver can be
X used with older kernels. */
+#if defined(__alpha__)
+static __inline__ unsigned long
+__cmpxchg_u32(volatile int *m, int old, int new)
+{
+ unsigned long prev, cmp;
+
+ __asm__ __volatile__(
+ "1: ldl_l %0,%2\n"
+ " cmpeq %0,%3,%1\n"
+ " beq %1,2f\n"
+ " mov %4,%1\n"
+ " stl_c %1,%2\n"
+ " beq %1,3f\n"
+ "2: mb\n"
+ ".subsection 2\n"
+ "3: br 1b\n"
+ ".previous"
+ : "=&r"(prev), "=&r"(cmp), "=m"(*m)
+ : "r"((long) old), "r"(new), "m"(*m));
+
+ return prev;
+}
+
+static __inline__ unsigned long
+__cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
+{
+ unsigned long prev, cmp;
+
+ __asm__ __volatile__(
+ "1: ldq_l %0,%2\n"
+ " cmpeq %0,%3,%1\n"
+ " beq %1,2f\n"
+ " mov %4,%1\n"
+ " stq_c %1,%2\n"
+ " beq %1,3f\n"
+ "2: mb\n"
+ ".subsection 2\n"
+ "3: br 1b\n"
+ ".previous"
+ : "=&r"(prev), "=&r"(cmp), "=m"(*m)
+ : "r"((long) old), "r"(new), "m"(*m));
+
+ return prev;
+}
+
+static __inline__ unsigned long
+__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
+{
+ switch (size) {
+ case 4:
+ return __cmpxchg_u32(ptr, old, new);
+ case 8:
+ return __cmpxchg_u64(ptr, old, new);
+ }
+ return old;
+}
+#define cmpxchg(ptr,o,n) \
+ ({ \
+ __typeof__(*(ptr)) _o_ = (o); \
+ __typeof__(*(ptr)) _n_ = (n); \
+ (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
+ (unsigned long)_n_, sizeof(*(ptr))); \
+ })
+
+#elif __i386__
X static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
X unsigned long new, int size)
X {
@@ -177,6 +251,7 @@
X #define cmpxchg(ptr,o,n) \
X ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o), \
X (unsigned long)(n),sizeof(*(ptr))))
+#endif /* i386 & alpha */
X #endif
X
X /* Macros to make printk easier */
@@ -355,6 +430,7 @@
X struct drm_file *next;
X struct drm_file *prev;
X struct drm_device *dev;
+ int remove_auth_on_close;
X } drm_file_t;
X
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/drm/gamma_dma.c linux/drivers/char/drm/gamma_dma.c
--- v2.4.0-test8/linux/drivers/char/drm/gamma_dma.c Tue Aug 29 21:09:10 2000
+++ linux/drivers/char/drm/gamma_dma.c Sun Oct 1 19:59:59 2000
@@ -542,10 +542,9 @@
X
X if (d->flags & _DRM_DMA_BLOCK) {
X DRM_DEBUG("%d waiting\n", current->pid);


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 046'
echo 'File patch-2.4.0-test9 is continued in part 047'
echo "047" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part047

#!/bin/sh -x
# this is part 047 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 047; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

- current->state = TASK_INTERRUPTIBLE;

X for (;;) {
- if (!last_buf->waiting
- && !last_buf->pending)


+ current->state = TASK_INTERRUPTIBLE;

+ if (!last_buf->waiting && !last_buf->pending)
X break; /* finished */


X schedule();
X if (signal_pending(current)) {

@@ -778,6 +777,7 @@
X }
X add_wait_queue(&dev->lock.lock_queue, &entry);


X for (;;) {
+ current->state = TASK_INTERRUPTIBLE;

X if (!dev->lock.hw_lock) {
X /* Device has been unregistered */
X ret = -EINTR;
@@ -794,7 +794,6 @@
X
X /* Contention */
X atomic_inc(&dev->total_sleeps);


- current->state = TASK_INTERRUPTIBLE;

X schedule();
X if (signal_pending(current)) {
X ret = -ERESTARTSYS;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/drm/gamma_drv.c linux/drivers/char/drm/gamma_drv.c
--- v2.4.0-test8/linux/drivers/char/drm/gamma_drv.c Tue Aug 29 21:09:10 2000
+++ linux/drivers/char/drm/gamma_drv.c Fri Sep 15 14:24:55 2000
@@ -11,11 +11,11 @@
X * the rights to use, copy, modify, merge, publish, distribute, sublicense,
X * and/or sell copies of the Software, and to permit persons to whom the
X * Software is furnished to do so, subject to the following conditions:
- *
+ *
X * The above copyright notice and this permission notice (including the next
X * paragraph) shall be included in all copies or substantial portions of the
X * Software.
- *
+ *
X * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
X * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
X * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
@@ -23,7 +23,7 @@
X * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
X * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
X * DEALINGS IN THE SOFTWARE.
- *
+ *
X * Authors:
X * Rickard E. (Rik) Faith <fa...@valinux.com>
X *


@@ -42,7 +42,7 @@
X

X #define GAMMA_NAME "gamma"
X #define GAMMA_DESC "3dlabs GMX 2000"
-#define GAMMA_DATE "20000719"
+#define GAMMA_DATE "20000910"
X #define GAMMA_MAJOR 1
X #define GAMMA_MINOR 0
X #define GAMMA_PATCHLEVEL 0
@@ -87,7 +87,7 @@
X [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { drm_infobufs, 1, 0 },
X [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { drm_mapbufs, 1, 0 },
X [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { drm_freebufs, 1, 0 },
-
+
X [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { drm_addctx, 1, 1 },
X [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { drm_rmctx, 1, 1 },
X [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { drm_modctx, 1, 1 },
@@ -120,7 +120,7 @@
X * passed via the boot-loader (e.g., LILO). It calls the insmod option
X * routine, drm_parse_options.
X */
-
+
X
X static int __init gamma_options(char *str)
X {
@@ -134,7 +134,7 @@
X static int gamma_setup(drm_device_t *dev)
X {
X int i;
-
+
X atomic_set(&dev->ioctl_count, 0);
X atomic_set(&dev->vma_count, 0);
X dev->buf_use = 0;
@@ -179,22 +179,22 @@
X #endif
X dev->ctx_start = 0;
X dev->lck_start = 0;
-
+
X dev->buf_rp = dev->buf;
X dev->buf_wp = dev->buf;
X dev->buf_end = dev->buf + DRM_BSZ;
X dev->buf_async = NULL;
X init_waitqueue_head(&dev->buf_readers);
X init_waitqueue_head(&dev->buf_writers);
-
+
X DRM_DEBUG("\n");
-
+
X /* The kernel's context could be created here, but is now created
X in drm_dma_enqueue. This is more resource-efficient for
X hardware that does not do DMA, but may mean that
X drm_select_queue fails between the time the interrupt is
X initialized and the time the queues are initialized. */
-
+


X return 0;
X }
X

@@ -209,15 +209,15 @@
X DRM_DEBUG("\n");
X
X if (dev->irq) gamma_irq_uninstall(dev);
-
+
X down(&dev->struct_sem);
X del_timer(&dev->timer);
-
+
X if (dev->devname) {
X drm_free(dev->devname, strlen(dev->devname)+1, DRM_MEM_DRIVER);
X dev->devname = NULL;
X }
-
+
X if (dev->unique) {
X drm_free(dev->unique, strlen(dev->unique)+1, DRM_MEM_DRIVER);
X dev->unique = NULL;


@@ -231,7 +231,7 @@
X }

X dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
X }
-
+
X /* Clear vma list (only built for debugging) */
X if (dev->vmalist) {
X for (vma = dev->vmalist; vma; vma = vma_next) {
@@ -240,7 +240,7 @@
X }
X dev->vmalist = NULL;
X }
-
+
X /* Clear map area and mtrr information */
X if (dev->maplist) {
X for (i = 0; i < dev->map_count; i++) {
@@ -278,7 +278,7 @@
X dev->maplist = NULL;
X dev->map_count = 0;
X }
-
+
X if (dev->queuelist) {
X for (i = 0; i < dev->queue_count; i++) {
X drm_waitlist_destroy(&dev->queuelist[i]->waitlist);
@@ -304,7 +304,7 @@
X wake_up_interruptible(&dev->lock.lock_queue);
X }
X up(&dev->struct_sem);
-
+


X return 0;
X }
X

@@ -349,7 +349,7 @@
X memset((void *)dev, 0, sizeof(*dev));
X dev->count_lock = SPIN_LOCK_UNLOCKED;
X sema_init(&dev->struct_sem, 1);
-
+
X #ifdef MODULE
X drm_parse_options(gamma);
X #endif
@@ -374,7 +374,7 @@
X GAMMA_DATE,
X gamma_misc.minor,
X devices);
-
+


X return 0;
X }
X

@@ -385,7 +385,7 @@
X drm_device_t *dev = &gamma_device;
X
X DRM_DEBUG("\n");
-
+
X drm_proc_cleanup();
X if (misc_deregister(&gamma_misc)) {
X DRM_ERROR("Cannot unload module\n");
@@ -438,7 +438,7 @@
X {
X drm_device_t *dev = &gamma_device;
X int retcode = 0;
-
+
X DRM_DEBUG("open_count = %d\n", dev->open_count);
X if (!(retcode = drm_open_helper(inode, filp, dev))) {
X #if LINUX_VERSION_CODE < 0x020333
@@ -505,7 +505,7 @@
X atomic_inc(&dev->ioctl_count);
X atomic_inc(&dev->total_ioctl);
X ++priv->ioctl_count;
-
+
X DRM_DEBUG("pid = %d, cmd = 0x%02x, nr = 0x%02x, dev 0x%x, auth = %d\n",
X current->pid, cmd, nr, dev->device, priv->authenticated);
X
@@ -525,7 +525,7 @@
X retcode = (func)(inode, filp, cmd, arg);
X }
X }
-
+
X atomic_dec(&dev->ioctl_count);
X return retcode;
X }
@@ -540,7 +540,7 @@
X
X if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
X return -EFAULT;
-
+
X if (lock.context == DRM_KERNEL_CONTEXT) {
X DRM_ERROR("Process %d using kernel context %d\n",
X current->pid, lock.context);
@@ -565,7 +565,7 @@
X atomic_inc(&dev->histo.lhld[drm_histogram_slot(get_cycles()
X - dev->lck_start)]);
X #endif
-
+
X unblock_all_signals();
X return 0;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/drm/i810_dma.c linux/drivers/char/drm/i810_dma.c
--- v2.4.0-test8/linux/drivers/char/drm/i810_dma.c Tue Aug 29 21:09:10 2000
+++ linux/drivers/char/drm/i810_dma.c Sun Oct 1 19:59:59 2000
@@ -252,16 +252,15 @@
X buf = i810_freelist_get(dev);
X if (!buf) {
X retcode = -ENOMEM;
- DRM_DEBUG("%s retcode %d\n", __FUNCTION__, retcode);
- goto out_get_buf;
+ DRM_DEBUG("retcode=%d\n", retcode);
+ return retcode;
X }
X
X retcode = i810_map_buffer(buf, filp);
X if(retcode) {
X i810_freelist_put(dev, buf);
- DRM_DEBUG("mapbuf failed in %s retcode %d\n",
- __FUNCTION__, retcode);
- goto out_get_buf;
+ DRM_DEBUG("mapbuf failed, retcode %d\n", retcode);
+ return retcode;
X }
X buf->pid = priv->pid;
X buf_priv = buf->dev_private;
@@ -270,7 +269,6 @@
X d->request_size = buf->total;
X d->virtual = buf_priv->virtual;
X
-out_get_buf:
X return retcode;
X }
X
@@ -1069,11 +1067,11 @@
X return;
X }
X atomic_set(&dev_priv->flush_done, 0);


- current->state = TASK_INTERRUPTIBLE;

X add_wait_queue(&dev_priv->flush_queue, &entry);
X end = jiffies + (HZ*3);
X

X for (;;) {
+ current->state = TASK_INTERRUPTIBLE;

X i810_dma_quiescent_emit(dev);
X if (atomic_read(&dev_priv->flush_done) == 1) break;
X if((signed)(end - jiffies) <= 0) {
@@ -1104,10 +1102,10 @@
X return 0;
X }
X atomic_set(&dev_priv->flush_done, 0);


- current->state = TASK_INTERRUPTIBLE;

X add_wait_queue(&dev_priv->flush_queue, &entry);
X end = jiffies + (HZ*3);


X for (;;) {
+ current->state = TASK_INTERRUPTIBLE;

X i810_dma_emit_flush(dev);
X if (atomic_read(&dev_priv->flush_done) == 1) break;
X if((signed)(end - jiffies) <= 0) {
@@ -1201,6 +1199,7 @@
X if (!ret) {
X add_wait_queue(&dev->lock.lock_queue, &entry);


X for (;;) {
+ current->state = TASK_INTERRUPTIBLE;

X if (!dev->lock.hw_lock) {
X /* Device has been unregistered */
X ret = -EINTR;
@@ -1216,7 +1215,6 @@
X
X /* Contention */
X atomic_inc(&dev->total_sleeps);


- current->state = TASK_INTERRUPTIBLE;

X DRM_DEBUG("Calling lock schedule\n");


X schedule();
X if (signal_pending(current)) {

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/drm/i810_drv.c linux/drivers/char/drm/i810_drv.c
--- v2.4.0-test8/linux/drivers/char/drm/i810_drv.c Tue Sep 5 13:51:30 2000
+++ linux/drivers/char/drm/i810_drv.c Sun Oct 1 20:00:00 2000
@@ -1,6 +1,6 @@
X /* i810_drv.c -- I810 driver -*- linux-c -*-
X * Created: Mon Dec 13 01:56:22 1999 by jhar...@precisioninsight.com
- *
+ *
X * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
X * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
X * All Rights Reserved.
@@ -11,11 +11,11 @@
X * the rights to use, copy, modify, merge, publish, distribute, sublicense,
X * and/or sell copies of the Software, and to permit persons to whom the
X * Software is furnished to do so, subject to the following conditions:
- *
+ *
X * The above copyright notice and this permission notice (including the next
X * paragraph) shall be included in all copies or substantial portions of the
X * Software.
- *
+ *
X * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
X * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
X * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
@@ -35,7 +35,7 @@
X
X #define I810_NAME "i810"
X #define I810_DESC "Intel I810"
-#define I810_DATE "20000719"
+#define I810_DATE "20000928"
X #define I810_MAJOR 1
X #define I810_MINOR 1
X #define I810_PATCHLEVEL 0
@@ -143,7 +143,7 @@
X static int i810_setup(drm_device_t *dev)
X {
X int i;
-
+
X atomic_set(&dev->ioctl_count, 0);
X atomic_set(&dev->vma_count, 0);
X dev->buf_use = 0;
@@ -188,22 +188,22 @@
X #endif
X dev->ctx_start = 0;
X dev->lck_start = 0;
-
+
X dev->buf_rp = dev->buf;
X dev->buf_wp = dev->buf;
X dev->buf_end = dev->buf + DRM_BSZ;
X dev->buf_async = NULL;
X init_waitqueue_head(&dev->buf_readers);
X init_waitqueue_head(&dev->buf_writers);
-
+
X DRM_DEBUG("\n");
-
+
X /* The kernel's context could be created here, but is now created
X in drm_dma_enqueue. This is more resource-efficient for
X hardware that does not do DMA, but may mean that
X drm_select_queue fails between the time the interrupt is
X initialized and the time the queues are initialized. */
-
+


X return 0;
X }
X

@@ -218,15 +218,15 @@
X DRM_DEBUG("\n");
X
X if (dev->irq) i810_irq_uninstall(dev);
-
+
X down(&dev->struct_sem);
X del_timer(&dev->timer);
-
+
X if (dev->devname) {
X drm_free(dev->devname, strlen(dev->devname)+1, DRM_MEM_DRIVER);
X dev->devname = NULL;
X }
-
+
X if (dev->unique) {
X drm_free(dev->unique, strlen(dev->unique)+1, DRM_MEM_DRIVER);
X dev->unique = NULL;
@@ -244,7 +244,7 @@
X if (dev->agp) {
X drm_agp_mem_t *entry;
X drm_agp_mem_t *nexte;
-
+
X /* Remove AGP resources, but leave dev->agp
X intact until r128_cleanup is called. */
X for (entry = dev->agp->memory; entry; entry = nexte) {
@@ -254,10 +254,10 @@
X drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
X }
X dev->agp->memory = NULL;
-
+
X if (dev->agp->acquired && drm_agp.release)
X (*drm_agp.release)();
-
+
X dev->agp->acquired = 0;
X dev->agp->enabled = 0;
X }


@@ -269,7 +269,7 @@
X }

X dev->vmalist = NULL;
X }
-
+
X /* Clear map area and mtrr information */
X if (dev->maplist) {
X for (i = 0; i < dev->map_count; i++) {
@@ -305,7 +305,7 @@
X dev->maplist = NULL;
X dev->map_count = 0;
X }
-
+
X if (dev->queuelist) {
X for (i = 0; i < dev->queue_count; i++) {
X drm_waitlist_destroy(&dev->queuelist[i]->waitlist);
@@ -331,7 +331,7 @@
X wake_up_interruptible(&dev->lock.lock_queue);
X }
X up(&dev->struct_sem);
-
+


X return 0;
X }
X

@@ -348,7 +348,7 @@
X memset((void *)dev, 0, sizeof(*dev));
X dev->count_lock = SPIN_LOCK_UNLOCKED;
X sema_init(&dev->struct_sem, 1);
-
+
X #ifdef MODULE
X drm_parse_options(i810);
X #endif
@@ -402,7 +402,7 @@
X drm_device_t *dev = &i810_device;
X
X DRM_DEBUG("\n");
-
+
X drm_proc_cleanup();
X if (misc_deregister(&i810_misc)) {
X DRM_ERROR("Cannot unload module\n");
@@ -461,7 +461,7 @@
X {
X drm_device_t *dev = &i810_device;
X int retcode = 0;
-
+
X DRM_DEBUG("open_count = %d\n", dev->open_count);
X if (!(retcode = drm_open_helper(inode, filp, dev))) {
X #if LINUX_VERSION_CODE < 0x020333
@@ -498,7 +498,7 @@
X drm_lock_free(dev,
X &dev->lock.hw_lock->lock,
X _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
-
+
X /* FIXME: may require heavy-handed reset of
X hardware at this point, possibly
X processed via a callback to the X
@@ -508,6 +508,7 @@
X DECLARE_WAITQUEUE(entry, current);
X add_wait_queue(&dev->lock.lock_queue, &entry);


X for (;;) {
+ current->state = TASK_INTERRUPTIBLE;

X if (!dev->lock.hw_lock) {
X /* Device has been unregistered */
X retcode = -EINTR;
@@ -519,10 +520,9 @@
X dev->lock.lock_time = jiffies;
X atomic_inc(&dev->total_locks);
X break; /* Got lock */
- }
+ }
X /* Contention */
X atomic_inc(&dev->total_sleeps);


- current->state = TASK_INTERRUPTIBLE;

X schedule();
X if (signal_pending(current)) {
X retcode = -ERESTARTSYS;
@@ -545,7 +545,7 @@
X if (priv->next) priv->next->prev = priv->prev;
X else dev->file_last = priv->prev;
X up(&dev->struct_sem);
-
+
X drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
X #if LINUX_VERSION_CODE < 0x020333
X MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */
@@ -585,7 +585,7 @@
X atomic_inc(&dev->ioctl_count);
X atomic_inc(&dev->total_ioctl);
X ++priv->ioctl_count;
-
+
X DRM_DEBUG("pid = %d, cmd = 0x%02x, nr = 0x%02x, dev 0x%x, auth = %d\n",
X current->pid, cmd, nr, dev->device, priv->authenticated);
X
@@ -605,7 +605,7 @@
X retcode = (func)(inode, filp, cmd, arg);
X }
X }
-
+
X atomic_dec(&dev->ioctl_count);
X return retcode;
X }
@@ -619,7 +619,7 @@
X
X if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
X return -EFAULT;
-
+
X if (lock.context == DRM_KERNEL_CONTEXT) {
X DRM_ERROR("Process %d using kernel context %d\n",
X current->pid, lock.context);
@@ -643,7 +643,7 @@
X atomic_inc(&dev->histo.lhld[drm_histogram_slot(get_cycles()
X - dev->lck_start)]);
X #endif
-
+
X unblock_all_signals();
X return 0;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/drm/lists.c linux/drivers/char/drm/lists.c
--- v2.4.0-test8/linux/drivers/char/drm/lists.c Mon Aug 21 08:08:12 2000
+++ linux/drivers/char/drm/lists.c Sun Oct 1 20:00:00 2000
@@ -34,7 +34,6 @@
X
X int drm_waitlist_create(drm_waitlist_t *bl, int count)
X {
- DRM_DEBUG("%d\n", count);
X if (bl->count) return -EINVAL;
X
X bl->count = count;
@@ -50,7 +49,6 @@
X
X int drm_waitlist_destroy(drm_waitlist_t *bl)
X {
- DRM_DEBUG("\n");
X if (bl->rp != bl->wp) return -EINVAL;
X if (bl->bufs) drm_free(bl->bufs,
X (bl->count + 2) * sizeof(*bl->bufs),
@@ -69,8 +67,6 @@
X unsigned long flags;
X
X left = DRM_LEFTCOUNT(bl);
- DRM_DEBUG("put %d (%d left, rp = %p, wp = %p)\n",
- buf->idx, left, bl->rp, bl->wp);
X if (!left) {
X DRM_ERROR("Overflow while adding buffer %d from pid %d\n",
X buf->idx, buf->pid);
@@ -103,13 +99,11 @@
X if (++bl->rp >= bl->end) bl->rp = bl->bufs;
X spin_unlock_irqrestore(&bl->read_lock, flags);
X
- DRM_DEBUG("get %d\n", buf->idx);
X return buf;
X }
X
X int drm_freelist_create(drm_freelist_t *bl, int count)
X {
- DRM_DEBUG("\n");
X atomic_set(&bl->count, 0);
X bl->next = NULL;
X init_waitqueue_head(&bl->waiting);
@@ -123,7 +117,6 @@
X
X int drm_freelist_destroy(drm_freelist_t *bl)
X {
- DRM_DEBUG("\n");
X atomic_set(&bl->count, 0);
X bl->next = NULL;
X return 0;
@@ -142,9 +135,6 @@
X DRM_ERROR("Freed buffer %d: w%d, p%d, l%d\n",
X buf->idx, buf->waiting, buf->pending, buf->list);
X }
- DRM_DEBUG("%d, count = %d, wfh = %d, w%d, p%d\n",
- buf->idx, atomic_read(&bl->count), atomic_read(&bl->wfh),
- buf->waiting, buf->pending);
X if (!bl) return 1;
X #if DRM_DMA_HISTOGRAM
X buf->time_freed = get_cycles();
@@ -190,9 +180,6 @@
X atomic_dec(&bl->count);
X buf->next = NULL;
X buf->list = DRM_LIST_NONE;
- DRM_DEBUG("%d, count = %d, wfh = %d, w%d, p%d\n",
- buf->idx, atomic_read(&bl->count), atomic_read(&bl->wfh),
- buf->waiting, buf->pending);
X if (buf->waiting || buf->pending) {
X DRM_ERROR("Free buffer %d: w%d, p%d, l%d\n",
X buf->idx, buf->waiting, buf->pending, buf->list);
@@ -212,13 +199,10 @@
X if (atomic_read(&bl->count) <= bl->low_mark) /* Became low */
X atomic_set(&bl->wfh, 1);
X if (atomic_read(&bl->wfh)) {
- DRM_DEBUG("Block = %d, count = %d, wfh = %d\n",
- block, atomic_read(&bl->count),
- atomic_read(&bl->wfh));
X if (block) {
X add_wait_queue(&bl->waiting, &entry);


- current->state = TASK_INTERRUPTIBLE;

X for (;;) {
+ current->state = TASK_INTERRUPTIBLE;

X if (!atomic_read(&bl->wfh)
X && (buf = drm_freelist_try(bl))) break;
X schedule();
@@ -230,7 +214,5 @@
X return buf;
X }
X
- DRM_DEBUG("Count = %d, wfh = %d\n",
- atomic_read(&bl->count), atomic_read(&bl->wfh));
X return drm_freelist_try(bl);
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/drm/lock.c linux/drivers/char/drm/lock.c
--- v2.4.0-test8/linux/drivers/char/drm/lock.c Tue Aug 29 14:09:15 2000
+++ linux/drivers/char/drm/lock.c Sun Oct 1 20:00:00 2000
@@ -50,7 +50,6 @@
X {
X unsigned int old, new, prev;
X
- DRM_DEBUG("%d attempts\n", context);
X do {
X old = *lock;
X if (old & _DRM_LOCK_HELD) new = old | _DRM_LOCK_CONT;
@@ -68,11 +67,8 @@
X }
X if (new == (context | _DRM_LOCK_HELD)) {
X /* Have lock */
- DRM_DEBUG("%d\n", context);
X return 1;
X }
- DRM_DEBUG("%d unable to get lock held by %d\n",
- context, _DRM_LOCKING_CONTEXT(old));


X return 0;
X }
X

@@ -89,7 +85,6 @@
X new = context | _DRM_LOCK_HELD;
X prev = cmpxchg(lock, old, new);
X } while (prev != old);
- DRM_DEBUG("%d => %d\n", _DRM_LOCKING_CONTEXT(old), context);
X return 1;
X }
X
@@ -99,7 +94,6 @@
X unsigned int old, new, prev;
X pid_t pid = dev->lock.pid;
X
- DRM_DEBUG("%d\n", context);
X dev->lock.pid = 0;
X do {
X old = *lock;
@@ -128,10 +122,10 @@
X atomic_inc(&q->use_count);
X if (atomic_read(&q->use_count) > 1) {
X atomic_inc(&q->block_write);


- current->state = TASK_INTERRUPTIBLE;

X add_wait_queue(&q->flush_queue, &entry);


X atomic_inc(&q->block_count);
X for (;;) {
+ current->state = TASK_INTERRUPTIBLE;

X if (!DRM_BUFCOUNT(&q->waitlist)) break;


X schedule();
X if (signal_pending(current)) {

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/drm/mga_bufs.c linux/drivers/char/drm/mga_bufs.c
--- v2.4.0-test8/linux/drivers/char/drm/mga_bufs.c Tue Aug 29 14:09:15 2000
+++ linux/drivers/char/drm/mga_bufs.c Sun Oct 1 20:00:00 2000
@@ -66,7 +66,7 @@
X order = drm_order(request.size);
X size = 1 << order;
X agp_offset = request.agp_start;
- alignment = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(size) :size;
+ alignment = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(size):size;
X page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
X total = PAGE_SIZE << page_order;
X byte_count = 0;
@@ -119,8 +119,6 @@
X buf->order = order;
X buf->used = 0;
X
- DRM_DEBUG("offset : %ld\n", offset);
-
X buf->offset = offset; /* Hrm */
X buf->bus_address = dev->agp->base + agp_offset + offset;
X buf->address = (void *)(agp_offset + offset + dev->agp->base);
@@ -130,7 +128,8 @@
X init_waitqueue_head(&buf->dma_wait);
X buf->pid = 0;
X
- buf->dev_private = drm_alloc(sizeof(drm_mga_buf_priv_t), DRM_MEM_BUFS);
+ buf->dev_private = drm_alloc(sizeof(drm_mga_buf_priv_t),
+ DRM_MEM_BUFS);
X buf->dev_priv_size = sizeof(drm_mga_buf_priv_t);
X
X #if DRM_DMA_HISTOGRAM
@@ -142,9 +141,6 @@
X offset = offset + alignment;
X entry->buf_count++;
X byte_count += PAGE_SIZE << page_order;
-
- DRM_DEBUG("buffer %d @ %p\n",
- entry->buf_count, buf->address);
X }
X
X dma->buflist = drm_realloc(dma->buflist,
@@ -234,7 +230,7 @@
X if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL;
X if (dev->queue_count) return -EBUSY; /* Not while in use */
X
- alignment = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(size) :size;
+ alignment = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(size):size;
X page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
X total = PAGE_SIZE << page_order;
X
@@ -402,8 +398,6 @@
X if (dma->bufs[i].buf_count) ++count;
X }
X
- DRM_DEBUG("count = %d\n", count);
-
X if (request.count >= count) {
X for (i = 0, count = 0; i < DRM_MAX_ORDER+1; i++) {
X if (dma->bufs[i].buf_count) {
@@ -426,13 +420,6 @@
X sizeof(dma->bufs[0]
X .freelist.high_mark)))
X return -EFAULT;
-
- DRM_DEBUG("%d %d %d %d %d\n",
- i,
- dma->bufs[i].buf_count,
- dma->bufs[i].buf_size,
- dma->bufs[i].freelist.low_mark,
- dma->bufs[i].freelist.high_mark);
X ++count;
X }
X }
@@ -459,13 +446,9 @@
X
X if (!dma) return -EINVAL;
X
- if (copy_from_user(&request,
- (drm_buf_desc_t *)arg,
- sizeof(request)))
+ if (copy_from_user(&request, (drm_buf_desc_t *)arg, sizeof(request)))
X return -EFAULT;
X
- DRM_DEBUG("%d, %d, %d\n",
- request.size, request.low_mark, request.high_mark);
X order = drm_order(request.size);
X if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL;
X entry = &dma->bufs[order];
@@ -499,7 +482,6 @@
X sizeof(request)))
X return -EFAULT;
X
- DRM_DEBUG("%d\n", request.count);
X for (i = 0; i < request.count; i++) {
X if (copy_from_user(&idx,
X &request.list[i],
@@ -537,12 +519,9 @@
X
X if (!dma) return -EINVAL;
X
- DRM_DEBUG("\n");
-
X spin_lock(&dev->count_lock);
X if (atomic_read(&dev->buf_alloc)) {
X spin_unlock(&dev->count_lock);
- DRM_DEBUG("Busy\n");
X return -EBUSY;
X }
X ++dev->buf_use; /* Can't allocate more after this call */
@@ -553,9 +532,6 @@
X sizeof(request)))
X return -EFAULT;
X
- DRM_DEBUG("mga_mapbufs\n");
- DRM_DEBUG("dma->flags : %x\n", dma->flags);
-
X if (request.count >= dma->buf_count) {
X if(dma->flags & _DRM_DMA_USE_AGP) {
X drm_mga_private_t *dev_priv = dev->dev_private;
@@ -563,7 +539,6 @@
X
X map = dev->maplist[dev_priv->buffer_map_idx];
X if (!map) {
- DRM_DEBUG("map is null\n");
X retcode = -EINVAL;
X goto done;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/drm/mga_context.c linux/drivers/char/drm/mga_context.c
--- v2.4.0-test8/linux/drivers/char/drm/mga_context.c Tue Aug 29 14:09:15 2000
+++ linux/drivers/char/drm/mga_context.c Sun Oct 1 20:00:00 2000
@@ -35,9 +35,7 @@
X
X static int mga_alloc_queue(drm_device_t *dev)
X {
- int temp = drm_ctxbitmap_next(dev);
- DRM_DEBUG("mga_alloc_queue: %d\n", temp);
- return temp;
+ return drm_ctxbitmap_next(dev);
X }
X
X int mga_context_switch(drm_device_t *dev, int old, int new)
@@ -102,7 +100,6 @@
X drm_ctx_t ctx;
X int i;
X
- DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
X if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res)))
X return -EFAULT;
X if (res.count >= DRM_RESERVED_CONTEXTS) {
@@ -135,8 +132,6 @@
X ctx.handle = mga_alloc_queue(dev);
X }
X if (ctx.handle == -1) {
- DRM_DEBUG("Not enough free contexts.\n");
- /* Should this return -EBUSY instead? */
X return -ENOMEM;
X }
X DRM_DEBUG("%d\n", ctx.handle);
@@ -204,6 +199,8 @@
X if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx)))
X return -EFAULT;
X DRM_DEBUG("%d\n", ctx.handle);
+ if(ctx.handle == DRM_KERNEL_CONTEXT+1) priv->remove_auth_on_close = 1;
+
X if(ctx.handle != DRM_KERNEL_CONTEXT) {
X drm_ctxbitmap_free(dev, ctx.handle);
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/drm/mga_dma.c linux/drivers/char/drm/mga_dma.c
--- v2.4.0-test8/linux/drivers/char/drm/mga_dma.c Tue Aug 29 21:09:10 2000
+++ linux/drivers/char/drm/mga_dma.c Sun Oct 1 20:00:00 2000
@@ -11,11 +11,11 @@
X * the rights to use, copy, modify, merge, publish, distribute, sublicense,
X * and/or sell copies of the Software, and to permit persons to whom the
X * Software is furnished to do so, subject to the following conditions:
- *
+ *
X * The above copyright notice and this permission notice (including the next
X * paragraph) shall be included in all copies or substantial portions of the
X * Software.
- *
+ *
X * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
X * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
X * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
@@ -51,53 +51,30 @@
X static unsigned long mga_alloc_page(drm_device_t *dev)
X {
X unsigned long address;
-
- DRM_DEBUG("%s\n", __FUNCTION__);
+
X address = __get_free_page(GFP_KERNEL);
X if(address == 0UL) {
X return 0;
X }
X atomic_inc(&virt_to_page(address)->count);
- set_bit(PG_locked, &virt_to_page(address)->flags);
-
+ set_bit(PG_reserved, &virt_to_page(address)->flags);
+
X return address;
X }
X
X static void mga_free_page(drm_device_t *dev, unsigned long page)
X {
- DRM_DEBUG("%s\n", __FUNCTION__);
-
- if(page == 0UL) {
- return;
- }
+ if(!page) return;
X atomic_dec(&virt_to_page(page)->count);
- clear_bit(PG_locked, &virt_to_page(page)->flags);
- wake_up(&virt_to_page(page)->wait);
+ clear_bit(PG_reserved, &virt_to_page(page)->flags);
X free_page(page);
X return;
X }
X
X static void mga_delay(void)
X {
- return;
-}
-
-#ifdef __i386__
-void mga_flush_write_combine(void)
-{
- int xchangeDummy;
- DRM_DEBUG("%s\n", __FUNCTION__);
-
- __asm__ volatile(" push %%eax ; xchg %%eax, %0 ; pop %%eax" : : "m" (xchangeDummy));
- __asm__ volatile(" push %%eax ; push %%ebx ; push %%ecx ; push %%edx ;"
- " movl $0,%%eax ; cpuid ; pop %%edx ; pop %%ecx ; pop %%ebx ;"
- " pop %%eax" : /* no outputs */ : /* no inputs */ );
-}
-#else
-void mga_flush_write_combine(void)
-{
+ return;
X }
-#endif
X
X /* These are two age tags that will never be sent to
X * the hardware */
@@ -113,13 +90,11 @@
X drm_mga_freelist_t *item;
X int i;
X
- DRM_DEBUG("%s\n", __FUNCTION__);
-
X dev_priv->head = drm_alloc(sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER);
X if(dev_priv->head == NULL) return -ENOMEM;
X memset(dev_priv->head, 0, sizeof(drm_mga_freelist_t));
X dev_priv->head->age = MGA_BUF_USED;
-
+
X for (i = 0; i < dma->buf_count; i++) {
X buf = dma->buflist[ i ];
X buf_priv = buf->dev_private;
@@ -139,7 +114,7 @@
X buf_priv->dispatched = 0;
X dev_priv->head->next = item;
X }
-
+


X return 0;
X }
X

@@ -149,15 +124,13 @@
X drm_mga_freelist_t *item;
X drm_mga_freelist_t *prev;
X
- DRM_DEBUG("%s\n", __FUNCTION__);
-
X item = dev_priv->head;
X while(item) {
X prev = item;
X item = item->next;
X drm_free(prev, sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER);
X }
-
+
X dev_priv->head = dev_priv->tail = NULL;
X }
X
@@ -170,19 +143,21 @@
X unsigned long end;
X int i;
X
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("dispatch_status = 0x%02x\n", dev_priv->dispatch_status);
X end = jiffies + (HZ*3);
X while(1) {
- if(!test_and_set_bit(MGA_IN_DISPATCH,
+ if(!test_and_set_bit(MGA_IN_DISPATCH,
X &dev_priv->dispatch_status)) {
X break;
X }
X if((signed)(end - jiffies) <= 0) {
- DRM_ERROR("irqs: %d wanted %d\n",
- atomic_read(&dev->total_irq),
+ DRM_ERROR("irqs: %d wanted %d\n",
+ atomic_read(&dev->total_irq),
X atomic_read(&dma->total_lost));
- DRM_ERROR("lockup\n");
- goto out_nolock;
+ DRM_ERROR("lockup: dispatch_status = 0x%02x,"
+ " jiffies = %lu, end = %lu\n",
+ dev_priv->dispatch_status, jiffies, end);
+ return;
X }
X for (i = 0 ; i < 2000 ; i++) mga_delay();
X }
@@ -190,19 +165,20 @@
X DRM_DEBUG("quiescent status : %x\n", MGA_READ(MGAREG_STATUS));
X while((MGA_READ(MGAREG_STATUS) & 0x00030001) != 0x00020000) {
X if((signed)(end - jiffies) <= 0) {
- DRM_ERROR("irqs: %d wanted %d\n",
- atomic_read(&dev->total_irq),
+ DRM_ERROR("irqs: %d wanted %d\n",
+ atomic_read(&dev->total_irq),
X atomic_read(&dma->total_lost));
- DRM_ERROR("lockup\n");
- goto out_status;
+ DRM_ERROR("lockup\n");
+ clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
+ return;
X }
- for (i = 0 ; i < 2000 ; i++) mga_delay();
+ for (i = 0 ; i < 2000 ; i++) mga_delay();
X }
X sarea_priv->dirty |= MGA_DMA_FLUSH;
X
-out_status:
X clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
-out_nolock:
+ DRM_DEBUG("exit, dispatch_status = 0x%02x\n",
+ dev_priv->dispatch_status);
X }
X
X static void mga_reset_freelist(drm_device_t *dev)
@@ -220,44 +196,44 @@
X }
X
X /* Least recently used :
- * These operations are not atomic b/c they are protected by the
+ * These operations are not atomic b/c they are protected by the
X * hardware lock */
X
X drm_buf_t *mga_freelist_get(drm_device_t *dev)
X {
X DECLARE_WAITQUEUE(entry, current);
- drm_mga_private_t *dev_priv =
+ drm_mga_private_t *dev_priv =
X (drm_mga_private_t *) dev->dev_private;
X drm_mga_freelist_t *prev;
X drm_mga_freelist_t *next;
X static int failed = 0;
+ int return_null = 0;
X
- DRM_DEBUG("%s : tail->age : %d last_prim_age : %d\n", __FUNCTION__,
- dev_priv->tail->age, dev_priv->last_prim_age);
-
X if(failed >= 1000 && dev_priv->tail->age >= dev_priv->last_prim_age) {
- DRM_DEBUG("I'm waiting on the freelist!!! %d\n",
- dev_priv->last_prim_age);
- set_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status);


- current->state = TASK_INTERRUPTIBLE;

+ DRM_DEBUG("Waiting on freelist,"
+ " tail->age = %d, last_prim_age= %d\n",
+ dev_priv->tail->age,
+ dev_priv->last_prim_age);
X add_wait_queue(&dev_priv->buf_queue, &entry);
+ set_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status);


X for (;;) {
+ current->state = TASK_INTERRUPTIBLE;

X mga_dma_schedule(dev, 0);
- if(!test_bit(MGA_IN_GETBUF,
- &dev_priv->dispatch_status))
+ if(dev_priv->tail->age < dev_priv->last_prim_age)
X break;
X atomic_inc(&dev->total_sleeps);


X schedule();
X if (signal_pending(current)) {

- clear_bit(MGA_IN_GETBUF,
- &dev_priv->dispatch_status);
- goto failed_getbuf;
+ ++return_null;
+ break;
X }
X }


- current->state = TASK_RUNNING;

+ clear_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status);
+ current->state = TASK_RUNNING;
X remove_wait_queue(&dev_priv->buf_queue, &entry);
+ if (return_null) return NULL;
X }
-
+
X if(dev_priv->tail->age < dev_priv->last_prim_age) {
X prev = dev_priv->tail->prev;
X next = dev_priv->tail;
@@ -269,22 +245,19 @@
X return next->buf;
X }
X
-failed_getbuf:
X failed++;
X return NULL;
X }
X
X int mga_freelist_put(drm_device_t *dev, drm_buf_t *buf)
X {
- drm_mga_private_t *dev_priv =
+ drm_mga_private_t *dev_priv =
X (drm_mga_private_t *) dev->dev_private;
X drm_mga_buf_priv_t *buf_priv = buf->dev_private;
X drm_mga_freelist_t *prev;
X drm_mga_freelist_t *head;
X drm_mga_freelist_t *next;
X
- DRM_DEBUG("%s\n", __FUNCTION__);
-
X if(buf_priv->my_freelist->age == MGA_BUF_USED) {
X /* Discarded buffer, put it on the tail */
X next = buf_priv->my_freelist;
@@ -294,7 +267,6 @@
X next->prev = prev;
X next->next = NULL;
X dev_priv->tail = next;
- DRM_DEBUG("Discarded\n");
X } else {
X /* Normally aged buffer, put it on the head + 1,
X * as the real head is a sentinal element
@@ -307,7 +279,7 @@
X next->prev = head;
X next->next = prev;
X }
-
+


X return 0;
X }
X

@@ -318,42 +290,41 @@
X int i, temp, size_of_buf;
X int offset = init->reserved_map_agpstart;
X
- DRM_DEBUG("%s\n", __FUNCTION__);
- dev_priv->primary_size = ((init->primary_size + PAGE_SIZE - 1) /
+ dev_priv->primary_size = ((init->primary_size + PAGE_SIZE - 1) /
X PAGE_SIZE) * PAGE_SIZE;
X size_of_buf = dev_priv->primary_size / MGA_NUM_PRIM_BUFS;
X dev_priv->warp_ucode_size = init->warp_ucode_size;
- dev_priv->prim_bufs = drm_alloc(sizeof(drm_mga_prim_buf_t *) *
- (MGA_NUM_PRIM_BUFS + 1),
+ dev_priv->prim_bufs = drm_alloc(sizeof(drm_mga_prim_buf_t *) *
+ (MGA_NUM_PRIM_BUFS + 1),
X DRM_MEM_DRIVER);
X if(dev_priv->prim_bufs == NULL) {
X DRM_ERROR("Unable to allocate memory for prim_buf\n");
X return -ENOMEM;
X }
- memset(dev_priv->prim_bufs,
+ memset(dev_priv->prim_bufs,
X 0, sizeof(drm_mga_prim_buf_t *) * (MGA_NUM_PRIM_BUFS + 1));
-
+
X temp = init->warp_ucode_size + dev_priv->primary_size;
X temp = ((temp + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE;
-
- dev_priv->ioremap = drm_ioremap(dev->agp->base + offset,
+
+ dev_priv->ioremap = drm_ioremap(dev->agp->base + offset,
X temp);
X if(dev_priv->ioremap == NULL) {
- DRM_DEBUG("Ioremap failed\n");
+ DRM_ERROR("Ioremap failed\n");
X return -ENOMEM;
X }
X init_waitqueue_head(&dev_priv->wait_queue);
-
+
X for(i = 0; i < MGA_NUM_PRIM_BUFS; i++) {
- prim_buffer = drm_alloc(sizeof(drm_mga_prim_buf_t),
+ prim_buffer = drm_alloc(sizeof(drm_mga_prim_buf_t),
X DRM_MEM_DRIVER);
X if(prim_buffer == NULL) return -ENOMEM;
X memset(prim_buffer, 0, sizeof(drm_mga_prim_buf_t));
X prim_buffer->phys_head = offset + dev->agp->base;
- prim_buffer->current_dma_ptr =
- prim_buffer->head =
- (u32 *) (dev_priv->ioremap +
- offset -
+ prim_buffer->current_dma_ptr =
+ prim_buffer->head =
+ (u32 *) (dev_priv->ioremap +
+ offset -
X init->reserved_map_agpstart);
X prim_buffer->num_dwords = 0;
X prim_buffer->max_dwords = size_of_buf / sizeof(u32);
@@ -365,11 +336,11 @@
X dev_priv->prim_bufs[i] = prim_buffer;
X }
X dev_priv->current_prim_idx = 0;
- dev_priv->next_prim =
- dev_priv->last_prim =
+ dev_priv->next_prim =
+ dev_priv->last_prim =
X dev_priv->current_prim =
X dev_priv->prim_bufs[0];
- dev_priv->next_prim_age = 2;
+ dev_priv->next_prim_age = 2;
X dev_priv->last_prim_age = 1;
X set_bit(MGA_BUF_IN_USE, &dev_priv->current_prim->buffer_status);
X return 0;
@@ -386,13 +357,12 @@
X int next_idx;
X PRIMLOCALS;
X
- DRM_DEBUG("%s\n", __FUNCTION__);
X dev_priv->last_prim = prim;
-
+
X /* We never check for overflow, b/c there is always room */
X PRIMPTR(prim);
X if(num_dwords <= 0) {
- DRM_DEBUG("num_dwords == 0 when dispatched\n");
+ DRM_ERROR("num_dwords == 0 when dispatched\n");
X goto out_prim_wait;
X }
X PRIMOUTREG( MGAREG_DMAPAD, 0);
@@ -403,32 +373,28 @@
X
X end = jiffies + (HZ*3);
X if(sarea_priv->dirty & MGA_DMA_FLUSH) {
- DRM_DEBUG("Dma top flush\n");
X while((MGA_READ(MGAREG_STATUS) & 0x00030001) != 0x00020000) {
X if((signed)(end - jiffies) <= 0) {
- DRM_ERROR("irqs: %d wanted %d\n",
- atomic_read(&dev->total_irq),
+ DRM_ERROR("irqs: %d wanted %d\n",
+ atomic_read(&dev->total_irq),
X atomic_read(&dma->total_lost));
- DRM_ERROR("lockup in fire primary "
- "(Dma Top Flush)\n");
+ DRM_ERROR("lockup (flush)\n");
X goto out_prim_wait;
X }
-
+
X for (i = 0 ; i < 4096 ; i++) mga_delay();
X }
X sarea_priv->dirty &= ~(MGA_DMA_FLUSH);
X } else {
- DRM_DEBUG("Status wait\n");
X while((MGA_READ(MGAREG_STATUS) & 0x00020001) != 0x00020000) {
X if((signed)(end - jiffies) <= 0) {
- DRM_ERROR("irqs: %d wanted %d\n",
- atomic_read(&dev->total_irq),
+ DRM_ERROR("irqs: %d wanted %d\n",
+ atomic_read(&dev->total_irq),
X atomic_read(&dma->total_lost));
- DRM_ERROR("lockup in fire primary "
- "(Status Wait)\n");
+ DRM_ERROR("lockup (wait)\n");
X goto out_prim_wait;
X }
-
+
X for (i = 0 ; i < 4096 ; i++) mga_delay();
X }
X }
@@ -439,9 +405,9 @@
X MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp);
X prim->num_dwords = 0;
X sarea_priv->last_enqueue = prim->prim_age;
-
+
X next_idx = prim->idx + 1;
- if(next_idx >= MGA_NUM_PRIM_BUFS)
+ if(next_idx >= MGA_NUM_PRIM_BUFS)
X next_idx = 0;
X
X dev_priv->next_prim = dev_priv->prim_bufs[next_idx];
@@ -464,28 +430,26 @@
X drm_device_dma_t *dma = dev->dma;
X int next_prim_idx;
X int ret = 0;
-
+
X /* This needs to reset the primary buffer if available,
X * we should collect stats on how many times it bites
X * it's tail */
- DRM_DEBUG("%s\n", __FUNCTION__);
-
+
X next_prim_idx = dev_priv->current_prim_idx + 1;
X if(next_prim_idx >= MGA_NUM_PRIM_BUFS)
X next_prim_idx = 0;
X prim_buffer = dev_priv->prim_bufs[next_prim_idx];
X set_bit(MGA_IN_WAIT, &dev_priv->dispatch_status);
-
+
X /* In use is cleared in interrupt handler */
-
+
X if(test_and_set_bit(MGA_BUF_IN_USE, &prim_buffer->buffer_status)) {
X add_wait_queue(&dev_priv->wait_queue, &entry);


- current->state = TASK_INTERRUPTIBLE;

-


X for (;;) {
+ current->state = TASK_INTERRUPTIBLE;

X mga_dma_schedule(dev, 0);
- if(!test_and_set_bit(MGA_BUF_IN_USE,
- &prim_buffer->buffer_status))
+ if(!test_and_set_bit(MGA_BUF_IN_USE,
+ &prim_buffer->buffer_status))
X break;
X atomic_inc(&dev->total_sleeps);
X atomic_inc(&dma->total_missed_sched);
@@ -495,7 +459,7 @@
X break;
X }
X }


- current->state = TASK_RUNNING;

+ current->state = TASK_RUNNING;
X remove_wait_queue(&dev_priv->wait_queue, &entry);
X if(ret) return ret;
X }
@@ -507,10 +471,10 @@
X prim_buffer->sec_used = 0;
X prim_buffer->prim_age = dev_priv->next_prim_age++;
X if(prim_buffer->prim_age == 0 || prim_buffer->prim_age == 0xffffffff) {
- mga_flush_queue(dev);
- mga_dma_quiescent(dev);
- mga_reset_freelist(dev);
- prim_buffer->prim_age = (dev_priv->next_prim_age += 2);
+ mga_flush_queue(dev);
+ mga_dma_quiescent(dev);
+ mga_reset_freelist(dev);
+ prim_buffer->prim_age = (dev_priv->next_prim_age += 2);
X }
X
X /* Reset all buffer status stuff */
@@ -527,88 +491,72 @@
X static inline int mga_decide_to_fire(drm_device_t *dev)
X {
X drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
- drm_device_dma_t *dma = dev->dma;
-
- DRM_DEBUG("%s\n", __FUNCTION__);
X
X if(test_bit(MGA_BUF_FORCE_FIRE, &dev_priv->next_prim->buffer_status)) {
- atomic_inc(&dma->total_prio);
X return 1;
X }
X
X if (test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status) &&
X dev_priv->next_prim->num_dwords) {
- atomic_inc(&dma->total_prio);
X return 1;
X }
X
X if (test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) &&
X dev_priv->next_prim->num_dwords) {
- atomic_inc(&dma->total_prio);
X return 1;
X }
-
+
X if(atomic_read(&dev_priv->pending_bufs) <= MGA_NUM_PRIM_BUFS - 1) {
- if(test_bit(MGA_BUF_SWAP_PENDING,
+ if(test_bit(MGA_BUF_SWAP_PENDING,
X &dev_priv->next_prim->buffer_status)) {
- atomic_inc(&dma->total_dmas);
X return 1;
X }
X }
X
X if(atomic_read(&dev_priv->pending_bufs) <= MGA_NUM_PRIM_BUFS / 2) {
X if(dev_priv->next_prim->sec_used >= MGA_DMA_BUF_NR / 8) {
- atomic_inc(&dma->total_hit);
X return 1;
X }
X }
X
X if(atomic_read(&dev_priv->pending_bufs) >= MGA_NUM_PRIM_BUFS / 2) {
X if(dev_priv->next_prim->sec_used >= MGA_DMA_BUF_NR / 4) {
- atomic_inc(&dma->total_missed_free);
X return 1;
X }
X }
X
- atomic_inc(&dma->total_tried);


X return 0;
X }
X

X int mga_dma_schedule(drm_device_t *dev, int locked)
X {
X drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
- drm_device_dma_t *dma = dev->dma;
- int retval = 0;
+ int retval = 0;
X
- if (test_and_set_bit(0, &dev->dma_flag)) {
- atomic_inc(&dma->total_missed_dma);
+ if (!dev_priv) return -EBUSY;
+
+ if (test_and_set_bit(0, &dev->dma_flag)) {
X retval = -EBUSY;
X goto sch_out_wakeup;
X }
-
- DRM_DEBUG("%s\n", __FUNCTION__);
X
- if(test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) ||
+ if(test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) ||
X test_bit(MGA_IN_WAIT, &dev_priv->dispatch_status) ||
X test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status)) {
X locked = 1;
X }
-
- if (!locked &&
+
+ if (!locked &&
X !drm_lock_take(&dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT)) {
- atomic_inc(&dma->total_missed_lock);
X clear_bit(0, &dev->dma_flag);
- DRM_DEBUG("Not locked\n");
X retval = -EBUSY;
X goto sch_out_wakeup;
X }
- DRM_DEBUG("I'm locked\n");
X
X if(!test_and_set_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status)) {
X /* Fire dma buffer */
X if(mga_decide_to_fire(dev)) {
- DRM_DEBUG("idx :%d\n", dev_priv->next_prim->idx);
- clear_bit(MGA_BUF_FORCE_FIRE,
+ clear_bit(MGA_BUF_FORCE_FIRE,
X &dev_priv->next_prim->buffer_status);
X if(dev_priv->current_prim == dev_priv->next_prim) {
X /* Schedule overflow for a later time */
@@ -619,10 +567,8 @@
X } else {
X clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
X }
- } else {
- DRM_DEBUG("I can't get the dispatch lock\n");
X }
-
+
X if (!locked) {
X if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
X DRM_KERNEL_CONTEXT)) {
@@ -630,6 +576,8 @@
X }
X }
X
+ clear_bit(0, &dev->dma_flag);
+
X sch_out_wakeup:
X if(test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status) &&
X atomic_read(&dev_priv->pending_bufs) == 0) {
@@ -638,18 +586,10 @@
X wake_up_interruptible(&dev_priv->flush_queue);
X }
X
- if(test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status) &&
- dev_priv->tail->age < dev_priv->last_prim_age) {
- clear_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status);
- DRM_DEBUG("Waking up buf queue\n");
+ if(test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status)
+ && dev_priv->tail->age < dev_priv->last_prim_age)
X wake_up_interruptible(&dev_priv->buf_queue);
- } else if (test_bit(MGA_IN_GETBUF, &dev_priv->dispatch_status)) {
- DRM_DEBUG("Not waking buf_queue on %d %d\n",
- atomic_read(&dev->total_irq),
- dev_priv->last_prim_age);
- }
X
- clear_bit(0, &dev->dma_flag);
X return retval;
X }
X
@@ -659,41 +599,40 @@
X drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
X drm_mga_prim_buf_t *last_prim_buffer;
X
- DRM_DEBUG("%s\n", __FUNCTION__);
X atomic_inc(&dev->total_irq);
X if((MGA_READ(MGAREG_STATUS) & 0x00000001) != 0x00000001) return;
X MGA_WRITE(MGAREG_ICLEAR, 0x00000001);
X last_prim_buffer = dev_priv->last_prim;
X last_prim_buffer->num_dwords = 0;
X last_prim_buffer->sec_used = 0;
- dev_priv->sarea_priv->last_dispatch =
+ dev_priv->sarea_priv->last_dispatch =
X dev_priv->last_prim_age = last_prim_buffer->prim_age;
X clear_bit(MGA_BUF_IN_USE, &last_prim_buffer->buffer_status);
- wake_up_interruptible(&dev_priv->wait_queue);
X clear_bit(MGA_BUF_SWAP_PENDING, &last_prim_buffer->buffer_status);
X clear_bit(MGA_IN_DISPATCH, &dev_priv->dispatch_status);
X atomic_dec(&dev_priv->pending_bufs);
X queue_task(&dev->tq, &tq_immediate);
X mark_bh(IMMEDIATE_BH);
+ wake_up_interruptible(&dev_priv->wait_queue);
X }
X
X static void mga_dma_task_queue(void *device)
X {
- DRM_DEBUG("%s\n", __FUNCTION__);
X mga_dma_schedule((drm_device_t *)device, 0);
X }
X
X int mga_dma_cleanup(drm_device_t *dev)
X {
- DRM_DEBUG("%s\n", __FUNCTION__);
-
X if(dev->dev_private) {
- drm_mga_private_t *dev_priv =
+ drm_mga_private_t *dev_priv =
X (drm_mga_private_t *) dev->dev_private;
-
+
+ if (dev->irq) mga_flush_queue(dev);
+ mga_dma_quiescent(dev);
+
X if(dev_priv->ioremap) {
- int temp = (dev_priv->warp_ucode_size +
- dev_priv->primary_size +
+ int temp = (dev_priv->warp_ucode_size +
+ dev_priv->primary_size +
X PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE;
X
X drm_ioremapfree((void *) dev_priv->ioremap, temp);
@@ -714,7 +653,7 @@
X }
X }
X drm_free(dev_priv->prim_bufs, sizeof(void *) *
- (MGA_NUM_PRIM_BUFS + 1),
+ (MGA_NUM_PRIM_BUFS + 1),
X DRM_MEM_DRIVER);
X }
X if(dev_priv->head != NULL) {
@@ -722,7 +661,7 @@
X }
X
X
- drm_free(dev->dev_private, sizeof(drm_mga_private_t),
+ drm_free(dev->dev_private, sizeof(drm_mga_private_t),
X DRM_MEM_DRIVER);
X dev->dev_private = NULL;


X }
@@ -733,9 +672,6 @@

X static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
X drm_mga_private_t *dev_priv;
X drm_map_t *sarea_map = NULL;
- int i;
-
- DRM_DEBUG("%s\n", __FUNCTION__);
X
X dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
X if(dev_priv == NULL) return -ENOMEM;
@@ -746,15 +682,14 @@
X if((init->reserved_map_idx >= dev->map_count) ||
X (init->buffer_map_idx >= dev->map_count)) {
X mga_dma_cleanup(dev);
- DRM_DEBUG("reserved_map or buffer_map are invalid\n");
X return -EINVAL;
X }
-
+
X dev_priv->reserved_map_idx = init->reserved_map_idx;
X dev_priv->buffer_map_idx = init->buffer_map_idx;
X sarea_map = dev->maplist[0];
- dev_priv->sarea_priv = (drm_mga_sarea_t *)
- ((u8 *)sarea_map->handle +
+ dev_priv->sarea_priv = (drm_mga_sarea_t *)
+ ((u8 *)sarea_map->handle +
X init->sarea_priv_offset);
X
X /* Scale primary size to the next page */
@@ -772,23 +707,17 @@
X init_waitqueue_head(&dev_priv->flush_queue);
X init_waitqueue_head(&dev_priv->buf_queue);
X dev_priv->WarpPipe = 0xff000000;
+ dev_priv->vertexsize = 0;
X
- DRM_DEBUG("chipset: %d ucode_size: %d backOffset: %x depthOffset: %x\n",
- dev_priv->chipset, dev_priv->warp_ucode_size,
+ DRM_DEBUG("chipset=%d ucode_size=%d backOffset=%x depthOffset=%x\n",
+ dev_priv->chipset, dev_priv->warp_ucode_size,
X dev_priv->backOffset, dev_priv->depthOffset);
X DRM_DEBUG("cpp: %d sgram: %d stride: %d maccess: %x\n",
- dev_priv->cpp, dev_priv->sgram, dev_priv->stride,
+ dev_priv->cpp, dev_priv->sgram, dev_priv->stride,
X dev_priv->mAccess);
-
- memcpy(&dev_priv->WarpIndex, &init->WarpIndex,
- sizeof(drm_mga_warp_index_t) * MGA_MAX_WARP_PIPES);
X
- for (i = 0 ; i < MGA_MAX_WARP_PIPES ; i++)
- DRM_DEBUG("warp pipe %d: installed: %d phys: %lx size: %x\n",
- i,
- dev_priv->WarpIndex[i].installed,
- dev_priv->WarpIndex[i].phys_addr,
- dev_priv->WarpIndex[i].size);
+ memcpy(&dev_priv->WarpIndex, &init->WarpIndex,
+ sizeof(drm_mga_warp_index_t) * MGA_MAX_WARP_PIPES);
X
X if(mga_init_primary_bufs(dev, init) != 0) {
X DRM_ERROR("Can not initialize primary buffers\n");
@@ -802,7 +731,7 @@
X return -ENOMEM;
X }
X
- dev_priv->status_page =
+ dev_priv->status_page =
X ioremap_nocache(virt_to_bus((void *)dev_priv->real_status_page),
X PAGE_SIZE);
X
@@ -813,15 +742,15 @@
X }
X
X /* Write status page when secend or softrap occurs */
- MGA_WRITE(MGAREG_PRIMPTR,
+ MGA_WRITE(MGAREG_PRIMPTR,
X virt_to_bus((void *)dev_priv->real_status_page) | 0x00000003);
-
+
X
X /* Private is now filled in, initialize the hardware */
X {
X PRIMLOCALS;
X PRIMGETPTR( dev_priv );
-
+
X PRIMOUTREG(MGAREG_DMAPAD, 0);
X PRIMOUTREG(MGAREG_DMAPAD, 0);
X PRIMOUTREG(MGAREG_DWGSYNC, 0x0100);
@@ -829,13 +758,13 @@
X /* Poll for the first buffer to insure that
X * the status register will be correct
X */
-
+
X mga_flush_write_combine();
X MGA_WRITE(MGAREG_PRIMADDRESS, phys_head | TT_GENERAL);
X
- MGA_WRITE(MGAREG_PRIMEND, ((phys_head + num_dwords * 4) |
+ MGA_WRITE(MGAREG_PRIMEND, ((phys_head + num_dwords * 4) |
X PDEA_pagpxfer_enable));
-
+
X while(MGA_READ(MGAREG_DWGSYNC) != 0x0100) ;
X }
X
@@ -853,12 +782,10 @@
X drm_file_t *priv = filp->private_data;
X drm_device_t *dev = priv->dev;
X drm_mga_init_t init;
-
- DRM_DEBUG("%s\n", __FUNCTION__);
X
X if (copy_from_user(&init, (drm_mga_init_t *)arg, sizeof(init)))
X return -EFAULT;
-
+
X switch(init.func) {
X case MGA_INIT_DMA:
X return mga_dma_initialize(dev, &init);
@@ -874,7 +801,7 @@
X int retcode;
X
X if (!irq) return -EINVAL;
-
+
X down(&dev->struct_sem);
X if (dev->irq) {
X up(&dev->struct_sem);
@@ -882,7 +809,7 @@
X }
X dev->irq = irq;
X up(&dev->struct_sem);
-
+
X DRM_DEBUG("install irq handler %d\n", irq);
X
X dev->context_flag = 0;
@@ -923,7 +850,7 @@
X irq = dev->irq;
X dev->irq = 0;
X up(&dev->struct_sem);
-
+
X if (!irq) return -EINVAL;
X DRM_DEBUG("remove irq handler %d\n", irq);
X MGA_WRITE(MGAREG_ICLEAR, 0x00000001);
@@ -938,12 +865,10 @@
X drm_file_t *priv = filp->private_data;
X drm_device_t *dev = priv->dev;
X drm_control_t ctl;
-
+
X if (copy_from_user(&ctl, (drm_control_t *)arg, sizeof(ctl)))
X return -EFAULT;
X
- DRM_DEBUG("%s\n", __FUNCTION__);
-
X switch (ctl.func) {
X case DRM_INST_HANDLER:
X return mga_irq_install(dev, ctl.irq);
@@ -960,31 +885,29 @@
X drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
X int ret = 0;
X
- DRM_DEBUG("%s\n", __FUNCTION__);
+ if(!dev_priv) return 0;
X
- if(dev_priv == NULL) {


- return 0;
- }
-

X if(dev_priv->next_prim->num_dwords != 0) {


- current->state = TASK_INTERRUPTIBLE;

X add_wait_queue(&dev_priv->flush_queue, &entry);
+ if (test_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status))
+ DRM_ERROR("Incorrect mga_flush_queue logic\n");
X set_bit(MGA_IN_FLUSH, &dev_priv->dispatch_status);
X mga_dma_schedule(dev, 0);
X for (;;) {
- if (!test_bit(MGA_IN_FLUSH,
- &dev_priv->dispatch_status))

+ current->state = TASK_INTERRUPTIBLE;

+ if (!test_bit(MGA_IN_FLUSH,
+ &dev_priv->dispatch_status))
X break;
X atomic_inc(&dev->total_sleeps);


X schedule();
X if (signal_pending(current)) {

X ret = -EINTR; /* Can't restart */
- clear_bit(MGA_IN_FLUSH,
+ clear_bit(MGA_IN_FLUSH,
X &dev_priv->dispatch_status);
X break;
X }
X }


- current->state = TASK_RUNNING;

+ current->state = TASK_RUNNING;
X remove_wait_queue(&dev_priv->flush_queue, &entry);
X }
X return ret;
@@ -1000,18 +923,19 @@
X if(dev->dev_private == NULL) return;
X if(dma->buflist == NULL) return;
X
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("buf_count=%d\n", dma->buf_count);
+
X mga_flush_queue(dev);
X
X for (i = 0; i < dma->buf_count; i++) {
X drm_buf_t *buf = dma->buflist[ i ];
X drm_mga_buf_priv_t *buf_priv = buf->dev_private;
X
- /* Only buffers that need to get reclaimed ever
- * get set to free
+ /* Only buffers that need to get reclaimed ever
+ * get set to free
X */
X if (buf->pid == pid && buf_priv) {
- if(buf_priv->my_freelist->age == MGA_BUF_USED)
+ if(buf_priv->my_freelist->age == MGA_BUF_USED)
X buf_priv->my_freelist->age = MGA_BUF_FREE;
X }
X }
@@ -1026,7 +950,6 @@
X int ret = 0;
X drm_lock_t lock;
X
- DRM_DEBUG("%s\n", __FUNCTION__);
X if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
X return -EFAULT;
X
@@ -1035,21 +958,16 @@
X current->pid, lock.context);
X return -EINVAL;
X }
-
- DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
- lock.context, current->pid, dev->lock.hw_lock->lock,
- lock.flags);
X
- if (lock.context < 0) {


- return -EINVAL;
- }
-

+ if (lock.context < 0) return -EINVAL;
+
X /* Only one queue:
X */
X
X if (!ret) {
X add_wait_queue(&dev->lock.lock_queue, &entry);


X for (;;) {
+ current->state = TASK_INTERRUPTIBLE;

X if (!dev->lock.hw_lock) {
X /* Device has been unregistered */
X ret = -EINTR;
@@ -1062,10 +980,9 @@
X atomic_inc(&dev->total_locks);
X break; /* Got lock */
X }
-
+
X /* Contention */
X atomic_inc(&dev->total_sleeps);


- current->state = TASK_INTERRUPTIBLE;

X schedule();
X if (signal_pending(current)) {
X ret = -ERESTARTSYS;
@@ -1075,7 +992,7 @@
X current->state = TASK_RUNNING;
X remove_wait_queue(&dev->lock.lock_queue, &entry);
X }
-
+
X if (!ret) {
X sigemptyset(&dev->sigmask);
X sigaddset(&dev->sigmask, SIGSTOP);
@@ -1092,12 +1009,13 @@
X mga_dma_quiescent(dev);
X }
X }
-
- DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
+
+ if (ret) DRM_DEBUG("%d %s\n", lock.context,
+ ret ? "interrupted" : "has lock");
X return ret;
X }
-
-int mga_flush_ioctl(struct inode *inode, struct file *filp,
+
+int mga_flush_ioctl(struct inode *inode, struct file *filp,
X unsigned int cmd, unsigned long arg)
X {
X drm_file_t *priv = filp->private_data;
@@ -1105,12 +1023,11 @@
X drm_lock_t lock;
X drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
X
- DRM_DEBUG("%s\n", __FUNCTION__);
X if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
X return -EFAULT;
X
X if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
- DRM_ERROR("mga_flush_ioctl called without lock held\n");
+ DRM_ERROR("lock not held\n");
X return -EINVAL;
X }
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/drm/mga_drm.h linux/drivers/char/drm/mga_drm.h
--- v2.4.0-test8/linux/drivers/char/drm/mga_drm.h Fri Jul 21 12:56:44 2000
+++ linux/drivers/char/drm/mga_drm.h Fri Sep 15 14:24:55 2000
@@ -73,17 +73,19 @@
X
X /* 3d state excluding texture units:
X */
-#define MGA_CTXREG_DSTORG 0 /* validated */
-#define MGA_CTXREG_MACCESS 1
-#define MGA_CTXREG_PLNWT 2
-#define MGA_CTXREG_DWGCTL 3
-#define MGA_CTXREG_ALPHACTRL 4
-#define MGA_CTXREG_FOGCOLOR 5
-#define MGA_CTXREG_WFLAG 6
-#define MGA_CTXREG_TDUAL0 7
-#define MGA_CTXREG_TDUAL1 8
-#define MGA_CTXREG_FCOL 9
-#define MGA_CTX_SETUP_SIZE 10
+#define MGA_CTXREG_DSTORG 0 /* validated */
+#define MGA_CTXREG_MACCESS 1
+#define MGA_CTXREG_PLNWT 2
+#define MGA_CTXREG_DWGCTL 3
+#define MGA_CTXREG_ALPHACTRL 4
+#define MGA_CTXREG_FOGCOLOR 5
+#define MGA_CTXREG_WFLAG 6
+#define MGA_CTXREG_TDUAL0 7
+#define MGA_CTXREG_TDUAL1 8
+#define MGA_CTXREG_FCOL 9
+#define MGA_CTXREG_STENCIL 10
+#define MGA_CTXREG_STENCILCTL 11
+#define MGA_CTX_SETUP_SIZE 12
X
X /* 2d state
X */
@@ -233,6 +235,7 @@
X /* Mechanism to validate card state.
X */
X int ctxOwner;
+ int vertexsize;
X } drm_mga_sarea_t;
X
X /* Device specific ioctls:
@@ -241,6 +244,8 @@
X unsigned int clear_color;
X unsigned int clear_depth;
X unsigned int flags;
+ unsigned int clear_depth_mask;
+ unsigned int clear_color_mask;
X } drm_mga_clear_t;
X
X typedef struct _drm_mga_swap {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/drm/mga_drv.c linux/drivers/char/drm/mga_drv.c
--- v2.4.0-test8/linux/drivers/char/drm/mga_drv.c Tue Aug 29 21:09:10 2000
+++ linux/drivers/char/drm/mga_drv.c Sun Oct 1 20:00:00 2000
@@ -1,6 +1,6 @@
X /* mga_drv.c -- Matrox g200/g400 driver -*- linux-c -*-
X * Created: Mon Dec 13 01:56:22 1999 by jhar...@precisioninsight.com
- *
+ *
X * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
X * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
X * All Rights Reserved.
@@ -11,11 +11,11 @@
X * the rights to use, copy, modify, merge, publish, distribute, sublicense,
X * and/or sell copies of the Software, and to permit persons to whom the
X * Software is furnished to do so, subject to the following conditions:
- *
+ *
X * The above copyright notice and this permission notice (including the next
X * paragraph) shall be included in all copies or substantial portions of the
X * Software.
- *
+ *
X * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
X * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
X * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
@@ -35,11 +35,11 @@
X #include "mga_drv.h"
X
X #define MGA_NAME "mga"
-#define MGA_DESC "Matrox g200/g400"
-#define MGA_DATE "20000719"
-#define MGA_MAJOR 1
+#define MGA_DESC "Matrox G200/G400"
+#define MGA_DATE "20000928"
+#define MGA_MAJOR 2
X #define MGA_MINOR 0
-#define MGA_PATCHLEVEL 0
+#define MGA_PATCHLEVEL 1
X
X static drm_device_t mga_device;
X drm_ctx_t mga_res_ctx;
@@ -123,7 +123,7 @@
X #endif
X
X MODULE_AUTHOR("VA Linux Systems, Inc.");
-MODULE_DESCRIPTION("Matrox g200/g400");
+MODULE_DESCRIPTION("Matrox G200/G400");
X MODULE_PARM(mga, "s");
X
X #ifndef MODULE
@@ -144,7 +144,7 @@
X static int mga_setup(drm_device_t *dev)
X {
X int i;
-
+
X atomic_set(&dev->ioctl_count, 0);
X atomic_set(&dev->vma_count, 0);
X dev->buf_use = 0;
@@ -187,22 +187,22 @@
X
X dev->ctx_start = 0;
X dev->lck_start = 0;
-
+
X dev->buf_rp = dev->buf;
X dev->buf_wp = dev->buf;
X dev->buf_end = dev->buf + DRM_BSZ;
X dev->buf_async = NULL;
X init_waitqueue_head(&dev->buf_readers);
X init_waitqueue_head(&dev->buf_writers);
-
+
X DRM_DEBUG("\n");
-
+
X /* The kernel's context could be created here, but is now created
X in drm_dma_enqueue. This is more resource-efficient for
X hardware that does not do DMA, but may mean that
X drm_select_queue fails between the time the interrupt is


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 047'
echo 'File patch-2.4.0-test9 is continued in part 048'
echo "048" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part048

#!/bin/sh -x
# this is part 048 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 048; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

X initialized and the time the queues are initialized. */
-
+
X return 0;
X }
X

@@ -216,16 +216,17 @@


X
X DRM_DEBUG("\n");

X
+ if (dev->dev_private) mga_dma_cleanup(dev);
X if (dev->irq) mga_irq_uninstall(dev);


-
+
X down(&dev->struct_sem);
X del_timer(&dev->timer);
-
+
X if (dev->devname) {
X drm_free(dev->devname, strlen(dev->devname)+1, DRM_MEM_DRIVER);
X dev->devname = NULL;
X }
-
+
X if (dev->unique) {
X drm_free(dev->unique, strlen(dev->unique)+1, DRM_MEM_DRIVER);
X dev->unique = NULL;

@@ -243,7 +244,7 @@


X if (dev->agp) {
X drm_agp_mem_t *entry;
X drm_agp_mem_t *nexte;
-
+
X /* Remove AGP resources, but leave dev->agp

X intact until cleanup is called. */


X for (entry = dev->agp->memory; entry; entry = nexte) {

@@ -253,10 +254,10 @@


X drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
X }
X dev->agp->memory = NULL;
-
+
X if (dev->agp->acquired && drm_agp.release)
X (*drm_agp.release)();
-
+
X dev->agp->acquired = 0;
X dev->agp->enabled = 0;
X }

@@ -268,7 +269,7 @@


X }
X dev->vmalist = NULL;
X }
-
+
X /* Clear map area and mtrr information */
X if (dev->maplist) {
X for (i = 0; i < dev->map_count; i++) {

@@ -304,7 +305,7 @@


X dev->maplist = NULL;
X dev->map_count = 0;
X }
-
+
X if (dev->queuelist) {
X for (i = 0; i < dev->queue_count; i++) {
X drm_waitlist_destroy(&dev->queuelist[i]->waitlist);

@@ -330,7 +331,7 @@


X wake_up_interruptible(&dev->lock.lock_queue);
X }
X up(&dev->struct_sem);
-
+
X return 0;
X }
X

@@ -347,11 +348,10 @@


X memset((void *)dev, 0, sizeof(*dev));
X dev->count_lock = SPIN_LOCK_UNLOCKED;
X sema_init(&dev->struct_sem, 1);
-
+
X #ifdef MODULE

X drm_parse_options(mga);
X #endif
- DRM_DEBUG("doing misc_register\n");
X if ((retcode = misc_register(&mga_misc))) {
X DRM_ERROR("Cannot register \"%s\"\n", MGA_NAME);
X return retcode;
@@ -359,11 +359,8 @@
X dev->device = MKDEV(MISC_MAJOR, mga_misc.minor);
X dev->name = MGA_NAME;
X
- DRM_DEBUG("doing mem init\n");
X drm_mem_init();
- DRM_DEBUG("doing proc init\n");
X drm_proc_init(dev);
- DRM_DEBUG("doing agp init\n");
X dev->agp = drm_agp_init();
X if(dev->agp == NULL) {
X DRM_INFO("The mga drm module requires the agpgart module"
@@ -380,7 +377,6 @@
X MTRR_TYPE_WRCOMB,
X 1);
X #endif
- DRM_DEBUG("doing ctxbitmap init\n");
X if((retcode = drm_ctxbitmap_init(dev))) {
X DRM_ERROR("Cannot allocate memory for context bitmap.\n");
X drm_proc_cleanup();
@@ -407,7 +403,7 @@
X drm_device_t *dev = &mga_device;


X
X DRM_DEBUG("\n");
-
+
X drm_proc_cleanup();

X if (misc_deregister(&mga_misc)) {


X DRM_ERROR("Cannot unload module\n");

@@ -415,11 +411,10 @@
X DRM_INFO("Module unloaded\n");
X }
X drm_ctxbitmap_cleanup(dev);
- mga_dma_cleanup(dev);
X #ifdef CONFIG_MTRR
X if(dev->agp && dev->agp->agp_mtrr) {
X int retval;
- retval = mtrr_del(dev->agp->agp_mtrr,
+ retval = mtrr_del(dev->agp->agp_mtrr,
X dev->agp->agp_info.aper_base,
X dev->agp->agp_info.aper_size * 1024*1024);
X DRM_DEBUG("mtrr_del = %d\n", retval);
@@ -477,7 +472,7 @@
X {
X drm_device_t *dev = &mga_device;


X int retcode = 0;
-
+
X DRM_DEBUG("open_count = %d\n", dev->open_count);
X if (!(retcode = drm_open_helper(inode, filp, dev))) {
X #if LINUX_VERSION_CODE < 0x020333

@@ -508,22 +503,27 @@
X if (dev->lock.hw_lock && _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)
X && dev->lock.pid == current->pid) {
X mga_reclaim_buffers(dev, priv->pid);
- DRM_ERROR("Process %d dead, freeing lock for context %d\n",
- current->pid,
- _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
+ DRM_INFO("Process %d dead (ctx %d, d_s = 0x%02x)\n",
+ current->pid,
+ _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock),
+ dev->dev_private ?
+ ((drm_mga_private_t *)dev->dev_private)
+ ->dispatch_status
+ : 0);
+
+ if (dev->dev_private)
+ ((drm_mga_private_t *)dev->dev_private)
+ ->dispatch_status &= MGA_IN_DISPATCH;
+

X drm_lock_free(dev,
X &dev->lock.hw_lock->lock,
X _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
-

- /* FIXME: may require heavy-handed reset of
- hardware at this point, possibly
- processed via a callback to the X
- server. */
X } else if (dev->lock.hw_lock) {
X /* The lock is required to reclaim buffers */


X DECLARE_WAITQUEUE(entry, current);
X add_wait_queue(&dev->lock.lock_queue, &entry);
X for (;;) {
+ current->state = TASK_INTERRUPTIBLE;
X if (!dev->lock.hw_lock) {
X /* Device has been unregistered */
X retcode = -EINTR;

@@ -535,10 +535,9 @@


X dev->lock.lock_time = jiffies;
X atomic_inc(&dev->total_locks);
X break; /* Got lock */
- }
+ }
X /* Contention */
X atomic_inc(&dev->total_sleeps);
- current->state = TASK_INTERRUPTIBLE;
X schedule();
X if (signal_pending(current)) {
X retcode = -ERESTARTSYS;

@@ -549,6 +548,9 @@
X remove_wait_queue(&dev->lock.lock_queue, &entry);
X if(!retcode) {
X mga_reclaim_buffers(dev, priv->pid);
+ if (dev->dev_private)
+ ((drm_mga_private_t *)dev->dev_private)
+ ->dispatch_status &= MGA_IN_DISPATCH;
X drm_lock_free(dev, &dev->lock.hw_lock->lock,
X DRM_KERNEL_CONTEXT);
X }
@@ -556,12 +558,19 @@
X drm_fasync(-1, filp, 0);
X
X down(&dev->struct_sem);
+ if (priv->remove_auth_on_close == 1) {
+ drm_file_t *temp = dev->file_first;
+ while(temp) {
+ temp->authenticated = 0;
+ temp = temp->next;
+ }
+ }
X if (priv->prev) priv->prev->next = priv->next;
X else dev->file_first = priv->next;


X if (priv->next) priv->next->prev = priv->prev;
X else dev->file_last = priv->prev;
X up(&dev->struct_sem);
-
+
X drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
X #if LINUX_VERSION_CODE < 0x020333
X MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */

@@ -602,9 +611,6 @@


X atomic_inc(&dev->ioctl_count);
X atomic_inc(&dev->total_ioctl);
X ++priv->ioctl_count;
-

- DRM_DEBUG("pid = %d, cmd = 0x%02x, nr = 0x%02x, dev 0x%x, auth = %d\n",
- current->pid, cmd, nr, dev->device, priv->authenticated);
X
X if (nr >= MGA_IOCTL_COUNT) {
X retcode = -EINVAL;
@@ -613,7 +619,10 @@
X func = ioctl->func;
X
X if (!func) {
- DRM_DEBUG("no function\n");
+ DRM_DEBUG("no function: pid = %d, cmd = 0x%02x,"
+ " nr = 0x%02x, dev 0x%x, auth = %d\n",
+ current->pid, cmd, nr, dev->device,
+ priv->authenticated);
X retcode = -EINVAL;
X } else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN))
X || (ioctl->auth_needed && !priv->authenticated)) {
@@ -622,7 +631,7 @@


X retcode = (func)(inode, filp, cmd, arg);
X }
X }
-
+
X atomic_dec(&dev->ioctl_count);
X return retcode;
X }

@@ -636,16 +645,13 @@


X
X if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
X return -EFAULT;
-
+
X if (lock.context == DRM_KERNEL_CONTEXT) {
X DRM_ERROR("Process %d using kernel context %d\n",
X current->pid, lock.context);

X return -EINVAL;
X }
X

- DRM_DEBUG("%d frees lock (%d holds)\n",
- lock.context,
- _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
X atomic_inc(&dev->total_unlocks);
X if (_DRM_LOCK_IS_CONT(dev->lock.hw_lock->lock))
X atomic_inc(&dev->total_contends);
@@ -653,9 +659,7 @@
X mga_dma_schedule(dev, 1);
X

X if (drm_lock_free(dev, &dev->lock.hw_lock->lock,

- DRM_KERNEL_CONTEXT)) {
- DRM_ERROR("\n");
- }
+ DRM_KERNEL_CONTEXT)) DRM_ERROR("\n");
X

X unblock_all_signals();
X return 0;

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/drm/mga_drv.h linux/drivers/char/drm/mga_drv.h
--- v2.4.0-test8/linux/drivers/char/drm/mga_drv.h Tue Aug 29 21:09:10 2000
+++ linux/drivers/char/drm/mga_drv.h Sun Oct 1 20:00:00 2000


@@ -11,11 +11,11 @@
X * the rights to use, copy, modify, merge, publish, distribute, sublicense,
X * and/or sell copies of the Software, and to permit persons to whom the
X * Software is furnished to do so, subject to the following conditions:
- *
+ *
X * The above copyright notice and this permission notice (including the next
X * paragraph) shall be included in all copies or substantial portions of the
X * Software.
- *
+ *
X * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
X * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
X * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL

@@ -50,7 +50,7 @@
X } drm_mga_prim_buf_t;
X
X typedef struct _drm_mga_freelist {
- unsigned int age;
+ __volatile__ unsigned int age;
X drm_buf_t *buf;
X struct _drm_mga_freelist *next;
X struct _drm_mga_freelist *prev;
@@ -82,6 +82,7 @@
X int use_agp;
X drm_mga_warp_index_t WarpIndex[MGA_MAX_G400_PIPES];
X unsigned int WarpPipe;
+ unsigned int vertexsize;
X atomic_t pending_bufs;
X void *status_page;
X unsigned long real_status_page;
@@ -97,7 +98,7 @@
X wait_queue_head_t wait_queue; /* Processes waiting until interrupt */
X wait_queue_head_t buf_queue; /* Processes waiting for a free buf */
X /* Some validated register values:
- */
+ */
X u32 mAccess;
X } drm_mga_private_t;
X
@@ -128,7 +129,6 @@
X extern int mga_dma_cleanup(drm_device_t *dev);
X extern int mga_flush_ioctl(struct inode *inode, struct file *filp,
X unsigned int cmd, unsigned long arg);
-extern void mga_flush_write_combine(void);
X extern unsigned int mga_create_sync_tag(drm_device_t *dev);
X extern drm_buf_t *mga_freelist_get(drm_device_t *dev);
X extern int mga_freelist_put(drm_device_t *dev, drm_buf_t *buf);
@@ -137,9 +137,9 @@
X
X
X /* mga_bufs.c */
-extern int mga_addbufs(struct inode *inode, struct file *filp,
+extern int mga_addbufs(struct inode *inode, struct file *filp,
X unsigned int cmd, unsigned long arg);
-extern int mga_infobufs(struct inode *inode, struct file *filp,
+extern int mga_infobufs(struct inode *inode, struct file *filp,


X unsigned int cmd, unsigned long arg);

X extern int mga_markbufs(struct inode *inode, struct file *filp,
X unsigned int cmd, unsigned long arg);
@@ -179,6 +179,7 @@
X extern int mga_context_switch(drm_device_t *dev, int old, int new);
X extern int mga_context_switch_complete(drm_device_t *dev, int new);
X
+#define mga_flush_write_combine() mb()
X
X typedef enum {
X TT_GENERAL,
@@ -201,7 +202,7 @@
X #define ISREG0(r) (r >= DWGREG0 && r <= DWGREG0_END)
X #define ADRINDEX0(r) (u8)((r - DWGREG0) >> 2)
X #define ADRINDEX1(r) (u8)(((r - DWGREG1) >> 2) | 0x80)
-#define ADRINDEX(r) (ISREG0(r) ? ADRINDEX0(r) : ADRINDEX1(r))
+#define ADRINDEX(r) (ISREG0(r) ? ADRINDEX0(r) : ADRINDEX1(r))
X
X #define MGA_VERBOSE 0
X #define MGA_NUM_PRIM_BUFS 8
@@ -212,13 +213,12 @@
X #define PRIM_OVERFLOW(dev, dev_priv, length) do { \
X drm_mga_prim_buf_t *tmp_buf = \
X dev_priv->prim_bufs[dev_priv->current_prim_idx]; \
- if( test_bit(MGA_BUF_NEEDS_OVERFLOW, \
- &tmp_buf->buffer_status)) { \
+ if( test_bit(MGA_BUF_NEEDS_OVERFLOW, &tmp_buf->buffer_status)) { \
X mga_advance_primary(dev); \
X mga_dma_schedule(dev, 1); \
X tmp_buf = dev_priv->prim_bufs[dev_priv->current_prim_idx]; \
X } else if( tmp_buf->max_dwords - tmp_buf->num_dwords < length || \
- tmp_buf->sec_used > MGA_DMA_BUF_NR/2) { \
+ tmp_buf->sec_used > MGA_DMA_BUF_NR/2) { \
X set_bit(MGA_BUF_FORCE_FIRE, &tmp_buf->buffer_status); \
X mga_advance_primary(dev); \
X mga_dma_schedule(dev, 1); \
@@ -295,7 +295,7 @@
X num_dwords + 1 + outcount, ADRINDEX(reg), val); \
X if( ++outcount == 4) { \
X outcount = 0; \
- dma_ptr[0] = *(u32 *)tempIndex; \
+ dma_ptr[0] = *(unsigned long *)tempIndex; \
X dma_ptr+=5; \
X num_dwords += 5; \
X } \
@@ -377,6 +377,72 @@
X #define MGAREG_YTOP 0x1c98
X #define MGAREG_ZORG 0x1c0c
X
+/* Warp registers */
+#define MGAREG_WR0 0x2d00
+#define MGAREG_WR1 0x2d04
+#define MGAREG_WR2 0x2d08
+#define MGAREG_WR3 0x2d0c
+#define MGAREG_WR4 0x2d10
+#define MGAREG_WR5 0x2d14
+#define MGAREG_WR6 0x2d18
+#define MGAREG_WR7 0x2d1c
+#define MGAREG_WR8 0x2d20
+#define MGAREG_WR9 0x2d24
+#define MGAREG_WR10 0x2d28
+#define MGAREG_WR11 0x2d2c
+#define MGAREG_WR12 0x2d30
+#define MGAREG_WR13 0x2d34
+#define MGAREG_WR14 0x2d38
+#define MGAREG_WR15 0x2d3c
+#define MGAREG_WR16 0x2d40
+#define MGAREG_WR17 0x2d44
+#define MGAREG_WR18 0x2d48
+#define MGAREG_WR19 0x2d4c
+#define MGAREG_WR20 0x2d50
+#define MGAREG_WR21 0x2d54
+#define MGAREG_WR22 0x2d58
+#define MGAREG_WR23 0x2d5c
+#define MGAREG_WR24 0x2d60
+#define MGAREG_WR25 0x2d64
+#define MGAREG_WR26 0x2d68
+#define MGAREG_WR27 0x2d6c
+#define MGAREG_WR28 0x2d70
+#define MGAREG_WR29 0x2d74
+#define MGAREG_WR30 0x2d78
+#define MGAREG_WR31 0x2d7c
+#define MGAREG_WR32 0x2d80
+#define MGAREG_WR33 0x2d84
+#define MGAREG_WR34 0x2d88
+#define MGAREG_WR35 0x2d8c
+#define MGAREG_WR36 0x2d90
+#define MGAREG_WR37 0x2d94
+#define MGAREG_WR38 0x2d98
+#define MGAREG_WR39 0x2d9c
+#define MGAREG_WR40 0x2da0
+#define MGAREG_WR41 0x2da4
+#define MGAREG_WR42 0x2da8
+#define MGAREG_WR43 0x2dac
+#define MGAREG_WR44 0x2db0
+#define MGAREG_WR45 0x2db4
+#define MGAREG_WR46 0x2db8
+#define MGAREG_WR47 0x2dbc
+#define MGAREG_WR48 0x2dc0
+#define MGAREG_WR49 0x2dc4
+#define MGAREG_WR50 0x2dc8
+#define MGAREG_WR51 0x2dcc
+#define MGAREG_WR52 0x2dd0
+#define MGAREG_WR53 0x2dd4
+#define MGAREG_WR54 0x2dd8
+#define MGAREG_WR55 0x2ddc
+#define MGAREG_WR56 0x2de0
+#define MGAREG_WR57 0x2de4
+#define MGAREG_WR58 0x2de8
+#define MGAREG_WR59 0x2dec
+#define MGAREG_WR60 0x2df0
+#define MGAREG_WR61 0x2df4
+#define MGAREG_WR62 0x2df8
+#define MGAREG_WR63 0x2dfc
+
X #define PDEA_pagpxfer_enable 0x2
X
X #define WIA_wmode_suspend 0x0
@@ -396,8 +462,8 @@
X #define DC_atype_zi 0x30
X #define DC_atype_blk 0x40
X #define DC_atype_i 0x70
-#define DC_linear_xy 0x0
-#define DC_linear_linear 0x80
+#define DC_linear_xy 0x0
+#define DC_linear_linear 0x80
X #define DC_zmode_nozcmp 0x0
X #define DC_zmode_ze 0x200
X #define DC_zmode_zne 0x300
@@ -405,16 +471,16 @@
X #define DC_zmode_zlte 0x500
X #define DC_zmode_zgt 0x600
X #define DC_zmode_zgte 0x700
-#define DC_solid_disable 0x0
-#define DC_solid_enable 0x800
-#define DC_arzero_disable 0x0
-#define DC_arzero_enable 0x1000
-#define DC_sgnzero_disable 0x0
-#define DC_sgnzero_enable 0x2000
-#define DC_shftzero_disable 0x0
-#define DC_shftzero_enable 0x4000
-#define DC_bop_SHIFT 16
-#define DC_trans_SHIFT 20
+#define DC_solid_disable 0x0
+#define DC_solid_enable 0x800
+#define DC_arzero_disable 0x0
+#define DC_arzero_enable 0x1000
+#define DC_sgnzero_disable 0x0
+#define DC_sgnzero_enable 0x2000
+#define DC_shftzero_disable 0x0
+#define DC_shftzero_enable 0x4000
+#define DC_bop_SHIFT 16
+#define DC_trans_SHIFT 20
X #define DC_bltmod_bmonolef 0x0
X #define DC_bltmod_bmonowf 0x8000000
X #define DC_bltmod_bplan 0x2000000
@@ -423,21 +489,22 @@
X #define DC_bltmod_bu32rgb 0xe000000
X #define DC_bltmod_bu24bgr 0x16000000
X #define DC_bltmod_bu24rgb 0x1e000000
-#define DC_pattern_disable 0x0
-#define DC_pattern_enable 0x20000000
-#define DC_transc_disable 0x0
-#define DC_transc_enable 0x40000000
-#define DC_clipdis_disable 0x0
-#define DC_clipdis_enable 0x80000000
+#define DC_pattern_disable 0x0
+#define DC_pattern_enable 0x20000000
+#define DC_transc_disable 0x0
+#define DC_transc_enable 0x40000000
+#define DC_clipdis_disable 0x0
+#define DC_clipdis_enable 0x80000000
X
-#define SETADD_mode_vertlist 0x0
+
+#define SETADD_mode_vertlist 0x0
X
X
X #define MGA_CLEAR_CMD (DC_opcod_trap | DC_arzero_enable | \
X DC_sgnzero_enable | DC_shftzero_enable | \
X (0xC << DC_bop_SHIFT) | DC_clipdis_enable | \
X DC_solid_enable | DC_transc_enable)
-
+
X
X #define MGA_COPY_CMD (DC_opcod_bitblt | DC_atype_rpl | DC_linear_xy | \
X DC_solid_disable | DC_arzero_disable | \
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/drm/mga_state.c linux/drivers/char/drm/mga_state.c
--- v2.4.0-test8/linux/drivers/char/drm/mga_state.c Tue Aug 29 21:09:10 2000
+++ linux/drivers/char/drm/mga_state.c Sun Oct 1 20:00:00 2000


@@ -11,11 +11,11 @@
X * the rights to use, copy, modify, merge, publish, distribute, sublicense,
X * and/or sell copies of the Software, and to permit persons to whom the
X * Software is furnished to do so, subject to the following conditions:
- *
+ *
X * The above copyright notice and this permission notice (including the next
X * paragraph) shall be included in all copies or substantial portions of the
X * Software.
- *
+ *
X * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
X * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
X * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL

@@ -38,13 +38,13 @@
X * change these values
X */
X
-#define MGAEMITCLIP_SIZE 10
-#define MGAEMITCTX_SIZE 15
-#define MGAG200EMITTEX_SIZE 20
-#define MGAG400EMITTEX0_SIZE 30
-#define MGAG400EMITTEX1_SIZE 25
-#define MGAG400EMITPIPE_SIZE 50
-#define MGAG200EMITPIPE_SIZE 15
+#define MGAEMITCLIP_SIZE 10
+#define MGAEMITCTX_SIZE 20
+#define MGAG200EMITTEX_SIZE 20
+#define MGAG400EMITTEX0_SIZE 30
+#define MGAG400EMITTEX1_SIZE 25
+#define MGAG400EMITPIPE_SIZE 50
+#define MGAG200EMITPIPE_SIZE 15
X
X #define MAX_STATE_SIZE ((MGAEMITCLIP_SIZE * MGA_NR_SAREA_CLIPRECTS) + \
X MGAEMITCTX_SIZE + MGAG400EMITTEX0_SIZE + \
@@ -56,24 +56,24 @@
X drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
X unsigned int *regs = sarea_priv->ContextState;
X PRIMLOCALS;


- DRM_DEBUG("%s\n", __FUNCTION__);
X

X /* This takes 10 dwords */
X PRIMGETPTR(dev_priv);
X
- /* Force reset of dwgctl (eliminates clip disable) */
+ /* Force reset of dwgctl on G400 (eliminates clip disable bit) */
+ if (dev_priv->chipset == MGA_CARD_TYPE_G400) {
X #if 0
- PRIMOUTREG(MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_DWGSYNC, 0);
- PRIMOUTREG(MGAREG_DWGSYNC, 0);
- PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]);
+ PRIMOUTREG(MGAREG_DMAPAD, 0);
+ PRIMOUTREG(MGAREG_DWGSYNC, 0);
+ PRIMOUTREG(MGAREG_DWGSYNC, 0);
+ PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]);
X #else
- PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]);
- PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0x80000000);
- PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]);
- PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0x80000000);
+ PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]);
+ PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0x80000000);
+ PRIMOUTREG(MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL]);
+ PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0x80000000);
X #endif
-
+ }
X PRIMOUTREG(MGAREG_DMAPAD, 0);
X PRIMOUTREG(MGAREG_CXBNDRY, ((box->x2) << 16) | (box->x1));
X PRIMOUTREG(MGAREG_YTOP, box->y1 * dev_priv->stride / dev_priv->cpp);
@@ -87,9 +87,8 @@
X drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
X unsigned int *regs = sarea_priv->ContextState;
X PRIMLOCALS;


- DRM_DEBUG("%s\n", __FUNCTION__);
X

- /* This takes a max of 15 dwords */
+ /* This takes a max of 20 dwords */
X PRIMGETPTR(dev_priv);
X
X PRIMOUTREG(MGAREG_DSTORG, regs[MGA_CTXREG_DSTORG]);
@@ -107,6 +106,11 @@
X PRIMOUTREG(MGAREG_TDUALSTAGE0, regs[MGA_CTXREG_TDUAL0]);
X PRIMOUTREG(MGAREG_TDUALSTAGE1, regs[MGA_CTXREG_TDUAL1]);
X PRIMOUTREG(MGAREG_FCOL, regs[MGA_CTXREG_FCOL]);
+
+ PRIMOUTREG(MGAREG_STENCIL, regs[MGA_CTXREG_STENCIL]);
+ PRIMOUTREG(MGAREG_STENCILCTL, regs[MGA_CTXREG_STENCILCTL]);
+ PRIMOUTREG(MGAREG_DMAPAD, 0);
+ PRIMOUTREG(MGAREG_DMAPAD, 0);
X } else {
X PRIMOUTREG(MGAREG_FCOL, regs[MGA_CTXREG_FCOL]);
X PRIMOUTREG(MGAREG_DMAPAD, 0);
@@ -122,7 +126,6 @@
X drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
X unsigned int *regs = sarea_priv->TexState[0];
X PRIMLOCALS;


- DRM_DEBUG("%s\n", __FUNCTION__);
X

X PRIMGETPTR(dev_priv);
X
@@ -141,9 +144,9 @@
X PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4]);
X PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH]);
X PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT]);
- PRIMOUTREG(0x2d00 + 24 * 4, regs[MGA_TEXREG_WIDTH]);
+ PRIMOUTREG(MGAREG_WR24, regs[MGA_TEXREG_WIDTH]);
X
- PRIMOUTREG(0x2d00 + 34 * 4, regs[MGA_TEXREG_HEIGHT]);
+ PRIMOUTREG(MGAREG_WR34, regs[MGA_TEXREG_HEIGHT]);
X PRIMOUTREG(MGAREG_TEXTRANS, 0xffff);
X PRIMOUTREG(MGAREG_TEXTRANSHIGH, 0xffff);
X PRIMOUTREG(MGAREG_DMAPAD, 0);
@@ -151,17 +154,17 @@
X PRIMADVANCE(dev_priv);
X }
X
+#define TMC_dualtex_enable 0x80
+
X static void mgaG400EmitTex0(drm_mga_private_t * dev_priv)
X {
X drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
X unsigned int *regs = sarea_priv->TexState[0];
- int multitex = sarea_priv->WarpPipe & MGA_T2;
X PRIMLOCALS;


- DRM_DEBUG("%s\n", __FUNCTION__);
X

X PRIMGETPTR(dev_priv);
X
- /* This takes a max of 30 dwords */
+ /* This takes 30 dwords */
X
X PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] | 0x00008000);
X PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL]);
@@ -176,22 +179,20 @@
X PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4]);
X PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH]);
X PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT]);
- PRIMOUTREG(0x2d00 + 49 * 4, 0);
+ PRIMOUTREG(MGAREG_WR49, 0);
X
- PRIMOUTREG(0x2d00 + 57 * 4, 0);
- PRIMOUTREG(0x2d00 + 53 * 4, 0);
- PRIMOUTREG(0x2d00 + 61 * 4, 0);
+ PRIMOUTREG(MGAREG_WR57, 0);
+ PRIMOUTREG(MGAREG_WR53, 0);
+ PRIMOUTREG(MGAREG_WR61, 0);
+ PRIMOUTREG(MGAREG_WR52, 0x40);
+
+ PRIMOUTREG(MGAREG_WR60, 0x40);
+ PRIMOUTREG(MGAREG_WR54, regs[MGA_TEXREG_WIDTH] | 0x40);
+ PRIMOUTREG(MGAREG_WR62, regs[MGA_TEXREG_HEIGHT] | 0x40);
X PRIMOUTREG(MGAREG_DMAPAD, 0);
X
- if (!multitex) {
- PRIMOUTREG(0x2d00 + 52 * 4, 0x40);
- PRIMOUTREG(0x2d00 + 60 * 4, 0x40);
- PRIMOUTREG(MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_DMAPAD, 0);
- }
-
- PRIMOUTREG(0x2d00 + 54 * 4, regs[MGA_TEXREG_WIDTH] | 0x40);
- PRIMOUTREG(0x2d00 + 62 * 4, regs[MGA_TEXREG_HEIGHT] | 0x40);
+ PRIMOUTREG(MGAREG_DMAPAD, 0);
+ PRIMOUTREG(MGAREG_DMAPAD, 0);
X PRIMOUTREG(MGAREG_TEXTRANS, 0xffff);
X PRIMOUTREG(MGAREG_TEXTRANSHIGH, 0xffff);
X
@@ -205,7 +206,6 @@
X drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
X unsigned int *regs = sarea_priv->TexState[1];
X PRIMLOCALS;


- DRM_DEBUG("%s\n", __FUNCTION__);
X

X PRIMGETPTR(dev_priv);
X
@@ -225,14 +225,14 @@
X PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4]);
X PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH]);
X PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT]);
- PRIMOUTREG(0x2d00 + 49 * 4, 0);
+ PRIMOUTREG(MGAREG_WR49, 0);
X
- PRIMOUTREG(0x2d00 + 57 * 4, 0);
- PRIMOUTREG(0x2d00 + 53 * 4, 0);
- PRIMOUTREG(0x2d00 + 61 * 4, 0);
- PRIMOUTREG(0x2d00 + 52 * 4, regs[MGA_TEXREG_WIDTH] | 0x40);
+ PRIMOUTREG(MGAREG_WR57, 0);
+ PRIMOUTREG(MGAREG_WR53, 0);
+ PRIMOUTREG(MGAREG_WR61, 0);
+ PRIMOUTREG(MGAREG_WR52, regs[MGA_TEXREG_WIDTH] | 0x40);
X
- PRIMOUTREG(0x2d00 + 60 * 4, regs[MGA_TEXREG_HEIGHT] | 0x40);
+ PRIMOUTREG(MGAREG_WR60, regs[MGA_TEXREG_HEIGHT] | 0x40);
X PRIMOUTREG(MGAREG_TEXTRANS, 0xffff);
X PRIMOUTREG(MGAREG_TEXTRANSHIGH, 0xffff);
X PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] | 0x00008000);
@@ -240,13 +240,16 @@
X PRIMADVANCE(dev_priv);
X }
X
+#define MAGIC_FPARAM_HEX_VALUE 0x46480000
+/* This is the hex value of 12800.0f which is a magic value we must
+ * set in wr56.
+ */
+
X static void mgaG400EmitPipe(drm_mga_private_t * dev_priv)
X {
X drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
X unsigned int pipe = sarea_priv->WarpPipe;
- float fParam = 12800.0f;
X PRIMLOCALS;


- DRM_DEBUG("%s\n", __FUNCTION__);
X

X PRIMGETPTR(dev_priv);
X
@@ -278,14 +281,14 @@
X PRIMOUTREG(MGAREG_DWGCTL, MGA_FLUSH_CMD);
X
X PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 1);
- PRIMOUTREG(MGAREG_DMAPAD, 0);
X PRIMOUTREG(MGAREG_DWGSYNC, 0x7000);
- PRIMOUTREG(MGAREG_DMAPAD, 0);
-
- PRIMOUTREG(MGAREG_TEXCTL2, 0 | 0x00008000);
+ PRIMOUTREG(MGAREG_TEXCTL2, 0x00008000);
X PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0);
+
X PRIMOUTREG(MGAREG_TEXCTL2, 0x80 | 0x00008000);
X PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0);
+ PRIMOUTREG(MGAREG_DMAPAD, 0);
+ PRIMOUTREG(MGAREG_DMAPAD, 0);
X }
X
X PRIMOUTREG(MGAREG_WVRTXSZ, 0x00001807);
@@ -301,18 +304,18 @@
X
X PRIMOUTREG(MGAREG_WFLAG, 0);
X PRIMOUTREG(MGAREG_WFLAG1, 0);
- PRIMOUTREG(0x2d00 + 56 * 4, *((u32 *) (&fParam)));
+ PRIMOUTREG(MGAREG_WR56, MAGIC_FPARAM_HEX_VALUE);
X PRIMOUTREG(MGAREG_DMAPAD, 0);
X
- PRIMOUTREG(0x2d00 + 49 * 4, 0); /* Tex stage 0 */
- PRIMOUTREG(0x2d00 + 57 * 4, 0); /* Tex stage 0 */
- PRIMOUTREG(0x2d00 + 53 * 4, 0); /* Tex stage 1 */
- PRIMOUTREG(0x2d00 + 61 * 4, 0); /* Tex stage 1 */
-
- PRIMOUTREG(0x2d00 + 54 * 4, 0x40); /* Tex stage 0 : w */
- PRIMOUTREG(0x2d00 + 62 * 4, 0x40); /* Tex stage 0 : h */
- PRIMOUTREG(0x2d00 + 52 * 4, 0x40); /* Tex stage 1 : w */
- PRIMOUTREG(0x2d00 + 60 * 4, 0x40); /* Tex stage 1 : h */
+ PRIMOUTREG(MGAREG_WR49, 0); /* Tex stage 0 */
+ PRIMOUTREG(MGAREG_WR57, 0); /* Tex stage 0 */
+ PRIMOUTREG(MGAREG_WR53, 0); /* Tex stage 1 */
+ PRIMOUTREG(MGAREG_WR61, 0); /* Tex stage 1 */
+
+ PRIMOUTREG(MGAREG_WR54, 0x40); /* Tex stage 0 : w */
+ PRIMOUTREG(MGAREG_WR62, 0x40); /* Tex stage 0 : h */
+ PRIMOUTREG(MGAREG_WR52, 0x40); /* Tex stage 1 : w */
+ PRIMOUTREG(MGAREG_WR60, 0x40); /* Tex stage 1 : h */
X
X /* Dma pading required due to hw bug */
X PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
@@ -329,7 +332,6 @@
X drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
X unsigned int pipe = sarea_priv->WarpPipe;
X PRIMLOCALS;


- DRM_DEBUG("%s\n", __FUNCTION__);
X

X PRIMGETPTR(dev_priv);
X
@@ -338,12 +340,12 @@
X PRIMOUTREG(MGAREG_WIADDR, WIA_wmode_suspend);
X PRIMOUTREG(MGAREG_WVRTXSZ, 7);
X PRIMOUTREG(MGAREG_WFLAG, 0);
- PRIMOUTREG(0x2d00 + 24 * 4, 0); /* tex w/h */
+ PRIMOUTREG(MGAREG_WR24, 0); /* tex w/h */
X
- PRIMOUTREG(0x2d00 + 25 * 4, 0x100);
- PRIMOUTREG(0x2d00 + 34 * 4, 0); /* tex w/h */
- PRIMOUTREG(0x2d00 + 42 * 4, 0xFFFF);
- PRIMOUTREG(0x2d00 + 60 * 4, 0xFFFF);
+ PRIMOUTREG(MGAREG_WR25, 0x100);
+ PRIMOUTREG(MGAREG_WR34, 0); /* tex w/h */
+ PRIMOUTREG(MGAREG_WR42, 0xFFFF);
+ PRIMOUTREG(MGAREG_WR60, 0xFFFF);
X
X /* Dma pading required due to hw bug */
X PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
@@ -360,7 +362,6 @@
X {
X drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
X unsigned int dirty = sarea_priv->dirty;


- DRM_DEBUG("%s\n", __FUNCTION__);
X

X if (dev_priv->chipset == MGA_CARD_TYPE_G400) {
X int multitex = sarea_priv->WarpPipe & MGA_T2;
@@ -402,7 +403,6 @@
X }
X }
X
-
X /* Disallow all write destinations except the front and backbuffer.
X */
X static int mgaVerifyContext(drm_mga_private_t * dev_priv)
@@ -410,8 +410,6 @@
X drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
X unsigned int *regs = sarea_priv->ContextState;


X
- DRM_DEBUG("%s\n", __FUNCTION__);
-

X if (regs[MGA_CTXREG_DSTORG] != dev_priv->frontOffset &&
X regs[MGA_CTXREG_DSTORG] != dev_priv->backOffset) {
X DRM_DEBUG("BAD DSTORG: %x (front %x, back %x)\n\n",
@@ -430,8 +428,6 @@
X {
X drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;


X
- DRM_DEBUG("%s\n", __FUNCTION__);
-

X if ((sarea_priv->TexState[unit][MGA_TEXREG_ORG] & 0x3) == 0x1) {
X DRM_DEBUG("BAD TEXREG_ORG: %x, unit %d\n",
X sarea_priv->TexState[unit][MGA_TEXREG_ORG],
@@ -449,8 +445,6 @@
X unsigned int dirty = sarea_priv->dirty;
X int rv = 0;


X
- DRM_DEBUG("%s\n", __FUNCTION__);

-
X if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
X sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
X
@@ -478,8 +472,6 @@
X unsigned long bus_address,
X unsigned int dstOrg, int length)


X {
- DRM_DEBUG("%s\n", __FUNCTION__);
-

X if (dstOrg < dev_priv->textureOffset ||
X dstOrg + length >
X (dev_priv->textureOffset + dev_priv->textureSize)) {
@@ -502,7 +494,6 @@
X int use_agp = PDEA_pagpxfer_enable | 0x00000001;
X u16 y2;
X PRIMLOCALS;


- DRM_DEBUG("%s\n", __FUNCTION__);
X

X y2 = length / 64;
X
@@ -510,7 +501,6 @@
X
X PRIMOUTREG(MGAREG_DSTORG, destOrg);
X PRIMOUTREG(MGAREG_MACCESS, 0x00000000);
- DRM_DEBUG("srcorg : %lx\n", bus_address | use_agp);
X PRIMOUTREG(MGAREG_SRCORG, (u32) bus_address | use_agp);
X PRIMOUTREG(MGAREG_AR5, 64);
X
@@ -524,10 +514,10 @@
X PRIMOUTREG(MGAREG_FXBNDRY, (63 << 16));
X PRIMOUTREG(MGAREG_YDSTLEN + MGAREG_MGA_EXEC, y2);
X
+ PRIMOUTREG(MGAREG_DMAPAD, 0);
X PRIMOUTREG(MGAREG_SRCORG, 0);
X PRIMOUTREG(MGAREG_PITCH, dev_priv->stride / dev_priv->cpp);
- PRIMOUTREG(MGAREG_DMAPAD, 0);
- PRIMOUTREG(MGAREG_DMAPAD, 0);
+ PRIMOUTREG(MGAREG_DWGSYNC, 0x7000);
X PRIMADVANCE(dev_priv);
X }
X
@@ -541,34 +531,22 @@
X int use_agp = PDEA_pagpxfer_enable;
X int i = 0;
X PRIMLOCALS;


- DRM_DEBUG("%s\n", __FUNCTION__);
-

- DRM_DEBUG("dispatch vertex %d addr 0x%lx, "
- "length 0x%x nbox %d dirty %x\n",
- buf->idx, address, length,
- sarea_priv->nbox, sarea_priv->dirty);
-
- DRM_DEBUG("used : %d, total : %d\n", buf->used, buf->total);
X
X if (buf->used) {
X /* WARNING: if you change any of the state functions verify
- * these numbers (Overestimating this doesn't hurt).
+ * these numbers (Overestimating this doesn't hurt).
X */
X buf_priv->dispatched = 1;
X PRIM_OVERFLOW(dev, dev_priv,
X (MAX_STATE_SIZE + (5 * MGA_NR_SAREA_CLIPRECTS)));
X mgaEmitState(dev_priv);
+
+#if 0
+ length = dev_priv->vertexsize * 3 * 4;
+#endif
+
X do {
X if (i < sarea_priv->nbox) {
- DRM_DEBUG("idx %d Emit box %d/%d:"
- "%d,%d - %d,%d\n",
- buf->idx,
- i, sarea_priv->nbox,
- sarea_priv->boxes[i].x1,
- sarea_priv->boxes[i].y1,
- sarea_priv->boxes[i].x2,
- sarea_priv->boxes[i].y2);
-
X mgaEmitClipRect(dev_priv,
X &sarea_priv->boxes[i]);
X }
@@ -605,16 +583,10 @@
X int use_agp = PDEA_pagpxfer_enable;
X int i = 0;
X PRIMLOCALS;


- DRM_DEBUG("%s\n", __FUNCTION__);
-

- DRM_DEBUG("dispatch indices %d addr 0x%x, "
- "start 0x%x end 0x%x nbox %d dirty %x\n",
- buf->idx, address, start, end,
- sarea_priv->nbox, sarea_priv->dirty);
X
X if (start != end) {
X /* WARNING: if you change any of the state functions verify
- * these numbers (Overestimating this doesn't hurt).
+ * these numbers (Overestimating this doesn't hurt).
X */
X buf_priv->dispatched = 1;
X PRIM_OVERFLOW(dev, dev_priv,
@@ -623,15 +595,6 @@
X
X do {
X if (i < sarea_priv->nbox) {
- DRM_DEBUG("idx %d Emit box %d/%d:"
- "%d,%d - %d,%d\n",
- buf->idx,
- i, sarea_priv->nbox,
- sarea_priv->boxes[i].x1,
- sarea_priv->boxes[i].y1,
- sarea_priv->boxes[i].x2,
- sarea_priv->boxes[i].y2);
-
X mgaEmitClipRect(dev_priv,
X &sarea_priv->boxes[i]);
X }
@@ -644,6 +607,7 @@
X SETADD_mode_vertlist));
X PRIMOUTREG(MGAREG_SETUPEND,
X ((address + end) | use_agp));
+/* ((address + start + 12) | use_agp)); */
X PRIMADVANCE(dev_priv);
X } while (++i < sarea_priv->nbox);
X }
@@ -658,7 +622,9 @@
X
X static void mga_dma_dispatch_clear(drm_device_t * dev, int flags,
X unsigned int clear_color,
- unsigned int clear_zval)
+ unsigned int clear_zval,
+ unsigned int clear_colormask,
+ unsigned int clear_depthmask)
X {
X drm_mga_private_t *dev_priv = dev->dev_private;
X drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
@@ -668,7 +634,6 @@
X unsigned int cmd;
X int i;
X PRIMLOCALS;


- DRM_DEBUG("%s\n", __FUNCTION__);
X

X if (dev_priv->sgram)
X cmd = MGA_CLEAR_CMD | DC_atype_blk;
@@ -680,14 +645,9 @@
X for (i = 0; i < nbox; i++) {
X unsigned int height = pbox[i].y2 - pbox[i].y1;
X
- DRM_DEBUG("dispatch clear %d,%d-%d,%d flags %x!\n",
- pbox[i].x1, pbox[i].y1, pbox[i].x2,
- pbox[i].y2, flags);
-
X if (flags & MGA_FRONT) {
- DRM_DEBUG("clear front\n");
- PRIMOUTREG(MGAREG_DMAPAD, 0);
X PRIMOUTREG(MGAREG_DMAPAD, 0);
+ PRIMOUTREG(MGAREG_PLNWT, clear_colormask);
X PRIMOUTREG(MGAREG_YDSTLEN,
X (pbox[i].y1 << 16) | height);
X PRIMOUTREG(MGAREG_FXBNDRY,
@@ -700,9 +660,8 @@
X }
X
X if (flags & MGA_BACK) {
- DRM_DEBUG("clear back\n");
- PRIMOUTREG(MGAREG_DMAPAD, 0);
X PRIMOUTREG(MGAREG_DMAPAD, 0);
+ PRIMOUTREG(MGAREG_PLNWT, clear_colormask);
X PRIMOUTREG(MGAREG_YDSTLEN,
X (pbox[i].y1 << 16) | height);
X PRIMOUTREG(MGAREG_FXBNDRY,
@@ -715,9 +674,8 @@
X }
X
X if (flags & MGA_DEPTH) {
- DRM_DEBUG("clear depth\n");
- PRIMOUTREG(MGAREG_DMAPAD, 0);
X PRIMOUTREG(MGAREG_DMAPAD, 0);
+ PRIMOUTREG(MGAREG_PLNWT, clear_depthmask);
X PRIMOUTREG(MGAREG_YDSTLEN,
X (pbox[i].y1 << 16) | height);
X PRIMOUTREG(MGAREG_FXBNDRY,
@@ -749,7 +707,6 @@
X int pixel_stride = dev_priv->stride / dev_priv->cpp;
X
X PRIMLOCALS;


- DRM_DEBUG("%s\n", __FUNCTION__);
X

X PRIM_OVERFLOW(dev, dev_priv, (MGA_NR_SAREA_CLIPRECTS * 5) + 20);
X
@@ -772,9 +729,6 @@
X unsigned int h = pbox[i].y2 - pbox[i].y1;
X unsigned int start = pbox[i].y1 * pixel_stride;
X
- DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n",
- pbox[i].x1, pbox[i].y1, pbox[i].x2, pbox[i].y2);
-
X PRIMOUTREG(MGAREG_AR0, start + pbox[i].x2 - 1);
X PRIMOUTREG(MGAREG_AR3, start + pbox[i].x1);
X PRIMOUTREG(MGAREG_FXBNDRY,
@@ -804,7 +758,6 @@
X
X if (copy_from_user(&clear, (drm_mga_clear_t *) arg, sizeof(clear)))
X return -EFAULT;


- DRM_DEBUG("%s\n", __FUNCTION__);
X

X if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
X DRM_ERROR("mga_clear_bufs called without lock held\n");
@@ -818,7 +771,10 @@
X */
X dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CTX;
X mga_dma_dispatch_clear(dev, clear.flags,
- clear.clear_color, clear.clear_depth);
+ clear.clear_color,
+ clear.clear_depth,
+ clear.clear_color_mask,
+ clear.clear_depth_mask);
X PRIMUPDATE(dev_priv);
X mga_flush_write_combine();
X mga_dma_schedule(dev, 1);
@@ -833,7 +789,6 @@
X drm_mga_private_t *dev_priv =


X (drm_mga_private_t *) dev->dev_private;

X drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;


- DRM_DEBUG("%s\n", __FUNCTION__);
X

X if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
X DRM_ERROR("mga_swap_bufs called without lock held\n");
@@ -868,9 +823,7 @@
X drm_mga_buf_priv_t *buf_priv;
X drm_mga_iload_t iload;
X unsigned long bus_address;


- DRM_DEBUG("%s\n", __FUNCTION__);
X

- DRM_DEBUG("Starting Iload\n");
X if (copy_from_user(&iload, (drm_mga_iload_t *) arg, sizeof(iload)))
X return -EFAULT;
X
@@ -882,8 +835,6 @@
X buf = dma->buflist[iload.idx];


X buf_priv = buf->dev_private;

X bus_address = buf->bus_address;
- DRM_DEBUG("bus_address %lx, length %d, destorg : %x\n",
- bus_address, iload.length, iload.destOrg);
X
X if (mgaVerifyIload(dev_priv,
X bus_address, iload.destOrg, iload.length)) {
@@ -914,7 +865,6 @@
X drm_buf_t *buf;
X drm_mga_buf_priv_t *buf_priv;
X drm_mga_vertex_t vertex;


- DRM_DEBUG("%s\n", __FUNCTION__);
X

X if (copy_from_user(&vertex, (drm_mga_vertex_t *) arg, sizeof(vertex)))
X return -EFAULT;
@@ -924,8 +874,6 @@


X return -EINVAL;
X }
X

- DRM_DEBUG("mga_vertex\n");
-
X buf = dma->buflist[vertex.idx];


X buf_priv = buf->dev_private;

X
@@ -939,7 +887,6 @@


X buf_priv->dispatched = 0;

X mga_freelist_put(dev, buf);
X }
- DRM_DEBUG("bad state\n");


X return -EINVAL;
X }
X

@@ -963,9 +910,9 @@
X drm_buf_t *buf;
X drm_mga_buf_priv_t *buf_priv;
X drm_mga_indices_t indices;


- DRM_DEBUG("%s\n", __FUNCTION__);
X

- if (copy_from_user(&indices, (drm_mga_indices_t *) arg, sizeof(indices)))
+ if (copy_from_user(&indices,
+ (drm_mga_indices_t *)arg, sizeof(indices)))


X return -EFAULT;
X
X if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {

@@ -973,8 +920,6 @@


X return -EINVAL;
X }
X

- DRM_DEBUG("mga_indices\n");
-
X buf = dma->buflist[indices.idx];


X buf_priv = buf->dev_private;

X
@@ -1004,7 +949,6 @@
X {
X int i;
X drm_buf_t *buf;


- DRM_DEBUG("%s\n", __FUNCTION__);
X

X for (i = d->granted_count; i < d->request_count; i++) {
X buf = mga_freelist_get(dev);
@@ -1012,8 +956,9 @@
X break;
X buf->pid = current->pid;
X if (copy_to_user(&d->request_indices[i],
- &buf->idx, sizeof(buf->idx)) ||
- copy_to_user(&d->request_sizes[i],
+ &buf->idx, sizeof(buf->idx)))
+ return -EFAULT;
+ if (copy_to_user(&d->request_sizes[i],
X &buf->total, sizeof(buf->total)))
X return -EFAULT;
X ++d->granted_count;
@@ -1029,12 +974,9 @@


X drm_device_dma_t *dma = dev->dma;

X int retcode = 0;
X drm_dma_t d;


- DRM_DEBUG("%s\n", __FUNCTION__);
X

X if (copy_from_user(&d, (drm_dma_t *) arg, sizeof(d)))
X return -EFAULT;
- DRM_DEBUG("%d %d: %d send, %d req\n",
- current->pid, d.context, d.send_count, d.request_count);
X
X if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
X DRM_ERROR("mga_dma called without lock held\n");
@@ -1065,8 +1007,6 @@
X retcode = mga_dma_get_buffers(dev, &d);
X }
X
- DRM_DEBUG("%d returning, granted = %d\n",
- current->pid, d.granted_count);
X if (copy_to_user((drm_dma_t *) arg, &d, sizeof(d)))
X return -EFAULT;
X return retcode;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/drm/r128_dma.c linux/drivers/char/drm/r128_dma.c
--- v2.4.0-test8/linux/drivers/char/drm/r128_dma.c Tue Aug 29 21:09:10 2000
+++ linux/drivers/char/drm/r128_dma.c Fri Sep 15 14:24:55 2000
@@ -68,30 +68,8 @@
X return R128_READ(R128_CLOCK_CNTL_DATA);
X }
X
-#ifdef __i386__
-static void r128_flush_write_combine(void)
-{
- int xchangeDummy;
+#define r128_flush_write_combine() mb()
X

- __asm__ volatile("push %%eax ;"

- "xchg %%eax, %0 ;"
- "pop %%eax" : : "m" (xchangeDummy));


- __asm__ volatile("push %%eax ;"

- "push %%ebx ;"
- "push %%ecx ;"
- "push %%edx ;"
- "movl $0,%%eax ;"
- "cpuid ;"
- "pop %%edx ;"
- "pop %%ecx ;"
- "pop %%ebx ;"


- "pop %%eax" : /* no outputs */ : /* no inputs */ );
-}
-#else

-static void r128_flush_write_combine(void)
-{
-}
-#endif
X
X static void r128_status(drm_device_t *dev)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/drm/r128_drv.c linux/drivers/char/drm/r128_drv.c
--- v2.4.0-test8/linux/drivers/char/drm/r128_drv.c Tue Aug 29 14:09:15 2000
+++ linux/drivers/char/drm/r128_drv.c Sun Oct 1 20:00:00 2000


@@ -35,7 +35,7 @@
X

X #define R128_NAME "r128"
X #define R128_DESC "ATI Rage 128"
-#define R128_DATE "20000719"
+#define R128_DATE "20000928"
X #define R128_MAJOR 1
X #define R128_MINOR 0
X #define R128_PATCHLEVEL 0
@@ -467,7 +467,7 @@
X }
X spin_unlock(&dev->count_lock);
X }
-
+
X return retcode;
X }
X
@@ -501,7 +501,7 @@
X }
X spin_unlock(&dev->count_lock);
X }
-
+
X unlock_kernel();
X return retcode;
X }
@@ -602,6 +602,7 @@
X #endif


X add_wait_queue(&dev->lock.lock_queue, &entry);
X for (;;) {
+ current->state = TASK_INTERRUPTIBLE;
X if (!dev->lock.hw_lock) {
X /* Device has been unregistered */
X ret = -EINTR;

@@ -617,7 +618,6 @@


X
X /* Contention */
X atomic_inc(&dev->total_sleeps);
- current->state = TASK_INTERRUPTIBLE;

X #if 1
X current->policy |= SCHED_YIELD;
X #endif
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/drm/r128_drv.h linux/drivers/char/drm/r128_drv.h
--- v2.4.0-test8/linux/drivers/char/drm/r128_drv.h Thu Jul 27 15:05:40 2000
+++ linux/drivers/char/drm/r128_drv.h Sun Oct 1 20:00:00 2000


@@ -11,11 +11,11 @@
X * the rights to use, copy, modify, merge, publish, distribute, sublicense,
X * and/or sell copies of the Software, and to permit persons to whom the
X * Software is furnished to do so, subject to the following conditions:
- *
+ *
X * The above copyright notice and this permission notice (including the next
X * paragraph) shall be included in all copies or substantial portions of the
X * Software.
- *
+ *
X * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
X * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
X * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL

@@ -23,7 +23,7 @@
X * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
X * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
X * DEALINGS IN THE SOFTWARE.
- *
+ *

X * Authors: Rickard E. (Rik) Faith <fa...@valinux.com>
X * Kevin E. Martin <mar...@valinux.com>
X *
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/drm/tdfx_drv.c linux/drivers/char/drm/tdfx_drv.c
--- v2.4.0-test8/linux/drivers/char/drm/tdfx_drv.c Tue Aug 29 21:09:10 2000
+++ linux/drivers/char/drm/tdfx_drv.c Sun Oct 1 20:00:00 2000
@@ -1,4 +1,4 @@
-/* tdfx.c -- tdfx driver -*- linux-c -*-
+/* tdfx_drv.c -- tdfx driver -*- linux-c -*-
X * Created: Thu Oct 7 10:38:32 1999 by fa...@precisioninsight.com
X *


X * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.

@@ -11,11 +11,11 @@
X * the rights to use, copy, modify, merge, publish, distribute, sublicense,
X * and/or sell copies of the Software, and to permit persons to whom the
X * Software is furnished to do so, subject to the following conditions:
- *
+ *
X * The above copyright notice and this permission notice (including the next
X * paragraph) shall be included in all copies or substantial portions of the
X * Software.
- *
+ *
X * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
X * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
X * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
@@ -23,7 +23,7 @@
X * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
X * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
X * DEALINGS IN THE SOFTWARE.
- *
+ *
X * Authors:
X * Rickard E. (Rik) Faith <fa...@valinux.com>

X * Daryll Strauss <dar...@valinux.com>
@@ -36,7 +36,7 @@
X
X #define TDFX_NAME "tdfx"
X #define TDFX_DESC "3dfx Banshee/Voodoo3+"
-#define TDFX_DATE "20000719"
+#define TDFX_DATE "20000928"
X #define TDFX_MAJOR 1
X #define TDFX_MINOR 0
X #define TDFX_PATCHLEVEL 0
@@ -76,7 +76,7 @@
X [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_unblock, 1, 1 },
X [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1 },
X [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap, 1, 1 },
-
+
X [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { tdfx_addctx, 1, 1 },
X [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { tdfx_rmctx, 1, 1 },
X [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { tdfx_modctx, 1, 1 },
@@ -128,7 +128,7 @@
X static int tdfx_setup(drm_device_t *dev)


X {
X int i;
-
+
X atomic_set(&dev->ioctl_count, 0);
X atomic_set(&dev->vma_count, 0);
X dev->buf_use = 0;

@@ -170,7 +170,7 @@


X
X dev->ctx_start = 0;
X dev->lck_start = 0;
-
+
X dev->buf_rp = dev->buf;
X dev->buf_wp = dev->buf;
X dev->buf_end = dev->buf + DRM_BSZ;

@@ -179,15 +179,15 @@
X init_waitqueue_head(&dev->buf_writers);
X
X tdfx_res_ctx.handle=-1;


-
+
X DRM_DEBUG("\n");
-
+
X /* The kernel's context could be created here, but is now created
X in drm_dma_enqueue. This is more resource-efficient for
X hardware that does not do DMA, but may mean that
X drm_select_queue fails between the time the interrupt is
X initialized and the time the queues are initialized. */
-
+
X return 0;
X }
X

@@ -203,12 +203,12 @@
X

X down(&dev->struct_sem);
X del_timer(&dev->timer);
-
+
X if (dev->devname) {
X drm_free(dev->devname, strlen(dev->devname)+1, DRM_MEM_DRIVER);
X dev->devname = NULL;
X }
-
+
X if (dev->unique) {
X drm_free(dev->unique, strlen(dev->unique)+1, DRM_MEM_DRIVER);
X dev->unique = NULL;

@@ -227,7 +227,7 @@
X if (dev->agp) {
X drm_agp_mem_t *temp;
X drm_agp_mem_t *temp_next;
-
+
X temp = dev->agp->memory;
X while(temp != NULL) {
X temp_next = temp->next;
@@ -246,7 +246,7 @@


X }
X dev->vmalist = NULL;
X }
-
+
X /* Clear map area and mtrr information */
X if (dev->maplist) {
X for (i = 0; i < dev->map_count; i++) {

@@ -284,14 +284,14 @@


X dev->maplist = NULL;
X dev->map_count = 0;
X }
-
+

X if (dev->lock.hw_lock) {
X dev->lock.hw_lock = NULL; /* SHM removed */


X dev->lock.pid = 0;

X wake_up_interruptible(&dev->lock.lock_queue);
X }
X up(&dev->struct_sem);
-
+
X return 0;
X }
X

@@ -308,7 +308,7 @@


X memset((void *)dev, 0, sizeof(*dev));
X dev->count_lock = SPIN_LOCK_UNLOCKED;
X sema_init(&dev->struct_sem, 1);
-
+
X #ifdef MODULE

X drm_parse_options(tdfx);
X #endif
@@ -340,7 +340,7 @@
X TDFX_PATCHLEVEL,
X TDFX_DATE,
X tdfx_misc.minor);


-
+
X return 0;
X }
X

@@ -351,7 +351,7 @@
X drm_device_t *dev = &tdfx_device;


X
X DRM_DEBUG("\n");
-
+
X drm_proc_cleanup();

X if (misc_deregister(&tdfx_misc)) {


X DRM_ERROR("Cannot unload module\n");

@@ -412,7 +412,7 @@
X {
X drm_device_t *dev = &tdfx_device;


X int retcode = 0;
-
+
X DRM_DEBUG("open_count = %d\n", dev->open_count);
X if (!(retcode = drm_open_helper(inode, filp, dev))) {
X #if LINUX_VERSION_CODE < 0x020333

@@ -480,7 +480,7 @@


X atomic_inc(&dev->ioctl_count);
X atomic_inc(&dev->total_ioctl);
X ++priv->ioctl_count;
-
+
X DRM_DEBUG("pid = %d, cmd = 0x%02x, nr = 0x%02x, dev 0x%x, auth = %d\n",
X current->pid, cmd, nr, dev->device, priv->authenticated);
X

@@ -500,7 +500,7 @@


X retcode = (func)(inode, filp, cmd, arg);
X }
X }
-
+
X atomic_dec(&dev->ioctl_count);
X return retcode;
X }
@@ -538,7 +538,7 @@

X if (lock.context < 0 || lock.context >= dev->queue_count)
X return -EINVAL;
X #endif
-
+
X if (!ret) {
X #if 0
X if (_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)
@@ -550,7 +550,7 @@
X /* Can't take lock if we just had it and
X there is contention. */
X DRM_DEBUG("%d (pid %d) delayed j=%d dev=%d jiffies=%d\n",
- lock.context, current->pid, j,
+ lock.context, current->pid, j,
X dev->lock.lock_time, jiffies);
X current->state = TASK_INTERRUPTIBLE;
X current->policy |= SCHED_YIELD;
@@ -561,6 +561,7 @@
X #endif


X add_wait_queue(&dev->lock.lock_queue, &entry);
X for (;;) {
+ current->state = TASK_INTERRUPTIBLE;
X if (!dev->lock.hw_lock) {
X /* Device has been unregistered */
X ret = -EINTR;

@@ -573,10 +574,9 @@


X atomic_inc(&dev->total_locks);
X break; /* Got lock */
X }
-
+
X /* Contention */
X atomic_inc(&dev->total_sleeps);
- current->state = TASK_INTERRUPTIBLE;

X #if 1
X current->policy |= SCHED_YIELD;
X #endif
@@ -648,7 +648,7 @@
X #if DRM_DMA_HISTOGRAM
X atomic_inc(&dev->histo.lacq[drm_histogram_slot(get_cycles() - start)]);
X #endif
-
+
X return ret;
X }
X
@@ -662,7 +662,7 @@


X
X if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
X return -EFAULT;
-
+
X if (lock.context == DRM_KERNEL_CONTEXT) {
X DRM_ERROR("Process %d using kernel context %d\n",
X current->pid, lock.context);

@@ -690,7 +690,7 @@
X current->priority = DEF_PRIORITY;
X }


X #endif
-
+
X unblock_all_signals();
X return 0;
X }

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/drm/vm.c linux/drivers/char/drm/vm.c
--- v2.4.0-test8/linux/drivers/char/drm/vm.c Fri Aug 11 19:14:46 2000
+++ linux/drivers/char/drm/vm.c Sun Oct 1 20:00:00 2000
@@ -67,8 +67,6 @@
X int write_access)
X #endif
X {
- DRM_DEBUG("0x%08lx, %d\n", address, write_access);
-
X return NOPAGE_SIGBUS; /* Disallow mremap */
X }
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/efirtc.c linux/drivers/char/efirtc.c
--- v2.4.0-test8/linux/drivers/char/efirtc.c Fri Aug 11 19:09:06 2000
+++ linux/drivers/char/efirtc.c Mon Sep 18 14:57:01 2000


@@ -249,7 +249,7 @@
X

X convert_from_efi_time(&eft, &wtime);
X
- return copy_to_user((void *)&ewp->time, &wtime, sizeof(struct rtc_time));
+ return copy_to_user((void *)&ewp->time, &wtime, sizeof(struct rtc_time)) ? -EFAULT : 0;
X }
X return -EINVAL;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/ftape/lowlevel/ftape-calibr.c linux/drivers/char/ftape/lowlevel/ftape-calibr.c
--- v2.4.0-test8/linux/drivers/char/ftape/lowlevel/ftape-calibr.c Tue Nov 25 14:45:27 1997
+++ linux/drivers/char/ftape/lowlevel/ftape-calibr.c Fri Sep 22 14:21:16 2000
@@ -183,7 +183,7 @@
X }
X #elif defined(__alpha__)
X #if CONFIG_FT_ALPHA_CLOCK == 0
-#error You must define and set CONFIG_FT_ALPHA_CLOCK in the Makefile !
+#error You must define and set CONFIG_FT_ALPHA_CLOCK in 'make config' !
X #endif
X extern struct hwrpb_struct *hwrpb;
X TRACE_FUN(ft_t_any);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/hp600_keyb.c linux/drivers/char/hp600_keyb.c
--- v2.4.0-test8/linux/drivers/char/hp600_keyb.c Wed Aug 9 13:59:04 2000
+++ linux/drivers/char/hp600_keyb.c Fri Sep 22 14:21:17 2000
@@ -7,7 +7,7 @@
X #include <linux/kernel.h>
X #include <linux/sched.h>
X #include <linux/init.h>
-#include <asm/delay.h>
+#include <linux/delay.h>
X #include <asm/io.h>
X #include "scan_keyb.h"
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/i810-tco.c linux/drivers/char/i810-tco.c
--- v2.4.0-test8/linux/drivers/char/i810-tco.c Fri Aug 11 17:56:40 2000
+++ linux/drivers/char/i810-tco.c Sun Oct 1 19:45:29 2000
@@ -301,10 +301,9 @@
X tco_timer_settimer ((unsigned char) i810_margin);
X tco_timer_reload ();
X
- /* FIXME: no floating point math */
X printk (KERN_INFO
X "i810 TCO timer: V0.02, timer margin: %d sec (0x%04x)\n",
- (int) (i810_margin * 0.6), TCOBASE);
+ (int) (i810_margin * 6 / 10), TCOBASE);


X return 0;
X }
X

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/i810_rng.c linux/drivers/char/i810_rng.c
--- v2.4.0-test8/linux/drivers/char/i810_rng.c Wed Jul 12 21:58:42 2000
+++ linux/drivers/char/i810_rng.c Mon Oct 2 12:00:16 2000
@@ -119,13 +119,6 @@
X * The timer and the character device may be used simultaneously,
X if desired.
X
- * FIXME: Currently only one open() of the character device is allowed.
- If another user tries to open() the device, they will get an
- -EBUSY error. Instead, this really should either support
- multiple simultaneous users of the character device (not hard),
- or simply block open() until the current user of the chrdev
- calls close().
-
X * FIXME: support poll()
X
X * FIXME: should we be crazy and support mmap()?
@@ -138,11 +131,16 @@
X This will slow things down but guarantee that bad data is
X never passed upstream.
X
+ * Since the RNG is accessed from a timer as well as normal
+ kernel code, but not from interrupts, we use spin_lock_bh
+ in regular code, and spin_lock in the timer function, to
+ serialize access to the RNG hardware area.
+
X ----------------------------------------------------------
X
X Change history:
X
- 0.6.2:
+ Version 0.6.2:
X * Clean up spinlocks. Since we don't have any interrupts
X to worry about, but we do have a timer to worry about,
X we use spin_lock_bh everywhere except the timer function
@@ -152,6 +150,20 @@
X * New timer interval sysctl
X * Clean up sysctl names
X
+ Version 0.9.0:
+ * Don't register a pci_driver, because we are really
+ using PCI bridge vendor/device ids, and someone
+ may want to register a driver for the bridge. (bug fix)
+ * Don't let the usage count go negative (bug fix)
+ * Clean up spinlocks (bug fix)
+ * Enable PCI device, if necessary (bug fix)
+ * iounmap on module unload (bug fix)
+ * If RNG chrdev is already in use when open(2) is called,
+ sleep until it is available.
+ * Remove redundant globals rng_allocated, rng_use_count
+ * Convert numeric globals to unsigned
+ * Module unload cleanup
+
X */
X
X
@@ -166,6 +178,7 @@
X #include <linux/sysctl.h>
X #include <linux/miscdevice.h>
X #include <linux/smp_lock.h>
+#include <linux/mm.h>
X
X #include <asm/io.h>
X #include <asm/uaccess.h>
@@ -174,7 +187,7 @@
X /*
X * core module and version information
X */
-#define RNG_VERSION "0.6.2"
+#define RNG_VERSION "0.9.0"
X #define RNG_MODULE_NAME "i810_rng"
X #define RNG_DRIVER_NAME RNG_MODULE_NAME " hardware driver " RNG_VERSION
X #define PFX RNG_MODULE_NAME ": "
@@ -253,22 +266,24 @@
X * various RNG status variables. they are globals
X * as we only support a single RNG device
X */
-static int rng_allocated; /* is someone using the RNG region? */
X static int rng_hw_enabled; /* is the RNG h/w enabled? */
X static int rng_timer_enabled; /* is the RNG timer enabled? */
-static int rng_use_count; /* number of times RNG has been enabled */
X static int rng_trusted; /* does FIPS trust out data? */
X static int rng_enabled_sysctl; /* sysctl for enabling/disabling RNG */
-static int rng_entropy = 8; /* number of entropy bits we submit to /dev/random */
-static int rng_entropy_sysctl; /* sysctl for changing entropy bits */
-static int rng_interval_sysctl; /* sysctl for changing timer interval */
+static unsigned int rng_entropy = 8; /* number of entropy bits we submit to /dev/random */
+static unsigned int rng_entropy_sysctl; /* sysctl for changing entropy bits */
+static unsigned int rng_interval_sysctl; /* sysctl for changing timer interval */
X static int rng_have_mem_region; /* did we grab RNG region via request_mem_region? */
-static int rng_fips_counter; /* size of internal FIPS test data pool */
-static int rng_timer_len = RNG_DEF_TIMER_LEN; /* timer interval, in jiffies */
+static unsigned int rng_fips_counter; /* size of internal FIPS test data pool */
+static unsigned int rng_timer_len = RNG_DEF_TIMER_LEN; /* timer interval, in jiffies */
X static void *rng_mem; /* token to our ioremap'd RNG register area */
X static spinlock_t rng_lock = SPIN_LOCK_UNLOCKED; /* hardware lock */
X static struct timer_list rng_timer; /* kernel timer for RNG hardware reads and tests */
-static int rng_open; /* boolean, 0 (false) if chrdev is closed, 1 (true) if open */
+static struct pci_dev *rng_pdev; /* Firmware Hub PCI device found during PCI probe */
+static struct semaphore rng_open_sem; /* Semaphore for serializing rng_open/release */
+static wait_queue_head_t rng_open_wait; /* Wait queue for serializing open/release */
+static int rng_open_mode; /* Open mode (we only allow reads) */
+
X
X /*
X * inlined helper functions for accessing RNG registers
@@ -320,6 +335,8 @@
X /* gimme some thermal noise, baby */
X rng_data = rng_data_read ();
X
+ spin_unlock (&rng_lock);
+
X /*
X * if RNG has been verified in the past, add
X * data just read to the /dev/random pool,
@@ -333,6 +350,8 @@
X rng_fips_test_store (rng_data);
X if (rng_fips_counter > RNG_FIPS_TEST_THRESHOLD)
X rng_run_fips_test ();
+ } else {
+ spin_unlock (&rng_lock);
X }
X
X /* run the timer again, if enabled */
@@ -340,9 +359,6 @@
X rng_timer.expires = jiffies + rng_timer_len;
X add_timer (&rng_timer);
X }
-
- spin_unlock (&rng_lock);
-
X }
X
X
@@ -351,8 +367,8 @@
X */
X static int rng_enable (int enable)
X {
- int rc = 0;
- u8 hw_status;
+ int rc = 0, action = 0;
+ u8 hw_status, new_status;
X
X DPRINTK ("ENTER\n");
X
@@ -362,28 +378,36 @@
X
X if (enable) {
X rng_hw_enabled = 1;
- rng_use_count++;
X MOD_INC_USE_COUNT;
X } else {
- rng_use_count--;
- if (rng_use_count == 0)
+#ifndef __alpha__
+ if (GET_USE_COUNT (THIS_MODULE) > 0)
+ MOD_DEC_USE_COUNT;
+ if (GET_USE_COUNT (THIS_MODULE) == 0)
X rng_hw_enabled = 0;
- MOD_DEC_USE_COUNT;
+#endif
X }
X
X if (rng_hw_enabled && ((hw_status & RNG_ENABLED) == 0)) {


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 048'
echo 'File patch-2.4.0-test9 is continued in part 049'
echo "049" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part049

#!/bin/sh -x
# this is part 049 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 049; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

X rng_hwstatus_set (hw_status | RNG_ENABLED);
- printk (KERN_INFO PFX "RNG h/w enabled\n");
+ action = 1;
X }
X
X else if (!rng_hw_enabled && (hw_status & RNG_ENABLED)) {
X rng_hwstatus_set (hw_status & ~RNG_ENABLED);
- printk (KERN_INFO PFX "RNG h/w disabled\n");
+ action = 2;
X }
X
+ new_status = rng_hwstatus ();
+
X spin_unlock_bh (&rng_lock);
X
- if ((!!enable) != (!!(rng_hwstatus () & RNG_ENABLED))) {
+ if (action == 1)
+ printk (KERN_INFO PFX "RNG h/w enabled\n");
+ else if (action == 2)
+ printk (KERN_INFO PFX "RNG h/w disabled\n");
+
+ if ((!!enable) != (!!(new_status & RNG_ENABLED))) {
X printk (KERN_ERR PFX "Unable to %sable the RNG\n",
X enable ? "en" : "dis");
X rc = -EIO;
@@ -406,15 +430,14 @@


X DPRINTK ("ENTER\n");
X

X spin_lock_bh (&rng_lock);
-
X rng_enabled_sysctl = enabled_save = rng_timer_enabled;
+ spin_unlock_bh (&rng_lock);
X
X rc = proc_dointvec (table, write, filp, buffer, lenp);
- if (rc) {
- spin_unlock_bh (&rng_lock);
+ if (rc)
X return rc;
- }
X
+ spin_lock_bh (&rng_lock);
X if (enabled_save != rng_enabled_sysctl) {
X rng_timer_enabled = rng_enabled_sysctl;
X spin_unlock_bh (&rng_lock);
@@ -591,53 +614,49 @@
X int rc = -EINVAL;
X
X if ((filp->f_mode & FMODE_READ) == 0)
- goto err_out;
+ goto err_out_ret;
X if (filp->f_mode & FMODE_WRITE)
- goto err_out;
+ goto err_out_ret;
X
- spin_lock_bh (&rng_lock);
-
- /* only allow one open of this device, exit with -EBUSY if already open */
- /* FIXME: we should sleep on a semaphore here, unless O_NONBLOCK */
- if (rng_open) {
- spin_unlock_bh (&rng_lock);
- rc = -EBUSY;
- goto err_out;
+ /* wait for device to become free */
+ down (&rng_open_sem);
+ while (rng_open_mode & filp->f_mode) {
+ if (filp->f_flags & O_NONBLOCK) {
+ up (&rng_open_sem);
+ return -EWOULDBLOCK;
+ }
+ up (&rng_open_sem);
+ interruptible_sleep_on (&rng_open_wait);
+ if (signal_pending (current))
+ return -ERESTARTSYS;
+ down (&rng_open_sem);
X }
X
- rng_open = 1;
-
- spin_unlock_bh (&rng_lock);
-
- if (rng_enable(1) != 0) {
- spin_lock_bh (&rng_lock);
- rng_open = 0;
- spin_unlock_bh (&rng_lock);
+ if (rng_enable (1)) {
X rc = -EIO;
X goto err_out;
X }
X
+ rng_open_mode |= filp->f_mode & (FMODE_READ | FMODE_WRITE);
+ up (&rng_open_sem);
X return 0;
X
X err_out:
+ up (&rng_open_sem);
+err_out_ret:
X return rc;
X }
X
X
X static int rng_dev_release (struct inode *inode, struct file *filp)
X {
+ down(&rng_open_sem);
X
- lock_kernel();
- if (rng_enable(0) != 0) {
- unlock_kernel();


- return -EIO;
- }
-

- spin_lock_bh (&rng_lock);
- rng_open = 0;
- spin_unlock_bh (&rng_lock);
- unlock_kernel();
+ rng_enable(0);
+ rng_open_mode &= (~filp->f_mode) & (FMODE_READ|FMODE_WRITE);
X
+ up (&rng_open_sem);
+ wake_up (&rng_open_wait);


X return 0;
X }
X

@@ -705,19 +724,15 @@
X /*
X * rng_init_one - look for and attempt to init a single RNG
X */
-static int __init rng_init_one (struct pci_dev *dev,
- const struct pci_device_id *id)
+static int __init rng_init_one (struct pci_dev *dev)
X {
X int rc;
X u8 hw_status;


X
X DPRINTK ("ENTER\n");
X

- if (rng_allocated) {
- printk (KERN_ERR PFX "this driver only supports one RNG\n");
- DPRINTK ("EXIT, returning -EBUSY\n");
- return -EBUSY;
- }
+ if (pci_enable_device (dev))
+ return -EIO;
X
X /* XXX currently fails, investigate who has our mem region */
X if (request_mem_region (RNG_ADDR, RNG_ADDR_LEN, RNG_MODULE_NAME))
@@ -728,7 +743,7 @@
X printk (KERN_ERR PFX "cannot ioremap RNG Memory\n");
X DPRINTK ("EXIT, returning -EBUSY\n");
X rc = -EBUSY;
- goto err_out;
+ goto err_out_free_res;
X }
X
X /* Check for Intel 82802 */
@@ -737,11 +752,9 @@
X printk (KERN_ERR PFX "RNG not detected\n");
X DPRINTK ("EXIT, returning -ENODEV\n");
X rc = -ENODEV;
- goto err_out;
+ goto err_out_free_map;
X }
X
- rng_allocated = 1;
-
X if (rng_entropy < 0 || rng_entropy > RNG_MAX_ENTROPY)
X rng_entropy = RNG_MAX_ENTROPY;
X
@@ -749,10 +762,11 @@
X init_timer (&rng_timer);
X rng_timer.function = rng_timer_tick;
X
+ /* turn RNG h/w off, if it's on */
X rc = rng_enable (0);
X if (rc) {
X printk (KERN_ERR PFX "cannot disable RNG, aborting\n");
- goto err_out;
+ goto err_out_free_map;
X }
X
X /* add sysctls */
@@ -761,9 +775,9 @@
X DPRINTK ("EXIT, returning 0\n");
X return 0;
X
-err_out:
- if (rng_mem)
- iounmap (rng_mem);
+err_out_free_map:
+ iounmap (rng_mem);
+err_out_free_res:
X if (rng_have_mem_region)
X release_mem_region (RNG_ADDR, RNG_ADDR_LEN);
X return rc;
@@ -772,6 +786,11 @@
X
X /*
X * Data for PCI driver interface
+ *
+ * This data only exists for exporting the supported
+ * PCI ids via MODULE_DEVICE_TABLE. We do not actually
+ * register a pci_driver, because someone else might one day
+ * want to register another driver on the same PCI id.
X */
X const static struct pci_device_id rng_pci_tbl[] __initdata = {
X { 0x8086, 0x2418, PCI_ANY_ID, PCI_ANY_ID, },
@@ -780,11 +799,6 @@
X };
X MODULE_DEVICE_TABLE (pci, rng_pci_tbl);
X
-static struct pci_driver rng_driver = {
- name: RNG_MODULE_NAME,
- id_table: rng_pci_tbl,
- probe: rng_init_one,
-};
X
X MODULE_AUTHOR("Jeff Garzik, Matt Sottek");
X MODULE_DESCRIPTION("Intel i8xx chipset Random Number Generator (RNG) driver");
@@ -813,23 +827,36 @@
X static int __init rng_init (void)
X {
X int rc;
+ struct pci_dev *pdev;


X
X DPRINTK ("ENTER\n");
X

- if (pci_register_driver (&rng_driver) < 1) {
- DPRINTK ("EXIT, returning -ENODEV\n");
+ init_MUTEX (&rng_open_sem);
+ init_waitqueue_head (&rng_open_wait);
+
+ pdev = pci_find_device (0x8086, 0x2418, NULL);
+ if (!pdev)
+ pdev = pci_find_device (0x8086, 0x2428, NULL);
+ if (!pdev)
X return -ENODEV;
- }
+
+ rc = rng_init_one (pdev);
+ if (rc)
+ return rc;
X
X rc = misc_register (&rng_miscdev);
X if (rc) {
- pci_unregister_driver (&rng_driver);
+ iounmap (rng_mem);
+ if (rng_have_mem_region)
+ release_mem_region (RNG_ADDR, RNG_ADDR_LEN);
X DPRINTK ("EXIT, returning %d\n", rc);
X return rc;
X }
X
X printk (KERN_INFO RNG_DRIVER_NAME " loaded\n");
X
+ rng_pdev = pdev;
+
X DPRINTK ("EXIT, returning 0\n");
X return 0;
X }
@@ -842,17 +869,16 @@


X {
X DPRINTK ("ENTER\n");
X

- del_timer_sync (&rng_timer);
+ assert (rng_timer_enabled == 0);
+ assert (rng_hw_enabled == 0);
+
+ misc_deregister (&rng_miscdev);
X
X rng_sysctl (0);
- pci_unregister_driver (&rng_driver);
X
+ iounmap (rng_mem);
X if (rng_have_mem_region)
X release_mem_region (RNG_ADDR, RNG_ADDR_LEN);
-
- rng_hwstatus_set (rng_hwstatus() & ~RNG_ENABLED);
-
- misc_deregister (&rng_miscdev);
X
X DPRINTK ("EXIT\n");
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/joystick/pcigame.c linux/drivers/char/joystick/pcigame.c
--- v2.4.0-test8/linux/drivers/char/joystick/pcigame.c Wed Jun 21 08:22:21 2000
+++ linux/drivers/char/joystick/pcigame.c Fri Sep 22 14:21:17 2000
@@ -40,8 +40,8 @@
X #include <linux/kernel.h>
X #include <linux/module.h>
X #include <linux/pci.h>
-#include <linux/pci_ids.h>
X #include <linux/init.h>
+#include <linux/slab.h>
X #include <linux/gameport.h>
X
X #define PCI_VENDOR_ID_AUREAL 0x12eb
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/lp.c linux/drivers/char/lp.c
--- v2.4.0-test8/linux/drivers/char/lp.c Tue Jul 18 15:59:05 2000
+++ linux/drivers/char/lp.c Sat Sep 23 21:10:30 2000
@@ -712,11 +712,12 @@
X if (parport_nr[0] == LP_PARPORT_AUTO &&
X port->probe_info[0].class != PARPORT_CLASS_PRINTER)
X return;
-
+ if (lp_count == LP_NO) {
+ printk("lp: ignoring parallel port (max. %d)\n",LP_NO);
+ return;
+ }
X if (!lp_register(lp_count, port))
- if (++lp_count == LP_NO)
- break;
-
+ lp_count++;
X break;
X
X default:
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/mem.c linux/drivers/char/mem.c
--- v2.4.0-test8/linux/drivers/char/mem.c Wed Jun 21 22:31:01 2000
+++ linux/drivers/char/mem.c Mon Sep 25 15:26:56 2000
@@ -28,12 +28,6 @@
X #ifdef CONFIG_I2C
X extern int i2c_init_all(void);
X #endif
-#ifdef CONFIG_SOUND
-void soundcore_init(void);
-#ifdef CONFIG_SOUND_OSS
-void soundcard_init(void);
-#endif
-#endif
X #ifdef CONFIG_SPARCAUDIO
X extern int sparcaudio_init(void);
X #endif
@@ -55,9 +49,6 @@
X #if defined(CONFIG_ADB)
X extern void adbdev_init(void);
X #endif
-#ifdef CONFIG_PHONE
-extern void telephony_init(void);
-#endif
X
X static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp,
X const char * buf, size_t count, loff_t *ppos)
@@ -258,25 +249,27 @@
X count -= read;
X }
X
- kbuf = (char *)__get_free_page(GFP_KERNEL);
- if (!kbuf)
- return -ENOMEM;
- while (count > 0) {
- int len = count;
-
- if (len > PAGE_SIZE)
- len = PAGE_SIZE;
- len = vread(kbuf, (char *)p, len);
- if (len && copy_to_user(buf, kbuf, len)) {
- free_page((unsigned long)kbuf);
- return -EFAULT;
+ if (count > 0) {
+ kbuf = (char *)__get_free_page(GFP_KERNEL);
+ if (!kbuf)
+ return -ENOMEM;
+ while (count > 0) {
+ int len = count;
+
+ if (len > PAGE_SIZE)
+ len = PAGE_SIZE;
+ len = vread(kbuf, (char *)p, len);
+ if (len && copy_to_user(buf, kbuf, len)) {
+ free_page((unsigned long)kbuf);
+ return -EFAULT;
+ }
+ count -= len;
+ buf += len;
+ virtr += len;
+ p += len;
X }
- count -= len;
- buf += len;
- virtr += len;
- p += len;
+ free_page((unsigned long)kbuf);
X }
- free_page((unsigned long)kbuf);
X *ppos = p;
X return virtr + read;
X }
@@ -642,15 +635,6 @@
X lp_m68k_init();
X #endif
X misc_init();
-#ifdef CONFIG_SOUND
- soundcore_init();
-#ifdef CONFIG_SOUND_OSS
- soundcard_init();
-#endif
-#endif
-#ifdef CONFIG_SPARCAUDIO
- sparcaudio_init();
-#endif
X #if CONFIG_QIC02_TAPE
X qic02_tape_init();
X #endif
@@ -666,8 +650,5 @@
X #ifdef CONFIG_VIDEO_DEV
X videodev_init();
X #endif
-#ifdef CONFIG_PHONE
- telephony_init();
-#endif
X return 0;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/misc.c linux/drivers/char/misc.c
--- v2.4.0-test8/linux/drivers/char/misc.c Mon Jul 24 17:04:12 2000
+++ linux/drivers/char/misc.c Sun Oct 1 19:45:29 2000
@@ -70,8 +70,6 @@
X extern void gfx_register(void);
X #endif
X extern void streamable_init(void);
-extern void watchdog_init(void);
-extern void pcwatchdog_init(void);
X extern int rtc_sun_init(void); /* Combines MK48T02 and MK48T08 */
X extern int rtc_DP8570A_init(void);
X extern int rtc_MK48T08_init(void);
@@ -81,6 +79,7 @@
X extern int pc110pad_init(void);
X extern int pmu_device_init(void);
X extern int qpmouse_init(void);
+extern int tosh_init(void);
X
X static int misc_read_proc(char *buf, char **start, off_t offset,
X int len, int *eof, void *private)
@@ -254,18 +253,6 @@
X #ifdef CONFIG_PC110_PAD
X pc110pad_init();
X #endif
-/*
- * Only one watchdog can succeed. We probe the pcwatchdog first,
- * then the wdt cards and finally the software watchdog which always
- * works. This means if your hardware watchdog dies or is 'borrowed'
- * for some reason the software watchdog still gives you some cover.
- */
-#ifdef CONFIG_PCWATCHDOG
- pcwatchdog_init();
-#endif
-#ifdef CONFIG_SOFT_WATCHDOG
- watchdog_init();
-#endif
X #ifdef CONFIG_MVME16x
X rtc_MK48T08_init();
X #endif
@@ -298,6 +285,9 @@
X #endif
X #ifdef CONFIG_SGI
X streamable_init ();
+#endif
+#ifdef CONFIG_TOSHIBA
+ tosh_init();
X #endif
X if (devfs_register_chrdev(MISC_MAJOR,"misc",&misc_fops)) {
X printk("unable to get major %d for misc devices\n",
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/mixcomwd.c linux/drivers/char/mixcomwd.c
--- v2.4.0-test8/linux/drivers/char/mixcomwd.c Wed Jul 12 21:58:42 2000
+++ linux/drivers/char/mixcomwd.c Sun Oct 1 19:45:29 2000
@@ -216,9 +216,10 @@


X return 1;
X }
X

-void __init mixcomwd_init(void)
+static int __init mixcomwd_init(void)
X {
X int i;
+ int ret;
X int found=0;
X
X for (i = 0; !found && mixcomwd_ioports[i] != 0; i++) {
@@ -238,23 +239,21 @@
X
X if (!found) {
X printk("mixcomwd: No card detected, or port not available.\n");
- return;
+ return -ENODEV;
X }
X
X request_region(watchdog_port,1,"MixCOM watchdog");
X
- misc_register(&mixcomwd_miscdev);
+ ret = misc_register(&mixcomwd_miscdev);
+ if (ret)
+ return ret;
+
X printk(KERN_INFO "MixCOM watchdog driver v%s, watchdog port at 0x%3x\n",VERSION,watchdog_port);
-}
X

-#ifdef MODULE
-int init_module(void)
-{

- mixcomwd_init();
X return 0;
-}
+}
X
-void cleanup_module(void)
+static void __exit mixcomwd_exit(void)
X {
X #ifndef CONFIG_WATCHDOG_NOWAYOUT
X if(mixcomwd_timer_alive) {
@@ -267,4 +266,6 @@
X release_region(watchdog_port,1);
X misc_deregister(&mixcomwd_miscdev);
X }
-#endif
+
+module_init(mixcomwd_init);
+module_exit(mixcomwd_exit);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/nvram.c linux/drivers/char/nvram.c
--- v2.4.0-test8/linux/drivers/char/nvram.c Sat Aug 26 16:24:58 2000
+++ linux/drivers/char/nvram.c Mon Sep 11 08:41:07 2000
@@ -109,7 +109,7 @@
X
X extern spinlock_t rtc_lock;
X
-static int nvram_open_cnt = 0; /* #times opened */
+static int nvram_open_cnt; /* #times opened */
X static int nvram_open_mode; /* special open modes */
X #define NVRAM_WRITE 1 /* opened for writing (exclusive) */
X #define NVRAM_EXCL 2 /* opened with O_EXCL */
@@ -415,14 +415,29 @@
X
X static int __init nvram_init(void)
X {
+ int ret;
+
X /* First test whether the driver should init at all */
X if (!CHECK_DRIVER_INIT())
X return( -ENXIO );
X
- printk(KERN_INFO "Non-volatile memory driver v%s\n", NVRAM_VERSION );
- misc_register( &nvram_dev );
- create_proc_read_entry("driver/nvram",0,0,nvram_read_proc,NULL);
- return( 0 );
+ ret = misc_register( &nvram_dev );
+ if (ret) {
+ printk(KERN_ERR "nvram: can't misc_register on minor=%d\n", NVRAM_MINOR);
+ goto out;
+ }
+ if (!create_proc_read_entry("driver/nvram",0,0,nvram_read_proc,NULL)) {
+ printk(KERN_ERR "nvram: can't create /proc/driver/nvram\n");
+ ret = -ENOMEM;
+ goto outmisc;
+ }
+ ret = 0;
+ printk(KERN_INFO "Non-volatile memory driver v" NVRAM_VERSION "\n");
+out:
+ return( ret );
+outmisc:
+ misc_deregister( &nvram_dev );
+ goto out;
X }
X
X static void __exit nvram_cleanup_module (void)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/nwflash.c linux/drivers/char/nwflash.c
--- v2.4.0-test8/linux/drivers/char/nwflash.c Sun Aug 13 09:54:15 2000
+++ linux/drivers/char/nwflash.c Mon Sep 18 15:15:22 2000
@@ -1,6 +1,9 @@
X /*
X * Flash memory interface rev.5 driver for the Intel
X * Flash chips used on the NetWinder.
+ *
+ * 20/08/2000 RMK use __ioremap to map flash into virtual memory
+ * make a few more places use "volatile"
X */
X
X #include <linux/module.h>
@@ -15,7 +18,7 @@
X #include <linux/spinlock.h>
X #include <linux/init.h>
X
-#include <asm/dec21285.h>
+#include <asm/hardware/dec21285.h>
X #include <asm/io.h>
X #include <asm/leds.h>
X #include <asm/mach-types.h>
@@ -33,7 +36,7 @@
X #define MSTATIC
X #endif
X
-#define NWFLASH_VERSION "6.2"
+#define NWFLASH_VERSION "6.3"
X
X MSTATIC void kick_open(void);
X MSTATIC int get_flash_id(void);
@@ -54,6 +57,7 @@
X
X static int gbWriteEnable;
X static int gbWriteBase64Enable;
+static volatile unsigned char *FLASH_BASE;
X MSTATIC int gbFlashSize = KFLASH_SIZE;
X
X extern spinlock_t gpio_lock;
@@ -93,25 +97,25 @@
X */
X kick_open();
X c2 = inb(0x80);
- *(unsigned char *) (FLASH_BASE + 0x8000) = 0x90;
+ *(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0x90;
X udelay(15);
- c1 = *(unsigned char *) FLASH_BASE;
+ c1 = *(volatile unsigned char *) FLASH_BASE;
X c2 = inb(0x80);
X
X /*
X * on 4 Meg flash the second byte is actually at offset 2...
X */
X if (c1 == 0xB0)
- c2 = *(unsigned char *) (FLASH_BASE + 2);
+ c2 = *(volatile unsigned char *) (FLASH_BASE + 2);
X else
- c2 = *(unsigned char *) (FLASH_BASE + 1);
+ c2 = *(volatile unsigned char *) (FLASH_BASE + 1);
X
X c2 += (c1 << 8);
X
X /*
X * set it back to read mode
X */
- *(unsigned char *) (FLASH_BASE + 0x8000) = 0xFF;
+ *(volatile unsigned char *) (FLASH_BASE + 0x8000) = 0xFF;
X
X if (c2 == KFLASH_ID4)
X gbFlashSize = KFLASH_SIZE4;
@@ -177,14 +181,9 @@
X if (count > gbFlashSize - p)
X count = gbFlashSize - p;
X
- /*
- * flash virtual address
- */
- p += FLASH_BASE;
-
X read = 0;
X
- if (copy_to_user(buf, (void *) p, count))
+ if (copy_to_user(buf, (void *)(FLASH_BASE + p), count))
X return -EFAULT;
X read += count;
X file->f_pos += read;
@@ -193,15 +192,15 @@
X
X static ssize_t flash_write(struct file *file, const char *buf, size_t count, loff_t * ppos)
X {
+ struct inode *inode = file->f_dentry->d_inode;
X unsigned long p = file->f_pos;
X int written;
X int nBlock, temp, rc;
X int i, j;
X
-
X if (flashdebug)
- printk("Flash_dev: flash_write: offset=0x%X, buffer=0x%X, count=0x%X.\n",
- (unsigned int) p, (unsigned int) buf, count);
+ printk("flash_write: offset=0x%lX, buffer=0x%p, count=0x%X.\n",
+ p, buf, count);
X
X if (!gbWriteEnable)
X return -EINVAL;
@@ -209,20 +208,25 @@
X if (p < 64 * 1024 && (!gbWriteBase64Enable))
X return -EINVAL;
X
- if (count < 0)
- return -EINVAL;
-
X /*
- * if write size to big - error!
+ * if byte count is -ve or to big - error!
X */
- if (count > gbFlashSize - p)
+ if (count < 0 || count > gbFlashSize - p)


X return -EINVAL;
X
-

X if (verify_area(VERIFY_READ, buf, count))


X return -EFAULT;
X
X

+ /*
+ * We now should lock around writes. Really, we shouldn't
+ * allow the flash to be opened more than once in write
+ * mode though (note that you can't stop two processes having
+ * it open even then). --rmk
+ */
+ if (down_interruptible(&inode->i_sem))
+ return -ERESTARTSYS;
+
X written = 0;
X
X leds_event(led_claim);
@@ -310,6 +314,8 @@
X */
X leds_event(led_release);
X
+ up(&inode->i_sem);
+
X return written;
X }
X
@@ -586,7 +592,7 @@
X if (time_before(jiffies, timeout)) {
X if (flashdebug)
X printk("FlashWrite: Retrying write (addr=0x%X)...\n",
- (unsigned int) pWritePtr - FLASH_BASE);
+ pWritePtr - FLASH_BASE);
X
X /*
X * no LED == waiting
@@ -604,7 +610,7 @@
X goto WriteRetry;
X } else {
X printk("Timeout in flash write! (addr=0x%X) Aborting...\n",
- (unsigned int) pWritePtr - FLASH_BASE);
+ pWritePtr - FLASH_BASE);
X /*
X * return error -2
X */
@@ -666,6 +672,10 @@
X if (machine_is_netwinder()) {
X int id;
X
+ FLASH_BASE = __ioremap(DC21285_FLASH, KFLASH_SIZE4, 0);
+ if (!FLASH_BASE)
+ goto out;
+
X id = get_flash_id();
X printk("Flash ROM driver v.%s, flash device ID 0x%04X, size %d Mb.\n",
X NWFLASH_VERSION, id, gbFlashSize / (1024 * 1024));
@@ -674,13 +684,14 @@
X
X ret = 0;
X }
-
+out:


X return ret;
X }
X

X MSTATIC void __exit nwflash_exit(void)
X {
X misc_deregister(&flash_miscdev);
+ iounmap((void *)FLASH_BASE);
X }
X
X EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/pcwd.c linux/drivers/char/pcwd.c
--- v2.4.0-test8/linux/drivers/char/pcwd.c Wed Jul 12 21:58:42 2000
+++ linux/drivers/char/pcwd.c Sun Oct 1 19:45:29 2000
@@ -564,11 +564,7 @@
X &pcwd_fops
X };
X
-#ifdef MODULE
-int init_module(void)
-#else
-int __init pcwatchdog_init(void)
-#endif
+static int __init pcwatchdog_init(void)
X {
X int i, found = 0;
X spin_lock_init(&io_lock);
@@ -644,8 +640,7 @@


X return 0;
X }
X

-#ifdef MODULE
-void cleanup_module(void)
+static void __exit pcwatchdog_exit(void)
X {
X /* Disable the board */
X if (revision == PCWD_REVISION_C) {
@@ -658,4 +653,6 @@
X
X release_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4);
X }
-#endif
+
+module_init(pcwatchdog_init);
+module_exit(pcwatchdog_exit);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/ppdev.c linux/drivers/char/ppdev.c
--- v2.4.0-test8/linux/drivers/char/ppdev.c Wed Jul 12 21:58:42 2000
+++ linux/drivers/char/ppdev.c Wed Sep 27 13:53:52 2000
@@ -39,7 +39,13 @@
X * read/write read or write in current IEEE 1284 protocol
X * select wait for interrupt (in readfds)
X *
+ * Changes:
X * Added SETTIME/GETTIME ioctl, Fred Barnes 1999.
+ *
+ * Arnaldo Carvalho de Melo <ac...@conectiva.com.br> 2000/08/25
+ * - On error, copy_from_user and copy_to_user do not return -EFAULT,
+ * They return the positive number of bytes *not* copied due to address
+ * space errors.
X */
X
X #include <linux/module.h>
@@ -179,7 +185,7 @@
X
X wrote = parport_write (pp->pdev->port, kbuffer, n);
X
- if (wrote < 0) {
+ if (wrote <= 0) {
X if (!bytes_written)
X bytes_written = wrote;
X break;
@@ -369,19 +375,19 @@
X
X case PPRSTATUS:
X reg = parport_read_status (port);
- return copy_to_user ((unsigned char *) arg, &reg,
- sizeof (reg));
-
+ if (copy_to_user ((unsigned char *) arg, &reg, sizeof (reg)))
+ return -EFAULT;
+ return 0;
X case PPRDATA:
X reg = parport_read_data (port);
- return copy_to_user ((unsigned char *) arg, &reg,
- sizeof (reg));
-
+ if (copy_to_user ((unsigned char *) arg, &reg, sizeof (reg)))
+ return -EFAULT;
+ return 0;
X case PPRCONTROL:
X reg = parport_read_control (port);
- return copy_to_user ((unsigned char *) arg, &reg,
- sizeof (reg));
-
+ if (copy_to_user ((unsigned char *) arg, &reg, sizeof (reg)))
+ return -EFAULT;
+ return 0;
X case PPYIELD:
X parport_yield_blocking (pp->pdev);
X return 0;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/qpmouse.c linux/drivers/char/qpmouse.c
--- v2.4.0-test8/linux/drivers/char/qpmouse.c Wed Jul 12 21:58:42 2000
+++ linux/drivers/char/qpmouse.c Tue Sep 19 08:01:34 2000
@@ -344,9 +344,14 @@
X
X printk(KERN_INFO "82C710 type pointing device detected -- driver installed.\n");
X /* printk("82C710 address = %x (should be 0x310)\n", qp_data); */
+ queue = (struct qp_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
+ if(queue==NULL)
+ {
+ printk(KERN_ERR "qpmouse: no queue memory.\n");
+ return -ENOMEM;
+ }
X qp_present = 1;
X misc_register(&qp_mouse);
- queue = (struct qp_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
X memset(queue, 0, sizeof(*queue));
X queue->head = queue->tail = 0;
X init_waitqueue_head(&queue->proc_list);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/raw.c linux/drivers/char/raw.c
--- v2.4.0-test8/linux/drivers/char/raw.c Wed Jul 12 21:58:42 2000
+++ linux/drivers/char/raw.c Sun Oct 1 20:35:15 2000
@@ -19,10 +19,10 @@
X
X #define dprintk(x...)
X
-static struct block_device *raw_device_bindings[256] = {};
-static int raw_device_inuse[256] = {};
-static int raw_device_sector_size[256] = {};
-static int raw_device_sector_bits[256] = {};
+static struct block_device *raw_device_bindings[256];
+static int raw_device_inuse[256];
+static int raw_device_sector_size[256];
+static int raw_device_sector_bits[256];
X
X static ssize_t rw_raw_dev(int rw, struct file *, char *, size_t, loff_t *);
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/rtc.c linux/drivers/char/rtc.c
--- v2.4.0-test8/linux/drivers/char/rtc.c Wed Jul 19 11:27:45 2000
+++ linux/drivers/char/rtc.c Fri Sep 22 14:09:00 2000
@@ -693,7 +693,7 @@
X if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
X BCD_TO_BIN(year); /* This should never happen... */
X
- if (year > 20 && year < 48) {
+ if (year >= 20 && year < 48) {
X epoch = 1980;
X guess = "ARC console";
X } else if (year >= 48 && year < 70) {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/sbc60xxwdt.c linux/drivers/char/sbc60xxwdt.c
--- v2.4.0-test8/linux/drivers/char/sbc60xxwdt.c Wed Jul 12 21:58:42 2000
+++ linux/drivers/char/sbc60xxwdt.c Sun Oct 1 19:45:29 2000
@@ -338,4 +338,4 @@
X }
X
X module_init(sbc60xxwdt_init);
-module_exit(sbc60xxwdt_unload)
+module_exit(sbc60xxwdt_unload);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/serial.c linux/drivers/char/serial.c
--- v2.4.0-test8/linux/drivers/char/serial.c Thu Sep 7 08:40:58 2000
+++ linux/drivers/char/serial.c Thu Sep 21 13:23:16 2000
@@ -331,6 +331,10 @@
X #define IS_PCI_REGION_IOPORT(dev, r) (pci_resource_flags((dev), (r)) & \
X IORESOURCE_IO)
X #endif
+#ifndef IS_PCI_REGION_IOMEM
+#define IS_PCI_REGION_IOMEM(dev, r) (pci_resource_flags((dev), (r)) & \
+ IORESOURCE_MEM)
+#endif
X #ifndef PCI_IRQ_RESOURCE
X #define PCI_IRQ_RESOURCE(dev, r) ((dev)->irq_resource[r].start)
X #endif
@@ -4185,7 +4189,7 @@
X * This is the configuration table for all of the PCI serial boards
X * which we support.
X */
-static struct pci_board pci_boards[] __initdata = {
+static struct pci_board pci_boards[] __devinitdata = {
X /*
X * Vendor ID, Device ID,
X * Subvendor ID, Subdevice ID,
@@ -4606,9 +4610,9 @@
X num_port++;
X if (first_port == -1)
X first_port = i;
- } else {
- num_iomem++;
X }
+ if (IS_PCI_REGION_IOMEM(dev, i))
+ num_iomem++;
X }
X
X /*
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/serial_amba.c linux/drivers/char/serial_amba.c
--- v2.4.0-test8/linux/drivers/char/serial_amba.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/serial_amba.c Mon Sep 18 15:15:22 2000
@@ -0,0 +1,2030 @@
+/*
+ * linux/drivers/char/serial_amba.c
+ *
+ * Driver for AMBA serial ports
+ *
+ * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ * Copyright 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd.


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *

+ * This is a generic driver for ARM AMBA-type serial ports. They
+ * have a lot of 16550-like features, but are not register compatable.
+ * Note that although they do have CTS, DCD and DSR inputs, they do
+ * not have an RI input, nor do they have DTR or RTS outputs. If
+ * required, these have to be supplied via some other means (eg, GPIO)
+ * and hooked into this driver.
+ *
+ * This could very easily become a generic serial driver for dumb UARTs
+ * (eg, {82,16x}50, 21285, SA1100).


+ */
+
+#include <linux/config.h>

+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/malloc.h>
+#include <linux/init.h>
+#include <linux/circ_buf.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+
+#include <asm/hardware/serial_amba.h>
+
+#define SERIAL_AMBA_NAME "ttyAM"
+#define SERIAL_AMBA_MAJOR 204
+#define SERIAL_AMBA_MINOR 16
+#define SERIAL_AMBA_NR 2
+
+#define CALLOUT_AMBA_NAME "cuaam"
+#define CALLOUT_AMBA_MAJOR 205
+#define CALLOUT_AMBA_MINOR 16
+#define CALLOUT_AMBA_NR SERIAL_AMBA_NR
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define DEBUG 0
+#define DEBUG_LEDS 0
+
+#if DEBUG_LEDS
+extern int get_leds(void);
+extern int set_leds(int);
+#endif
+
+/*
+ * Access routines for the AMBA UARTs
+ */
+#define UART_GET_INT_STATUS(p) IO_READ((p)->uart_base + AMBA_UARTIIR)
+#define UART_GET_FR(p) IO_READ((p)->uart_base + AMBA_UARTFR)
+#define UART_GET_CHAR(p) IO_READ((p)->uart_base + AMBA_UARTDR)
+#define UART_PUT_CHAR(p, c) IO_WRITE((p)->uart_base + AMBA_UARTDR, (c))
+#define UART_GET_RSR(p) IO_READ((p)->uart_base + AMBA_UARTRSR)
+#define UART_GET_CR(p) IO_READ((p)->uart_base + AMBA_UARTCR)
+#define UART_PUT_CR(p,c) IO_WRITE((p)->uart_base + AMBA_UARTCR, (c))
+#define UART_GET_LCRL(p) IO_READ((p)->uart_base + AMBA_UARTLCR_L)
+#define UART_PUT_LCRL(p,c) IO_WRITE((p)->uart_base + AMBA_UARTLCR_L, (c))
+#define UART_GET_LCRM(p) IO_READ((p)->uart_base + AMBA_UARTLCR_M)
+#define UART_PUT_LCRM(p,c) IO_WRITE((p)->uart_base + AMBA_UARTLCR_M, (c))
+#define UART_GET_LCRH(p) IO_READ((p)->uart_base + AMBA_UARTLCR_H)
+#define UART_PUT_LCRH(p,c) IO_WRITE((p)->uart_base + AMBA_UARTLCR_H, (c))
+#define UART_RX_DATA(s) (((s) & AMBA_UARTFR_RXFE) == 0)
+#define UART_TX_READY(s) (((s) & AMBA_UARTFR_TXFF) == 0)
+#define UART_TX_EMPTY(p) ((UART_GET_FR(p) & AMBA_UARTFR_TMSK) == 0)
+
+#define AMBA_UARTRSR_ANY (AMBA_UARTRSR_OE|AMBA_UARTRSR_BE|AMBA_UARTRSR_PE|AMBA_UARTRSR_FE)
+#define AMBA_UARTFR_MODEM_ANY (AMBA_UARTFR_DCD|AMBA_UARTFR_DSR|AMBA_UARTFR_CTS)
+
+/*
+ * Things needed by tty driver
+ */
+static struct tty_driver ambanormal_driver, ambacallout_driver;
+static int ambauart_refcount;
+static struct tty_struct *ambauart_table[SERIAL_AMBA_NR];
+static struct termios *ambauart_termios[SERIAL_AMBA_NR];
+static struct termios *ambauart_termios_locked[SERIAL_AMBA_NR];
+
+#if defined(CONFIG_SERIAL_AMBA_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+/*
+ * Things needed internally to this driver
+ */
+
+/*
+ * tmp_buf is used as a temporary buffer by serial_write. We need to
+ * lock it in case the copy_from_user blocks while swapping in a page,
+ * and some other program tries to do a serial write at the same time.
+ * Since the lock will only come under contention when the system is
+ * swapping and available memory is low, it makes sense to share one
+ * buffer across all the serial ports, since it significantly saves
+ * memory if large numbers of serial ports are open.
+ */
+static u_char *tmp_buf;
+static DECLARE_MUTEX(tmp_buf_sem);
+
+#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
+
+/* number of characters left in xmit buffer before we ask for more */
+#define WAKEUP_CHARS 256
+#define AMBA_ISR_PASS_LIMIT 256
+
+#define EVT_WRITE_WAKEUP 0
+
+struct amba_icount {
+ __u32 cts;
+ __u32 dsr;
+ __u32 rng;
+ __u32 dcd;
+ __u32 rx;
+ __u32 tx;
+ __u32 frame;
+ __u32 overrun;
+ __u32 parity;
+ __u32 brk;
+ __u32 buf_overrun;
+};
+
+/*
+ * Static information about the port
+ */
+struct amba_port {
+ unsigned int uart_base;
+ unsigned int irq;
+ unsigned int uartclk;
+ unsigned int fifosize;
+ unsigned int tiocm_support;
+ void (*set_mctrl)(struct amba_port *, u_int mctrl);
+};
+
+/*
+ * This is the state information which is persistent across opens
+ */
+struct amba_state {
+ struct amba_icount icount;
+ unsigned int line;
+ unsigned int close_delay;
+ unsigned int closing_wait;
+ unsigned int custom_divisor;
+ unsigned int flags;
+ struct termios normal_termios;
+ struct termios callout_termios;
+
+ int count;
+ struct amba_info *info;
+};
+
+#define AMBA_XMIT_SIZE 1024
+/*
+ * This is the state information which is only valid when the port is open.
+ */
+struct amba_info {
+ struct amba_port *port;
+ struct amba_state *state;
+ struct tty_struct *tty;
+ unsigned char x_char;
+ unsigned char old_status;
+ unsigned char read_status_mask;
+ unsigned char ignore_status_mask;
+ struct circ_buf xmit;
+ unsigned int flags;
+#ifdef SUPPORT_SYSRQ
+ unsigned long sysrq;
+#endif
+
+ unsigned int event;
+ unsigned int timeout;
+ unsigned int lcr_h;
+ unsigned int mctrl;
+ int blocked_open;
+ pid_t session;
+ pid_t pgrp;
+
+ struct tasklet_struct tlet;
+
+ wait_queue_head_t open_wait;
+ wait_queue_head_t close_wait;
+ wait_queue_head_t delta_msr_wait;
+};
+
+#ifdef CONFIG_SERIAL_AMBA_CONSOLE
+static struct console ambauart_cons;
+#endif
+static void ambauart_change_speed(struct amba_info *info, struct termios *old_termios);
+static void ambauart_wait_until_sent(struct tty_struct *tty, int timeout);
+
+#if 1 //def CONFIG_SERIAL_INTEGRATOR
+static void amba_set_mctrl_null(struct amba_port *port, u_int mctrl)
+{
+}
+
+static struct amba_port amba_ports[SERIAL_AMBA_NR] = {
+ {
+ uart_base: IO_ADDRESS(INTEGRATOR_UART0_BASE),
+ irq: IRQ_UARTINT0,
+ uartclk: 14745600,
+ fifosize: 8,
+ set_mctrl: amba_set_mctrl_null,
+ },
+ {
+ uart_base: IO_ADDRESS(INTEGRATOR_UART1_BASE),
+ irq: IRQ_UARTINT1,
+ uartclk: 14745600,
+ fifosize: 8,
+ set_mctrl: amba_set_mctrl_null,
+ }
+};
+#endif
+
+static struct amba_state amba_state[SERIAL_AMBA_NR];
+
+static void ambauart_enable_rx_interrupt(struct amba_info *info)
+{
+ unsigned int cr;
+
+ cr = UART_GET_CR(info->port);
+ cr |= AMBA_UARTCR_RIE | AMBA_UARTCR_RTIE;
+ UART_PUT_CR(info->port, cr);
+}
+
+static void ambauart_disable_rx_interrupt(struct amba_info *info)
+{
+ unsigned int cr;
+
+ cr = UART_GET_CR(info->port);
+ cr &= ~(AMBA_UARTCR_RIE | AMBA_UARTCR_RTIE);
+ UART_PUT_CR(info->port, cr);
+}
+
+static void ambauart_enable_tx_interrupt(struct amba_info *info)
+{
+ unsigned int cr;
+
+ cr = UART_GET_CR(info->port);
+ cr |= AMBA_UARTCR_TIE;
+ UART_PUT_CR(info->port, cr);
+}
+
+static void ambauart_disable_tx_interrupt(struct amba_info *info)
+{
+ unsigned int cr;
+
+ cr = UART_GET_CR(info->port);
+ cr &= ~AMBA_UARTCR_TIE;
+ UART_PUT_CR(info->port, cr);
+}
+
+static void ambauart_stop(struct tty_struct *tty)
+{
+ struct amba_info *info = tty->driver_data;


+ unsigned long flags;
+

+ save_flags(flags); cli();
+ ambauart_disable_tx_interrupt(info);
+ restore_flags(flags);
+}
+
+static void ambauart_start(struct tty_struct *tty)
+{
+ struct amba_info *info = tty->driver_data;


+ unsigned long flags;
+

+ save_flags(flags); cli();
+ if (info->xmit.head != info->xmit.tail
+ && info->xmit.buf)
+ ambauart_enable_tx_interrupt(info);
+ restore_flags(flags);
+}
+
+
+/*
+ * This routine is used by the interrupt handler to schedule
+ * processing in the software interrupt portion of the driver.
+ */
+static void ambauart_event(struct amba_info *info, int event)
+{
+ info->event |= 1 << event;
+ tasklet_schedule(&info->tlet);
+}
+
+static void
+#ifdef SUPPORT_SYSRQ
+ambauart_rx_chars(struct amba_info *info, struct pt_regs *regs)
+#else
+ambauart_rx_chars(struct amba_info *info)
+#endif
+{
+ struct tty_struct *tty = info->tty;
+ unsigned int status, ch, rsr, flg, ignored = 0;
+ struct amba_icount *icount = &info->state->icount;
+ struct amba_port *port = info->port;
+
+ status = UART_GET_FR(port);
+ while (UART_RX_DATA(status)) {
+ ch = UART_GET_CHAR(port);
+
+ if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+ goto ignore_char;
+ icount->rx++;
+
+ flg = TTY_NORMAL;
+
+ /*
+ * Note that the error handling code is
+ * out of the main execution path
+ */
+ rsr = UART_GET_RSR(port);
+ if (rsr & AMBA_UARTRSR_ANY)
+ goto handle_error;
+#ifdef SUPPORT_SYSRQ
+ if (info->sysrq) {
+ if (ch && time_before(jiffies, info->sysrq)) {
+ handle_sysrq(ch, regs, NULL, NULL);
+ info->sysrq = 0;
+ goto ignore_char;
+ }
+ info->sysrq = 0;
+ }
+#endif
+ error_return:
+ *tty->flip.flag_buf_ptr++ = flg;
+ *tty->flip.char_buf_ptr++ = ch;
+ tty->flip.count++;
+ ignore_char:
+ status = UART_GET_FR(port);
+ }
+out:
+ tty_flip_buffer_push(tty);
+ return;
+
+handle_error:
+ if (rsr & AMBA_UARTRSR_BE) {
+ rsr &= ~(AMBA_UARTRSR_FE | AMBA_UARTRSR_PE);
+ icount->brk++;
+
+#ifdef SUPPORT_SYSRQ
+ if (info->state->line == ambauart_cons.index) {
+ if (!info->sysrq) {
+ info->sysrq = jiffies + HZ*5;
+ goto ignore_char;
+ }
+ }
+#endif
+ } else if (rsr & AMBA_UARTRSR_PE)
+ icount->parity++;
+ else if (rsr & AMBA_UARTRSR_FE)
+ icount->frame++;
+ if (rsr & AMBA_UARTRSR_OE)
+ icount->overrun++;
+
+ if (rsr & info->ignore_status_mask) {
+ if (++ignored > 100)
+ goto out;
+ goto ignore_char;
+ }
+ rsr &= info->read_status_mask;
+
+ if (rsr & AMBA_UARTRSR_BE)
+ flg = TTY_BREAK;
+ else if (rsr & AMBA_UARTRSR_PE)
+ flg = TTY_PARITY;
+ else if (rsr & AMBA_UARTRSR_FE)
+ flg = TTY_FRAME;
+
+ if (rsr & AMBA_UARTRSR_OE) {
+ /*
+ * CHECK: does overrun affect the current character?
+ * ASSUMPTION: it does not.
+ */
+ *tty->flip.flag_buf_ptr++ = flg;
+ *tty->flip.char_buf_ptr++ = ch;
+ tty->flip.count++;
+ if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+ goto ignore_char;
+ ch = 0;
+ flg = TTY_OVERRUN;
+ }
+#ifdef SUPPORT_SYSRQ
+ info->sysrq = 0;
+#endif
+ goto error_return;
+}
+
+static void ambauart_tx_chars(struct amba_info *info)
+{
+ struct amba_port *port = info->port;
+ int count;
+
+ if (info->x_char) {
+ UART_PUT_CHAR(port, info->x_char);
+ info->state->icount.tx++;
+ info->x_char = 0;
+ return;
+ }
+ if (info->xmit.head == info->xmit.tail
+ || info->tty->stopped
+ || info->tty->hw_stopped) {
+ ambauart_disable_tx_interrupt(info);
+ return;
+ }
+
+ count = port->fifosize;
+ do {
+ UART_PUT_CHAR(port, info->xmit.buf[info->xmit.tail]);
+ info->xmit.tail = (info->xmit.tail + 1) & (AMBA_XMIT_SIZE - 1);
+ info->state->icount.tx++;
+ if (info->xmit.head == info->xmit.tail)
+ break;
+ } while (--count > 0);
+
+ if (CIRC_CNT(info->xmit.head,
+ info->xmit.tail,
+ AMBA_XMIT_SIZE) < WAKEUP_CHARS)
+ ambauart_event(info, EVT_WRITE_WAKEUP);
+
+ if (info->xmit.head == info->xmit.tail) {
+ ambauart_disable_tx_interrupt(info);
+ }
+}
+
+static void ambauart_modem_status(struct amba_info *info)
+{
+ unsigned int status, delta;
+ struct amba_icount *icount = &info->state->icount;
+
+ status = UART_GET_FR(info->port) & AMBA_UARTFR_MODEM_ANY;
+
+ delta = status ^ info->old_status;
+ info->old_status = status;
+
+ if (!delta)
+ return;
+
+ if (delta & AMBA_UARTFR_DCD) {
+ icount->dcd++;
+#ifdef CONFIG_HARD_PPS
+ if ((info->flags & ASYNC_HARDPPS_CD) &&
+ (status & AMBA_UARTFR_DCD)
+ hardpps();
+#endif
+ if (info->flags & ASYNC_CHECK_CD) {
+ if (status & AMBA_UARTFR_DCD)
+ wake_up_interruptible(&info->open_wait);
+ else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+ (info->flags & ASYNC_CALLOUT_NOHUP))) {
+ if (info->tty)
+ tty_hangup(info->tty);
+ }
+ }
+ }
+
+ if (delta & AMBA_UARTFR_DSR)
+ icount->dsr++;
+
+ if (delta & AMBA_UARTFR_CTS) {
+ icount->cts++;
+
+ if (info->flags & ASYNC_CTS_FLOW) {
+ status &= AMBA_UARTFR_CTS;
+
+ if (info->tty->hw_stopped) {
+ if (status) {
+ info->tty->hw_stopped = 0;
+ ambauart_enable_tx_interrupt(info);
+ ambauart_event(info, EVT_WRITE_WAKEUP);
+ }
+ } else {
+ if (!status) {
+ info->tty->hw_stopped = 1;
+ ambauart_disable_tx_interrupt(info);
+ }
+ }
+ }
+ }
+ wake_up_interruptible(&info->delta_msr_wait);
+
+}
+
+static void ambauart_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct amba_info *info = dev_id;
+ unsigned int status, pass_counter = 0;
+
+#if DEBUG_LEDS
+ // tell the world
+ set_leds(get_leds() | RED_LED);
+#endif
+
+ status = UART_GET_INT_STATUS(info->port);
+ do {
+ /*
+ * FIXME: what about clearing the interrupts?
+ */
+
+ if (status & (AMBA_UARTIIR_RTIS | AMBA_UARTIIR_RIS))
+#ifdef SUPPORT_SYSRQ
+ ambauart_rx_chars(info, regs);
+#else
+ ambauart_rx_chars(info);
+#endif
+ if (status & AMBA_UARTIIR_TIS)
+ ambauart_tx_chars(info);
+ if (status & AMBA_UARTIIR_MIS)
+ ambauart_modem_status(info);
+ if (pass_counter++ > AMBA_ISR_PASS_LIMIT)
+ break;
+
+ status = UART_GET_INT_STATUS(info->port);
+ } while (status & (AMBA_UARTIIR_RTIS | AMBA_UARTIIR_RIS | AMBA_UARTIIR_TIS));
+
+#if DEBUG_LEDS
+ // tell the world
+ set_leds(get_leds() & ~RED_LED);
+#endif
+}
+
+static void ambauart_tasklet_action(unsigned long data)
+{
+ struct amba_info *info = (struct amba_info *)data;
+ struct tty_struct *tty;
+
+ tty = info->tty;
+ if (!tty || !test_and_clear_bit(EVT_WRITE_WAKEUP, &info->event))
+ return;
+
+ if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+ tty->ldisc.write_wakeup)
+ (tty->ldisc.write_wakeup)(tty);
+ wake_up_interruptible(&tty->write_wait);
+}
+
+static int ambauart_startup(struct amba_info *info)
+{
+ unsigned long flags;
+ unsigned long page;


+ int retval = 0;

+
+ page = get_zeroed_page(GFP_KERNEL);
+ if (!page)
+ return -ENOMEM;
+
+ save_flags(flags); cli();
+
+ if (info->flags & ASYNC_INITIALIZED) {
+ free_page(page);
+ goto errout;
+ }
+
+ if (info->xmit.buf)
+ free_page(page);
+ else
+ info->xmit.buf = (unsigned char *) page;
+
+ /*
+ * Allocate the IRQ
+ */
+ retval = request_irq(info->port->irq, ambauart_int, 0, "amba", info);
+ if (retval) {
+ if (capable(CAP_SYS_ADMIN)) {
+ if (info->tty)
+ set_bit(TTY_IO_ERROR, &info->tty->flags);
+ retval = 0;
+ }
+ goto errout;
+ }
+
+ info->mctrl = 0;
+ if (info->tty->termios->c_cflag & CBAUD)
+ info->mctrl = TIOCM_RTS | TIOCM_DTR;
+ info->port->set_mctrl(info->port, info->mctrl);
+
+ /*
+ * initialise the old status of the modem signals
+ */
+ info->old_status = UART_GET_FR(info->port) & AMBA_UARTFR_MODEM_ANY;
+
+ /*
+ * Finally, enable interrupts
+ */
+ ambauart_enable_rx_interrupt(info);
+
+ if (info->tty)
+ clear_bit(TTY_IO_ERROR, &info->tty->flags);
+ info->xmit.head = info->xmit.tail = 0;
+
+ /*
+ * Set up the tty->alt_speed kludge
+ */
+ if (info->tty) {
+ if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+ info->tty->alt_speed = 57600;
+ if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+ info->tty->alt_speed = 115200;
+ if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+ info->tty->alt_speed = 230400;
+ if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+ info->tty->alt_speed = 460800;
+ }
+
+ /*
+ * and set the speed of the serial port
+ */
+ ambauart_change_speed(info, 0);
+
+ info->flags |= ASYNC_INITIALIZED;
+ restore_flags(flags);
+ return 0;
+
+errout:
+ restore_flags(flags);
+ return retval;
+}
+
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void ambauart_shutdown(struct amba_info *info)
+{


+ unsigned long flags;
+

+ if (!(info->flags & ASYNC_INITIALIZED))
+ return;
+
+ save_flags(flags); cli(); /* Disable interrupts */
+
+ /*
+ * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
+ * here so the queue might never be woken up
+ */
+ wake_up_interruptible(&info->delta_msr_wait);
+
+ /*
+ * Free the IRQ
+ */
+ free_irq(info->port->irq, info);
+
+ if (info->xmit.buf) {
+ unsigned long pg = (unsigned long) info->xmit.buf;
+ info->xmit.buf = NULL;
+ free_page(pg);
+ }
+
+ /*
+ * disable all interrupts, disable the port
+ */
+ UART_PUT_CR(info->port, 0);
+
+ /* disable break condition and fifos */
+ UART_PUT_LCRH(info->port, UART_GET_LCRH(info->port) &
+ ~(AMBA_UARTLCR_H_BRK | AMBA_UARTLCR_H_FEN));
+
+ if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
+ info->mctrl &= ~(TIOCM_DTR|TIOCM_RTS);
+ info->port->set_mctrl(info->port, info->mctrl);
+
+ /* kill off our tasklet */
+ tasklet_kill(&info->tlet);
+ if (info->tty)
+ set_bit(TTY_IO_ERROR, &info->tty->flags);
+
+ info->flags &= ~ASYNC_INITIALIZED;
+ restore_flags(flags);
+}
+
+static void ambauart_change_speed(struct amba_info *info, struct termios *old_termios)
+{
+ unsigned int lcr_h, baud, quot, cflag, old_cr, bits;


+ unsigned long flags;
+

+ if (!info->tty || !info->tty->termios)
+ return;
+
+ cflag = info->tty->termios->c_cflag;
+
+#if DEBUG
+ printk("ambauart_set_cflag(0x%x) called\n", cflag);
+#endif
+ /* byte size and parity */
+ switch (cflag & CSIZE) {
+ case CS5: lcr_h = AMBA_UARTLCR_H_WLEN_5; bits = 7; break;
+ case CS6: lcr_h = AMBA_UARTLCR_H_WLEN_6; bits = 8; break;
+ case CS7: lcr_h = AMBA_UARTLCR_H_WLEN_7; bits = 9; break;
+ default: lcr_h = AMBA_UARTLCR_H_WLEN_8; bits = 10; break; // CS8
+ }
+ if (cflag & CSTOPB) {
+ lcr_h |= AMBA_UARTLCR_H_STP2;
+ bits ++;
+ }
+ if (cflag & PARENB) {
+ lcr_h |= AMBA_UARTLCR_H_PEN;
+ bits++;
+ if (!(cflag & PARODD))
+ lcr_h |= AMBA_UARTLCR_H_EPS;
+ }
+ if (info->port->fifosize > 1)
+ lcr_h |= AMBA_UARTLCR_H_FEN;
+
+ do {
+ /* Determine divisor based on baud rate */
+ baud = tty_get_baud_rate(info->tty);
+ if (!baud)
+ baud = 9600;
+
+ if (baud == 38400 &&
+ ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
+ quot = info->state->custom_divisor;
+ else
+ quot = (info->port->uartclk / (16 * baud)) - 1;
+
+ if (!quot && old_termios) {
+ info->tty->termios->c_cflag &= ~CBAUD;
+ info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD);
+ old_termios = NULL;
+ }
+ } while (quot == 0 && old_termios);
+
+ /* As a last resort, if the quotient is zero, default to 9600 bps */
+ if (!quot)
+ quot = (info->port->uartclk / (16 * 9600)) - 1;
+
+ info->timeout = (info->port->fifosize * HZ * bits * quot) /
+ (info->port->uartclk / 16);
+ info->timeout += HZ/50; /* Add .02 seconds of slop */
+
+ if (cflag & CRTSCTS)
+ info->flags |= ASYNC_CTS_FLOW;
+ else
+ info->flags &= ~ASYNC_CTS_FLOW;
+ if (cflag & CLOCAL)
+ info->flags &= ~ASYNC_CHECK_CD;
+ else
+ info->flags |= ASYNC_CHECK_CD;
+
+ /*
+ * Set up parity check flag
+ */
+#define RELEVENT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+
+ info->read_status_mask = AMBA_UARTRSR_OE;
+ if (I_INPCK(info->tty))
+ info->read_status_mask |= AMBA_UARTRSR_FE | AMBA_UARTRSR_PE;
+ if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
+ info->read_status_mask |= AMBA_UARTRSR_BE;
+
+ /*
+ * Characters to ignore
+ */
+ info->ignore_status_mask = 0;
+ if (I_IGNPAR(info->tty))
+ info->ignore_status_mask |= AMBA_UARTRSR_FE | AMBA_UARTRSR_PE;
+ if (I_IGNBRK(info->tty)) {
+ info->ignore_status_mask |= AMBA_UARTRSR_BE;
+ /*
+ * If we're ignoring parity and break indicators,
+ * ignore overruns to (for real raw support).
+ */
+ if (I_IGNPAR(info->tty))
+ info->ignore_status_mask |= AMBA_UARTRSR_OE;
+ }
+
+ /* first, disable everything */
+ save_flags(flags); cli();
+ old_cr = UART_GET_CR(info->port) &= ~AMBA_UARTCR_MSIE;
+
+ if ((info->flags & ASYNC_HARDPPS_CD) ||
+ (cflag & CRTSCTS) ||
+ !(cflag & CLOCAL))
+ old_cr |= AMBA_UARTCR_MSIE;
+
+ UART_PUT_CR(info->port, 0);
+ restore_flags(flags);
+
+ /* Set baud rate */
+ UART_PUT_LCRM(info->port, ((quot & 0xf00) >> 8));
+ UART_PUT_LCRL(info->port, (quot & 0xff));
+
+ /*
+ * ----------v----------v----------v----------v-----
+ * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L
+ * ----------^----------^----------^----------^-----
+ */
+ UART_PUT_LCRH(info->port, lcr_h);
+ UART_PUT_CR(info->port, old_cr);
+}
+
+static void ambauart_put_char(struct tty_struct *tty, u_char ch)
+{
+ struct amba_info *info = tty->driver_data;


+ unsigned long flags;
+

+ if (!tty || !info->xmit.buf)
+ return;
+
+ save_flags(flags); cli();
+ if (CIRC_SPACE(info->xmit.head, info->xmit.tail, AMBA_XMIT_SIZE) != 0) {
+ info->xmit.buf[info->xmit.head] = ch;
+ info->xmit.head = (info->xmit.head + 1) & (AMBA_XMIT_SIZE - 1);
+ }
+ restore_flags(flags);
+}
+
+static void ambauart_flush_chars(struct tty_struct *tty)
+{
+ struct amba_info *info = tty->driver_data;


+ unsigned long flags;
+

+ if (info->xmit.head == info->xmit.tail
+ || tty->stopped
+ || tty->hw_stopped
+ || !info->xmit.buf)
+ return;
+
+ save_flags(flags); cli();
+ ambauart_enable_tx_interrupt(info);
+ restore_flags(flags);
+}
+
+static int ambauart_write(struct tty_struct *tty, int from_user,
+ const u_char * buf, int count)
+{
+ struct amba_info *info = tty->driver_data;
+ unsigned long flags;
+ int c, ret = 0;
+
+ if (!tty || !info->xmit.buf || !tmp_buf)
+ return 0;
+
+ save_flags(flags);
+ if (from_user) {
+ down(&tmp_buf_sem);
+ while (1) {
+ int c1;
+ c = CIRC_SPACE_TO_END(info->xmit.head,
+ info->xmit.tail,
+ AMBA_XMIT_SIZE);
+ if (count < c)
+ c = count;
+ if (c <= 0)
+ break;
+
+ c -= copy_from_user(tmp_buf, buf, c);
+ if (!c) {
+ if (!ret)
+ ret = -EFAULT;
+ break;
+ }
+ cli();
+ c1 = CIRC_SPACE_TO_END(info->xmit.head,
+ info->xmit.tail,
+ AMBA_XMIT_SIZE);
+ if (c1 < c)
+ c = c1;
+ memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c);
+ info->xmit.head = (info->xmit.head + c) &
+ (AMBA_XMIT_SIZE - 1);
+ restore_flags(flags);
+ buf += c;
+ count -= c;
+ ret += c;
+ }
+ up(&tmp_buf_sem);
+ } else {
+ cli();
+ while (1) {
+ c = CIRC_SPACE_TO_END(info->xmit.head,
+ info->xmit.tail,
+ AMBA_XMIT_SIZE);
+ if (count < c)
+ c = count;
+ if (c <= 0)
+ break;
+ memcpy(info->xmit.buf + info->xmit.head, buf, c);
+ info->xmit.head = (info->xmit.head + c) &
+ (AMBA_XMIT_SIZE - 1);
+ buf += c;
+ count -= c;
+ ret += c;
+ }
+ restore_flags(flags);
+ }
+ if (info->xmit.head != info->xmit.tail
+ && !tty->stopped
+ && !tty->hw_stopped)
+ ambauart_enable_tx_interrupt(info);
+ return ret;
+}
+
+static int ambauart_write_room(struct tty_struct *tty)
+{
+ struct amba_info *info = tty->driver_data;
+
+ return CIRC_SPACE(info->xmit.head, info->xmit.tail, AMBA_XMIT_SIZE);
+}
+
+static int ambauart_chars_in_buffer(struct tty_struct *tty)
+{
+ struct amba_info *info = tty->driver_data;
+
+ return CIRC_CNT(info->xmit.head, info->xmit.tail, AMBA_XMIT_SIZE);
+}
+
+static void ambauart_flush_buffer(struct tty_struct *tty)
+{
+ struct amba_info *info = tty->driver_data;


+ unsigned long flags;
+

+#if DEBUG
+ printk("ambauart_flush_buffer(%d) called\n",
+ MINOR(tty->device) - tty->driver.minor_start);
+#endif
+ save_flags(flags); cli();
+ info->xmit.head = info->xmit.tail = 0;
+ restore_flags(flags);
+ wake_up_interruptible(&tty->write_wait);
+ if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+ tty->ldisc.write_wakeup)
+ (tty->ldisc.write_wakeup)(tty);
+}
+
+/*
+ * This function is used to send a high-priority XON/XOFF character to
+ * the device
+ */
+static void ambauart_send_xchar(struct tty_struct *tty, char ch)
+{
+ struct amba_info *info = tty->driver_data;
+
+ info->x_char = ch;
+ if (ch)
+ ambauart_enable_tx_interrupt(info);
+}
+
+static void ambauart_throttle(struct tty_struct *tty)
+{
+ struct amba_info *info = tty->driver_data;


+ unsigned long flags;
+

+ if (I_IXOFF(tty))
+ ambauart_send_xchar(tty, STOP_CHAR(tty));
+
+ if (tty->termios->c_cflag & CRTSCTS) {
+ save_flags(flags); cli();
+ info->mctrl &= ~TIOCM_RTS;
+ info->port->set_mctrl(info->port, info->mctrl);
+ restore_flags(flags);
+ }
+}
+
+static void ambauart_unthrottle(struct tty_struct *tty)
+{
+ struct amba_info *info = (struct amba_info *) tty->driver_data;


+ unsigned long flags;
+

+ if (I_IXOFF(tty)) {
+ if (info->x_char)
+ info->x_char = 0;
+ else
+ ambauart_send_xchar(tty, START_CHAR(tty));
+ }
+
+ if (tty->termios->c_cflag & CRTSCTS) {
+ save_flags(flags); cli();
+ info->mctrl |= TIOCM_RTS;
+ info->port->set_mctrl(info->port, info->mctrl);
+ restore_flags(flags);
+ }
+}
+
+static int get_serial_info(struct amba_info *info, struct serial_struct *retinfo)
+{
+ struct amba_state *state = info->state;
+ struct amba_port *port = info->port;
+ struct serial_struct tmp;
+
+ memset(&tmp, 0, sizeof(tmp));
+ tmp.type = 0;
+ tmp.line = state->line;
+ tmp.port = port->uart_base;
+ if (HIGH_BITS_OFFSET)
+ tmp.port_high = port->uart_base >> HIGH_BITS_OFFSET;
+ tmp.irq = port->irq;
+ tmp.flags = 0;
+ tmp.xmit_fifo_size = port->fifosize;
+ tmp.baud_base = port->uartclk / 16;
+ tmp.close_delay = state->close_delay;
+ tmp.closing_wait = state->closing_wait;
+ tmp.custom_divisor = state->custom_divisor;
+
+ if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
+ return -EFAULT;


+ return 0;
+}
+

+static int set_serial_info(struct amba_info *info,
+ struct serial_struct *newinfo)
+{
+ struct serial_struct new_serial;
+ struct amba_state *state, old_state;
+ struct amba_port *port;
+ unsigned long new_port;
+ unsigned int i, change_irq, change_port;


+ int retval = 0;

+
+ if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
+ return -EFAULT;
+
+ state = info->state;
+ old_state = *state;
+ port = info->port;
+
+ new_port = new_serial.port;
+ if (HIGH_BITS_OFFSET)
+ new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET;
+
+ change_irq = new_serial.irq != port->irq;
+ change_port = new_port != port->uart_base;
+
+ if (!capable(CAP_SYS_ADMIN)) {
+ if (change_irq || change_port ||
+ (new_serial.baud_base != port->uartclk / 16) ||
+ (new_serial.close_delay != state->close_delay) ||
+ (new_serial.xmit_fifo_size != port->fifosize) ||
+ ((new_serial.flags & ~ASYNC_USR_MASK) !=
+ (state->flags & ~ASYNC_USR_MASK)))
+ return -EPERM;
+ state->flags = ((state->flags & ~ASYNC_USR_MASK) |
+ (new_serial.flags & ASYNC_USR_MASK));
+ info->flags = ((info->flags & ~ASYNC_USR_MASK) |
+ (new_serial.flags & ASYNC_USR_MASK));
+ state->custom_divisor = new_serial.custom_divisor;
+ goto check_and_exit;
+ }
+
+ if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) ||
+ (new_serial.baud_base < 9600))
+ return -EINVAL;
+
+ if (new_serial.type && change_port) {
+ for (i = 0; i < SERIAL_AMBA_NR; i++)
+ if ((port != amba_ports + i) &&
+ amba_ports[i].uart_base != new_port)
+ return -EADDRINUSE;
+ }
+
+ if ((change_port || change_irq) && (state->count > 1))
+ return -EBUSY;
+
+ /*
+ * OK, past this point, all the error checking has been done.
+ * At this point, we start making changes.....
+ */
+ port->uartclk = new_serial.baud_base * 16;
+ state->flags = ((state->flags & ~ASYNC_FLAGS) |
+ (new_serial.flags & ASYNC_FLAGS));
+ info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) |
+ (info->flags & ASYNC_INTERNAL_FLAGS));
+ state->custom_divisor = new_serial.custom_divisor;
+ state->close_delay = new_serial.close_delay * HZ / 100;
+ state->closing_wait = new_serial.closing_wait * HZ / 100;
+ info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+ port->fifosize = new_serial.xmit_fifo_size;
+
+ if (change_port || change_irq) {
+ /*
+ * We need to shutdown the serial port at the old
+ * port/irq combination.
+ */
+ ambauart_shutdown(info);
+ port->irq = new_serial.irq;
+ port->uart_base = new_port;
+ }
+
+check_and_exit:
+ if (!port->uart_base)
+ return 0;
+ if (info->flags & ASYNC_INITIALIZED) {
+ if ((old_state.flags & ASYNC_SPD_MASK) !=
+ (state->flags & ASYNC_SPD_MASK) ||
+ (old_state.custom_divisor != state->custom_divisor)) {
+ if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+ info->tty->alt_speed = 57600;
+ if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+ info->tty->alt_speed = 115200;
+ if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+ info->tty->alt_speed = 230400;
+ if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+ info->tty->alt_speed = 460800;
+ ambauart_change_speed(info, NULL);
+ }
+ } else
+ retval = ambauart_startup(info);
+ return retval;
+}
+
+
+/*
+ * get_lsr_info - get line status register info
+ */
+static int get_lsr_info(struct amba_info *info, unsigned int *value)
+{
+ unsigned int result, status;


+ unsigned long flags;
+

+ save_flags(flags); cli();
+ status = UART_GET_FR(info->port);
+ restore_flags(flags);
+ result = status & AMBA_UARTFR_BUSY ? TIOCSER_TEMT : 0;
+
+ /*
+ * If we're about to load something into the transmit
+ * register, we'll pretend the transmitter isn't empty to
+ * avoid a race condition (depending on when the transmit
+ * interrupt happens).
+ */
+ if (info->x_char ||
+ ((CIRC_CNT(info->xmit.head, info->xmit.tail,
+ AMBA_XMIT_SIZE) > 0) &&
+ !info->tty->stopped && !info->tty->hw_stopped))
+ result &= TIOCSER_TEMT;
+
+ return put_user(result, value);
+}
+
+static int get_modem_info(struct amba_info *info, unsigned int *value)
+{
+ unsigned int result = info->mctrl;
+ unsigned int status;
+
+ status = UART_GET_FR(info->port);
+ if (status & AMBA_UARTFR_DCD)
+ result |= TIOCM_CAR;
+ if (status & AMBA_UARTFR_DSR)
+ result |= TIOCM_DSR;
+ if (status & AMBA_UARTFR_CTS)
+ result |= TIOCM_CTS;
+
+ return put_user(result, value);
+}
+
+static int set_modem_info(struct amba_info *info, unsigned int cmd,
+ unsigned int *value)
+{
+ unsigned int arg, old;


+ unsigned long flags;
+

+ if (get_user(arg, value))
+ return -EFAULT;
+
+ old = info->mctrl;
+ switch (cmd) {
+ case TIOCMBIS:
+ info->mctrl |= arg;
+ break;
+
+ case TIOCMBIC:
+ info->mctrl &= ~arg;
+ break;
+
+ case TIOCMSET:
+ info->mctrl = arg;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ save_flags(flags); cli();
+ if (old != info->mctrl)
+ info->port->set_mctrl(info->port, info->mctrl);
+ restore_flags(flags);


+ return 0;
+}
+

+static void ambauart_break_ctl(struct tty_struct *tty, int break_state)
+{
+ struct amba_info *info = tty->driver_data;
+ unsigned long flags;
+ unsigned int lcr_h;
+
+ save_flags(flags); cli();
+ lcr_h = UART_GET_LCRH(info->port);
+ if (break_state == -1)
+ lcr_h |= AMBA_UARTLCR_H_BRK;
+ else
+ lcr_h &= ~AMBA_UARTLCR_H_BRK;
+ UART_PUT_LCRH(info->port, lcr_h);
+ restore_flags(flags);
+}
+
+static int ambauart_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct amba_info *info = tty->driver_data;
+ struct amba_icount cprev, cnow;
+ struct serial_icounter_struct icount;


+ unsigned long flags;
+

+ if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+ (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
+ (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
+ if (tty->flags & (1 << TTY_IO_ERROR))
+ return -EIO;
+ }
+
+ switch (cmd) {
+ case TIOCMGET:
+ return get_modem_info(info, (unsigned int *)arg);
+ case TIOCMBIS:
+ case TIOCMBIC:
+ case TIOCMSET:
+ return set_modem_info(info, cmd, (unsigned int *)arg);
+ case TIOCGSERIAL:
+ return get_serial_info(info,
+ (struct serial_struct *)arg);
+ case TIOCSSERIAL:
+ return set_serial_info(info,
+ (struct serial_struct *)arg);
+ case TIOCSERGETLSR: /* Get line status register */
+ return get_lsr_info(info, (unsigned int *)arg);


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 049'
echo 'File patch-2.4.0-test9 is continued in part 050'
echo "050" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part050

#!/bin/sh -x
# this is part 050 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 050; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ /*
+ * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
+ * - mask passed in arg for lines of interest
+ * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
+ * Caller should use TIOCGICOUNT to see which one it was
+ */
+ case TIOCMIWAIT:
+ save_flags(flags); cli();
+ /* note the counters on entry */
+ cprev = info->state->icount;
+ /* Force modem status interrupts on */
+ UART_PUT_CR(info->port, UART_GET_CR(info->port) | AMBA_UARTCR_MSIE);
+ restore_flags(flags);
+ while (1) {
+ interruptible_sleep_on(&info->delta_msr_wait);
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+ save_flags(flags); cli();
+ cnow = info->state->icount; /* atomic copy */
+ restore_flags(flags);
+ if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
+ cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
+ return -EIO; /* no change => error */
+ if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+ ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+ ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
+ ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
+ return 0;
+ }
+ cprev = cnow;
+ }
+ /* NOTREACHED */
+
+ /*
+ * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+ * Return: write counters to the user passed counter struct
+ * NB: both 1->0 and 0->1 transitions are counted except for
+ * RI where only 0->1 is counted.
+ */
+ case TIOCGICOUNT:
+ save_flags(flags); cli();
+ cnow = info->state->icount;
+ restore_flags(flags);
+ icount.cts = cnow.cts;
+ icount.dsr = cnow.dsr;
+ icount.rng = cnow.rng;
+ icount.dcd = cnow.dcd;
+ icount.rx = cnow.rx;
+ icount.tx = cnow.tx;
+ icount.frame = cnow.frame;
+ icount.overrun = cnow.overrun;
+ icount.parity = cnow.parity;
+ icount.brk = cnow.brk;
+ icount.buf_overrun = cnow.buf_overrun;
+
+ return copy_to_user((void *)arg, &icount, sizeof(icount))
+ ? -EFAULT : 0;
+
+ default:
+ return -ENOIOCTLCMD;
+ }


+ return 0;
+}
+

+static void ambauart_set_termios(struct tty_struct *tty, struct termios *old_termios)
+{


+ struct amba_info *info = tty->driver_data;
+ unsigned long flags;

+ unsigned int cflag = tty->termios->c_cflag;
+
+ if ((cflag ^ old_termios->c_cflag) == 0 &&
+ RELEVENT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0)
+ return;
+
+ ambauart_change_speed(info, old_termios);
+
+ /* Handle transition to B0 status */
+ if ((old_termios->c_cflag & CBAUD) &&
+ !(cflag & CBAUD)) {
+ save_flags(flags); cli();
+ info->mctrl &= ~(TIOCM_RTS | TIOCM_DTR);


+ info->port->set_mctrl(info->port, info->mctrl);
+ restore_flags(flags);
+ }
+

+ /* Handle transition away from B0 status */
+ if (!(old_termios->c_cflag & CBAUD) &&
+ (cflag & CBAUD)) {
+ save_flags(flags); cli();
+ info->mctrl |= TIOCM_DTR;
+ if (!(cflag & CRTSCTS) ||
+ !test_bit(TTY_THROTTLED, &tty->flags))


+ info->mctrl |= TIOCM_RTS;
+ info->port->set_mctrl(info->port, info->mctrl);
+ restore_flags(flags);
+ }
+

+ /* Handle turning off CRTSCTS */
+ if ((old_termios->c_cflag & CRTSCTS) &&
+ !(cflag & CRTSCTS)) {
+ tty->hw_stopped = 0;
+ ambauart_start(tty);
+ }
+
+#if 0
+ /*
+ * No need to wake up processes in open wait, since they
+ * sample the CLOCAL flag once, and don't recheck it.
+ * XXX It's not clear whether the current behavior is correct
+ * or not. Hence, this may change.....
+ */
+ if (!(old_termios->c_cflag & CLOCAL) &&
+ (tty->termios->c_cflag & CLOCAL))
+ wake_up_interruptible(&info->open_wait);
+#endif
+}
+
+static void ambauart_close(struct tty_struct *tty, struct file *filp)


+{
+ struct amba_info *info = tty->driver_data;

+ struct amba_state *state;


+ unsigned long flags;
+

+ if (!info)
+ return;


+
+ state = info->state;
+

+#if DEBUG
+ printk("ambauart_close() called\n");
+#endif


+
+ save_flags(flags); cli();
+

+ if (tty_hung_up_p(filp)) {
+ MOD_DEC_USE_COUNT;
+ restore_flags(flags);
+ return;
+ }
+
+ if ((tty->count == 1) && (state->count != 1)) {
+ /*
+ * Uh, oh. tty->count is 1, which means that the tty
+ * structure will be freed. state->count should always
+ * be one in these conditions. If it's greater than
+ * one, we've got real problems, since it means the
+ * serial port won't be shutdown.
+ */
+ printk("ambauart_close: bad serial port count; tty->count is 1, "
+ "state->count is %d\n", state->count);
+ state->count = 1;
+ }
+ if (--state->count < 0) {
+ printk("rs_close: bad serial port count for %s%d: %d\n",
+ tty->driver.name, info->state->line, state->count);
+ state->count = 0;
+ }
+ if (state->count) {
+ MOD_DEC_USE_COUNT;
+ restore_flags(flags);
+ return;
+ }
+ info->flags |= ASYNC_CLOSING;
+ restore_flags(flags);
+ /*
+ * Save the termios structure, since this port may have
+ * separate termios for callout and dialin.
+ */
+ if (info->flags & ASYNC_NORMAL_ACTIVE)
+ info->state->normal_termios = *tty->termios;
+ if (info->flags & ASYNC_CALLOUT_ACTIVE)
+ info->state->callout_termios = *tty->termios;
+ /*
+ * Now we wait for the transmit buffer to clear; and we notify
+ * the line discipline to only process XON/XOFF characters.
+ */
+ tty->closing = 1;
+ if (info->state->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+ tty_wait_until_sent(tty, info->state->closing_wait);
+ /*
+ * At this point, we stop accepting input. To do this, we
+ * disable the receive line status interrupts.
+ */
+ if (info->flags & ASYNC_INITIALIZED) {
+ ambauart_disable_rx_interrupt(info);
+ /*
+ * Before we drop DTR, make sure the UART transmitter
+ * has completely drained; this is especially
+ * important if there is a transmit FIFO!
+ */
+ ambauart_wait_until_sent(tty, info->timeout);
+ }
+ ambauart_shutdown(info);
+ if (tty->driver.flush_buffer)
+ tty->driver.flush_buffer(tty);
+ if (tty->ldisc.flush_buffer)
+ tty->ldisc.flush_buffer(tty);
+ tty->closing = 0;
+ info->event = 0;
+ info->tty = NULL;
+ if (info->blocked_open) {
+ if (info->state->close_delay) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(info->state->close_delay);
+ }
+ wake_up_interruptible(&info->open_wait);
+ }
+ info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
+ ASYNC_CLOSING);
+ wake_up_interruptible(&info->close_wait);
+ MOD_DEC_USE_COUNT;
+}
+


+static void ambauart_wait_until_sent(struct tty_struct *tty, int timeout)

+{
+ struct amba_info *info = (struct amba_info *) tty->driver_data;

+ unsigned long char_time, expire;


+ unsigned int status;
+

+ if (info->port->fifosize == 0)
+ return;
+
+ /*
+ * Set the check interval to be 1/5 of the estimated time to
+ * send a single character, and make it at least 1. The check
+ * interval should also be less than the timeout.
+ *
+ * Note: we have to use pretty tight timings here to satisfy
+ * the NIST-PCTS.
+ */
+ char_time = (info->timeout - HZ/50) / info->port->fifosize;
+ char_time = char_time / 5;
+ if (char_time == 0)
+ char_time = 1;
+ if (timeout && timeout < char_time)
+ char_time = timeout;
+ /*
+ * If the transmitter hasn't cleared in twice the approximate
+ * amount of time to send the entire FIFO, it probably won't
+ * ever clear. This assumes the UART isn't doing flow
+ * control, which is currently the case. Hence, if it ever
+ * takes longer than info->timeout, this is probably due to a
+ * UART bug of some kind. So, we clamp the timeout parameter at
+ * 2*info->timeout.
+ */
+ if (!timeout || timeout > 2 * info->timeout)
+ timeout = 2 * info->timeout;
+
+ expire = jiffies + timeout;
+#if DEBUG
+ printk("ambauart_wait_until_sent(%d), jiff=%lu, expire=%lu...\n",
+ MINOR(tty->device) - tty->driver.minor_start, jiffies,
+ expire);
+#endif
+ while (UART_GET_FR(info->port) & AMBA_UARTFR_BUSY) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(char_time);
+ if (signal_pending(current))
+ break;
+ if (timeout && time_after(jiffies, expire))
+ break;


+ status = UART_GET_FR(info->port);
+ }

+ set_current_state(TASK_RUNNING);
+}
+
+static void ambauart_hangup(struct tty_struct *tty)


+{
+ struct amba_info *info = tty->driver_data;

+ struct amba_state *state = info->state;
+

+ ambauart_flush_buffer(tty);
+ if (info->flags & ASYNC_CLOSING)
+ return;
+ ambauart_shutdown(info);
+ info->event = 0;
+ state->count = 0;
+ info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+ info->tty = NULL;
+ wake_up_interruptible(&info->open_wait);
+}
+
+static int block_til_ready(struct tty_struct *tty, struct file *filp,
+ struct amba_info *info)
+{
+ DECLARE_WAITQUEUE(wait, current);


+ struct amba_state *state = info->state;

+ unsigned long flags;
+ int do_clocal = 0, extra_count = 0, retval;
+
+ /*
+ * If the device is in the middle of being closed, then block
+ * until it's done, and then try again.
+ */
+ if (tty_hung_up_p(filp) ||
+ (info->flags & ASYNC_CLOSING)) {
+ if (info->flags & ASYNC_CLOSING)
+ interruptible_sleep_on(&info->close_wait);
+ return (info->flags & ASYNC_HUP_NOTIFY) ?
+ -EAGAIN : -ERESTARTSYS;
+ }
+
+ /*
+ * If this is a callout device, then just make sure the normal
+ * device isn't being used.
+ */
+ if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
+ if (info->flags & ASYNC_NORMAL_ACTIVE)
+ return -EBUSY;
+ if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+ (info->flags & ASYNC_SESSION_LOCKOUT) &&
+ (info->session != current->session))
+ return -EBUSY;
+ if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+ (info->flags & ASYNC_PGRP_LOCKOUT) &&
+ (info->pgrp != current->pgrp))
+ return -EBUSY;
+ info->flags |= ASYNC_CALLOUT_ACTIVE;


+ return 0;
+ }
+

+ /*
+ * If non-blocking mode is set, or the port is not enabled,
+ * then make the check up front and then exit.
+ */
+ if ((filp->f_flags & O_NONBLOCK) ||
+ (tty->flags & (1 << TTY_IO_ERROR))) {
+ if (info->flags & ASYNC_CALLOUT_ACTIVE)
+ return -EBUSY;
+ info->flags |= ASYNC_NORMAL_ACTIVE;


+ return 0;
+ }
+

+ if (info->flags & ASYNC_CALLOUT_ACTIVE) {
+ if (state->normal_termios.c_cflag & CLOCAL)
+ do_clocal = 1;
+ } else {
+ if (tty->termios->c_cflag & CLOCAL)
+ do_clocal = 1;
+ }
+
+ /*
+ * Block waiting for the carrier detect and the line to become
+ * free (i.e., not in use by the callout). While we are in
+ * this loop, state->count is dropped by one, so that
+ * rs_close() knows when to free things. We restore it upon
+ * exit, either normal or abnormal.
+ */
+ retval = 0;
+ add_wait_queue(&info->open_wait, &wait);
+ save_flags(flags); cli();
+ if (!tty_hung_up_p(filp)) {
+ extra_count = 1;
+ state->count--;
+ }
+ restore_flags(flags);
+ info->blocked_open++;
+ while (1) {
+ save_flags(flags); cli();
+ if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
+ (tty->termios->c_cflag & CBAUD)) {
+ info->mctrl = TIOCM_DTR | TIOCM_RTS;


+ info->port->set_mctrl(info->port, info->mctrl);
+ }

+ restore_flags(flags);
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (tty_hung_up_p(filp) ||
+ !(info->flags & ASYNC_INITIALIZED)) {
+ if (info->flags & ASYNC_HUP_NOTIFY)
+ retval = -EAGAIN;
+ else
+ retval = -ERESTARTSYS;
+ break;
+ }
+ if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
+ !(info->flags & ASYNC_CLOSING) &&
+ (do_clocal || (UART_GET_FR(info->port) & AMBA_UARTFR_DCD)))
+ break;
+ if (signal_pending(current)) {
+ retval = -ERESTARTSYS;
+ break;
+ }
+ schedule();
+ }
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&info->open_wait, &wait);
+ if (extra_count)
+ state->count++;
+ info->blocked_open--;
+ if (retval)
+ return retval;
+ info->flags |= ASYNC_NORMAL_ACTIVE;


+ return 0;
+}
+

+static struct amba_info *ambauart_get(int line)
+{
+ struct amba_info *info;
+ struct amba_state *state = amba_state + line;
+
+ state->count++;
+ if (state->info)
+ return state->info;
+ info = kmalloc(sizeof(struct amba_info), GFP_KERNEL);
+ if (info) {
+ memset(info, 0, sizeof(struct amba_info));
+ init_waitqueue_head(&info->open_wait);
+ init_waitqueue_head(&info->close_wait);
+ init_waitqueue_head(&info->delta_msr_wait);
+ info->flags = state->flags;
+ info->state = state;
+ info->port = amba_ports + line;
+ tasklet_init(&info->tlet, ambauart_tasklet_action,
+ (unsigned long)info);
+ }
+ if (state->info) {
+ kfree(info);
+ return state->info;
+ }
+ state->info = info;
+ return info;
+}
+
+static int ambauart_open(struct tty_struct *tty, struct file *filp)
+{
+ struct amba_info *info;
+ int retval, line = MINOR(tty->device) - tty->driver.minor_start;
+
+#if DEBUG
+ printk("ambauart_open(%d) called\n", line);
+#endif
+
+ // is this a line that we've got?
+ MOD_INC_USE_COUNT;
+ if (line >= SERIAL_AMBA_NR) {
+ MOD_DEC_USE_COUNT;


+ return -ENODEV;
+ }
+

+ info = ambauart_get(line);
+ if (!info)
+ return -ENOMEM;
+
+ tty->driver_data = info;
+ info->tty = tty;


+ info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+

+ /*
+ * Make sure we have the temporary buffer allocated
+ */
+ if (!tmp_buf) {
+ unsigned long page = get_zeroed_page(GFP_KERNEL);
+ if (tmp_buf)
+ free_page(page);
+ else if (!page) {
+ MOD_DEC_USE_COUNT;
+ return -ENOMEM;
+ }
+ tmp_buf = (u_char *)page;
+ }
+
+ /*
+ * If the port is in the middle of closing, bail out now.
+ */
+ if (tty_hung_up_p(filp) ||
+ (info->flags & ASYNC_CLOSING)) {
+ if (info->flags & ASYNC_CLOSING)
+ interruptible_sleep_on(&info->close_wait);
+ MOD_DEC_USE_COUNT;
+ return -EAGAIN;
+ }
+
+ /*
+ * Start up the serial port
+ */
+ retval = ambauart_startup(info);
+ if (retval) {
+ MOD_DEC_USE_COUNT;


+ return retval;
+ }
+

+ retval = block_til_ready(tty, filp, info);
+ if (retval) {
+ MOD_DEC_USE_COUNT;


+ return retval;
+ }
+

+ if ((info->state->count == 1) &&
+ (info->flags & ASYNC_SPLIT_TERMIOS)) {
+ if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+ *tty->termios = info->state->normal_termios;
+ else
+ *tty->termios = info->state->callout_termios;
+ }
+#ifdef CONFIG_SERIAL_AMBA_CONSOLE
+ if (ambauart_cons.cflag && ambauart_cons.index == line) {
+ tty->termios->c_cflag = ambauart_cons.cflag;
+ ambauart_cons.cflag = 0;
+ }
+#endif
+ ambauart_change_speed(info, NULL);
+ info->session = current->session;
+ info->pgrp = current->pgrp;


+ return 0;
+}
+

+int __init ambauart_init(void)


+{
+ int i;
+

+ ambanormal_driver.magic = TTY_DRIVER_MAGIC;
+ ambanormal_driver.driver_name = "serial_amba";
+ ambanormal_driver.name = SERIAL_AMBA_NAME;
+ ambanormal_driver.major = SERIAL_AMBA_MAJOR;
+ ambanormal_driver.minor_start = SERIAL_AMBA_MINOR;
+ ambanormal_driver.num = SERIAL_AMBA_NR;
+ ambanormal_driver.type = TTY_DRIVER_TYPE_SERIAL;
+ ambanormal_driver.subtype = SERIAL_TYPE_NORMAL;
+ ambanormal_driver.init_termios = tty_std_termios;
+ ambanormal_driver.init_termios.c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL;
+ ambanormal_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+ ambanormal_driver.refcount = &ambauart_refcount;
+ ambanormal_driver.table = ambauart_table;
+ ambanormal_driver.termios = ambauart_termios;
+ ambanormal_driver.termios_locked = ambauart_termios_locked;
+
+ ambanormal_driver.open = ambauart_open;
+ ambanormal_driver.close = ambauart_close;
+ ambanormal_driver.write = ambauart_write;
+ ambanormal_driver.put_char = ambauart_put_char;
+ ambanormal_driver.flush_chars = ambauart_flush_chars;
+ ambanormal_driver.write_room = ambauart_write_room;
+ ambanormal_driver.chars_in_buffer = ambauart_chars_in_buffer;
+ ambanormal_driver.flush_buffer = ambauart_flush_buffer;
+ ambanormal_driver.ioctl = ambauart_ioctl;
+ ambanormal_driver.throttle = ambauart_throttle;
+ ambanormal_driver.unthrottle = ambauart_unthrottle;
+ ambanormal_driver.send_xchar = ambauart_send_xchar;
+ ambanormal_driver.set_termios = ambauart_set_termios;
+ ambanormal_driver.stop = ambauart_stop;
+ ambanormal_driver.start = ambauart_start;
+ ambanormal_driver.hangup = ambauart_hangup;
+ ambanormal_driver.break_ctl = ambauart_break_ctl;
+ ambanormal_driver.wait_until_sent = ambauart_wait_until_sent;
+ ambanormal_driver.read_proc = NULL;
+
+ /*
+ * The callout device is just like the normal device except for
+ * the major number and the subtype code.
+ */
+ ambacallout_driver = ambanormal_driver;
+ ambacallout_driver.name = CALLOUT_AMBA_NAME;
+ ambacallout_driver.major = CALLOUT_AMBA_MAJOR;
+ ambacallout_driver.subtype = SERIAL_TYPE_CALLOUT;
+ ambacallout_driver.read_proc = NULL;
+ ambacallout_driver.proc_entry = NULL;
+
+ if (tty_register_driver(&ambanormal_driver))
+ panic("Couldn't register AMBA serial driver\n");
+ if (tty_register_driver(&ambacallout_driver))
+ panic("Couldn't register AMBA callout driver\n");
+


+ for (i = 0; i < SERIAL_AMBA_NR; i++) {

+ struct amba_state *state = amba_state + i;
+ state->line = i;
+ state->close_delay = 5 * HZ / 10;
+ state->closing_wait = 30 * HZ;
+ state->callout_termios = ambacallout_driver.init_termios;
+ state->normal_termios = ambanormal_driver.init_termios;
+ }
+


+ return 0;
+}
+

+__initcall(ambauart_init);
+
+#ifdef CONFIG_SERIAL_AMBA_CONSOLE
+/************** console driver *****************/
+
+/*
+ * This code is currently never used; console->read is never called.
+ * Therefore, although we have an implementation, we don't use it.
+ * FIXME: the "const char *s" should be fixed to "char *s" some day.
+ * (when the definition in include/linux/console.h is also fixed)
+ */
+#ifdef used_and_not_const_char_pointer
+static int ambauart_console_read(struct console *co, const char *s, u_int count)
+{
+ struct amba_port *port = &amba_ports[co->index];
+ unsigned int status;
+ char *w;
+ int c;
+#if DEBUG
+ printk("ambauart_console_read() called\n");
+#endif
+
+ c = 0;
+ w = s;
+ while (c < count) {
+ status = UART_GET_FR(port);
+ if (UART_RX_DATA(status)) {
+ *w++ = UART_GET_CHAR(port);
+ c++;
+ } else {
+ // nothing more to get, return


+ return c;
+ }
+ }

+ // return the count
+ return c;
+}
+#endif
+
+/*
+ * Print a string to the serial port trying not to disturb
+ * any possible real use of the port...
+ *
+ * The console_lock must be held when we get here.
+ */
+static void ambauart_console_write(struct console *co, const char *s, u_int count)
+{
+ struct amba_port *port = &amba_ports[co->index];
+ unsigned int status, old_cr;
+ int i;
+
+ /*
+ * First save the CR then disable the interrupts
+ */
+ old_cr = UART_GET_CR(port);
+ UART_PUT_CR(port, AMBA_UARTCR_UARTEN);
+
+ /*
+ * Now, do each character
+ */
+ for (i = 0; i < count; i++) {
+ do {
+ status = UART_GET_FR(port);
+ } while (!UART_TX_READY(status));
+ UART_PUT_CHAR(port, s[i]);
+ if (s[i] == '\n') {
+ do {
+ status = UART_GET_FR(port);
+ } while (!UART_TX_READY(status));
+ UART_PUT_CHAR(port, '\r');
+ }
+ }
+
+ /*
+ * Finally, wait for transmitter to become empty
+ * and restore the TCR
+ */
+ do {
+ status = UART_GET_FR(port);
+ } while (status & AMBA_UARTFR_BUSY);
+ UART_PUT_CR(port, old_cr);
+}
+
+/*
+ * Receive character from the serial port
+ */
+static int ambauart_console_wait_key(struct console *co)
+{
+ struct amba_port *port = &amba_ports[co->index];
+ unsigned int status;
+ int c;
+
+ do {
+ status = UART_GET_FR(port);
+ } while (!UART_RX_DATA(status));
+ c = UART_GET_CHAR(port);


+ return c;
+}
+

+static kdev_t ambauart_console_device(struct console *c)
+{
+ return MKDEV(SERIAL_AMBA_MAJOR, SERIAL_AMBA_MINOR + c->index);
+}
+
+static int __init ambauart_console_setup(struct console *co, char *options)
+{
+ struct amba_port *port;
+ int baud = 38400;
+ int bits = 8;
+ int parity = 'n';
+ u_int cflag = CREAD | HUPCL | CLOCAL;
+ u_int lcr_h, quot;
+
+ if (co->index >= SERIAL_AMBA_NR)
+ co->index = 0;
+
+ port = &amba_ports[co->index];
+
+ if (options) {
+ char *s = options;
+ baud = simple_strtoul(s, NULL, 10);
+ while (*s >= '0' && *s <= '9')
+ s++;
+ if (*s) parity = *s++;
+ if (*s) bits = *s - '0';
+ }
+
+ /*
+ * Now construct a cflag setting.
+ */
+ switch (baud) {
+ case 1200: cflag |= B1200; break;
+ case 2400: cflag |= B2400; break;
+ case 4800: cflag |= B4800; break;
+ default: cflag |= B9600; baud = 9600; break;
+ case 19200: cflag |= B19200; break;
+ case 38400: cflag |= B38400; break;
+ case 57600: cflag |= B57600; break;
+ case 115200: cflag |= B115200; break;
+ }
+ switch (bits) {
+ case 7: cflag |= CS7; lcr_h = AMBA_UARTLCR_H_WLEN_7; break;
+ default: cflag |= CS8; lcr_h = AMBA_UARTLCR_H_WLEN_8; break;
+ }
+ switch (parity) {
+ case 'o':
+ case 'O': cflag |= PARODD; lcr_h |= AMBA_UARTLCR_H_PEN; break;
+ case 'e':
+ case 'E': cflag |= PARENB; lcr_h |= AMBA_UARTLCR_H_PEN |
+ AMBA_UARTLCR_H_EPS; break;
+ }
+
+ co->cflag = cflag;
+
+ if (port->fifosize > 1)


+ lcr_h |= AMBA_UARTLCR_H_FEN;
+

+ quot = (port->uartclk / (16 * baud)) - 1;
+
+ UART_PUT_LCRL(port, (quot & 0xff));
+ UART_PUT_LCRM(port, (quot >> 8));
+ UART_PUT_LCRH(port, lcr_h);
+
+ /* we will enable the port as we need it */
+ UART_PUT_CR(port, 0);
+


+ return 0;
+}
+

+static struct console ambauart_cons =
+{
+ name: SERIAL_AMBA_NAME,
+ write: ambauart_console_write,
+#ifdef used_and_not_const_char_pointer
+ read: ambauart_console_read,
+#endif
+ device: ambauart_console_device,
+ wait_key: ambauart_console_wait_key,
+ unblank: NULL,
+ setup: ambauart_console_setup,
+ flags: CON_PRINTBUFFER,
+ index: -1,
+};
+
+void __init ambauart_console_init(void)
+{
+ register_console(&ambauart_cons);
+}
+
+#endif /* CONFIG_SERIAL_AMBA_CONSOLE */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/sh-sci.c linux/drivers/char/sh-sci.c
--- v2.4.0-test8/linux/drivers/char/sh-sci.c Wed Aug 9 13:59:04 2000
+++ linux/drivers/char/sh-sci.c Mon Oct 2 11:57:34 2000
@@ -90,6 +90,8 @@
X MODULE_PARM(sci_debug, "i");
X #endif
X
+#define dprintk(x...) do { if (sci_debug) printk(x); } while(0)
+
X static void put_char(struct sci_port *port, char c)
X {
X unsigned long flags;
@@ -329,6 +331,9 @@
X case 38400:
X t = BPS_38400;
X break;
+ case 57600:
+ t = BPS_57600;
+ break;
X default:
X printk(KERN_INFO "sci: unsupported baud rate: %d, using 115200 instead.\n", baud);
X case 115200:
@@ -341,6 +346,8 @@
X if(t >= 256) {
X sci_out(port, SCSMR, (sci_in(port, SCSMR) & ~3) | 1);
X t >>= 2;
+ } else {
+ sci_out(port, SCSMR, sci_in(port, SCSMR) & ~3);
X }
X sci_out(port, SCBRR, t);
X udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */
@@ -374,10 +381,9 @@
X if (cflag & CSTOPB)
X smr_val |= 0x08;
X sci_out(port, SCSMR, smr_val);
+ sci_set_baud(port, baud);
X
X port->init_pins(port, cflag);
-
- sci_set_baud(port, baud);
X sci_out(port, SCSCR, SCSCR_INIT(port));
X }
X
@@ -528,13 +534,28 @@
X if (count == 0)
X break;
X
- for (i=0; i<count; i++)
- tty->flip.char_buf_ptr[i] = sci_in(port, SCxRDR);
+ if (port->type == PORT_SCI) {
+ tty->flip.char_buf_ptr[0] = sci_in(port, SCxRDR);
+ tty->flip.flag_buf_ptr[0] = TTY_NORMAL;
+ } else {
+ for (i=0; i<count; i++) {
+ tty->flip.char_buf_ptr[i] = sci_in(port, SCxRDR);
+ status = sci_in(port, SCxSR);
+ if (status&SCxSR_FER(port)) {
+ tty->flip.flag_buf_ptr[i] = TTY_FRAME;
+ dprintk("sci: frame error\n");
+ } else if (status&SCxSR_PER(port)) {
+ tty->flip.flag_buf_ptr[i] = TTY_PARITY;
+ dprintk("sci: parity error\n");
+ } else {
+ tty->flip.flag_buf_ptr[i] = TTY_NORMAL;
+ }
+ }
+ }
+
X sci_in(port, SCxSR); /* dummy read */
X sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
X
- memset(tty->flip.flag_buf_ptr, TTY_NORMAL, count);
-
X /* Update the kernel buffer end */
X tty->flip.count += count;
X tty->flip.char_buf_ptr += count;
@@ -549,6 +570,82 @@
X tty_flip_buffer_push(tty);
X }
X
+static inline int sci_handle_errors(struct sci_port *port)
+{
+ int copied = 0;
+ unsigned short status = sci_in(port, SCxSR);
+ struct tty_struct *tty = port->gs.tty;
+
+ if (status&SCxSR_ORER(port) && tty->flip.count<TTY_FLIPBUF_SIZE) {
+ /* overrun error */
+ copied++;
+ *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
+ dprintk("sci: overrun error\n");
+ }
+
+ if (status&SCxSR_FER(port) && tty->flip.count<TTY_FLIPBUF_SIZE) {
+ if (sci_rxd_in(port) == 0) {
+ /* Notify of BREAK */
+ copied++;
+ *tty->flip.flag_buf_ptr++ = TTY_BREAK;
+ dprintk("sci: BREAK detected\n");
+ }
+ else {
+ /* frame error */
+ copied++;
+ *tty->flip.flag_buf_ptr++ = TTY_FRAME;
+ dprintk("sci: frame error\n");
+ }
+ }
+
+ if (status&SCxSR_PER(port) && tty->flip.count<TTY_FLIPBUF_SIZE) {
+ /* parity error */
+ copied++;
+ *tty->flip.flag_buf_ptr++ = TTY_PARITY;
+ dprintk("sci: parity error\n");
+ }
+
+ if (copied) {
+ tty->flip.count += copied;
+ tty_flip_buffer_push(tty);
+ }
+
+ return copied;
+}
+
+static inline int sci_handle_breaks(struct sci_port *port)
+{
+ int copied = 0;
+ unsigned short status = sci_in(port, SCxSR);
+ struct tty_struct *tty = port->gs.tty;
+
+ if (status&SCxSR_BRK(port) && tty->flip.count<TTY_FLIPBUF_SIZE) {
+ /* Notify of BREAK */
+ copied++;
+ *tty->flip.flag_buf_ptr++ = TTY_BREAK;
+ dprintk("sci: BREAK detected\n");
+ }
+
+#if defined(CONFIG_CPU_SUBTYPE_SH7750)
+ /* XXX: Handle SCIF overrun error */
+ if (port->type == PORT_SCIF && (ctrl_inw(SCLSR2) & SCIF_ORER) != 0) {
+ ctrl_outw(0, SCLSR2);
+ if(tty->flip.count<TTY_FLIPBUF_SIZE) {
+ copied++;
+ *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
+ dprintk("sci: overrun error\n");
+ }
+ }
+#endif
+
+ if (copied) {
+ tty->flip.count += copied;
+ tty_flip_buffer_push(tty);
+ }
+
+ return copied;
+}
+
X static void sci_rx_interrupt(int irq, void *ptr, struct pt_regs *regs)
X {
X struct sci_port *port = ptr;
@@ -577,13 +674,31 @@
X struct sci_port *port = ptr;
X
X /* Handle errors */
- if (sci_in(port, SCxSR) & SCxSR_ERRORS(port))
- sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
+ if (port->type == PORT_SCI) {
+ if(sci_handle_errors(port)) {
+ /* discard character in rx buffer */
+ sci_in(port, SCxSR);
+ sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
+ }
+ }
+ else
+ sci_rx_interrupt(irq, ptr, regs);
+
+ sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
X
X /* Kick the transmission */
X sci_tx_interrupt(irq, ptr, regs);
X }
X
+static void sci_br_interrupt(int irq, void *ptr, struct pt_regs *regs)
+{
+ struct sci_port *port = ptr;
+
+ /* Handle BREAKs */
+ sci_handle_breaks(port);
+ sci_out(port, SCxSR, SCxSR_BREAK_CLEAR(port));
+}
+
X static void do_softint(void *private_)
X {
X struct sci_port *port = (struct sci_port *) private_;
@@ -983,8 +1098,9 @@
X {
X struct sci_port *port;
X int i, j;
- void (*handlers[3])(int irq, void *ptr, struct pt_regs *regs) = {
- sci_er_interrupt, sci_rx_interrupt, sci_tx_interrupt
+ void (*handlers[4])(int irq, void *ptr, struct pt_regs *regs) = {
+ sci_er_interrupt, sci_rx_interrupt, sci_tx_interrupt,
+ sci_br_interrupt,
X };
X
X printk("SuperH SCI(F) driver initialized\n");
@@ -993,7 +1109,8 @@
X port = &sci_ports[j];
X printk("ttySC%d at 0x%08x is a %s\n", j, port->base,
X (port->type == PORT_SCI) ? "SCI" : "SCIF");
- for (i=0; i<3; i++) {
+ for (i=0; i<4; i++) {
+ if (!port->irqs[i]) continue;
X if (request_irq(port->irqs[i], handlers[i], SA_INTERRUPT,
X "sci", port)) {
X printk(KERN_ERR "sci: Cannot allocate irq.\n");
@@ -1001,7 +1118,6 @@
X }
X }
X }
- /* XXX: How about BRI interrupt?? */
X
X sci_init_drivers();
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/sh-sci.h linux/drivers/char/sh-sci.h
--- v2.4.0-test8/linux/drivers/char/sh-sci.h Wed Aug 9 13:59:04 2000
+++ linux/drivers/char/sh-sci.h Mon Oct 2 11:57:34 2000
@@ -20,11 +20,11 @@
X #define SCIx_RXI_IRQ 1
X #define SCIx_TXI_IRQ 2
X
-/* ERI, RXI, TXI, */
-#define SCI_IRQS { 23, 24, 25 }
-#define SH3_SCIF_IRQS { 56, 57, 59 }
-#define SH3_IRDA_IRQS { 52, 53, 55 }
-#define SH4_SCIF_IRQS { 40, 41, 43 }
+/* ERI, RXI, TXI, BRI */
+#define SCI_IRQS { 23, 24, 25, 0 }
+#define SH3_SCIF_IRQS { 56, 57, 59, 58 }
+#define SH3_IRDA_IRQS { 52, 53, 55, 54 }
+#define SH4_SCIF_IRQS { 40, 41, 43, 42 }
X
X #if defined(CONFIG_CPU_SUBTYPE_SH7708)
X # define SCI_NPORTS 1
@@ -54,6 +54,7 @@
X # define SCSPTR1 0xffe0001c /* 8 bit SCI */
X # define SCSPTR2 0xFFE80020 /* 16 bit SCIF */
X # define SCLSR2 0xFFE80024 /* 16 bit SCIF */
+# define SCIF_ORER 0x0001 /* overrun error bit */
X # define SCSCR_INIT(port) (((port)->type == PORT_SCI) ? \
X 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ : \
X 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ )
@@ -102,25 +103,40 @@
X # define SCxSR_ERRORS(port) SCI_ERRORS
X # define SCxSR_RDxF(port) SCI_RDRF
X # define SCxSR_TDxE(port) SCI_TDRE
+# define SCxSR_ORER(port) SCI_ORER
+# define SCxSR_FER(port) SCI_FER
+# define SCxSR_PER(port) SCI_PER
+# define SCxSR_BRK(port) 0x00
X # define SCxSR_RDxF_CLEAR(port) 0xbc
X # define SCxSR_ERROR_CLEAR(port) 0xc4
X # define SCxSR_TDxE_CLEAR(port) 0x78
+# define SCxSR_BREAK_CLEAR(port) 0xc4
X #elif defined(SCIF_ONLY)
X # define SCxSR_TEND(port) SCIF_TEND
X # define SCxSR_ERRORS(port) SCIF_ERRORS
X # define SCxSR_RDxF(port) SCIF_RDF
X # define SCxSR_TDxE(port) SCIF_TDFE
+# define SCxSR_ORER(port) 0x0000
+# define SCxSR_FER(port) SCIF_FER
+# define SCxSR_PER(port) SCIF_PER
+# define SCxSR_BRK(port) SCIF_BRK
X # define SCxSR_RDxF_CLEAR(port) 0x00fc
-# define SCxSR_ERROR_CLEAR(port) 0x0063
+# define SCxSR_ERROR_CLEAR(port) 0x0073
X # define SCxSR_TDxE_CLEAR(port) 0x00df
+# define SCxSR_BREAK_CLEAR(port) 0x00e3
X #else
X # define SCxSR_TEND(port) (((port)->type == PORT_SCI) ? SCI_TEND : SCIF_TEND)
X # define SCxSR_ERRORS(port) (((port)->type == PORT_SCI) ? SCI_ERRORS : SCIF_ERRORS)
X # define SCxSR_RDxF(port) (((port)->type == PORT_SCI) ? SCI_RDRF : SCIF_RDF)
X # define SCxSR_TDxE(port) (((port)->type == PORT_SCI) ? SCI_TDRE : SCIF_TDFE)
+# define SCxSR_ORER(port) (((port)->type == PORT_SCI) ? SCI_ORER : 0x0000)
+# define SCxSR_FER(port) (((port)->type == PORT_SCI) ? SCI_FER : SCIF_FER)
+# define SCxSR_PER(port) (((port)->type == PORT_SCI) ? SCI_PER : SCIF_PER)
+# define SCxSR_BRK(port) (((port)->type == PORT_SCI) ? 0x00 : SCIF_BRK)
X # define SCxSR_RDxF_CLEAR(port) (((port)->type == PORT_SCI) ? 0xbc : 0x00fc)
-# define SCxSR_ERROR_CLEAR(port) (((port)->type == PORT_SCI) ? 0xc4 : 0x0063)
+# define SCxSR_ERROR_CLEAR(port) (((port)->type == PORT_SCI) ? 0xc4 : 0x0073)
X # define SCxSR_TDxE_CLEAR(port) (((port)->type == PORT_SCI) ? 0x78 : 0x00df)
+# define SCxSR_BREAK_CLEAR(port) (((port)->type == PORT_SCI) ? 0xc4 : 0x00e3)
X #endif
X
X /* SCFCR */
@@ -169,7 +185,7 @@
X struct gs_port gs;
X int type;
X unsigned int base;
- unsigned char irqs[3]; /* ERI, RXI, TXI */
+ unsigned char irqs[4]; /* ERI, RXI, TXI, BRI */
X void (*init_pins)(struct sci_port* port, unsigned int cflag);
X unsigned int old_cflag;
X struct async_icount icount;
@@ -248,6 +264,34 @@
X #define sci_in(port, reg) sci_##reg##_in(port)
X #define sci_out(port, reg, value) sci_##reg##_out(port, value)
X
+#if defined(CONFIG_CPU_SUBTYPE_SH7708)
+static inline int sci_rxd_in(struct sci_port *port)
+{
+ if (port->base == 0xfffffe80)
+ return ctrl_inb(SCSPTR)&0x01 ? 1 : 0; /* SCI */
+ return 1;
+}
+#elif defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709)
+static inline int sci_rxd_in(struct sci_port *port)
+{
+ if (port->base == 0xfffffe80)
+ return ctrl_inb(SCPDR)&0x01 ? 1 : 0; /* SCI */
+ if (port->base == 0xa4000150)
+ return ctrl_inb(SCPDR)&0x10 ? 1 : 0; /* SCIF */
+ if (port->base == 0xa4000140)
+ return ctrl_inb(SCPDR)&0x04 ? 1 : 0; /* IRDA */
+ return 1;
+}
+#elif defined(CONFIG_CPU_SUBTYPE_SH7750)
+static inline int sci_rxd_in(struct sci_port *port)
+{
+ if (port->base == 0xffe00000)
+ return ctrl_inb(SCSPTR1)&0x01 ? 1 : 0; /* SCI */
+ if (port->base == 0xffe80000)
+ return ctrl_inw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */


+ return 1;
+}
+#endif

X
X /*
X * Values for the BitRate Register (SCBRR)
@@ -289,5 +333,6 @@
X #define BPS_9600 SCBRR_VALUE(9600)
X #define BPS_19200 SCBRR_VALUE(19200)
X #define BPS_38400 SCBRR_VALUE(38400)
+#define BPS_57600 SCBRR_VALUE(57600)
X #define BPS_115200 SCBRR_VALUE(115200)
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/softdog.c linux/drivers/char/softdog.c
--- v2.4.0-test8/linux/drivers/char/softdog.c Wed Jul 12 21:58:42 2000
+++ linux/drivers/char/softdog.c Sun Oct 1 19:45:29 2000
@@ -53,7 +53,11 @@
X * Our timer
X */
X
-struct timer_list watchdog_ticktock;
+static void watchdog_fire(unsigned long);
+
+static struct timer_list watchdog_ticktock = {
+ function: watchdog_fire,
+};
X static int timer_alive = 0;
X
X
@@ -164,23 +168,24 @@
X &softdog_fops
X };
X
-void __init watchdog_init(void)
+static int __init watchdog_init(void)
X {
- misc_register(&softdog_miscdev);
- init_timer(&watchdog_ticktock);
- watchdog_ticktock.function=watchdog_fire;
+ int ret;
+
+ ret = misc_register(&softdog_miscdev);
+


+ if (ret)
+ return ret;
+

X printk("Software Watchdog Timer: 0.05, timer margin: %d sec\n", soft_margin);


-}
X
-#ifdef MODULE
-int init_module(void)
-{

- watchdog_init();


X return 0;
-}
+}
X
-void cleanup_module(void)

+static void __exit watchdog_exit(void)
X {
X misc_deregister(&softdog_miscdev);
X }
-#endif
+
+module_init(watchdog_init);
+module_exit(watchdog_exit);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/toshiba.c linux/drivers/char/toshiba.c
--- v2.4.0-test8/linux/drivers/char/toshiba.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/toshiba.c Wed Sep 27 13:53:56 2000
@@ -0,0 +1,522 @@
+/* toshiba.c -- Linux driver for accessing the SMM on Toshiba laptops
+ *
+ * Copyright (c) 1996-2000 Jonathan A. Buzzard (jona...@buzzard.org.uk)
+ *
+ * Valuable assistance and patches from:
+ * Tom May <t...@you-bastards.com>
+ * Rob Napier <rna...@employees.org>
+ *
+ * Fn status port numbers for machine ID's courtesy of
+ * 0xfc08: Garth Berry <ga...@itsbruce.net>
+ * 0xfc11: Spencer Olson <sol...@novell.com>
+ * 0xfc13: Claudius Frankewitz <kr...@gmx.de>
+ * 0xfc15: Tom May <t...@you-bastards.com>
+ * 0xfc17: Dave Konrad <kon...@xenia.it>
+ * 0xfc1a: George Betzos <bet...@engr.colostate.edu>
+ * 0xfc1d: Arthur Liu <ar...@slap.mine.nu>
+ *
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ *
+ * This code is covered by the GNU GPL and you are free to make any
+ * changes you wish to it under the terms of the license. However the
+ * code has the potential to render your computer and/or someone else's
+ * unusable. Please proceed with care when modifying the code.
+ *
+ * Note: Unfortunately the laptop hardware can close the System Configuration
+ * Interface on it's own accord. It is therefore necessary for *all*
+ * programs using this driver to be aware that *any* SCI call can fail at
+ * *any* time. It is up to any program to be aware of this eventuality
+ * and take appropriate steps.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * The information used to write this driver has been obtained by reverse
+ * engineering the software supplied by Toshiba for their portable computers in
+ * strict accordance with the European Council Directive 92/250/EEC on the legal
+ * protection of computer programs, and it's implementation into English Law by
+ * the Copyright (Computer Programs) Regulations 1992 (S.I. 1992 No.3233).


+ *
+ */
+

+#define TOSH_VERSION "1.7 22/6/2000"
+#define TOSH_DEBUG 0
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/miscdevice.h>
+#include <linux/ioport.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <linux/init.h>
+#include <linux/stat.h>
+#include <linux/proc_fs.h>
+
+#include <linux/toshiba.h>
+
+#define TOSH_MINOR_DEV 181
+
+static int tosh_id = 0x0000;
+static int tosh_bios = 0x0000;
+static int tosh_date = 0x0000;
+static int tosh_sci = 0x0000;
+static int tosh_fan = 0;
+
+static int tosh_fn = 0;
+
+MODULE_PARM(tosh_fn, "i");
+
+
+static int tosh_get_info(char *, char **, off_t, int);
+static int tosh_ioctl(struct inode *, struct file *, unsigned int,
+ unsigned long);
+
+
+static struct file_operations tosh_fops = {
+ owner: THIS_MODULE,
+ ioctl: tosh_ioctl,
+};
+
+static struct miscdevice tosh_device = {
+ TOSH_MINOR_DEV,
+ "toshiba",
+ &tosh_fops
+};
+
+/*
+ * Read the Fn key status
+ */
+static int tosh_fn_status(void)
+{
+ unsigned char scan;


+ unsigned long flags;
+

+ if (tosh_fn!=0) {
+ scan = inb(tosh_fn);
+ } else {
+ save_flags(flags);
+ cli();
+ outb(0x8e, 0xe4);
+ scan = inb(0xe5);
+ restore_flags(flags);
+ }
+
+ return (int) scan;
+}
+
+
+/*
+ * At some point we need to emulate setting the HDD auto off times for
+ * the new laptops. We can do this by calling the ide_ioctl on /dev/hda.
+ * The values we need for the various times are
+ *
+ * Disabled 0x00
+ * 1 minute 0x0c
+ * 3 minutes 0x24
+ * 5 minutes 0x3c
+ * 10 minutes 0x78
+ * 15 minutes 0xb4
+ * 20 minutes 0xf0
+ * 30 minutes 0xf1
+ *
+ */
+/*static int tosh_emulate_hdd(SMMRegisters *regs)
+{
+ return 0;
+}*/
+
+
+/*
+ * For the Portage 610CT and the Tecra 700CS/700CDT emulate the HCI fan function
+ */
+static int tosh_emulate_fan(SMMRegisters *regs)
+{
+ unsigned long eax,ecx,flags;
+ unsigned char al;
+
+ eax = regs->eax & 0xff00;
+ ecx = regs->ecx & 0xffff;
+
+ /* Portage 610CT */
+
+ if (tosh_id==0xfccb) {
+ if (eax==0xfe00) {
+ /* fan status */
+ save_flags(flags);
+ cli();
+ outb(0xbe, 0xe4);
+ al = inb(0xe5);
+ restore_flags(flags);
+ regs->eax = 0x00;
+ regs->ecx = (unsigned int) (al & 0x01);
+ }
+ if ((eax==0xff00) && (ecx==0x0000)) {
+ /* fan off */
+ save_flags(flags);
+ cli();
+ outb(0xbe, 0xe4);
+ al = inb(0xe5);
+ outb(0xbe, 0xe4);
+ outb (al | 0x01, 0xe5);
+ restore_flags(flags);
+ regs->eax = 0x00;
+ regs->ecx = 0x00;
+ }
+ if ((eax==0xff00) && (ecx==0x0001)) {
+ /* fan on */
+ save_flags(flags);
+ cli();
+ outb(0xbe, 0xe4);
+ al = inb(0xe5);
+ outb(0xbe, 0xe4);
+ outb(al & 0xfe, 0xe5);
+ restore_flags(flags);
+ regs->eax = 0x00;
+ regs->ecx = 0x01;
+ }
+ }
+
+ /* Tecra 700CS/CDT */
+
+ if (tosh_id==0xfccc) {
+ if (eax==0xfe00) {
+ /* fan status */
+ save_flags(flags);
+ cli();
+ outb(0xe0, 0xe4);
+ al = inb(0xe5);
+ restore_flags(flags);
+ regs->eax = 0x00;
+ regs->ecx = al & 0x01;
+ }
+ if ((eax==0xff00) && (ecx==0x0000)) {
+ /* fan off */
+ save_flags(flags);
+ cli();
+ outb(0xe0, 0xe4);
+ al = inb(0xe5);
+ outw(0xe0 | ((al & 0xfe) << 8), 0xe4);
+ restore_flags(flags);
+ regs->eax = 0x00;
+ regs->ecx = 0x00;
+ }
+ if ((eax==0xff00) && (ecx==0x0001)) {
+ /* fan on */
+ save_flags(flags);
+ cli();
+ outb(0xe0, 0xe4);
+ al = inb(0xe5);
+ outw(0xe0 | ((al | 0x01) << 8), 0xe4);
+ restore_flags(flags);
+ regs->eax = 0x00;
+ regs->ecx = 0x01;
+ }
+ }
+


+ return 0;
+}
+

+
+/*
+ * Put the laptop into System Management Mode
+ */
+static int tosh_smm(SMMRegisters *regs)
+{
+ int eax;
+
+ asm ("# load the values into the registers\n\t" \
+ "pushl %%eax\n\t" \
+ "movl 0(%%eax),%%edx\n\t" \
+ "push %%edx\n\t" \
+ "movl 4(%%eax),%%ebx\n\t" \
+ "movl 8(%%eax),%%ecx\n\t" \
+ "movl 12(%%eax),%%edx\n\t" \
+ "movl 16(%%eax),%%esi\n\t" \
+ "movl 20(%%eax),%%edi\n\t" \
+ "popl %%eax\n\t" \
+ "# call the System Management mode\n\t" \
+ "inb $0xb2,%%al\n\t"
+ "# fill out the memory with the values in the registers\n\t" \
+ "xchgl %%eax,(%%esp)\n\t"
+ "movl %%ebx,4(%%eax)\n\t" \
+ "movl %%ecx,8(%%eax)\n\t" \
+ "movl %%edx,12(%%eax)\n\t" \
+ "movl %%esi,16(%%eax)\n\t" \
+ "movl %%edi,20(%%eax)\n\t" \
+ "popl %%edx\n\t" \
+ "movl %%edx,0(%%eax)\n\t" \
+ "# setup the return value to the carry flag\n\t" \
+ "lahf\n\t" \
+ "shrl $8,%%eax\n\t" \
+ "andl $1,%%eax\n" \
+ : "=a" (eax)
+ : "a" (regs)
+ : "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
+
+ return eax;
+}
+
+
+static int tosh_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
+ unsigned long arg)
+{
+ SMMRegisters regs;
+ unsigned short ax,bx;
+ int err;
+
+ if (!arg)
+ return -EINVAL;
+
+ if(copy_from_user(&regs, (SMMRegisters *) arg, sizeof(SMMRegisters)))
+ return -EFAULT;
+
+ switch (cmd) {
+ case TOSH_SMM:
+ ax = regs.eax & 0xff00;
+ bx = regs.ebx & 0xffff;
+ /* block HCI calls to read/write memory & PCI devices */
+ if (((ax==0xff00) || (ax==0xfe00)) && (bx>0x0069))
+ return -EINVAL;
+
+ /* do we need to emulate the fan ? */
+ if (tosh_fan==1) {
+ if (((ax==0xf300) || (ax==0xf400)) && (bx==0x0004)) {
+ err = tosh_emulate_fan(&regs);
+ break;
+ }
+ }
+ err = tosh_smm(&regs);
+ break;


+ default:
+ return -EINVAL;
+ }
+

+ if(copy_to_user((SMMRegisters *) arg, &regs, sizeof(SMMRegisters)))
+ return -EFAULT;
+
+ return (err==0) ? 0:-EINVAL;
+}
+
+
+/*
+ * Print the information for /proc/toshiba
+ */
+int tosh_get_info(char *buffer, char **start, off_t fpos, int length)
+{
+ char *temp;
+ int key;
+
+ temp = buffer;
+ key = tosh_fn_status();
+
+ /* Arguments
+ 0) Linux driver version (this will change if format changes)
+ 1) Machine ID
+ 2) SCI version
+ 3) BIOS version (major, minor)
+ 4) BIOS date (in SCI date format)
+ 5) Fn Key status
+ */
+
+ temp += sprintf(temp, "1.1 0x%04x %d.%d %d.%d 0x%04x 0x%02x\n",
+ tosh_id,
+ (tosh_sci & 0xff00)>>8,
+ tosh_sci & 0xff,
+ (tosh_bios & 0xff00)>>8,
+ tosh_bios & 0xff,
+ tosh_date,
+ key);
+
+ return temp-buffer;
+}
+
+
+/*
+ * Determine which port to use for the Fn key status
+ */
+static void tosh_set_fn_port(void)
+{
+ switch (tosh_id) {
+ case 0xfc11: case 0xfc13: case 0xfc15: case 0xfc1a:
+ tosh_fn = 0x62;
+ break;
+ case 0xfc08: case 0xfc17: case 0xfc1d: case 0xfcd1:
+ case 0xfce0: case 0xfce2:
+ tosh_fn = 0x68;
+ break;
+ default:
+ tosh_fn = 0x00;
+ break;
+ }
+


+ return;
+}
+
+

+/*
+ * Get the machine identification number of the current model
+ */
+static int tosh_get_machine_id(void)
+{
+ int id;
+ SMMRegisters regs;
+ unsigned short bx,cx;
+ unsigned long address;
+
+ id = (0x100*(int) isa_readb(0xffffe))+((int) isa_readb(0xffffa));
+
+ /* do we have a SCTTable machine identication number on our hands */
+
+ if (id==0xfc2f) {
+
+ /* start by getting a pointer into the BIOS */
+
+ regs.eax = 0xc000;
+ regs.ebx = 0x0000;
+ regs.ecx = 0x0000;
+ tosh_smm(&regs);
+ bx = (unsigned short) (regs.ebx & 0xffff);
+
+ /* At this point in the Toshiba routines under MS Windows
+ the bx register holds 0xe6f5. However my code is producing
+ a different value! For the time being I will just fudge the
+ value. This has been verified on a Satellite Pro 430CDT,
+ Tecra 750CDT, Tecra 780DVD and Satellite 310CDT. */
+#if TOSH_DEBUG
+ printk("toshiba: debugging ID ebx=0x%04x\n", regs.ebx);
+#endif
+ bx = 0xe6f5;
+
+ /* now twiddle with our pointer a bit */
+
+ address = 0x000f0000+bx;
+ cx = isa_readw(address);
+ address = 0x000f0009+bx+cx;
+ cx = isa_readw(address);
+ address = 0x000f000a+cx;
+ cx = isa_readw(address);
+
+ /* now construct our machine identification number */
+
+ id = ((cx & 0xff)<<8)+((cx & 0xff00)>>8);
+ }
+
+ return id;
+}
+
+
+/*
+ * Probe for the presence of a Toshiba laptop
+ *
+ * returns and non-zero if unable to detect the presence of a Toshiba
+ * laptop, otherwise zero and determines the Machine ID, BIOS version and
+ * date, and SCI version.
+ */
+int tosh_probe(void)
+{
+ int major,minor,day,year,month,flag;
+ SMMRegisters regs;
+
+ /* call the Toshiba SCI support check routine */
+
+ regs.eax = 0xf0f0;
+ regs.ebx = 0x0000;
+ regs.ecx = 0x0000;
+ flag = tosh_smm(&regs);
+
+ /* if this is not a Toshiba laptop carry flag is set and ah=0x86 */
+
+ if ((flag==1) || ((regs.eax & 0xff00)==0x8600)) {
+ printk("toshiba: not a supported Toshiba laptop\n");


+ return -ENODEV;
+ }
+

+ /* if we get this far then we are running on a Toshiba (probably)! */
+
+ tosh_sci = regs.edx & 0xffff;
+
+ /* next get the machine ID of the current laptop */
+
+ tosh_id = tosh_get_machine_id();
+
+ /* get the BIOS version */
+
+ major = isa_readb(0xfe009)-'0';
+ minor = ((isa_readb(0xfe00b)-'0')*10)+(isa_readb(0xfe00c)-'0');
+ tosh_bios = (major*0x100)+minor;
+
+ /* get the BIOS date */
+
+ day = ((isa_readb(0xffff5)-'0')*10)+(isa_readb(0xffff6)-'0');
+ month = ((isa_readb(0xffff8)-'0')*10)+(isa_readb(0xffff9)-'0');
+ year = ((isa_readb(0xffffb)-'0')*10)+(isa_readb(0xffffc)-'0');
+ tosh_date = (((year-90) & 0x1f)<<10) | ((month & 0xf)<<6)
+ | ((day & 0x1f)<<1);
+
+
+ /* in theory we should check the ports we are going to use for the
+ fn key detection (and the fan on the Portage 610/Tecra700), and
+ then request them to stop other drivers using them. However as
+ the keyboard driver grabs 0x60-0x6f and the pic driver grabs
+ 0xa0-0xbf we can't. We just have to live dangerously and use the
+ ports anyway, oh boy! */
+
+
+ /* do we need to emulate the fan? */
+
+ if ((tosh_id==0xfccb) || (tosh_id==0xfccc))
+ tosh_fan = 1;
+


+ return 0;
+}
+

+int __init tosh_init(void)
+{
+ /* are we running on a Toshiba laptop */
+
+ if (tosh_probe()!=0)
+ return -EIO;
+
+ printk(KERN_INFO "Toshiba System Managment Mode driver v"
+ TOSH_VERSION"\n");
+
+ /* set the port to use for Fn status if not specified as a parameter */
+
+ if (tosh_fn==0x00)
+ tosh_set_fn_port();
+
+ /* register the device file */
+
+ misc_register(&tosh_device);
+
+ /* register the proc entry */
+ create_proc_info_entry("toshiba", 0, NULL, tosh_get_info);


+ return 0;
+}
+

+#ifdef MODULE
+int init_module(void)
+{
+ return tosh_init();
+}
+
+void cleanup_module(void)
+{
+ /* remove the proc entry */
+ remove_proc_entry("toshiba", NULL);
+
+ /* unregister the device file */
+ misc_deregister(&tosh_device);
+}
+#endif
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/tty_io.c linux/drivers/char/tty_io.c
--- v2.4.0-test8/linux/drivers/char/tty_io.c Sat Aug 12 19:48:04 2000
+++ linux/drivers/char/tty_io.c Mon Sep 18 15:15:22 2000
@@ -2202,6 +2202,9 @@
X #ifdef CONFIG_SERIAL_SA1100_CONSOLE
X sa1100_rs_console_init();
X #endif
+#ifdef CONFIG_SERIAL_AMBA_CONSOLE
+ ambauart_console_init();
+#endif
X }
X
X static struct tty_driver dev_tty_driver, dev_syscons_driver;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/wdt.c linux/drivers/char/wdt.c
--- v2.4.0-test8/linux/drivers/char/wdt.c Fri Jul 14 16:08:11 2000
+++ linux/drivers/char/wdt.c Sun Oct 1 19:45:29 2000
@@ -26,6 +26,7 @@
X * Alan Cox : Cleaned up copy/user stuff
X * Tim Hockin : Added insmod parameters, comment cleanup
X * Parameterized timeout
+ * Tigran Aivazian : Restructured wdt_init() to handle failures
X */
X
X #include <linux/config.h>
@@ -49,7 +50,7 @@
X #include <linux/reboot.h>
X #include <linux/init.h>
X
-static int wdt_is_open=0;
+static int wdt_is_open;
X
X /*
X * You must set these - there is no sane way to probe for this board.
@@ -458,10 +459,6 @@
X 0


X };
X
-#ifdef MODULE
-

-#define wdt_init init_module
-
X /**
X * cleanup_module:
X *
@@ -472,7 +469,7 @@
X * module in 60 seconds or reboot.
X */
X
-void cleanup_module(void)
+static void __exit wdt_exit(void)
X {
X misc_deregister(&wdt_miscdev);
X #ifdef CONFIG_WDT_501
@@ -483,8 +480,6 @@
X free_irq(irq, NULL);
X }
X
-#endif
-
X /**
X * wdt_init:
X *
@@ -493,20 +488,58 @@
X * The open() function will actually kick the board off.
X */
X
-int __init wdt_init(void)
+static int __init wdt_init(void)
X {
- printk(KERN_INFO "WDT500/501-P driver 0.07 at %X (Interrupt %d)\n", io,irq);
- if(request_irq(irq, wdt_interrupt, SA_INTERRUPT, "wdt501p", &wdt_miscdev))
- {
- printk(KERN_ERR "IRQ %d is not free.\n", irq);
- return -EIO;
+ int ret;
+
+ ret = misc_register(&wdt_miscdev);
+ if (ret) {
+ printk(KERN_ERR "wdt: can't misc_register on minor=%d\n", WATCHDOG_MINOR);
+ goto out;
X }
- misc_register(&wdt_miscdev);
-#ifdef CONFIG_WDT_501
- misc_register(&temp_miscdev);
-#endif
- request_region(io, 8, "wdt501p");
- register_reboot_notifier(&wdt_notifier);
- return 0;
+ ret = request_irq(irq, wdt_interrupt, SA_INTERRUPT, "wdt501p", NULL);
+ if(ret) {
+ printk(KERN_ERR "wdt: IRQ %d is not free.\n", irq);
+ goto outmisc;
+ }
+ if (!request_region(io, 8, "wdt501p")) {
+ printk(KERN_ERR "wdt: IO %X is not free.\n", io);
+ ret = -EBUSY;
+ goto outirq;
+ }
+ ret = register_reboot_notifier(&wdt_notifier);
+ if(ret) {
+ printk(KERN_ERR "wdt: can't register reboot notifier (err=%d)\n", ret);
+ goto outreg;
+ }
+
+#ifdef CONFIG_WDT_501
+ ret = misc_register(&temp_miscdev);
+ if (ret) {
+ printk(KERN_ERR "wdt: can't misc_register (temp) on minor=%d\n", TEMP_MINOR);
+ goto outrbt;
+ }
+#endif


+
+ ret = 0;

+ printk(KERN_INFO "WDT500/501-P driver 0.07 at %X (Interrupt %d)\n", io, irq);
+out:
+ return ret;
+
+#ifdef CONFIG_WDT_501
+outrbt:
+ unregister_reboot_notifier(&wdt_notifier);
+#endif
+
+outreg:
+ release_region(io,8);
+outirq:
+ free_irq(irq, NULL);
+outmisc:
+ misc_deregister(&wdt_miscdev);
+ goto out;
X }
+
+module_init(wdt_init);
+module_exit(wdt_exit);
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/wdt285.c linux/drivers/char/wdt285.c
--- v2.4.0-test8/linux/drivers/char/wdt285.c Sun Aug 13 09:54:15 2000
+++ linux/drivers/char/wdt285.c Mon Sep 18 15:15:22 2000
@@ -6,8 +6,7 @@
X *
X * SoftDog 0.05: A Software Watchdog Device
X *
- * (c) Copyright 1996 Alan Cox <al...@cymru.net>, All Rights Reserved.
- * http://www.cymru.net
+ * (c) Copyright 1996 Alan Cox <al...@redhat.com>, All Rights Reserved.
X *
X * This program is free software; you can redistribute it and/or
X * modify it under the terms of the GNU General Public License
@@ -32,7 +31,7 @@
X #include <asm/uaccess.h>
X #include <asm/hardware.h>
X #include <asm/mach-types.h>


-#include <asm/dec21285.h>
+#include <asm/hardware/dec21285.h>
X

X /*
X * Define this to stop the watchdog actually rebooting the machine.
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/wdt977.c linux/drivers/char/wdt977.c
--- v2.4.0-test8/linux/drivers/char/wdt977.c Wed Jul 12 21:58:42 2000
+++ linux/drivers/char/wdt977.c Mon Sep 18 15:15:22 2000
@@ -24,6 +24,7 @@
X
X #include <asm/io.h>
X #include <asm/system.h>
+#include <asm/mach-types.h>
X
X #define WATCHDOG_MINOR 130
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/char/wdt_pci.c linux/drivers/char/wdt_pci.c
--- v2.4.0-test8/linux/drivers/char/wdt_pci.c Wed Jul 12 21:58:42 2000
+++ linux/drivers/char/wdt_pci.c Sun Oct 1 19:45:29 2000
@@ -29,6 +29,7 @@
X * JP Nollmann : Added support for PCI wdt501p
X * Alan Cox : Split ISA and PCI cards into two drivers
X * Jeff Garzik : PCI cleanups
+ * Tigran Aivazian : Restructured wdtpci_init_one() to handle failures
X */
X
X #include <linux/config.h>
@@ -70,7 +71,7 @@
X #define PCI_DEVICE_ID_WDG_CSM 0x22c0
X #endif
X
-static int wdt_is_open=0;
+static int wdt_is_open;
X
X /*
X * You must set these - there is no sane way to probe for this board.
@@ -273,7 +274,7 @@
X * @ptr: offset (no seek allowed)
X *
X * Read reports the temperature in degrees Fahrenheit. The API is in
- * farenheit. It was designed by an imperial measurement luddite.
+ * fahrenheit. It was designed by an imperial measurement luddite.
X */
X
X static ssize_t wdtpci_read(struct file *file, char *buf, size_t count, loff_t *ptr)
@@ -499,6 +500,7 @@
X const struct pci_device_id *ent)
X {
X static int dev_count = 0;
+ int ret = -EIO;
X
X dev_count++;
X if (dev_count > 1) {
@@ -513,33 +515,53 @@
X "(Interrupt %d)\n", io, irq);
X
X if (pci_enable_device (dev))
- goto err_out;
+ goto out;
X
X if (request_region (io, 16, "wdt-pci") == NULL) {
X printk (KERN_ERR PFX "I/O %d is not free.\n", io);
- goto err_out;
+ goto out;
X }
X
X if (request_irq (irq, wdtpci_interrupt, SA_INTERRUPT | SA_SHIRQ,
X "wdt-pci", &wdtpci_miscdev)) {
X printk (KERN_ERR PFX "IRQ %d is not free.\n", irq);
- goto err_out_free_res;
+ goto out_reg;
X }
X
- misc_register (&wdtpci_miscdev);
+ ret = misc_register (&wdtpci_miscdev);
+ if (ret) {
+ printk (KERN_ERR PFX "can't misc_register on minor=%d\n", WATCHDOG_MINOR);
+ goto out_irq;
+ }
X
+ ret = register_reboot_notifier (&wdtpci_notifier);
+ if (ret) {
+ printk (KERN_ERR PFX "can't misc_register on minor=%d\n", WATCHDOG_MINOR);
+ goto out_misc;
+ }
X #ifdef CONFIG_WDT_501
- misc_register (&temp_miscdev);
+ ret = misc_register (&temp_miscdev);
+ if (ret) {
+ printk (KERN_ERR PFX "can't misc_register (temp) on minor=%d\n", TEMP_MINOR);
+ goto out_rbt;
+ }
X #endif
X
- register_reboot_notifier (&wdtpci_notifier);
+ ret = 0;
+out:
+ return ret;
X
- return 0;
-
-err_out_free_res:
+#ifdef CONFIG_WDT_501
+out_rbt:
+ unregister_reboot_notifier(&wdtpci_notifier);
+#endif
+out_misc:
+ misc_deregister(&wdtpci_miscdev);
+out_irq:
+ free_irq(irq, &wdtpci_miscdev);
+out_reg:
X release_region (io, 16);
-err_out:
- return -EIO;


+ goto out;
X }
X
X

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/i2c/i2c-algo-bit.c linux/drivers/i2c/i2c-algo-bit.c
--- v2.4.0-test8/linux/drivers/i2c/i2c-algo-bit.c Tue Jul 25 18:10:42 2000
+++ linux/drivers/i2c/i2c-algo-bit.c Sun Oct 1 20:35:16 2000


@@ -62,9 +62,9 @@
X

X /* module parameters:
X */
-static int i2c_debug=0;
-static int bit_test=0; /* see if the line-setting functions work */
-static int bit_scan=0; /* have a look at what's hanging 'round */
+static int i2c_debug;
+static int bit_test; /* see if the line-setting functions work */
+static int bit_scan; /* have a look at what's hanging 'round */
X
X /* --- setting states on the bus with the right timing: --------------- */
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/i2c/i2c-core.c linux/drivers/i2c/i2c-core.c
--- v2.4.0-test8/linux/drivers/i2c/i2c-core.c Tue Jul 25 18:10:42 2000
+++ linux/drivers/i2c/i2c-core.c Sun Oct 1 20:35:16 2000
@@ -105,7 +105,7 @@
X };
X #endif
X
-static int i2cproc_initialized = 0;
+static int i2cproc_initialized;
X
X #else /* undef CONFIG_PROC_FS */
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/i2o/i2o_proc.c linux/drivers/i2o/i2o_proc.c
--- v2.4.0-test8/linux/drivers/i2o/i2o_proc.c Wed Apr 12 09:38:53 2000
+++ linux/drivers/i2o/i2o_proc.c Sun Sep 17 09:45:06 2000
@@ -3319,7 +3319,7 @@
X return 0;
X }
X
-static int destroy_i2o_procfs(void)
+static int __exit destroy_i2o_procfs(void)
X {
X struct i2o_controller *pctrl = NULL;
X int i;
@@ -3342,10 +3342,6 @@


X return 0;
X }
X
-#ifdef MODULE

-#define i2o_proc_init init_module
-#endif
-
X int __init i2o_proc_init(void)
X {
X if (i2o_install_handler(&i2o_proc_handler) < 0)
@@ -3360,14 +3356,17 @@


X return 0;
X }
X
-#ifdef MODULE
-

X MODULE_AUTHOR("Deepak Saxena");
X MODULE_DESCRIPTION("I2O procfs Handler");
X
-void cleanup_module(void)
+static void __exit i2o_proc_exit(void)
X {
X destroy_i2o_procfs();
X i2o_remove_handler(&i2o_proc_handler);
X }
+
+#ifdef MODULE
+module_init(i2o_proc_init);
X #endif
+module_exit(i2o_proc_exit);
+
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/ide/icside.c linux/drivers/ide/icside.c
--- v2.4.0-test8/linux/drivers/ide/icside.c Tue Jun 20 07:52:36 2000
+++ linux/drivers/ide/icside.c Mon Sep 18 15:15:22 2000
@@ -255,43 +255,7 @@
X static int
X icside_build_dmatable(ide_drive_t *drive, int reading)
X {
- dmasg_t *ide_sg = (dmasg_t *)HWIF(drive)->dmatable_cpu;
- unsigned int count = 0;
- int i;
- struct scatterlist *sg;
-
- HWIF(drive)->sg_nents = i = ide_build_sglist(HWIF(drive), HWGROUP(drive)->rq);
-
- sg = HWIF(drive)->sg_table;
- while (i && sg_dma_len(sg)) {
- u32 cur_addr;
- u32 cur_len;
-
- cur_addr = sg_dma_address(sg);
- cur_len = sg_dma_len(sg);
-
- if (count >= (TABLE_SIZE / sizeof(dmasg_t))) {
- printk("%s: DMA table too small\n",
- drive->name);
- pci_unmap_sg(NULL,
- HWIF(drive)->sg_table,
- HWIF(drive)->sg_nents,
- HWIF(drive)->sg_dma_direction);
- return 0;
- } else {
- ide_sg[count].address = cur_addr;
- ide_sg[count].length = cur_len;
- }
-
- count++;
- sg++;
- i--;
- }
-
- if (!count)
- printk("%s: empty DMA table?\n", drive->name);
-
- return count;
+ return HWIF(drive)->sg_nents = ide_build_sglist(HWIF(drive), HWGROUP(drive)->rq);
X }
X
X /* Teardown mappings after DMA has completed. */
@@ -435,7 +399,7 @@
X */
X set_dma_speed(hwif->hw.dma, drive->drive_data);
X
- set_dma_sg(hwif->hw.dma, (dmasg_t *)hwif->dmatable_cpu, count);
+ set_dma_sg(hwif->hw.dma, HWIF(drive)->sg_table, count);
X set_dma_mode(hwif->hw.dma, reading ? DMA_MODE_READ
X : DMA_MODE_WRITE);
X
@@ -465,31 +429,6 @@
X }
X }
X
-static void *icside_alloc_dmatable(void)
-{
- static unsigned long dmatable;
- static unsigned int leftover;
- unsigned long table;
-
- if (leftover < TABLE_SIZE) {
-#if PAGE_SIZE == TABLE_SIZE * 2
- dmatable = __get_free_pages(GFP_KERNEL, 1);
- leftover = PAGE_SIZE;
-#else
- dmatable = kmalloc(TABLE_SIZE, GFP_KERNEL);
- leftover = TABLE_SIZE;
-#endif
- }
-
- table = dmatable;
- if (table) {
- dmatable += TABLE_SIZE;
- leftover -= TABLE_SIZE;
- }
-
- return (void *)table;
-}
-
X static int
X icside_setup_dma(ide_hwif_t *hwif, int autodma)
X {
@@ -500,14 +439,8 @@
X if (!hwif->sg_table)
X goto failed;
X
- hwif->dmatable_cpu = icside_alloc_dmatable();


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 050'
echo 'File patch-2.4.0-test9 is continued in part 051'
echo "051" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part051

#!/bin/sh -x
# this is part 051 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 051; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

-
- if (!hwif->dmatable_cpu) {
- kfree(hwif->sg_table);
- hwif->sg_table = NULL;
- goto failed;
- }
-
+ hwif->dmatable_cpu = NULL;
+ hwif->dmatable_dma = 0;
X hwif->speedproc = icside_set_speed;
X hwif->dmaproc = icside_dmaproc;
X hwif->autodma = autodma;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/ide/ide-pci.c linux/drivers/ide/ide-pci.c
--- v2.4.0-test8/linux/drivers/ide/ide-pci.c Thu Jul 27 16:40:57 2000
+++ linux/drivers/ide/ide-pci.c Mon Oct 2 11:49:25 2000
@@ -493,6 +493,7 @@
X byte tmp = 0;
X ide_hwif_t *hwif, *mate = NULL;
X unsigned int class_rev;
+ int pci_class_ide;
X
X #ifdef CONFIG_IDEDMA_AUTO
X autodma = 1;
@@ -538,7 +539,8 @@
X * Can we trust the reported IRQ?
X */
X pciirq = dev->irq;
- if ((dev->class & ~(0xfa)) != ((PCI_CLASS_STORAGE_IDE << 8) | 5)) {
+ pci_class_ide = ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE);
+ if (!pci_class_ide) {
X printk("%s: not 100%% native mode: will probe irqs later\n", d->name);
X /*
X * This allows offboard ide-pci cards the enable a BIOS,
@@ -548,11 +550,17 @@
X */
X pciirq = (d->init_chipset) ? d->init_chipset(dev, d->name) : ide_special_settings(dev, d->name);
X } else if (tried_config) {
- printk("%s: will probe irqs later\n", d->name);
+ printk(KERN_INFO "%s: will probe irqs later\n", d->name);
X pciirq = 0;
X } else if (!pciirq) {
- printk("%s: bad irq (%d): will probe later\n", d->name, pciirq);
- pciirq = 0;
+ if (pci_class_ide) {
+ /* this is the normal path for most IDE devices */
+ if (d->init_chipset)
+ pciirq = d->init_chipset(dev, d->name);
+ else
+ printk(KERN_INFO "%s standard IDE storage device detected\n", d->name);
+ } else
+ printk(KERN_WARNING "%s: bad irq (0): will probe later\n", d->name);
X } else {
X if (d->init_chipset)
X (void) d->init_chipset(dev, d->name);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/ide/ide-proc.c linux/drivers/ide/ide-proc.c
--- v2.4.0-test8/linux/drivers/ide/ide-proc.c Thu Apr 13 22:54:26 2000
+++ linux/drivers/ide/ide-proc.c Mon Sep 18 14:57:01 2000
@@ -159,7 +159,7 @@
X unsigned long startn = 0, n, flags;
X const char *start = NULL, *msg = NULL;
X
- if (!capable(CAP_SYS_ADMIN))
+ if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
X return -EACCES;
X /*
X * Skip over leading whitespace
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/ide/ide.c linux/drivers/ide/ide.c
--- v2.4.0-test8/linux/drivers/ide/ide.c Tue Sep 5 13:08:42 2000
+++ linux/drivers/ide/ide.c Mon Sep 11 08:42:57 2000
@@ -1082,7 +1082,7 @@
X {
X byte *args = rq->buffer;
X if (args && rq->cmd == IDE_DRIVE_TASK) {
-
+ byte sel;
X #ifdef DEBUG
X printk("%s: DRIVE_TASK_CMD data=x%02x cmd=0x%02x fr=0x%02x ns=0x%02x sc=0x%02x lcyl=0x%02x hcyl=0x%02x sel=0x%02x\n",
X drive->name, args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
@@ -1091,7 +1091,10 @@
X OUT_BYTE(args[3], IDE_SECTOR_REG);
X OUT_BYTE(args[4], IDE_LCYL_REG);
X OUT_BYTE(args[5], IDE_HCYL_REG);
- OUT_BYTE(args[6], IDE_SELECT_REG);
+ sel = (args[6] & ~0x10);
+ if (drive->select.b.unit)
+ sel |= 0x10;
+ OUT_BYTE(sel, IDE_SELECT_REG);
X ide_cmd(drive, args[0], args[2], &drive_cmd_intr);
X return ide_started;
X } else if (args) {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/ide/via82cxxx.c linux/drivers/ide/via82cxxx.c
--- v2.4.0-test8/linux/drivers/ide/via82cxxx.c Wed Sep 6 08:07:56 2000
+++ linux/drivers/ide/via82cxxx.c Mon Oct 2 11:55:04 2000
@@ -1,5 +1,5 @@
X /*
- * $Id: via82cxxx.c,v 2.1 2000/08/29 01:34:60 vojtech Exp $
+ * $Id: via82cxxx.c,v 2.1d 2000/10/01 10:01:00 vojtech Exp $
X *
X * Copyright (c) 2000 Vojtech Pavlik
X *
@@ -97,7 +97,6 @@
X { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, XFER_UDMA_2 },
X { "vt82c586a", PCI_DEVICE_ID_VIA_82C586_0, XFER_UDMA_2 },
X { "vt82c586", PCI_DEVICE_ID_VIA_82C586_0, XFER_MW_DMA_2 },
- { "Unknown SouthBridge", 0, XFER_UDMA_4 },
X { "Unknown SouthBridge", 0, XFER_UDMA_2 },
X };
X
@@ -140,8 +139,8 @@
X { XFER_MW_DMA_1, "MDMA1", 45, 80, 50, 150, 0 },
X { XFER_MW_DMA_0, "MDMA0", 60, 215, 215, 480, 0 },
X
- { XFER_SW_DMA_0, "SDMA0", 60, 120, 120, 240, 0 },
- { XFER_SW_DMA_0, "SDMA0", 90, 240, 240, 480, 0 },
+ { XFER_SW_DMA_2, "SDMA2", 60, 120, 120, 240, 0 },
+ { XFER_SW_DMA_1, "SDMA1", 90, 240, 240, 480, 0 },
X { XFER_SW_DMA_0, "SDMA0",120, 480, 480, 960, 0 },
X
X { XFER_PIO_5, "PIO5", 20, 50, 30, 100, 0 },


@@ -193,7 +192,7 @@
X

X via_print("----------VIA BusMastering IDE Configuration----------------");
X
- via_print("Driver Version: 2.1");
+ via_print("Driver Version: 2.1d");
X
X pci_read_config_byte(isa_dev, PCI_REVISION_ID, &t);
X via_print("South Bridge: VIA %s rev %#x", via_isa_bridges[via_config].name, t);
@@ -213,9 +212,6 @@
X via_print("FIFO Output Data 1/2 Clock Advance: %s", (t & 16) ? "on" : "off" );
X via_print("BM IDE Status Register Read Retry: %s", (t & 8) ? "on" : "off" );
X
- pci_read_config_byte(dev, VIA_MISC_2, &t);
- sprintf(p, "Interrupt Steering Swap: %s", (t & 64) ? "on" : "off");
-
X pci_read_config_byte(dev, VIA_MISC_3, &t);
X via_print("Max DRDY Pulse Width: %s%s", via_control3[(t & 0x03)], (t & 0x03) ? "PCI clocks" : "");
X
@@ -337,15 +333,13 @@
X * UDMA cycle
X */
X
- if (via_timing[i].udma) {
- t = 0xe8;
- if (via_isa_bridges[via_config].speed >= XFER_UDMA_4)
- t |= FIT(ENOUGH(via_timing[i].udma, T >> 1) - 2, 0, 7);
- else
- t |= FIT(ENOUGH(via_timing[i].udma, T ) - 2, 0, 3);
- } else t = 0x0b;
+ switch(via_isa_bridges[via_config].speed) {
+ case XFER_UDMA_2: t = via_timing[i].udma ? (0xe0 | (FIT(via_timing[i].udma, 2, 5) - 2)) : 0x03; break;
+ case XFER_UDMA_4: t = via_timing[i].udma ? (0xe8 | (FIT(via_timing[i].udma, 2, 9) - 2)) : 0x0f; break;
+ }
X
- via_write_config_byte(dev, VIA_UDMA_TIMING + (3 - drive->dn), t);
+ if (via_isa_bridges[via_config].speed != XFER_MW_DMA_2)
+ via_write_config_byte(dev, VIA_UDMA_TIMING + (3 - drive->dn), t);
X
X /*
X * Drive init
@@ -511,6 +505,11 @@
X if (t < 0x20) via_config++; /* vt82c586 */
X }
X
+ if (via_isa_bridges[via_config].id == PCI_DEVICE_ID_VIA_82C596) {
+ pci_read_config_byte(isa, PCI_REVISION_ID, &t);
+ if (t < 0x10) via_config++; /* vt82c596a */
+ }
+
X /*
X * Check UDMA66 mode set by BIOS.
X */
@@ -530,13 +529,8 @@
X /*
X * Set UDMA66 double clock bits.
X */
-
- pci_write_config_dword(dev, VIA_UDMA_TIMING, u | 0x80008);
- pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
-
- if ((via_isa_bridges[via_config].id == PCI_DEVICE_ID_VIA_82C596 || !isa)
- && (u & 0x80008) != 0x80008)
- via_config++; /* vt82c596a / Unknown UDMA33 */
+ if (via_isa_bridges[via_config].speed == XFER_UDMA_4)
+ pci_write_config_dword(dev, VIA_UDMA_TIMING, u | 0x80008);
X
X /*
X * Set up FIFO, flush, prefetch and post-writes.
@@ -594,7 +588,7 @@
X
X unsigned int __init ata66_via82cxxx(ide_hwif_t *hwif)
X {
- return ((via_enabled && via_ata66) >> hwif->channel) & 1;
+ return ((via_enabled & via_ata66) >> hwif->channel) & 1;
X }
X
X void __init ide_init_via82cxxx(ide_hwif_t *hwif)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/ieee1394/hosts.c linux/drivers/ieee1394/hosts.c
--- v2.4.0-test8/linux/drivers/ieee1394/hosts.c Wed Jul 5 13:03:56 2000
+++ linux/drivers/ieee1394/hosts.c Sun Oct 1 19:53:07 2000
@@ -61,8 +61,9 @@
X struct hpsb_host_template *tmpl;
X struct hpsb_host *h;
X int retval = 0;
+ unsigned long flags;
X
- spin_lock(&templates_lock);
+ spin_lock_irqsave(&templates_lock, flags);
X
X for (tmpl = templates; (tmpl != NULL) && !retval; tmpl = tmpl->next) {
X for (h = tmpl->hosts; h != NULL; h = h->next) {
@@ -74,7 +75,7 @@
X }
X }
X
- spin_unlock(&templates_lock);
+ spin_unlock_irqrestore(&templates_lock, flags);
X
X return retval;
X }
@@ -99,11 +100,11 @@
X }
X
X memset(h, 0, sizeof(struct hpsb_host) + hd_size);
- h->tlabel_count = 64;
X INIT_LIST_HEAD(&h->pending_packets);
X spin_lock_init(&h->pending_pkt_lock);
+
+ sema_init(&h->tlabel_count, 64);
X spin_lock_init(&h->tlabel_lock);
- init_waitqueue_head(&h->tlabel_wait);
X
X h->timeout_tq.routine = (void (*)(void*))abort_timedouts;
X h->timeout_tq.data = h;
@@ -154,10 +155,7 @@
X host->initialized = 1;
X
X highlevel_add_host(host);
- reset_host_bus(host);
-
- //kernel_thread(hpsb_host_thread, host,
- // CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
+ hpsb_reset_bus(host);
X }
X }
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/ieee1394/hosts.h linux/drivers/ieee1394/hosts.h
--- v2.4.0-test8/linux/drivers/ieee1394/hosts.h Sun Feb 20 20:32:50 2000
+++ linux/drivers/ieee1394/hosts.h Sun Oct 1 19:53:07 2000


@@ -4,6 +4,7 @@
X

X #include <linux/wait.h>
X #include <linux/tqueue.h>
+#include <asm/semaphore.h>
X
X #include "ieee1394_types.h"
X #include "csr.h"
@@ -22,9 +23,8 @@
X /* A bitmask where a set bit means that this tlabel is in use.
X * FIXME - should be handled per node instead of per bus. */
X u32 tlabel_pool[2];
- int tlabel_count;
+ struct semaphore tlabel_count;
X spinlock_t tlabel_lock;
- wait_queue_head_t tlabel_wait;
X
X int reset_retries;
X quadlet_t *topology_map;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/ieee1394/ieee1394_core.c linux/drivers/ieee1394/ieee1394_core.c
--- v2.4.0-test8/linux/drivers/ieee1394/ieee1394_core.c Wed Jul 5 13:03:56 2000
+++ linux/drivers/ieee1394/ieee1394_core.c Sun Oct 1 19:53:07 2000
@@ -127,30 +127,37 @@
X }
X
X
-void reset_host_bus(struct hpsb_host *host)
+int hpsb_reset_bus(struct hpsb_host *host)
X {
X if (!host->initialized) {
- return;
+ return 1;
X }
X
- hpsb_bus_reset(host);
- host->template->devctl(host, RESET_BUS, 0);
+ if (!hpsb_bus_reset(host)) {
+ host->template->devctl(host, RESET_BUS, 0);
+ return 0;
+ } else {
+ return 1;
+ }
X }
X
X
-void hpsb_bus_reset(struct hpsb_host *host)
+int hpsb_bus_reset(struct hpsb_host *host)
X {
- if (!host->in_bus_reset) {
- abort_requests(host);
- host->in_bus_reset = 1;
- host->irm_id = -1;
- host->busmgr_id = -1;
- host->node_count = 0;
- host->selfid_count = 0;
- } else {
+ if (host->in_bus_reset) {
X HPSB_NOTICE(__FUNCTION__
X " called while bus reset already in progress");
+ return 1;
X }
+
+ abort_requests(host);
+ host->in_bus_reset = 1;
+ host->irm_id = -1;
+ host->busmgr_id = -1;
+ host->node_count = 0;
+ host->selfid_count = 0;
+
+ return 0;
X }
X
X
@@ -311,7 +318,7 @@
X if (host->reset_retries++ < 20) {
X /* selfid stage did not complete without error */
X HPSB_NOTICE("error in SelfID stage - resetting");
- reset_host_bus(host);
+ hpsb_reset_bus(host);
X return;
X } else {
X HPSB_NOTICE("stopping out-of-control reset loop");
@@ -332,6 +339,7 @@
X
X host->reset_retries = 0;
X inc_hpsb_generation();
+ if (isroot) host->template->devctl(host, ACT_CYCLE_MASTER, 1);
X highlevel_host_reset(host);
X }
X
@@ -374,7 +382,7 @@
X *
X * The packet is sent through the host specified in the packet->host field.
X * Before sending, the packet's transmit speed is automatically determined using
- * the local speed map.
+ * the local speed map when it is an async, non-broadcast packet.
X *
X * Possibilities for failure are that host is either not initialized, in bus
X * reset, the packet's generation number doesn't match the current generation
@@ -392,8 +400,12 @@
X }
X
X packet->state = queued;
- packet->speed_code = host->speed_map[(host->node_id & NODE_MASK) * 64
- + (packet->node_id & NODE_MASK)];
+
+ if (packet->type == async && packet->node_id != ALL_NODES) {
+ packet->speed_code =
+ host->speed_map[(host->node_id & NODE_MASK) * 64
+ + (packet->node_id & NODE_MASK)];
+ }
X
X #ifdef CONFIG_IEEE1394_VERBOSEDEBUG
X switch (packet->speed_code) {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/ieee1394/ieee1394_core.h linux/drivers/ieee1394/ieee1394_core.h
--- v2.4.0-test8/linux/drivers/ieee1394/ieee1394_core.h Wed Jul 5 13:03:56 2000
+++ linux/drivers/ieee1394/ieee1394_core.h Sun Oct 1 19:53:07 2000
@@ -73,7 +73,6 @@
X };
X
X
-void reset_host_bus(struct hpsb_host *host);
X void abort_timedouts(struct hpsb_host *host);
X void abort_requests(struct hpsb_host *host);
X
@@ -106,6 +105,9 @@
X */
X int hpsb_send_packet(struct hpsb_packet *packet);
X
+/* Initiate bus reset on the given host. Returns 1 if bus reset already in
+ * progress, 0 otherwise. */
+int hpsb_reset_bus(struct hpsb_host *host);
X
X /*
X * The following functions are exported for host driver module usage. All of
@@ -114,8 +116,9 @@
X * them directly.
X */
X
-/* Notify a bus reset to the core. */
-void hpsb_bus_reset(struct hpsb_host *host);
+/* Notify a bus reset to the core. Returns 1 if bus reset already in progress,
+ * 0 otherwise. */
+int hpsb_bus_reset(struct hpsb_host *host);
X
X /*
X * Hand over received selfid packet to the core. Complement check (second
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/ieee1394/ieee1394_syms.c linux/drivers/ieee1394/ieee1394_syms.c
--- v2.4.0-test8/linux/drivers/ieee1394/ieee1394_syms.c Wed Jul 5 13:03:56 2000
+++ linux/drivers/ieee1394/ieee1394_syms.c Sun Oct 1 19:53:07 2000
@@ -17,7 +17,6 @@
X #include "hosts.h"
X #include "ieee1394_core.h"
X #include "ieee1394_transactions.h"
-/* #include "events.h" */
X #include "highlevel.h"
X #include "guid.h"
X
@@ -30,6 +29,7 @@
X EXPORT_SYMBOL(alloc_hpsb_packet);
X EXPORT_SYMBOL(free_hpsb_packet);
X EXPORT_SYMBOL(hpsb_send_packet);
+EXPORT_SYMBOL(hpsb_reset_bus);
X EXPORT_SYMBOL(hpsb_bus_reset);
X EXPORT_SYMBOL(hpsb_selfid_received);
X EXPORT_SYMBOL(hpsb_selfid_complete);
@@ -39,6 +39,16 @@
X
X EXPORT_SYMBOL(get_tlabel);
X EXPORT_SYMBOL(free_tlabel);
+EXPORT_SYMBOL(fill_async_readquad);
+EXPORT_SYMBOL(fill_async_readquad_resp);
+EXPORT_SYMBOL(fill_async_readblock);
+EXPORT_SYMBOL(fill_async_readblock_resp);
+EXPORT_SYMBOL(fill_async_writequad);
+EXPORT_SYMBOL(fill_async_writeblock);
+EXPORT_SYMBOL(fill_async_write_resp);
+EXPORT_SYMBOL(fill_async_lock);
+EXPORT_SYMBOL(fill_async_lock_resp);
+EXPORT_SYMBOL(fill_iso_packet);
X EXPORT_SYMBOL(hpsb_make_readqpacket);
X EXPORT_SYMBOL(hpsb_make_readbpacket);
X EXPORT_SYMBOL(hpsb_make_writeqpacket);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/ieee1394/ieee1394_transactions.c linux/drivers/ieee1394/ieee1394_transactions.c
--- v2.4.0-test8/linux/drivers/ieee1394/ieee1394_transactions.c Wed Jul 5 13:03:56 2000
+++ linux/drivers/ieee1394/ieee1394_transactions.c Sun Oct 1 19:53:07 2000
@@ -155,56 +155,29 @@
X * Return value: The allocated transaction label or -1 if there was no free
X * tlabel and @wait is false.
X */
-static int __get_tlabel(struct hpsb_host *host, nodeid_t nodeid)
+int get_tlabel(struct hpsb_host *host, nodeid_t nodeid, int wait)
X {
X int tlabel;


+ unsigned long flags;
X

- if (host->tlabel_count) {
- host->tlabel_count--;
-
- if (host->tlabel_pool[0] != ~0) {
- tlabel = ffz(host->tlabel_pool[0]);
- host->tlabel_pool[0] |= 1 << tlabel;
- } else {
- tlabel = ffz(host->tlabel_pool[1]);
- host->tlabel_pool[1] |= 1 << tlabel;
- tlabel += 32;
- }
- return tlabel;
+ if (wait) {
+ down(&host->tlabel_count);
+ } else {
+ if (down_trylock(&host->tlabel_count)) return -1;
X }


- return -1;
-}
-

-int get_tlabel(struct hpsb_host *host, nodeid_t nodeid, int wait)


-{
- unsigned long flags;

- int tlabel;
- wait_queue_t wq;
X
X spin_lock_irqsave(&host->tlabel_lock, flags);
X
- tlabel = __get_tlabel(host, nodeid);
- if (tlabel != -1 || !wait) {
- spin_unlock_irqrestore(&host->tlabel_lock, flags);
- return tlabel;
- }
-
- init_waitqueue_entry(&wq, current);
- add_wait_queue(&host->tlabel_wait, &wq);


-
- for (;;) {

- set_current_state(TASK_UNINTERRUPTIBLE);
- tlabel = __get_tlabel(host, nodeid);
- if (tlabel != -1) break;
-
- spin_unlock_irqrestore(&host->tlabel_lock, flags);
- schedule();
- spin_lock_irqsave(&host->tlabel_lock, flags);
+ if (host->tlabel_pool[0] != ~0) {
+ tlabel = ffz(host->tlabel_pool[0]);
+ host->tlabel_pool[0] |= 1 << tlabel;
+ } else {
+ tlabel = ffz(host->tlabel_pool[1]);
+ host->tlabel_pool[1] |= 1 << tlabel;
+ tlabel += 32;
X }
X
X spin_unlock_irqrestore(&host->tlabel_lock, flags);
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&host->tlabel_wait, &wq);
X
X return tlabel;
X }
@@ -233,11 +206,9 @@
X host->tlabel_pool[1] &= ~(1 << (tlabel-32));
X }
X
- host->tlabel_count++;
-
X spin_unlock_irqrestore(&host->tlabel_lock, flags);
X
- wake_up(&host->tlabel_wait);
+ up(&host->tlabel_count);
X }
X
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/ieee1394/ieee1394_types.h linux/drivers/ieee1394/ieee1394_types.h
--- v2.4.0-test8/linux/drivers/ieee1394/ieee1394_types.h Wed Jul 5 13:03:56 2000
+++ linux/drivers/ieee1394/ieee1394_types.h Sun Oct 1 19:53:07 2000
@@ -53,7 +53,7 @@
X return order;
X }
X
-
+#include <linux/mm.h>
X #include <linux/pci.h>
X inline static int pci_enable_device(struct pci_dev *dev)
X {
@@ -114,7 +114,7 @@
X BUG();
X }
X
-struct scatterlist {};
+#include <asm/scatterlist.h>
X extern inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
X int nents, int direction)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/ieee1394/ohci1394.c linux/drivers/ieee1394/ohci1394.c
--- v2.4.0-test8/linux/drivers/ieee1394/ohci1394.c Wed Jul 5 13:03:56 2000
+++ linux/drivers/ieee1394/ohci1394.c Sun Oct 1 19:53:07 2000
@@ -56,6 +56,8 @@
X * . Apple PowerBook detection
X * Daniel Kobras <daniel...@student.uni-tuebingen.de>
X * . Reset the board properly before leaving + misc cleanups
+ * Leon van Stuivenberg <leo...@iae.nl>
+ * . Bug fixes


X */
X
X #include <linux/config.h>

@@ -253,7 +255,7 @@
X return -1;
X }
X
- size = ((self_id_count&0x0000EFFC)>>2) - 1;
+ size = ((self_id_count&0x00001FFC)>>2) - 1;
X q++;
X
X while (size > 0) {
@@ -652,6 +654,15 @@
X * FIXME: check that the packet data buffer
X * do not cross a page boundary
X */
+ if (cross_bound((unsigned long)packet->data,
+ packet->data_size)>0) {
+ /* FIXME: do something about it */
+ PRINT(KERN_ERR, ohci->id, __FUNCTION__
+ ": packet data addr: %p size %d bytes "
+ "cross page boundary",
+ packet->data, packet->data_size);
+ }
+
X d->prg_cpu[idx]->end.address =
X pci_map_single(ohci->dev, packet->data,
X packet->data_size, PCI_DMA_TODEVICE);
@@ -734,7 +745,7 @@
X unsigned char tcode;


X unsigned long flags;
X

- if (packet->data_size >= ohci->max_packet_size) {
+ if (packet->data_size > ohci->max_packet_size) {
X PRINT(KERN_ERR, ohci->id,
X "transmit packet size = %d too big",
X packet->data_size);
@@ -803,11 +814,11 @@
X u32 nodeId = reg_read(ohci, OHCI1394_NodeID);
X if ((nodeId & (1<<30)) && (nodeId & 0x3f)) {
X /*
- * enable cycleTimer cycleMaster cycleSource
+ * enable cycleTimer, cycleMaster
X */
X DBGMSG(ohci->id, "Cycle master enabled");
X reg_write(ohci, OHCI1394_LinkControlSet,
- 0x00700000);
+ 0x00300000);
X }
X } else {
X /* disable cycleTimer, cycleMaster, cycleSource */
@@ -830,61 +841,67 @@
X break;
X
X case ISO_LISTEN_CHANNEL:
+ {
+ int *isochannels, offset= OHCI1394_IRMultiChanMaskLoSet;
+ unsigned int channel= (unsigned int)arg;
+ unsigned int channelbit= channel;
+ u32 setMask= 0x00000001;
+
+ /* save people from themselves */
+ if (channel > 63)
+ break;
+
+ if (channel > 31) {
+ isochannels= &(((int*)&ohci->IR_channel_usage)[0]);
+ channelbit-= 32;
+ offset= OHCI1394_IRMultiChanMaskHiSet;
+ }
+ else
+ isochannels= &(((int*)&ohci->IR_channel_usage)[1]);
X
- spin_lock_irqsave(&ohci->IR_channel_lock, flags);
+ while(channelbit--) setMask= setMask << 1;
X
- if (!test_and_set_bit(arg, &ohci->IR_channel_usage)) {
- DBGMSG(ohci->id,
- "listening enabled on channel %d", arg);
-
- if (arg > 31) {
- u32 setMask= 0x00000001;
- arg-= 32;
- while(arg--) setMask= setMask << 1;
- reg_write(ohci, OHCI1394_IRMultiChanMaskHiSet,
- setMask);
- } else {
- u32 setMask= 0x00000001;
- while(arg--) setMask= setMask << 1;
- reg_write(ohci, OHCI1394_IRMultiChanMaskLoSet,
- setMask);
- }
+ spin_lock_irqsave(&ohci->IR_channel_lock, flags);
X
- }
+ if (!test_and_set_bit(channelbit, isochannels))
+ reg_write(ohci, offset, setMask);
X
X spin_unlock_irqrestore(&ohci->IR_channel_lock, flags);
+ DBGMSG(ohci->id, "listening enabled on channel %u", channel);
X break;
-
+ }
X case ISO_UNLISTEN_CHANNEL:
+ {
+ int *isochannels, offset= OHCI1394_IRMultiChanMaskLoClear;
+ unsigned int channel= (unsigned int)arg;
+ unsigned int channelbit= channel;
+ u32 clearMask= 0x00000001;
+
+ /* save people from themselves */
+ if (channel > 63)
+ break;
+
+ if (channel > 31) {
+ isochannels= &(((int*)&ohci->IR_channel_usage)[0]);
+ channelbit-= 32;
+ offset= OHCI1394_IRMultiChanMaskHiClear;
+ }
+ else
+ isochannels= &(((int*)&ohci->IR_channel_usage)[1]);
X
- spin_lock_irqsave(&ohci->IR_channel_lock, flags);
+ while(channelbit--) clearMask= clearMask << 1;
X
- if (test_and_clear_bit(arg, &ohci->IR_channel_usage)) {
- DBGMSG(ohci->id,
- "listening disabled on iso channel %d", arg);
-
- if (arg > 31) {
- u32 clearMask= 0x00000001;
- arg-= 32;
- while(arg--) clearMask= clearMask << 1;
- reg_write(ohci,
- OHCI1394_IRMultiChanMaskHiClear,
- clearMask);
- } else {
- u32 clearMask= 0x00000001;
- while(arg--) clearMask= clearMask << 1;
- reg_write(ohci,
- OHCI1394_IRMultiChanMaskLoClear,
- clearMask);
- }
+ spin_lock_irqsave(&ohci->IR_channel_lock, flags);
X
- }
+ if (!test_and_clear_bit(channelbit, isochannels))
+ reg_write(ohci, offset, clearMask);
X
X spin_unlock_irqrestore(&ohci->IR_channel_lock, flags);
+ DBGMSG(ohci->id, "listening disabled on channel %u", channel);
X break;
-
+ }
X default:
- PRINT_G(KERN_ERR, "ohci_devctl cmd %d not implemented yet\n",
+ PRINT_G(KERN_ERR, "ohci_devctl cmd %d not implemented yet",
X cmd);
X break;
X }
@@ -904,6 +921,7 @@
X {
X struct ti_ohci *ohci;
X unsigned long flags;
+ struct hpsb_packet *nextpacket;
X
X if (d==NULL) {
X PRINT_G(KERN_ERR, "dma_trm_reset called with NULL arg");
@@ -919,8 +937,9 @@
X PRINT(KERN_INFO, ohci->id,
X "AT dma reset ctx=%d, aborting transmission",
X d->ctx);
+ nextpacket = d->fifo_first->xnext;
X hpsb_packet_sent(ohci->host, d->fifo_first, ACKX_ABORTED);
- d->fifo_first = d->fifo_first->xnext;
+ d->fifo_first = nextpacket;
X }
X d->fifo_first = d->fifo_last = NULL;
X
@@ -929,9 +948,10 @@
X PRINT(KERN_INFO, ohci->id,
X "AT dma reset ctx=%d, aborting transmission",
X d->ctx);
+ nextpacket = d->pending_first->xnext;
X hpsb_packet_sent(ohci->host, d->pending_first,
X ACKX_ABORTED);
- d->pending_first = d->pending_first->xnext;
+ d->pending_first = nextpacket;
X }
X d->pending_first = d->pending_last = NULL;
X
@@ -1072,6 +1092,20 @@
X }
X if (event & OHCI1394_selfIDComplete) {
X if (host->in_bus_reset) {
+ /*
+ * Begin Fix (JSG): Check to make sure our
+ * node id is valid
+ */
+ node_id = reg_read(ohci, OHCI1394_NodeID);
+ if (!(node_id & 0x80000000)) {
+ mdelay(1); /* phy is upset -
+ * this happens once in
+ * a while on hot-plugs...
+ * give it a ms to recover
+ */
+ }
+ /* End Fix (JSG) */
+
X node_id = reg_read(ohci, OHCI1394_NodeID);
X if (node_id & 0x80000000) { /* NodeID valid */
X phyid = node_id & 0x0000003f;
@@ -1346,9 +1380,10 @@
X {
X struct dma_trm_ctx *d = (struct dma_trm_ctx*)data;
X struct ti_ohci *ohci = (struct ti_ohci*)(d->ohci);
- struct hpsb_packet *packet;
+ struct hpsb_packet *packet, *nextpacket;
X unsigned long flags;
X u32 ack;
+ size_t datasize;
X
X spin_lock_irqsave(&d->lock, flags);
X
@@ -1363,7 +1398,8 @@
X
X while (d->fifo_first) {
X packet = d->fifo_first;
- if (packet->data_size)
+ datasize = d->fifo_first->data_size;
+ if (datasize)
X ack = d->prg_cpu[d->sent_ind]->end.status>>16;
X else
X ack = d->prg_cpu[d->sent_ind]->begin.status>>16;
@@ -1372,20 +1408,40 @@
X /* this packet hasn't been sent yet*/
X break;
X
- DBGMSG(ohci->id,
- "Packet sent to node %d ack=0x%X spd=%d ctx=%d",
- (packet->header[0]>>16)&0x3f, ack&0x1f, (ack>>5)&0x3,
- d->ctx);
+#ifdef OHCI1394_DEBUG
+ if (datasize)
+ DBGMSG(ohci->id,
+ "Packet sent to node %d tcode=0x%X tLabel="
+ "0x%02X ack=0x%X spd=%d dataLength=%d ctx=%d",
+ (d->prg_cpu[d->sent_ind]->data[1]>>16)&0x3f,
+ (d->prg_cpu[d->sent_ind]->data[0]>>4)&0xf,
+ (d->prg_cpu[d->sent_ind]->data[0]>>10)&0x3f,
+ ack&0x1f, (ack>>5)&0x3,
+ d->prg_cpu[d->sent_ind]->data[3]>>16,
+ d->ctx);
+ else
+ DBGMSG(ohci->id,
+ "Packet sent to node %d tcode=0x%X tLabel="
+ "0x%02X ack=0x%X spd=%d data=0x%08X ctx=%d",
+ (d->prg_cpu[d->sent_ind]->data[1]>>16)&0x3f,
+ (d->prg_cpu[d->sent_ind]->data[0]>>4)&0xf,
+ (d->prg_cpu[d->sent_ind]->data[0]>>10)&0x3f,
+ ack&0x1f, (ack>>5)&0x3,
+ d->prg_cpu[d->sent_ind]->data[3],
+ d->ctx);
+#endif
+
+ nextpacket = packet->xnext;
X hpsb_packet_sent(ohci->host, packet, ack&0xf);
X
- if (packet->data_size)
+ if (datasize)
X pci_unmap_single(ohci->dev,
X d->prg_cpu[d->sent_ind]->end.address,
- packet->data_size, PCI_DMA_TODEVICE);
+ datasize, PCI_DMA_TODEVICE);
X
X d->sent_ind = (d->sent_ind+1)%d->num_desc;
X d->free_prgs++;
- d->fifo_first = d->fifo_first->xnext;
+ d->fifo_first = nextpacket;
X }
X if (d->fifo_first==NULL) d->fifo_last=NULL;
X
@@ -1687,22 +1743,36 @@
X FAIL("failed to allocate buffer config rom");
X }
X
- DBGMSG(ohci->id, "The 1st byte at offset 0x404 is: 0x%02x",
- *((char *)ohci->csr_config_rom_cpu+4));
-
X /*
X * self-id dma buffer allocation
X * FIXME: some early chips may need 8KB alignment for the
- * selfid buffer
+ * selfid buffer... if you have problems a temporary fic
+ * is to allocate 8192 bytes instead of 2048
X */
X ohci->selfid_buf_cpu =
X pci_alloc_consistent(ohci->dev, 2048, &ohci->selfid_buf_bus);
X if (ohci->selfid_buf_cpu == NULL) {
X FAIL("failed to allocate DMA buffer for self-id packets");
X }
- if ((unsigned long)ohci->selfid_buf_cpu & 0xfff)
+ if ((unsigned long)ohci->selfid_buf_cpu & 0x1fff)
X PRINT(KERN_INFO, ohci->id, "Selfid buffer %p not aligned on "
- "8Kb boundary", ohci->selfid_buf_cpu);
+ "8Kb boundary... may cause pb on some CXD3222 chip",
+ ohci->selfid_buf_cpu);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,13)
+ ohci->registers = ioremap_nocache(dev->base_address[0],
+ OHCI1394_REGISTER_SIZE);
+#else
+ ohci->registers = ioremap_nocache(dev->resource[0].start,
+ OHCI1394_REGISTER_SIZE);
+#endif
+
+ if (ohci->registers == NULL) {
+ FAIL("failed to remap registers - card not accessible");
+ }
+
+ PRINT(KERN_INFO, ohci->id, "remapped memory spaces reg 0x%p",
+ ohci->registers);
X
X ohci->ar_req_context =
X alloc_dma_rcv_ctx(ohci, 0, AR_REQ_NUM_DESC,
@@ -1711,7 +1781,9 @@
X OHCI1394_AsReqRcvContextControlClear,
X OHCI1394_AsReqRcvCommandPtr);
X
- if (ohci->ar_req_context == NULL) return 1;
+ if (ohci->ar_req_context == NULL) {
+ FAIL("failed to allocate AR Req context");
+ }
X
X ohci->ar_resp_context =
X alloc_dma_rcv_ctx(ohci, 1, AR_RESP_NUM_DESC,
@@ -1758,21 +1830,6 @@
X ohci->IR_channel_usage= 0x0000000000000000;
X spin_lock_init(&ohci->IR_channel_lock);
X
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,13)
- ohci->registers = ioremap_nocache(dev->base_address[0],
- OHCI1394_REGISTER_SIZE);
-#else
- ohci->registers = ioremap_nocache(dev->resource[0].start,
- OHCI1394_REGISTER_SIZE);
-#endif
-
- if (ohci->registers == NULL) {
- FAIL("failed to remap registers - card not accessible");
- }
-
- PRINT(KERN_INFO, ohci->id, "remapped memory spaces reg 0x%p",
- ohci->registers);
-
X if (!request_irq(dev->irq, ohci_irq_handler, SA_SHIRQ,
X OHCI1394_DRIVER_NAME, ohci)) {
X PRINT(KERN_INFO, ohci->id, "allocated interrupt %d", dev->irq);
@@ -1782,6 +1839,9 @@
X
X ohci_init_config_rom(ohci);
X
+ DBGMSG(ohci->id, "The 1st byte at offset 0x404 is: 0x%02x",
+ *((char *)ohci->csr_config_rom_cpu+4));
+
X return 0;
X #undef FAIL
X }
@@ -2116,7 +2176,7 @@
X create_proc_read_entry ("ohci1394", 0, NULL, ohci1394_read_proc, NULL);
X #else
X if (proc_register(&proc_root, &ohci_proc_entry)) {
- PRINT_G(KERN_ERR, "unable to register proc file\n");
+ PRINT_G(KERN_ERR, "unable to register proc file");
X return -EIO;
X }
X #endif
@@ -2290,7 +2350,7 @@
X #endif
X #endif
X
- PRINT_G(KERN_INFO, "removed " OHCI1394_DRIVER_NAME " module\n");
+ PRINT_G(KERN_INFO, "removed " OHCI1394_DRIVER_NAME " module");
X }
X
X int init_module(void)
@@ -2298,7 +2358,7 @@
X memset(cards, 0, MAX_OHCI1394_CARDS * sizeof (struct ti_ohci));
X
X if (hpsb_register_lowlevel(get_ohci_template())) {
- PRINT_G(KERN_ERR, "registering failed\n");
+ PRINT_G(KERN_ERR, "registering failed");
X return -ENXIO;
X }
X return 0;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/ieee1394/ohci1394.h linux/drivers/ieee1394/ohci1394.h
--- v2.4.0-test8/linux/drivers/ieee1394/ohci1394.h Wed Jul 5 13:03:56 2000
+++ linux/drivers/ieee1394/ohci1394.h Sun Oct 1 19:53:07 2000
@@ -91,16 +91,16 @@
X #define OHCI1394_MAX_SELF_ID_ERRORS 16
X
X #define AR_REQ_NUM_DESC 4 /* number of AR req descriptors */
-#define AR_REQ_BUF_SIZE 4096 /* size of AR req buffers */
-#define AR_REQ_SPLIT_BUF_SIZE 4096 /* split packet buffer */
+#define AR_REQ_BUF_SIZE PAGE_SIZE /* size of AR req buffers */
+#define AR_REQ_SPLIT_BUF_SIZE PAGE_SIZE /* split packet buffer */
X
X #define AR_RESP_NUM_DESC 4 /* number of AR resp descriptors */
-#define AR_RESP_BUF_SIZE 4096 /* size of AR resp buffers */
-#define AR_RESP_SPLIT_BUF_SIZE 4096 /* split packet buffer */
+#define AR_RESP_BUF_SIZE PAGE_SIZE /* size of AR resp buffers */
+#define AR_RESP_SPLIT_BUF_SIZE PAGE_SIZE /* split packet buffer */
X
X #define IR_NUM_DESC 16 /* number of IR descriptors */
-#define IR_BUF_SIZE 4096 /* 6480 bytes/buffer */
-#define IR_SPLIT_BUF_SIZE 4096 /* split packet buffer */
+#define IR_BUF_SIZE PAGE_SIZE /* 4096 bytes/buffer */
+#define IR_SPLIT_BUF_SIZE PAGE_SIZE /* split packet buffer */
X
X #define AT_REQ_NUM_DESC 32 /* number of AT req descriptors */
X #define AT_RESP_NUM_DESC 32 /* number of AT resp descriptors */
@@ -112,10 +112,17 @@
X u32 status;
X };
X
+/*
+ * FIXME:
+ * It is important that a single at_dma_prg does not cross a page boundary
+ * The proper way to do it would be to do the check dynamically as the
+ * programs are inserted into the AT fifo.
+ */
X struct at_dma_prg {
X struct dma_cmd begin;
X quadlet_t data[4];
X struct dma_cmd end;
+ quadlet_t pad[4]; /* FIXME: quick hack for memory alignment */
X };
X
X /* DMA receive context */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/ieee1394/pcilynx.c linux/drivers/ieee1394/pcilynx.c
--- v2.4.0-test8/linux/drivers/ieee1394/pcilynx.c Fri Jul 21 19:51:56 2000
+++ linux/drivers/ieee1394/pcilynx.c Sun Oct 1 19:53:07 2000
@@ -18,16 +18,6 @@
X * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
X */
X
-/*
- * Lynx DMA usage:
- *
- * 0 is used for Lynx local bus transfers
- * 1 is async/selfid receive
- * 2 is iso receive
- * 3 is async transmit
- */
-
-
X #include <linux/config.h>
X #include <linux/kernel.h>
X #include <linux/slab.h>
@@ -63,8 +53,8 @@
X #define PRINT_GD(level, fmt, args...) printk(level "pcilynx: " fmt "\n" , ## args)
X #define PRINTD(level, card, fmt, args...) printk(level "pcilynx%d: " fmt "\n" , card , ## args)
X #else
-#define PRINT_GD(level, fmt, args...)
-#define PRINTD(level, card, fmt, args...)
+#define PRINT_GD(level, fmt, args...) do {} while (0)
+#define PRINTD(level, card, fmt, args...) do {} while (0)
X #endif
X
X static struct ti_lynx cards[MAX_PCILYNX_CARDS];


@@ -177,8 +167,8 @@
X

X spin_lock_irqsave(&lynx->phy_reg_lock, flags);
X
+ reg_write(lynx, LINK_PHY, LINK_PHY_READ | LINK_PHY_ADDR(addr));
X do {
- reg_write(lynx, LINK_PHY, LINK_PHY_READ | LINK_PHY_ADDR(addr));
X retval = reg_read(lynx, LINK_PHY);
X
X if (i > 10000) {
@@ -309,12 +299,11 @@
X lsid = 0x80400000 | ((phyreg[0] & 0xfc) << 22);
X lsid |= (phyreg[1] & 0x3f) << 16; /* gap count */
X lsid |= (phyreg[2] & 0xc0) << 8; /* max speed */
- /* lsid |= (phyreg[6] & 0x01) << 11; *//* contender (phy dependent) */
- lsid |= 1 << 11; /* set contender (hack) */
+ lsid |= (phyreg[6] & 0x01) << 11; /* contender (phy dependent) */
+ /* lsid |= 1 << 11; *//* set contender (hack) */
X lsid |= (phyreg[6] & 0x10) >> 3; /* initiated reset */
X
- //for (i = 0; i < (phyreg[2] & 0xf); i++) { /* ports */
- for (i = 0; i < (phyreg[2] & 0x1f); i++) { /* ports */
+ for (i = 0; i < (phyreg[2] & 0xf); i++) { /* ports */
X if (phyreg[3 + i] & 0x4) {
X lsid |= (((phyreg[3 + i] & 0x8) | 0x10) >> 3)
X << (6 - i*2);
@@ -380,47 +369,63 @@
X hpsb_selfid_received(host, lsid);
X }
X
+ if (isroot) reg_set_bits(lynx, LINK_CONTROL, LINK_CONTROL_CYCMASTER);
+
X hpsb_selfid_complete(host, phyid, isroot);
X }
X
X
X
-/* This must be called with the async.queue_lock held. */
-static void send_next_async(struct ti_lynx *lynx)
+/* This must be called with the respective queue_lock held. */
+static void send_next(struct ti_lynx *lynx, int what)
X {
X struct ti_pcl pcl;
- struct hpsb_packet *packet = lynx->async.queue;
+ struct lynx_send_data *d;
+ struct hpsb_packet *packet;
+
+ d = (what == iso ? &lynx->iso_send : &lynx->async);
+ packet = d->queue;
X
- lynx->async.header_dma = pci_map_single(lynx->dev, packet->header,
- packet->header_size,
- PCI_DMA_TODEVICE);
+ d->header_dma = pci_map_single(lynx->dev, packet->header,
+ packet->header_size, PCI_DMA_TODEVICE);
X if (packet->data_size) {
- lynx->async.data_dma = pci_map_single(lynx->dev, packet->data,
- packet->data_size,
- PCI_DMA_TODEVICE);
+ d->data_dma = pci_map_single(lynx->dev, packet->data,
+ packet->data_size,
+ PCI_DMA_TODEVICE);
X } else {
- lynx->async.data_dma = 0;
+ d->data_dma = 0;
X }
X
X pcl.next = PCL_NEXT_INVALID;
X pcl.async_error_next = PCL_NEXT_INVALID;
X #ifdef __BIG_ENDIAN
- pcl.buffer[0].control = PCL_CMD_XMT | packet->speed_code << 14
- | packet->header_size;
+ pcl.buffer[0].control = packet->speed_code << 14 | packet->header_size;
X #else
- pcl.buffer[0].control = PCL_CMD_XMT | packet->speed_code << 14
- | packet->header_size | PCL_BIGENDIAN;
+ pcl.buffer[0].control = packet->speed_code << 14 | packet->header_size
+ | PCL_BIGENDIAN;
X #endif
- pcl.buffer[0].pointer = lynx->async.header_dma;
+ pcl.buffer[0].pointer = d->header_dma;
X pcl.buffer[1].control = PCL_LAST_BUFF | packet->data_size;
- pcl.buffer[1].pointer = lynx->async.data_dma;
+ pcl.buffer[1].pointer = d->data_dma;
+
+ switch (packet->type) {
+ case async:
+ pcl.buffer[0].control |= PCL_CMD_XMT;
+ break;
+ case iso:
+ pcl.buffer[0].control |= PCL_CMD_XMT | PCL_ISOMODE;
+ break;
+ case raw:
+ pcl.buffer[0].control |= PCL_CMD_UNFXMT;
+ break;
+ }
X
X if (!packet->data_be) {
X pcl.buffer[1].control |= PCL_BIGENDIAN;
X }
X
- put_pcl(lynx, lynx->async.pcl, &pcl);
- run_pcl(lynx, lynx->async.pcl_start, 3);
+ put_pcl(lynx, d->pcl, &pcl);
+ run_pcl(lynx, d->pcl_start, d->channel);
X }
X
X
@@ -475,6 +480,10 @@
X pcl.async_error_next = pcl_bus(lynx, lynx->async.pcl);
X put_pcl(lynx, lynx->async.pcl_start, &pcl);
X
+ pcl.next = pcl_bus(lynx, lynx->iso_send.pcl);
+ pcl.async_error_next = PCL_NEXT_INVALID;
+ put_pcl(lynx, lynx->iso_send.pcl_start, &pcl);
+
X pcl.next = PCL_NEXT_INVALID;
X pcl.async_error_next = PCL_NEXT_INVALID;
X pcl.buffer[0].control = PCL_CMD_RCV | 4;
@@ -499,15 +508,18 @@
X }
X put_pcl(lynx, lynx->iso_rcv.pcl_start, &pcl);
X
- /* 85 bytes for each FIFO - FIXME - optimize or make configurable */
- /* reg_write(lynx, FIFO_SIZES, 0x00555555); */
- reg_write(lynx, FIFO_SIZES, 0x002020c0);
+ /* FIFO sizes from left to right: ITF=48 ATF=48 GRF=160 */
+ reg_write(lynx, FIFO_SIZES, 0x003030a0);
X /* 20 byte threshold before triggering PCI transfer */
X reg_write(lynx, DMA_GLOBAL_REGISTER, 0x2<<24);
- /* 69 byte threshold on both send FIFOs before transmitting */
- reg_write(lynx, FIFO_XMIT_THRESHOLD, 0x4545);
+ /* threshold on both send FIFOs before transmitting:
+ FIFO size - cache line size - 1 */
+ i = reg_read(lynx, PCI_LATENCY_CACHELINE) & 0xff;
+ i = 0x30 - i - 1;
+ reg_write(lynx, FIFO_XMIT_THRESHOLD, (i << 8) | i);
X
X reg_set_bits(lynx, PCI_INT_ENABLE, PCI_INT_1394);
+
X reg_write(lynx, LINK_INT_ENABLE, LINK_INT_PHY_TIMEOUT
X | LINK_INT_PHY_REG_RCVD | LINK_INT_PHY_BUSRESET
X | LINK_INT_ISO_STUCK | LINK_INT_ASYNC_STUCK
@@ -515,15 +527,15 @@
X | LINK_INT_GRF_OVERFLOW | LINK_INT_ITF_UNDERFLOW
X | LINK_INT_ATF_UNDERFLOW);
X
- reg_write(lynx, DMA1_WORD0_CMP_VALUE, 0);
- reg_write(lynx, DMA1_WORD0_CMP_ENABLE, 0xa<<4);
- reg_write(lynx, DMA1_WORD1_CMP_VALUE, 0);
- reg_write(lynx, DMA1_WORD1_CMP_ENABLE, DMA_WORD1_CMP_MATCH_NODE_BCAST
- | DMA_WORD1_CMP_MATCH_BROADCAST | DMA_WORD1_CMP_MATCH_LOCAL
- | DMA_WORD1_CMP_MATCH_BUS_BCAST | DMA_WORD1_CMP_ENABLE_SELF_ID
- | DMA_WORD1_CMP_ENABLE_MASTER);
+ reg_write(lynx, DMA_WORD0_CMP_VALUE(CHANNEL_ASYNC_RCV), 0);
+ reg_write(lynx, DMA_WORD0_CMP_ENABLE(CHANNEL_ASYNC_RCV), 0xa<<4);
+ reg_write(lynx, DMA_WORD1_CMP_VALUE(CHANNEL_ASYNC_RCV), 0);
+ reg_write(lynx, DMA_WORD1_CMP_ENABLE(CHANNEL_ASYNC_RCV),
+ DMA_WORD1_CMP_MATCH_NODE_BCAST | DMA_WORD1_CMP_MATCH_BROADCAST
+ | DMA_WORD1_CMP_MATCH_LOCAL | DMA_WORD1_CMP_MATCH_BUS_BCAST
+ | DMA_WORD1_CMP_ENABLE_SELF_ID | DMA_WORD1_CMP_ENABLE_MASTER);
X
- run_pcl(lynx, lynx->rcv_pcl_start, 1);
+ run_pcl(lynx, lynx->rcv_pcl_start, CHANNEL_ASYNC_RCV);
X
X reg_write(lynx, DMA_WORD0_CMP_VALUE(CHANNEL_ISO_RCV), 0);
X reg_write(lynx, DMA_WORD0_CMP_ENABLE(CHANNEL_ISO_RCV), 0x9<<4);
@@ -536,7 +548,7 @@
X | LINK_CONTROL_TX_ISO_EN | LINK_CONTROL_RX_ISO_EN
X | LINK_CONTROL_TX_ASYNC_EN | LINK_CONTROL_RX_ASYNC_EN
X | LINK_CONTROL_RESET_TX | LINK_CONTROL_RESET_RX
- | LINK_CONTROL_CYCSOURCE | LINK_CONTROL_CYCTIMEREN);
+ | LINK_CONTROL_CYCTIMEREN);
X
X /* attempt to enable contender bit -FIXME- would this work elsewhere? */
X reg_set_bits(lynx, GPIO_CTRL_A, 0x1);
@@ -559,14 +571,10 @@
X }
X }
X
-
-/*
- * FIXME - does not support iso/raw transmits yet and will choke on them.
- */
X static int lynx_transmit(struct hpsb_host *host, struct hpsb_packet *packet)
X {
X struct ti_lynx *lynx = host->hostdata;
- struct hpsb_packet *p;
+ struct lynx_send_data *d;


X unsigned long flags;
X

X if (packet->data_size >= 4096) {
@@ -575,27 +583,38 @@


X return 0;
X }
X

+ switch (packet->type) {
+ case async:
+ case raw:
+ d = &lynx->async;
+ break;
+ case iso:
+ d = &lynx->iso_send;
+ break;
+ default:
+ PRINT(KERN_ERR, lynx->id, "invalid packet type %d",
+ packet->type);


+ return 0;
+ }
+

X packet->xnext = NULL;
X if (packet->tcode == TCODE_WRITEQ
X || packet->tcode == TCODE_READQ_RESPONSE) {
X cpu_to_be32s(&packet->header[3]);
X }
X
- spin_lock_irqsave(&lynx->async.queue_lock, flags);
+ spin_lock_irqsave(&d->queue_lock, flags);
X
- if (lynx->async.queue == NULL) {
- lynx->async.queue = packet;
- send_next_async(lynx);
+ if (d->queue == NULL) {
+ d->queue = packet;
+ d->queue_last = packet;
+ send_next(lynx, packet->type);
X } else {
- p = lynx->async.queue;
- while (p->xnext != NULL) {
- p = p->xnext;
- }
-
- p->xnext = packet;
+ d->queue_last->xnext = packet;
+ d->queue_last = packet;
X }
X
- spin_unlock_irqrestore(&lynx->async.queue_lock, flags);
+ spin_unlock_irqrestore(&d->queue_lock, flags);
X
X return 1;
X }
@@ -652,7 +671,7 @@
X case CANCEL_REQUESTS:
X spin_lock_irqsave(&lynx->async.queue_lock, flags);
X
- reg_write(lynx, DMA3_CHAN_CTRL, 0);
+ reg_write(lynx, DMA_CHAN_CTRL(CHANNEL_ASYNC_SEND), 0);
X packet = lynx->async.queue;
X lynx->async.queue = NULL;
X
@@ -718,18 +737,19 @@
X static int mem_open(struct inode*, struct file*);
X static int mem_release(struct inode*, struct file*);
X static unsigned int aux_poll(struct file*, struct poll_table_struct*);
+static loff_t mem_llseek(struct file*, loff_t, int);
X static ssize_t mem_read (struct file*, char*, size_t, loff_t*);
X static ssize_t mem_write(struct file*, const char*, size_t, loff_t*);
X
X
X static struct file_operations aux_ops = {
X OWNER_THIS_MODULE
- /* FIXME: should have custom llseek with bounds checking */
- read: mem_read,
- write: mem_write,
- poll: aux_poll,
- open: mem_open,
- release: mem_release,
+ read: mem_read,
+ write: mem_write,
+ poll: aux_poll,
+ llseek: mem_llseek,
+ open: mem_open,
+ release: mem_release,
X };
X
X
@@ -745,7 +765,7 @@
X static int mem_open(struct inode *inode, struct file *file)
X {
X int cid = MINOR(inode->i_rdev);
- enum { rom, aux, ram } type;
+ enum { t_rom, t_aux, t_ram } type;
X struct memdata *md;
X
X V22_COMPAT_MOD_INC_USE_COUNT;
@@ -760,14 +780,14 @@
X V22_COMPAT_MOD_DEC_USE_COUNT;
X return -ENXIO;
X }
- type = aux;
+ type = t_aux;
X } else if (cid < PCILYNX_MINOR_RAM_START) {
X cid -= PCILYNX_MINOR_ROM_START;
X if (cid >= num_of_cards || !cards[cid].local_rom) {
X V22_COMPAT_MOD_DEC_USE_COUNT;
X return -ENXIO;
X }
- type = rom;
+ type = t_rom;
X } else {
X /* WARNING: Know what you are doing when opening RAM.
X * It is currently used inside the driver! */
@@ -776,10 +796,10 @@
X V22_COMPAT_MOD_DEC_USE_COUNT;
X return -ENXIO;
X }
- type = ram;
+ type = t_ram;
X }
X
- md = (struct memdata *)vmalloc(sizeof(struct memdata));
+ md = (struct memdata *)kmalloc(sizeof(struct memdata), SLAB_KERNEL);
X if (md == NULL) {
X V22_COMPAT_MOD_DEC_USE_COUNT;
X return -ENOMEM;
@@ -789,13 +809,13 @@
X md->cid = cid;
X
X switch (type) {
- case rom:
+ case t_rom:
X md->type = rom;
X break;
- case ram:
+ case t_ram:
X md->type = ram;
X break;
- case aux:
+ case t_aux:
X atomic_set(&md->aux_intr_last_seen,
X atomic_read(&cards[cid].aux_intr_seen));
X md->type = aux;


@@ -811,7 +831,7 @@
X {

X struct memdata *md = (struct memdata *)file->private_data;
X
- vfree(md);
+ kfree(md);
X
X V22_COMPAT_MOD_DEC_USE_COUNT;
X return 0;
@@ -839,6 +859,29 @@
X return mask;
X }
X
+loff_t mem_llseek(struct file *file, loff_t offs, int orig)
+{
+ loff_t newoffs;
+
+ switch (orig) {
+ case 0:
+ newoffs = offs;
+ break;
+ case 1:
+ newoffs = offs + file->f_pos;
+ break;
+ case 2:
+ newoffs = PCILYNX_MAX_MEMORY + 1 + offs;


+ break;
+ default:
+ return -EINVAL;
+ }
+

+ if (newoffs < 0 || newoffs > PCILYNX_MAX_MEMORY + 1) return -EINVAL;
+
+ file->f_pos = newoffs;
+ return newoffs;
+}
X
X /*
X * do not DMA if count is too small because this will have a serious impact
@@ -857,8 +900,6 @@
X int i;
X DECLARE_WAITQUEUE(wait, current);
X
- //printk("buf 0x%08x %x count %d offset %d\n", physbuf, physbuf % 3, count, offset);
-
X count &= ~3;
X count = MIN(count, 53196);
X retval = count;
@@ -868,17 +909,7 @@
X PRINT(KERN_WARNING, md->lynx->id, "DMA ALREADY ACTIVE!");
X }
X
- switch (md->type) {
- case rom:
- reg_write(md->lynx, LBUS_ADDR, LBUS_ADDR_SEL_ROM | offset);
- break;
- case ram:
- reg_write(md->lynx, LBUS_ADDR, LBUS_ADDR_SEL_RAM | offset);
- break;
- case aux:
- reg_write(md->lynx, LBUS_ADDR, LBUS_ADDR_SEL_AUX | offset);
- break;
- }
+ reg_write(md->lynx, LBUS_ADDR, md->type | offset);
X
X pcl = edit_pcl(md->lynx, md->lynx->dmem_pcl, &pcltmp);
X pcl->buffer[0].control = PCL_CMD_LBUS_TO_PCI | MIN(count, 4092);
@@ -933,7 +964,7 @@
X if ((off + count) > PCILYNX_MAX_MEMORY + 1) {
X count = PCILYNX_MAX_MEMORY + 1 - off;
X }
- if (count <= 0) {
+ if (count == 0) {


X return 0;
X }
X

@@ -1041,12 +1072,17 @@
X {
X struct ti_lynx *lynx = (struct ti_lynx *)dev_id;
X struct hpsb_host *host = lynx->host;
- u32 intmask = reg_read(lynx, PCI_INT_STATUS);
- u32 linkint = reg_read(lynx, LINK_INT_STATUS);
+ u32 intmask;
+ u32 linkint;
+
+ linkint = reg_read(lynx, LINK_INT_STATUS);
+ intmask = reg_read(lynx, PCI_INT_STATUS);
+
+ PRINTD(KERN_DEBUG, lynx->id, "interrupt: 0x%08x / 0x%08x", intmask,
+ linkint);
X
- reg_write(lynx, PCI_INT_STATUS, intmask);
X reg_write(lynx, LINK_INT_STATUS, linkint);
- //printk("-%d- one interrupt: 0x%08x / 0x%08x\n", lynx->id, intmask, linkint);
+ reg_write(lynx, PCI_INT_STATUS, intmask);
X
X #ifdef CONFIG_IEEE1394_PCILYNX_PORTS
X if (intmask & PCI_INT_AUX_INT) {
@@ -1054,7 +1090,7 @@
X wake_up_interruptible(&lynx->aux_intr_wait);
X }
X
- if (intmask & PCI_INT_DMA0_HLT) {
+ if (intmask & PCI_INT_DMA_HLT(CHANNEL_LOCALBUS)) {
X wake_up_interruptible(&lynx->mem_dma_intr_wait);
X }
X #endif
@@ -1125,14 +1161,13 @@
X mark_bh(IMMEDIATE_BH);
X }
X
- if (intmask & PCI_INT_DMA3_HLT) {
- /* async send DMA completed */
+ if (intmask & PCI_INT_DMA_HLT(CHANNEL_ASYNC_SEND)) {
X u32 ack;
X struct hpsb_packet *packet;
X
X spin_lock(&lynx->async.queue_lock);
X
- ack = reg_read(lynx, DMA3_CHAN_STAT);
+ ack = reg_read(lynx, DMA_CHAN_STAT(CHANNEL_ASYNC_SEND));
X packet = lynx->async.queue;
X lynx->async.queue = packet->xnext;
X
@@ -1144,7 +1179,7 @@
X }
X
X if (lynx->async.queue != NULL) {
- send_next_async(lynx);
+ send_next(lynx, async);
X }
X
X spin_unlock(&lynx->async.queue_lock);
@@ -1160,9 +1195,33 @@
X hpsb_packet_sent(host, packet, ack);
X }
X
- if (intmask & (PCI_INT_DMA1_HLT | PCI_INT_DMA1_PCL)) {
+ if (intmask & PCI_INT_DMA_HLT(CHANNEL_ISO_SEND)) {
+ struct hpsb_packet *packet;
+
+ spin_lock(&lynx->iso_send.queue_lock);
+
+ packet = lynx->iso_send.queue;
+ lynx->iso_send.queue = packet->xnext;
+
+ pci_unmap_single(lynx->dev, lynx->iso_send.header_dma,
+ packet->header_size, PCI_DMA_TODEVICE);
+ if (packet->data_size) {
+ pci_unmap_single(lynx->dev, lynx->iso_send.data_dma,
+ packet->data_size, PCI_DMA_TODEVICE);
+ }
+
+ if (lynx->iso_send.queue != NULL) {
+ send_next(lynx, iso);
+ }
+
+ spin_unlock(&lynx->iso_send.queue_lock);
+
+ hpsb_packet_sent(host, packet, ACK_COMPLETE);
+ }
+
+ if (intmask & PCI_INT_DMA_HLT(CHANNEL_ASYNC_RCV)) {
X /* general receive DMA completed */
- int stat = reg_read(lynx, DMA1_CHAN_STAT);
+ int stat = reg_read(lynx, DMA_CHAN_STAT(CHANNEL_ASYNC_RCV));
X
X PRINTD(KERN_DEBUG, lynx->id, "received packet size %d",
X stat & 0x1fff);
@@ -1182,7 +1241,7 @@
X hpsb_packet_received(host, q_data, stat & 0x1fff, 0);
X }
X
- run_pcl(lynx, lynx->rcv_pcl_start, 1);
+ run_pcl(lynx, lynx->rcv_pcl_start, CHANNEL_ASYNC_RCV);
X }
X }
X
@@ -1263,14 +1322,6 @@
X }
X pci_set_master(dev);
X
- if (!request_irq(dev->irq, lynx_irq_handler, SA_SHIRQ,
- PCILYNX_DRIVER_NAME, lynx)) {
- PRINT(KERN_INFO, lynx->id, "allocated interrupt %d", dev->irq);
- lynx->state = have_intr;
- } else {
- FAIL("failed to allocate shared interrupt %d", dev->irq);
- }
-
X #ifndef CONFIG_IEEE1394_PCILYNX_LOCALRAM
X lynx->pcl_mem = pci_alloc_consistent(dev, LOCALRAM_SIZE,
X &lynx->pcl_mem_dma);
@@ -1329,6 +1380,16 @@
X }
X #endif
X
+ reg_write(lynx, MISC_CONTROL, MISC_CONTROL_SWRESET);
+
+ if (!request_irq(dev->irq, lynx_irq_handler, SA_SHIRQ,
+ PCILYNX_DRIVER_NAME, lynx)) {
+ PRINT(KERN_INFO, lynx->id, "allocated interrupt %d", dev->irq);
+ lynx->state = have_intr;
+ } else {
+ FAIL("failed to allocate shared interrupt %d", dev->irq);
+ }
+
X /* alloc_pcl return values are not checked, it is expected that the
X * provided PCL space is sufficient for the initial allocations */
X #ifdef CONFIG_IEEE1394_PCILYNX_PORTS
@@ -1342,6 +1403,8 @@
X lynx->rcv_pcl_start = alloc_pcl(lynx);
X lynx->async.pcl = alloc_pcl(lynx);
X lynx->async.pcl_start = alloc_pcl(lynx);
+ lynx->iso_send.pcl = alloc_pcl(lynx);
+ lynx->iso_send.pcl_start = alloc_pcl(lynx);
X
X for (i = 0; i < NUM_ISORCV_PCL; i++) {
X lynx->iso_rcv.pcl[i] = alloc_pcl(lynx);
@@ -1362,6 +1425,11 @@
X lynx->iso_rcv.tq.routine = (void (*)(void*))iso_rcv_bh;
X lynx->iso_rcv.tq.data = lynx;
X lynx->iso_rcv.lock = SPIN_LOCK_UNLOCKED;
+
+ lynx->async.queue_lock = SPIN_LOCK_UNLOCKED;
+ lynx->async.channel = CHANNEL_ASYNC_SEND;
+ lynx->iso_send.queue_lock = SPIN_LOCK_UNLOCKED;
+ lynx->iso_send.channel = CHANNEL_ISO_SEND;
X
X PRINT(KERN_INFO, lynx->id, "remapped memory spaces reg 0x%p, rom 0x%p, "
X "ram 0x%p, aux 0x%p", lynx->registers, lynx->local_rom,
@@ -1388,6 +1456,8 @@
X int i;
X
X switch (lynx->state) {
+ case have_intr:
+ free_irq(lynx->dev->irq, lynx);
X case have_iomappings:
X reg_write(lynx, PCI_INT_ENABLE, 0);
X reg_write(lynx, MISC_CONTROL, MISC_CONTROL_SWRESET);
@@ -1410,13 +1480,11 @@
X pci_free_consistent(lynx->dev, 65536, lynx->mem_dma_buffer,
X lynx->mem_dma_buffer_dma);
X #endif
- case have_pcl_mem:
+ case have_pcl_mem:
X #ifndef CONFIG_IEEE1394_PCILYNX_LOCALRAM
X pci_free_consistent(lynx->dev, LOCALRAM_SIZE, lynx->pcl_mem,
X lynx->pcl_mem_dma);
X #endif
- case have_intr:
- free_irq(lynx->dev->irq, lynx);
X case clear:
X /* do nothing - already freed */
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/ieee1394/pcilynx.h linux/drivers/ieee1394/pcilynx.h
--- v2.4.0-test8/linux/drivers/ieee1394/pcilynx.h Wed Jul 5 13:03:56 2000
+++ linux/drivers/ieee1394/pcilynx.h Sun Oct 1 19:53:07 2000
@@ -19,11 +19,11 @@
X #define ISORCV_PER_PAGE (PAGE_SIZE / MAX_ISORCV_SIZE)
X #define ISORCV_PAGES (NUM_ISORCV_PCL / ISORCV_PER_PAGE)
X
-/* only iso rcv and localbus use these definitions so far */
X #define CHANNEL_LOCALBUS 0
X #define CHANNEL_ASYNC_RCV 1
X #define CHANNEL_ISO_RCV 2
X #define CHANNEL_ASYNC_SEND 3
+#define CHANNEL_ISO_SEND 4
X
X typedef int pcl_t;
X
@@ -88,12 +88,13 @@
X dma_addr_t rcv_page_dma;
X int rcv_active;
X
- struct {
+ struct lynx_send_data {
X pcl_t pcl_start, pcl;


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 051'
echo 'File patch-2.4.0-test9 is continued in part 052'
echo "052" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part052

#!/bin/sh -x
# this is part 052 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 052; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

- struct hpsb_packet *queue;
+ struct hpsb_packet *queue, *queue_last;
X spinlock_t queue_lock;
X dma_addr_t header_dma, data_dma;
- } async;
+ int channel;
+ } async, iso_send;
X
X struct {
X pcl_t pcl[NUM_ISORCV_PCL];
@@ -113,7 +114,8 @@
X struct ti_lynx *lynx;
X int cid;
X atomic_t aux_intr_last_seen;


- enum { rom, aux, ram } type;

+ /* enum values are the same as LBUS_ADDR_SEL_* values below */
+ enum { rom = 0x10000, aux = 0x20000, ram = 0 } type;
X };
X
X
@@ -147,6 +149,8 @@
X
X /* chip register definitions follow */
X
+#define PCI_LATENCY_CACHELINE 0x0c
+
X #define MISC_CONTROL 0x40
X #define MISC_CONTROL_SWRESET (1<<0)
X
@@ -495,6 +499,7 @@
X #define PCL_LAST_CMD (PCL_LAST_BUFF)
X #define PCL_WAITSTAT (1<<17)
X #define PCL_BIGENDIAN (1<<16)
+#define PCL_ISOMODE (1<<12)
X
X
X #define _(x) (__constant_cpu_to_be32(x))
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/ieee1394/raw1394.c linux/drivers/ieee1394/raw1394.c
--- v2.4.0-test8/linux/drivers/ieee1394/raw1394.c Wed Jul 12 21:58:42 2000
+++ linux/drivers/ieee1394/raw1394.c Sun Oct 1 19:53:07 2000
@@ -33,6 +33,15 @@
X #include "raw1394.h"
X
X
+#if BITS_PER_LONG == 64
+#define int2ptr(x) ((void *)x)
+#define ptr2int(x) ((u64)x)
+#else
+#define int2ptr(x) ((void *)(u32)x)
+#define ptr2int(x) ((u64)(u32)x)
+#endif
+
+
X static devfs_handle_t devfs_handle = NULL;
X
X LIST_HEAD(host_info_list);
@@ -204,8 +213,13 @@
X req->file_info = fi;
X req->req.type = RAW1394_REQ_BUS_RESET;
X req->req.generation = get_hpsb_generation();
- req->req.misc = (host->node_id << 16)
+ req->req.misc = (host->node_id << 16)
X | host->node_count;
+ if (fi->protocol_version > 3) {
+ req->req.misc |= ((host->irm_id
+ & NODE_MASK) << 8);
+ }
+
X queue_complete_req(req);
X }
X
@@ -268,7 +282,7 @@
X req->req.type = RAW1394_REQ_ISO_RECEIVE;
X req->req.generation = get_hpsb_generation();
X req->req.misc = 0;
- req->req.recvb = (u64)fi->iso_buffer;
+ req->req.recvb = ptr2int(fi->iso_buffer);
X req->req.length = MIN(length, fi->iso_buffer_length);
X
X list_add_tail(&req->list, &reqs);
@@ -337,7 +351,7 @@
X req->req.type = RAW1394_REQ_FCP_REQUEST;
X req->req.generation = get_hpsb_generation();
X req->req.misc = nodeid | (direction << 16);
- req->req.recvb = (u64)fi->fcp_buffer;
+ req->req.recvb = ptr2int(fi->fcp_buffer);
X req->req.length = length;
X
X list_add_tail(&req->list, &reqs);
@@ -387,7 +401,7 @@
X req = list_entry(lh, struct pending_request, list);
X
X if (req->req.length) {
- if (copy_to_user((void *)req->req.recvb, req->data,
+ if (copy_to_user(int2ptr(req->req.recvb), req->data,
X req->req.length)) {
X req->req.error = RAW1394_ERROR_MEMFAULT;
X }
@@ -402,11 +416,16 @@
X static int state_opened(struct file_info *fi, struct pending_request *req)
X {
X if (req->req.type == RAW1394_REQ_INITIALIZE) {
- if (req->req.misc == RAW1394_KERNELAPI_VERSION) {
+ switch (req->req.misc) {
+ case RAW1394_KERNELAPI_VERSION:
+ case 3:
X fi->state = initialized;
+ fi->protocol_version = req->req.misc;
X req->req.error = RAW1394_ERROR_NONE;
X req->req.generation = get_hpsb_generation();
- } else {


+ break;
+
+ default:

X req->req.error = RAW1394_ERROR_COMPAT;
X req->req.misc = RAW1394_KERNELAPI_VERSION;
X }
@@ -488,6 +507,10 @@
X req->req.error = RAW1394_ERROR_NONE;
X req->req.misc = (fi->host->node_id << 16)
X | fi->host->node_count;
+ if (fi->protocol_version > 3) {
+ req->req.misc |=
+ (fi->host->irm_id & NODE_MASK) << 8;
+ }
X } else {
X req->req.error = RAW1394_ERROR_INVALID_ARG;
X }
@@ -519,7 +542,7 @@
X } else {
X fi->listen_channels |= 1ULL << channel;
X hpsb_listen_channel(hl_handle, fi->host, channel);
- fi->iso_buffer = (void *)req->req.recvb;
+ fi->iso_buffer = int2ptr(req->req.recvb);
X fi->iso_buffer_length = req->req.length;
X }
X } else {
@@ -545,7 +568,7 @@
X if (fi->fcp_buffer) {
X req->req.error = RAW1394_ERROR_ALREADY;
X } else {
- fi->fcp_buffer = (u8 *)req->req.recvb;
+ fi->fcp_buffer = (u8 *)int2ptr(req->req.recvb);
X }
X } else {
X if (!fi->fcp_buffer) {
@@ -575,7 +598,7 @@
X break;
X
X case RAW1394_REQ_ASYNC_WRITE:
- if (copy_from_user(req->data, (void *)req->req.sendb,
+ if (copy_from_user(req->data, int2ptr(req->req.sendb),
X req->req.length)) {
X req->req.error = RAW1394_ERROR_MEMFAULT;
X break;
@@ -600,7 +623,7 @@
X }
X }
X
- if (copy_from_user(req->data, (void *)req->req.sendb,
+ if (copy_from_user(req->data, int2ptr(req->req.sendb),
X req->req.length)) {
X req->req.error = RAW1394_ERROR_MEMFAULT;
X break;
@@ -658,7 +681,7 @@
X if (req->req.length == 4) {
X quadlet_t x;
X
- if (copy_from_user(&x, (void *)req->req.sendb, 4)) {
+ if (copy_from_user(&x, int2ptr(req->req.sendb), 4)) {
X req->req.error = RAW1394_ERROR_MEMFAULT;
X }
X
@@ -670,7 +693,7 @@
X req->req.length);
X if (!packet) return -ENOMEM;
X
- if (copy_from_user(packet->data, (void *)req->req.sendb,
+ if (copy_from_user(packet->data, int2ptr(req->req.sendb),
X req->req.length)) {
X req->req.error = RAW1394_ERROR_MEMFAULT;
X }
@@ -696,7 +719,7 @@
X req->req.misc);
X if (!packet) return -ENOMEM;
X
- if (copy_from_user(packet->data, (void *)req->req.sendb,
+ if (copy_from_user(packet->data, int2ptr(req->req.sendb),
X req->req.length)) {
X req->req.error = RAW1394_ERROR_MEMFAULT;
X break;
@@ -735,12 +758,52 @@
X return sizeof(struct raw1394_request);
X }
X
+static int handle_iso_send(struct file_info *fi, struct pending_request *req,
+ int channel)
+{


+ struct hpsb_packet *packet;
+

+ packet = alloc_hpsb_packet(req->req.length);
+ if (!packet) return -ENOMEM;
+ req->packet = packet;
+
+ fill_iso_packet(packet, req->req.length, channel & 0x3f,
+ (req->req.misc >> 16) & 0x3, req->req.misc & 0xf);
+ packet->type = iso;
+ packet->speed_code = req->req.address & 0x3;
+ packet->host = fi->host;
+
+ if (copy_from_user(packet->data, int2ptr(req->req.sendb),
+ req->req.length)) {
+ req->req.error = RAW1394_ERROR_MEMFAULT;
+ req->req.length = 0;
+ queue_complete_req(req);
+ return sizeof(struct raw1394_request);
+ }
+
+ req->tq.data = req;
+ req->tq.routine = (void (*)(void*))queue_complete_req;
+ req->req.length = 0;
+ queue_task(&req->tq, &packet->complete_tq);
+
+ if (!hpsb_send_packet(packet)) {
+ req->req.error = RAW1394_ERROR_SEND_ERROR;
+ queue_complete_req(req);
+ }
+
+ return sizeof(struct raw1394_request);
+}
+
X static int state_connected(struct file_info *fi, struct pending_request *req)
X {
X int node = req->req.address >> 48;
X
X req->req.error = RAW1394_ERROR_NONE;
X
+ if (req->req.type == RAW1394_REQ_ISO_SEND) {
+ return handle_iso_send(fi, req, node);
+ }
+
X if (req->req.generation != get_hpsb_generation()) {
X req->req.error = RAW1394_ERROR_GENERATION;
X req->req.generation = get_hpsb_generation();
@@ -749,14 +812,18 @@
X return sizeof(struct raw1394_request);
X }
X
- if (req->req.type == RAW1394_REQ_ISO_LISTEN) {
+ switch (req->req.type) {
+ case RAW1394_REQ_ISO_LISTEN:
X handle_iso_listen(fi, req);
X return sizeof(struct raw1394_request);
- }
X
- if (req->req.type == RAW1394_REQ_FCP_LISTEN) {
+ case RAW1394_REQ_FCP_LISTEN:
X handle_fcp_listen(fi, req);
X return sizeof(struct raw1394_request);
+
+ case RAW1394_REQ_RESET_BUS:
+ hpsb_reset_bus(fi->host);
+ return sizeof(struct raw1394_request);
X }
X
X if (req->req.length == 0) {
@@ -870,7 +937,7 @@
X struct pending_request *req;
X int done = 0, i;
X
- lock_kernel();
+ lock_kernel();
X for (i = 0; i < 64; i++) {
X if (fi->listen_channels & (1ULL << i)) {
X hpsb_unlisten_channel(hl_handle, fi->host, i);
@@ -915,7 +982,7 @@
X kfree(fi);
X
X V22_COMPAT_MOD_DEC_USE_COUNT;
- unlock_kernel();
+ unlock_kernel();


X return 0;
X }
X

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/ieee1394/raw1394.h linux/drivers/ieee1394/raw1394.h
--- v2.4.0-test8/linux/drivers/ieee1394/raw1394.h Wed Jul 5 13:03:56 2000
+++ linux/drivers/ieee1394/raw1394.h Sun Oct 1 19:53:07 2000
@@ -4,7 +4,7 @@
X #define RAW1394_DEVICE_MAJOR 171
X #define RAW1394_DEVICE_NAME "raw1394"
X
-#define RAW1394_KERNELAPI_VERSION 3
+#define RAW1394_KERNELAPI_VERSION 4
X
X /* state: opened */
X #define RAW1394_REQ_INITIALIZE 1
@@ -18,9 +18,11 @@
X #define RAW1394_REQ_ASYNC_WRITE 101
X #define RAW1394_REQ_LOCK 102
X #define RAW1394_REQ_LOCK64 103
+#define RAW1394_REQ_ISO_SEND 104
X
X #define RAW1394_REQ_ISO_LISTEN 200
X #define RAW1394_REQ_FCP_LISTEN 201
+#define RAW1394_REQ_RESET_BUS 202
X
X /* kernel to user */
X #define RAW1394_REQ_BUS_RESET 10000
@@ -79,6 +81,7 @@
X struct list_head list;
X
X enum { opened, initialized, connected } state;
+ unsigned int protocol_version;
X
X struct hpsb_host *host;
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/ieee1394/video1394.c linux/drivers/ieee1394/video1394.c
--- v2.4.0-test8/linux/drivers/ieee1394/video1394.c Mon Aug 7 21:01:36 2000
+++ linux/drivers/ieee1394/video1394.c Sun Oct 1 19:53:07 2000
@@ -57,6 +57,10 @@
X #define ISO_RECEIVE 0
X #define ISO_TRANSMIT 1
X
+#ifndef virt_to_page
+#define virt_to_page(x) MAP_NR(x)
+#endif
+
X struct it_dma_prg {


X struct dma_cmd begin;
X quadlet_t data[4];

@@ -84,6 +88,7 @@
X int cmdPtr;
X int ctxMatch;
X wait_queue_head_t waitq;
+ spinlock_t lock;
X };
X
X struct video_card {
@@ -144,7 +149,7 @@
X */
X
X #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
-#define page_address(x) ((void *) (x))
+#define page_address(x) (x)
X #endif
X
X /* Given PGD from the address space's page table, return the kernel
@@ -163,7 +168,7 @@
X pte = *ptep;
X if(pte_present(pte)) {
X ret = (unsigned long) page_address(pte_page(pte));
- ret |= (adr & (PAGE_SIZE - 1));
+ ret |= (adr & (PAGE_SIZE - 1));
X }
X }
X }
@@ -212,7 +217,7 @@
X void * mem;
X unsigned long adr, page;
X
- mem=vmalloc(size);
+ mem=vmalloc_32(size);
X if (mem)
X {
X memset(mem, 0, size); /* Clear the ram out,
@@ -374,7 +379,7 @@
X
X d->packet_size = packet_size;
X
- if (PAGE_SIZE % packet_size || packet_size>2048) {
+ if (PAGE_SIZE % packet_size || packet_size>4096) {
X PRINT(KERN_ERR, ohci->id,
X "Packet size %d not yet supported\n",
X packet_size);


@@ -413,6 +418,8 @@
X }

X memset(d->buffer_status, 0, d->num_desc * sizeof(unsigned int));
X
+ spin_lock_init(&d->lock);
+
X PRINT(KERN_INFO, ohci->id, "Iso %s DMA: %d buffers "
X "of size %d allocated for a frame size %d, each with %d prgs",
X (type==ISO_RECEIVE) ? "receive" : "transmit",
@@ -531,12 +538,14 @@


X return -EFAULT;
X }
X

+ spin_lock(&d->lock);
X for (i=0;i<d->num_desc;i++) {
X if (d->ir_prg[i][d->nb_cmd-1].status & 0xFFFF0000) {
X reset_ir_status(d, i);
X d->buffer_status[i] = VIDEO1394_BUFFER_READY;
X }
X }
+ spin_unlock(&d->lock);
X if (waitqueue_active(&d->waitq)) wake_up_interruptible(&d->waitq);
X return 0;
X }
@@ -551,12 +560,14 @@


X return -EFAULT;
X }
X

+ spin_lock(&d->lock);
X for (i=0;i<d->num_desc;i++) {
X if (d->it_prg[i][d->nb_cmd-1].end.status & 0xFFFF0000) {
X d->it_prg[i][d->nb_cmd-1].end.status = 0;
X d->buffer_status[i] = VIDEO1394_BUFFER_READY;
X }
X }
+ spin_unlock(&d->lock);
X if (waitqueue_active(&d->waitq)) wake_up_interruptible(&d->waitq);
X return 0;
X }
@@ -664,6 +675,7 @@
X {
X struct video_card *video = &video_cards[MINOR(inode->i_rdev)];
X struct ti_ohci *ohci= video->ohci;


+ unsigned long flags;
X

X switch(cmd)
X {
@@ -832,9 +844,12 @@


X return -EFAULT;
X }
X

- if (d->buffer_status[v.buffer]!=VIDEO1394_BUFFER_FREE) {
+ spin_lock_irqsave(&d->lock,flags);
+
+ if (d->buffer_status[v.buffer]==VIDEO1394_BUFFER_QUEUED) {
X PRINT(KERN_ERR, ohci->id,
X "buffer %d is already used",v.buffer);
+ spin_unlock_irqrestore(&d->lock,flags);


X return -EFAULT;
X }
X

@@ -849,6 +864,8 @@
X

X d->ir_prg[d->last_buffer][d->nb_cmd-1].branchAddress = 0;
X
+ spin_unlock_irqrestore(&d->lock,flags);
+
X if (!(reg_read(ohci, d->ctrlSet) & 0x8000))
X {
X DBGMSG(ohci->id, "Starting iso DMA ctx=%d",d->ctx);
@@ -890,16 +907,26 @@


X return -EFAULT;
X }
X
+ /*

+ * I change the way it works so that it returns
+ * the last received frame.
+ */
+ spin_lock_irqsave(&d->lock, flags);
X switch(d->buffer_status[v.buffer]) {
X case VIDEO1394_BUFFER_READY:
X d->buffer_status[v.buffer]=VIDEO1394_BUFFER_FREE;
- return 0;
+ break;
X case VIDEO1394_BUFFER_QUEUED:
X #if 1
X while(d->buffer_status[v.buffer]!=
X VIDEO1394_BUFFER_READY) {
+ spin_unlock_irqrestore(&d->lock, flags);
X interruptible_sleep_on(&d->waitq);
- if(signal_pending(current)) return -EINTR;
+ spin_lock_irqsave(&d->lock, flags);
+ if(signal_pending(current)) {
+ spin_unlock_irqrestore(&d->lock,flags);
+ return -EINTR;
+ }
X }
X #else
X if (wait_event_interruptible(d->waitq,
@@ -909,12 +936,30 @@
X return -EINTR;
X #endif
X d->buffer_status[v.buffer]=VIDEO1394_BUFFER_FREE;
- return 0;
+ break;
X default:
X PRINT(KERN_ERR, ohci->id,
X "buffer %d is not queued",v.buffer);
+ spin_unlock_irqrestore(&d->lock, flags);
X return -EFAULT;
X }
+
+ /*
+ * Look ahead to see how many more buffers have been received
+ */
+ i=0;
+ while (d->buffer_status[(v.buffer+1)%d->num_desc]==
+ VIDEO1394_BUFFER_READY) {
+ v.buffer=(v.buffer+1)%d->num_desc;
+ i++;
+ }
+ spin_unlock_irqrestore(&d->lock, flags);
+
+ v.buffer=i;
+ if(copy_to_user((void *)arg, &v, sizeof(v)))
+ return -EFAULT;


+
+ return 0;
X }

X case VIDEO1394_TALK_QUEUE_BUFFER:
X {
@@ -935,9 +980,12 @@


X return -EFAULT;
X }
X

+ spin_lock_irqsave(&d->lock,flags);
+
X if (d->buffer_status[v.buffer]!=VIDEO1394_BUFFER_FREE) {
X PRINT(KERN_ERR, ohci->id,
X "buffer %d is already used",v.buffer);
+ spin_unlock_irqrestore(&d->lock,flags);


X return -EFAULT;
X }
X

@@ -957,6 +1005,8 @@
X d->last_buffer = v.buffer;
X
X d->it_prg[d->last_buffer][d->nb_cmd-1].end.branchAddress = 0;
+
+ spin_unlock_irqrestore(&d->lock,flags);
X
X if (!(reg_read(ohci, d->ctrlSet) & 0x8000))
X {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/ieee1394/video1394.h linux/drivers/ieee1394/video1394.h
--- v2.4.0-test8/linux/drivers/ieee1394/video1394.h Wed Jul 5 13:03:56 2000
+++ linux/drivers/ieee1394/video1394.h Sun Oct 1 19:53:07 2000
@@ -22,7 +22,7 @@
X
X #define VIDEO1394_DRIVER_NAME "video1394"
X
-#define VIDEO1394_MAX_SIZE 0x400000
+#define VIDEO1394_MAX_SIZE 0x4000000
X
X enum {
X VIDEO1394_BUFFER_FREE = 0,
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/isdn/avmb1/b1.c linux/drivers/isdn/avmb1/b1.c
--- v2.4.0-test8/linux/drivers/isdn/avmb1/b1.c Mon Aug 21 07:49:02 2000
+++ linux/drivers/isdn/avmb1/b1.c Mon Sep 18 15:02:02 2000
@@ -517,7 +517,7 @@
X struct sk_buff *skb;
X
X unsigned ApplId;
- unsigned MsgLen;
+ signed MsgLen;
X unsigned DataB3Len;
X unsigned NCCI;
X unsigned WindowSize;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/isdn/avmb1/b1dma.c linux/drivers/isdn/avmb1/b1dma.c
--- v2.4.0-test8/linux/drivers/isdn/avmb1/b1dma.c Mon Aug 21 07:49:02 2000
+++ linux/drivers/isdn/avmb1/b1dma.c Mon Sep 18 15:02:02 2000
@@ -475,7 +475,8 @@
X struct capi_ctr *ctrl = cinfo->capi_ctrl;
X struct sk_buff *skb;
X void *p = dma->recvbuf+4;
- __u32 ApplId, MsgLen, DataB3Len, NCCI, WindowSize;
+ __u32 ApplId, DataB3Len, NCCI, WindowSize;
+ __s32 MsgLen;
X __u8 b1cmd = _get_byte(&p);
X
X #ifdef CONFIG_B1DMA_DEBUG
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/isdn/avmb1/c4.c linux/drivers/isdn/avmb1/c4.c
--- v2.4.0-test8/linux/drivers/isdn/avmb1/c4.c Mon Aug 21 07:49:02 2000
+++ linux/drivers/isdn/avmb1/c4.c Mon Sep 18 15:02:02 2000
@@ -572,7 +572,8 @@
X avmctrl_info *cinfo;
X struct sk_buff *skb;
X void *p = dma->recvbuf;
- __u32 ApplId, MsgLen, DataB3Len, NCCI, WindowSize;
+ __u32 ApplId, DataB3Len, NCCI, WindowSize;
+ __s32 MsgLen;
X __u8 b1cmd = _get_byte(&p);
X __u32 cidx;
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/isdn/avmb1/capi.c linux/drivers/isdn/avmb1/capi.c
--- v2.4.0-test8/linux/drivers/isdn/avmb1/capi.c Mon Aug 21 07:49:02 2000
+++ linux/drivers/isdn/avmb1/capi.c Sun Sep 17 09:45:05 2000
@@ -212,6 +212,7 @@
X #include <linux/capi.h>
X #include <linux/kernelcapi.h>
X #include <linux/devfs_fs_kernel.h>
+#include <linux/init.h>
X #include "capiutil.h"
X #include "capicmd.h"
X #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
@@ -1930,7 +1931,7 @@
X { "capi/capi20ncci", 0 , proc_capincci_read_proc },
X };
X
-static void proc_init(void)
+static void __init proc_init(void)
X {
X int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]);
X int i;
@@ -1942,7 +1943,7 @@
X }
X }
X
-static void proc_exit(void)
+static void __exit proc_exit(void)
X {
X int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]);
X int i;
@@ -1981,7 +1982,7 @@
X #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
X }
X
-static int alloc_init(void)
+static int __init alloc_init(void)
X {
X capidev_cachep = kmem_cache_create("capi20_dev",
X sizeof(struct capidev),
@@ -2052,10 +2053,6 @@
X }
X }
X
-#ifdef MODULE
-#define capi_init init_module
-#endif
-
X static struct capi_interface_user cuser = {
X "capi20",
X lower_callback,
@@ -2063,7 +2060,7 @@
X
X static char rev[10];
X
-int capi_init(void)
+int __init capi_init(void)
X {
X char *p;
X
@@ -2152,8 +2149,7 @@


X return 0;
X }
X

-#ifdef MODULE
-void cleanup_module(void)
+static void __exit capi_exit(void)
X {
X #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
X unsigned int j;
@@ -2177,4 +2173,8 @@
X printk(KERN_NOTICE "capi: Rev%s: unloaded\n", rev);
X }
X
+#ifdef MODULE
+module_init(capi_init);
X #endif
+module_exit(capi_exit);
+
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/isdn/avmb1/capidrv.c linux/drivers/isdn/avmb1/capidrv.c
--- v2.4.0-test8/linux/drivers/isdn/avmb1/capidrv.c Mon Aug 21 07:49:02 2000
+++ linux/drivers/isdn/avmb1/capidrv.c Sun Sep 17 09:45:05 2000
@@ -200,6 +200,7 @@
X #include <linux/capi.h>
X #include <linux/kernelcapi.h>
X #include <linux/ctype.h>
+#include <linux/init.h>
X #include <asm/segment.h>
X
X #include "capiutil.h"
@@ -2436,7 +2437,7 @@
X { "capi/capidrv", 0 , proc_capidrv_read_proc },
X };
X
-static void proc_init(void)
+static void __init proc_init(void)
X {
X int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]);
X int i;
@@ -2448,7 +2449,7 @@
X }
X }
X
-static void proc_exit(void)
+static void __exit proc_exit(void)
X {
X int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]);
X int i;
@@ -2467,11 +2468,7 @@
X lower_callback
X };
X
-#ifdef MODULE
-#define capidrv_init init_module
-#endif
-
-int capidrv_init(void)
+int __init capidrv_init(void)
X {
X struct capi_register_params rparam;
X capi_profile profile;
@@ -2531,8 +2528,7 @@


X return 0;
X }
X

-#ifdef MODULE
-void cleanup_module(void)
+static void __exit capidrv_exit(void)
X {
X char rev[10];
X char *p;
@@ -2554,4 +2550,8 @@
X printk(KERN_NOTICE "capidrv: Rev%s: unloaded\n", rev);
X }
X
+#ifdef MODULE
+module_init(capidrv_init);
X #endif
+module_exit(capidrv_exit);
+
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/isdn/avmb1/t1isa.c linux/drivers/isdn/avmb1/t1isa.c
--- v2.4.0-test8/linux/drivers/isdn/avmb1/t1isa.c Mon Aug 21 07:49:02 2000
+++ linux/drivers/isdn/avmb1/t1isa.c Mon Sep 18 15:02:02 2000
@@ -200,7 +200,7 @@
X struct sk_buff *skb;
X
X unsigned ApplId;
- unsigned MsgLen;
+ signed MsgLen;
X unsigned DataB3Len;
X unsigned NCCI;
X unsigned WindowSize;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/isdn/eicon/Divas_mod.c linux/drivers/isdn/eicon/Divas_mod.c
--- v2.4.0-test8/linux/drivers/isdn/eicon/Divas_mod.c Mon Aug 14 13:09:07 2000
+++ linux/drivers/isdn/eicon/Divas_mod.c Wed Sep 27 13:45:40 2000
@@ -42,11 +42,13 @@
X
X #ifdef MODULE
X #include "idi.h"
-void EtdM_DIDD_Write(DESCRIPTOR *, int);
-EXPORT_SYMBOL_NOVERS(EtdM_DIDD_Read);
-EXPORT_SYMBOL_NOVERS(EtdM_DIDD_Write);
+void DIVA_DIDD_Write(DESCRIPTOR *, int);
+EXPORT_SYMBOL_NOVERS(DIVA_DIDD_Read);
+EXPORT_SYMBOL_NOVERS(DIVA_DIDD_Write);
X EXPORT_SYMBOL_NOVERS(DivasPrintf);
X #define Divas_init init_module
+#else
+#define Divas_init eicon_init
X #endif
X
X extern char *file_check(void);
@@ -58,7 +60,7 @@
X {
X printk(KERN_DEBUG "DIVA Server Driver - initialising\n");
X
- printk(KERN_DEBUG "DIVA Server Driver - Version 2.0.12 (%s)\n",file_check());
+ printk(KERN_DEBUG "DIVA Server Driver - Version 2.0.15 (%s)\n",file_check());
X
X
X #if !defined(CONFIG_PCI)
@@ -164,9 +166,5 @@
X MOD_DEC_USE_COUNT;
X }
X
-#else
-Divas_setup(char *str, int *ints)
-{
-}
X #endif
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/isdn/eicon/common.c linux/drivers/isdn/eicon/common.c
--- v2.4.0-test8/linux/drivers/isdn/eicon/common.c Sun Aug 13 10:05:32 2000
+++ linux/drivers/isdn/eicon/common.c Wed Sep 27 13:45:40 2000
@@ -81,29 +81,33 @@
X dia_config_t *DivasConfig(card_t *, dia_config_t *);
X
X static
-DESCRIPTOR DIDD_Table[16];
-static
-int DIDD_Length = 0;
+DESCRIPTOR DIDD_Table[32];
X
-void EtdM_DIDD_Read( DESCRIPTOR *table, int *tablelength )
+void DIVA_DIDD_Read( DESCRIPTOR *table, int tablelength )
X {
- int table_size = sizeof(DIDD_Table);
+ bzero(table, tablelength);
+
+ if (tablelength > sizeof(DIDD_Table))
+ tablelength = sizeof(DIDD_Table);
X
- bcopy((caddr_t)DIDD_Table, (caddr_t)table, table_size);
+ if(tablelength % sizeof(DESCRIPTOR)) {
+ tablelength /= sizeof(DESCRIPTOR);
+ tablelength *= sizeof(DESCRIPTOR);
+ }
X
- *tablelength = DIDD_Length;
+ if (tablelength > 0)
+ bcopy((caddr_t)DIDD_Table, (caddr_t)table, tablelength);
X

X return;
X }
X
X static

-void EtdM_DIDD_Write(DESCRIPTOR *table, int tablelength)
+void DIVA_DIDD_Write(DESCRIPTOR *table, int tablelength)
X {
- int table_size = sizeof(DIDD_Table);
-
- bcopy((caddr_t)table, (caddr_t)DIDD_Table, table_size);
+ if (tablelength > sizeof(DIDD_Table))
+ tablelength = sizeof(DIDD_Table);
X
- DIDD_Length = tablelength;
+ bcopy((caddr_t)table, (caddr_t)DIDD_Table, tablelength);
X
X return;
X }
@@ -111,19 +115,16 @@
X static
X void init_idi_tab(void)
X {
- int length = 0;
+ DESCRIPTOR d[32];
X
- DESCRIPTOR d[16];
+ bzero(d, sizeof(d));
X
- EtdM_DIDD_Read(d, &length);
-
- d[length].type = IDI_DIMAINT; /* identify the DIMAINT entry */
- d[length].channels = 0; /* zero channels associated with dimaint*/
- d[length].features = 0; /* no features associated with dimaint */
- d[length].request = (IDI_CALL) DivasPrintf;
- length++;
+ d[0].type = IDI_DIMAINT; /* identify the DIMAINT entry */
+ d[0].channels = 0; /* zero channels associated with dimaint*/
+ d[0].features = 0; /* no features associated with dimaint */
+ d[0].request = (IDI_CALL) DivasPrintf;
X
- EtdM_DIDD_Write(d, length);
+ DIVA_DIDD_Write(d, sizeof(d));
X
X return;
X }


@@ -663,7 +664,7 @@
X

X static int idi_register(card_t *card, byte channels)
X {
- DESCRIPTOR d[16];
+ DESCRIPTOR d[32];
X int length, num_entities;
X
X DPRINTF(("divas: registering card with IDI"));
@@ -680,9 +681,12 @@
X bzero(card->e_tbl, sizeof(E_INFO) * num_entities);
X card->e_max = num_entities;
X
- EtdM_DIDD_Read(d, &length);
+ DIVA_DIDD_Read(d, sizeof(d));
+
+ for(length=0; length < DIM(d); length++)
+ if (d[length].type == 0) break;
X
- if (length == DIM(d))
+ if (length >= DIM(d))
X {
X KDPRINTF((KERN_WARNING "Divas: IDI register failed - table full"));
X return -1;
@@ -692,18 +696,18 @@
X {
X case DIA_CARD_TYPE_DIVA_SERVER:
X d[length].type = IDI_ADAPTER_PR;
- d[length].serial = card->serial_no;
+ /* d[length].serial = card->serial_no; */
X break;
X
X case DIA_CARD_TYPE_DIVA_SERVER_B:
X d[length].type = IDI_ADAPTER_MAESTRA;
- d[length].serial = card->serial_no;
+ /* d[length].serial = card->serial_no; */
X break;
X
X // 4BRI is treated as 4 BRI adapters
X case DIA_CARD_TYPE_DIVA_SERVER_Q:
X d[length].type = IDI_ADAPTER_MAESTRA;
- d[length].serial = card->cfg.serial;
+ /* d[length].serial = card->cfg.serial; */
X }
X
X d[length].features = 0;
@@ -727,7 +731,7 @@
X
X length++;
X
- EtdM_DIDD_Write(d, length);
+ DIVA_DIDD_Write(d, sizeof(d));
X
X return 0;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/isdn/eicon/eicon_mod.c linux/drivers/isdn/eicon/eicon_mod.c
--- v2.4.0-test8/linux/drivers/isdn/eicon/eicon_mod.c Sun Aug 13 10:05:32 2000
+++ linux/drivers/isdn/eicon/eicon_mod.c Wed Sep 27 13:45:40 2000
@@ -1,4 +1,4 @@
-/* $Id: eicon_mod.c,v 1.35 2000/08/12 18:00:47 armin Exp $
+/* $Id: eicon_mod.c,v 1.37 2000/09/02 11:16:47 armin Exp $
X *
X * ISDN lowlevel-module for Eicon active cards.
X *
@@ -32,7 +32,7 @@
X
X #define DRIVERNAME "Eicon active ISDN driver"
X #define DRIVERRELEASE "2.0"
-#define DRIVERPATCH ".14"
+#define DRIVERPATCH ".15"
X
X
X #include <linux/config.h>
@@ -55,7 +55,7 @@
X static eicon_card *cards = (eicon_card *) NULL; /* glob. var , contains
X start of card-list */
X
-static char *eicon_revision = "$Revision: 1.35 $";
+static char *eicon_revision = "$Revision: 1.37 $";
X
X extern char *eicon_pci_revision;
X extern char *eicon_isa_revision;
@@ -78,8 +78,7 @@
X
X spinlock_t eicon_lock;
X
-DESCRIPTOR idi_d[16];
-int idi_dlength;
+DESCRIPTOR idi_d[32];
X
X /* Parameters to be set by insmod */
X #ifdef CONFIG_ISDN_DRV_EICON_ISA
@@ -210,6 +209,7 @@
X #ifdef CONFIG_PCI
X #ifdef CONFIG_ISDN_DRV_EICON_PCI
X dia_start_t dstart;
+ int idi_length = 0;
X #endif
X #endif
X isdn_ctrl cmd;
@@ -399,8 +399,15 @@
X (unsigned long) a);
X if (((c->arg - EICON_IOCTL_DIA_OFFSET)==DIA_IOCTL_START) && (!ret)) {
X if (card->type != EICON_CTYPE_MAESTRAQ) {
- EtdM_DIDD_Read(idi_d, &idi_dlength);
- card->d = &idi_d[idi_dlength - 1];
+ DIVA_DIDD_Read(idi_d, sizeof(idi_d));
+ for(idi_length = 0; idi_length < 32; idi_length++) {
+ if (idi_d[idi_length].type == 0) break;
+ }
+ if ((idi_length < 1) || (idi_length >= 32)) {
+ eicon_log(card, 1, "eicon: invalid idi table length.\n");
+ break;
+ }
+ card->d = &idi_d[idi_length - 1];
X card->flags |= EICON_FLAGS_LOADED;
X card->flags |= EICON_FLAGS_RUNNING;
X eicon_pci_init_conf(card);
@@ -414,19 +421,25 @@
X cmd.driver = card->myid;
X cmd.arg = 0;
X card->interface.statcallb(&cmd);
- eicon_log(card, 1, "Eicon: %s started, %d channels (feat. 0x%x, SerNo. %d)\n",
+ eicon_log(card, 1, "Eicon: %s started, %d channels (feat. 0x%x)\n",
X (card->type == EICON_CTYPE_MAESTRA) ? "BRI" : "PRI",
- card->d->channels, card->d->features, card->d->serial);
+ card->d->channels, card->d->features);
X } else {
X int i;
- EtdM_DIDD_Read(idi_d, &idi_dlength);
+ DIVA_DIDD_Read(idi_d, sizeof(idi_d));
+ for(idi_length = 0; idi_length < 32; idi_length++)
+ if (idi_d[idi_length].type == 0) break;
+ if ((idi_length < 1) || (idi_length >= 32)) {
+ eicon_log(card, 1, "eicon: invalid idi table length.\n");
+ break;
+ }
X for(i = 3; i >= 0; i--) {
X if (!(card = eicon_findnpcicard(dstart.card_id - i)))
X return -EINVAL;
X
X card->flags |= EICON_FLAGS_LOADED;
X card->flags |= EICON_FLAGS_RUNNING;
- card->d = &idi_d[idi_dlength - (i+1)];
+ card->d = &idi_d[idi_length - (i+1)];
X eicon_pci_init_conf(card);
X if (card->d->channels > 1) {
X cmd.command = ISDN_STAT_ADDCH;
@@ -438,8 +451,8 @@
X cmd.driver = card->myid;
X cmd.arg = 0;
X card->interface.statcallb(&cmd);
- eicon_log(card, 1, "Eicon: %d/4BRI started, %d channels (feat. 0x%x, SerNo. %d)\n",
- 4-i, card->d->channels, card->d->features, card->d->serial);
+ eicon_log(card, 1, "Eicon: %d/4BRI started, %d channels (feat. 0x%x)\n",
+ 4-i, card->d->channels, card->d->features);
X }
X }
X }
@@ -1392,9 +1405,9 @@
X }
X
X #ifdef CONFIG_ISDN_DRV_EICON_PCI
-void EtdM_DIDD_Write(DESCRIPTOR *, int);
-EXPORT_SYMBOL_NOVERS(EtdM_DIDD_Read);
-EXPORT_SYMBOL_NOVERS(EtdM_DIDD_Write);
+void DIVA_DIDD_Write(DESCRIPTOR *, int);
+EXPORT_SYMBOL_NOVERS(DIVA_DIDD_Read);
+EXPORT_SYMBOL_NOVERS(DIVA_DIDD_Write);
X EXPORT_SYMBOL_NOVERS(DivasPrintf);
X #else
X int DivasCardNext;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/isdn/eicon/idi.h linux/drivers/isdn/eicon/idi.h
--- v2.4.0-test8/linux/drivers/isdn/eicon/idi.h Sun Aug 13 10:05:32 2000
+++ linux/drivers/isdn/eicon/idi.h Wed Sep 27 13:45:40 2000
@@ -112,11 +112,11 @@
X byte type;
X byte channels;
X word features;
- dword serial;
+ /* dword serial; */
X IDI_CALL request;
X } DESCRIPTOR;
X
-extern void EtdM_DIDD_Read(DESCRIPTOR *, int *);
+extern void DIVA_DIDD_Read(DESCRIPTOR *, int);
X
X /* descriptor type field coding */
X #define IDI_ADAPTER_S 1
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/isdn/eicon/md5sums.asc linux/drivers/isdn/eicon/md5sums.asc
--- v2.4.0-test8/linux/drivers/isdn/eicon/md5sums.asc Sun Aug 13 10:05:32 2000
+++ linux/drivers/isdn/eicon/md5sums.asc Wed Sep 27 13:45:40 2000
@@ -3,7 +3,7 @@
X # For changes and modifications in these files please
X # read ../../../Documentation/isdn/README.eicon
X #
-9b0e381d4558af3a6eba66843e1ee5d9 common.c
+34bfe8d08d337a97c699ac8326f1d9b6 common.c
X dbb92cba52db31ff8325a252b3f595c3 idi.c
X 15687687ef82f099966ed42772001cd3 bri.c
X c3e3b720c3351b66635bd548195e29e8 pri.c
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/isdn/hisax/hfc_pci.c linux/drivers/isdn/hisax/hfc_pci.c
--- v2.4.0-test8/linux/drivers/isdn/hisax/hfc_pci.c Mon Aug 21 07:49:03 2000
+++ linux/drivers/isdn/hisax/hfc_pci.c Tue Sep 19 08:01:34 2000
@@ -1686,6 +1686,7 @@
X printk(KERN_WARNING "HFC-PCI: No PCI card found\n");
X return (0);
X }
+#ifdef notdef
X if (((int) cs->hw.hfcpci.pci_io & (PAGE_SIZE - 1))) {
X printk(KERN_WARNING "HFC-PCI shared mem address will be corrected\n");
X pcibios_write_config_word(cs->hw.hfcpci.pci_bus,
@@ -1719,6 +1720,7 @@
X }
X dev_hfcpci->resource[1].start = (int) cs->hw.hfcpci.pci_io;
X }
+#endif
X if (!cs->hw.hfcpci.pci_io) {
X printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n");
X return (0);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/macintosh/Makefile linux/drivers/macintosh/Makefile
--- v2.4.0-test8/linux/drivers/macintosh/Makefile Sat May 20 12:07:56 2000
+++ linux/drivers/macintosh/Makefile Sun Sep 17 09:48:05 2000
@@ -9,76 +9,67 @@
X # parent makes..
X #
X
-SUB_DIRS :=
-MOD_SUB_DIRS := $(SUB_DIRS)
+# Subdirs.
X
-O_TARGET := macintosh.o
-O_OBJS :=
-M_OBJS :=


+SUB_DIRS :=
+MOD_SUB_DIRS := $(SUB_DIRS)

+MOD_IN_SUB_DIRS := $(SUB_DIRS)
+ALL_SUB_DIRS := $(SUB_DIRS)
X
-ifeq ($(CONFIG_PMAC_PBOOK),y)
- O_OBJS += mediabay.o
-else
- ifeq ($(CONFIG_MAC_FLOPPY),y)
- O_OBJS += mediabay.o
- endif
-endif
+# The target object and module list name.
X
-ifeq ($(CONFIG_MAC_SERIAL),y)
- O_OBJS += macserial.o
-else
- ifeq ($(CONFIG_MAC_SERIAL),m)
- M_OBJS += macserial.o
- endif
-endif
+O_TARGET := macintosh.o
+M_OBJS :=
+O_OBJS :=
+MOD_LIST_NAME := MACINTOSH_MODULES
X
-ifeq ($(CONFIG_NVRAM),y)
- O_OBJS += nvram.o
-else
- ifeq ($(CONFIG_NVRAM),m)
- M_OBJS += nvram.o
- endif
-endif
+# Objects that export symbols.
X
-ifdef CONFIG_ADB
- OX_OBJS := adb.o
-endif
+export-objs := adb.o rtc.o mac_hid.o
X
-ifdef CONFIG_ADB_KEYBOARD
- O_OBJS += mac_keyb.o
-endif
+# Object file lists.
X
-ifdef CONFIG_ADB_MACII
- O_OBJS += via-macii.o
-endif
+obj-y :=
+obj-m :=
+obj-n :=
+obj- :=
X
-ifdef CONFIG_ADB_MACIISI
- O_OBJS += via-maciisi.o
-endif
+# Each configuration option enables a list of files.
X
-ifdef CONFIG_ADB_CUDA
- O_OBJS += via-cuda.o
+ifeq ($(CONFIG_PMAC_PBOOK),y)
+ obj-y += mediabay.o
X endif
X
-ifdef CONFIG_ADB_IOP
- O_OBJS += adb-iop.o
-endif
+obj-$(CONFIG_MAC_SERIAL) += macserial.o
+obj-$(CONFIG_NVRAM) += nvram.o
+obj-$(CONFIG_MAC_HID) += mac_hid.o
+obj-$(CONFIG_INPUT_ADBHID) += adbhid.o
+obj-$(CONFIG_PPC_RTC) += rtc.o
X
-ifdef CONFIG_ADB_PMU
- O_OBJS += via-pmu.o
-endif
+obj-$(CONFIG_ADB_PMU) += via-pmu.o
+obj-$(CONFIG_ADB_CUDA) += via-cuda.o
X
-ifdef CONFIG_ADB_PMU68K
- O_OBJS += via-pmu68k.o
-endif
+obj-$(CONFIG_ADB) += adb.o
+obj-$(CONFIG_ADB_KEYBOARD) += mac_keyb.o
+obj-$(CONFIG_ADB_MACII) += via-macii.o
+obj-$(CONFIG_ADB_MACIISI) += via-maciisi.o
+obj-$(CONFIG_ADB_IOP) += adb-iop.o
+obj-$(CONFIG_ADB_PMU68K) += via-pmu68k.o
+obj-$(CONFIG_ADB_MACIO) += macio-adb.o
X
-ifdef CONFIG_ADB_MACIO
- O_OBJS += macio-adb.o
-endif
+# Files that are both resident and modular: remove from modular.
+
+obj-m := $(filter-out $(obj-y), $(obj-m))
+int-m := $(filter-out $(int-y), $(int-m))
+
+# Translate to Rules.make lists.
+
+O_OBJS := $(sort $(filter-out $(export-objs), $(obj-y)))
+OX_OBJS := $(sort $(filter $(export-objs), $(obj-y)))
+M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m)))
+MX_OBJS := $(sort $(filter $(export-objs), $(obj-m)))
+
+# The global Rules.make.
X
X include $(TOPDIR)/Rules.make
X
-# Integrated in mac_keyb.c
-# mackeymap.map is retained for historical reasons
-#mackeymap.c: mackeymap.map
-# loadkeys --mktable mackeymap.map > mackeymap.c
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/macintosh/adb.c linux/drivers/macintosh/adb.c
--- v2.4.0-test8/linux/drivers/macintosh/adb.c Wed Jul 12 21:58:42 2000
+++ linux/drivers/macintosh/adb.c Sun Sep 17 09:48:05 2000
@@ -393,6 +393,15 @@
X return ids->nids;
X }
X
+int
+adb_unregister(int index)
+{
+ if (!adb_handler[index].handler)
+ return -ENODEV;
+ adb_handler[index].handler = 0;


+ return 0;
+}
+

X void
X adb_input(unsigned char *buf, int nb, struct pt_regs *regs, int autopoll)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/macintosh/adbhid.c linux/drivers/macintosh/adbhid.c
--- v2.4.0-test8/linux/drivers/macintosh/adbhid.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/macintosh/adbhid.c Sun Sep 17 09:48:05 2000
@@ -0,0 +1,875 @@
+/*
+ * drivers/input/adbhid.c
+ *
+ * ADB HID driver for Power Macintosh computers.
+ *
+ * Adapted from drivers/macintosh/mac_keyb.c by Franz Sirl
+ * (see that file for its authors and contributors).
+ *
+ * Copyright (C) 2000 Franz Sirl.
+ *
+ * Adapted to ADB changes and support for more devices by
+ * Benjamin Herrenschmidt. Adapted from code in MkLinux
+ * and reworked.
+ *
+ * Supported devices:
+ *
+ * - Standard 1 button mouse
+ * - All standard Apple Extended protocol (handler ID 4)
+ * - mouseman and trackman mice & trackballs
+ * - PowerBook Trackpad (default setup: enable tapping)
+ * - MicroSpeed mouse & trackball (needs testing)
+ * - CH Products Trackball Pro (needs testing)
+ * - Contour Design (Contour Mouse)
+ * - Hunter digital (NoHandsMouse)
+ * - Kensignton TurboMouse 5 (needs testing)
+ * - Mouse Systems A3 mice and trackballs <ai...@kublai.com>
+ * - MacAlly 2-buttons mouse (needs testing) <poc...@denise.shiny.it>
+ *
+ * To do:
+ *
+ * Improve Kensington support.


+ */
+
+#include <linux/config.h>
+#include <linux/module.h>

+#include <linux/malloc.h>
+#include <linux/init.h>
+#include <linux/notifier.h>
+#include <linux/input.h>
+#include <linux/kbd_ll.h>
+
+#include <linux/adb.h>
+#include <linux/cuda.h>
+#include <linux/pmu.h>
+#ifdef CONFIG_PMAC_BACKLIGHT
+#include <asm/backlight.h>
+#endif
+
+MODULE_AUTHOR("Franz Sirl <Franz.Si...@lauterbach.com>");
+
+#define KEYB_KEYREG 0 /* register # for key up/down data */
+#define KEYB_LEDREG 2 /* register # for leds on ADB keyboard */
+#define MOUSE_DATAREG 0 /* reg# for movement/button codes from mouse */
+
+static int adb_message_handler(struct notifier_block *, unsigned long, void *);
+static struct notifier_block adbhid_adb_notifier = {
+ notifier_call: adb_message_handler,
+};
+
+unsigned char adb_to_linux_keycodes[128] = {
+ 30, 31, 32, 33, 35, 34, 44, 45, 46, 47, 86, 48, 16, 17, 18, 19,
+ 21, 20, 2, 3, 4, 5, 7, 6, 13, 10, 8, 12, 9, 11, 27, 24,
+ 22, 26, 23, 25, 28, 38, 36, 40, 37, 39, 43, 51, 53, 49, 50, 52,
+ 15, 57, 41, 14, 96, 1, 29,125, 42, 58, 56,105,106,108,103, 0,
+ 0, 83, 0, 55, 0, 78, 0, 69, 0, 0, 0, 98, 96, 0, 74, 0,
+ 0,117, 82, 79, 80, 81, 75, 76, 77, 71, 0, 72, 73,183,181,124,
+ 63, 64, 65, 61, 66, 67,191, 87,190, 99, 0, 70, 0, 68,101, 88,
+ 0,119,110,102,104,111, 62,107, 60,109, 59, 54,100, 97,116,116
+};
+
+struct adbhid {
+ struct input_dev input;
+ int id;
+ int default_id;
+ int original_handler_id;
+ int current_handler_id;
+ int mouse_kind;
+ unsigned char *keycode;
+ char name[64];
+};
+
+static struct adbhid *adbhid[16] = { 0 };
+
+static void adbhid_probe(void);
+
+static void adbhid_input_keycode(int, int, int);
+static void leds_done(struct adb_request *);
+
+static void init_trackpad(int id);
+static void init_trackball(int id);
+static void init_turbomouse(int id);
+static void init_microspeed(int id);
+static void init_ms_a3(int id);
+
+static struct adb_ids keyboard_ids;
+static struct adb_ids mouse_ids;
+static struct adb_ids buttons_ids;
+
+/* Kind of keyboard, see Apple technote 1152 */
+#define ADB_KEYBOARD_UNKNOWN 0
+#define ADB_KEYBOARD_ANSI 0x0100
+#define ADB_KEYBOARD_ISO 0x0200
+#define ADB_KEYBOARD_JIS 0x0300
+
+/* Kind of mouse */
+#define ADBMOUSE_STANDARD_100 0 /* Standard 100cpi mouse (handler 1) */
+#define ADBMOUSE_STANDARD_200 1 /* Standard 200cpi mouse (handler 2) */
+#define ADBMOUSE_EXTENDED 2 /* Apple Extended mouse (handler 4) */
+#define ADBMOUSE_TRACKBALL 3 /* TrackBall (handler 4) */
+#define ADBMOUSE_TRACKPAD 4 /* Apple's PowerBook trackpad (handler 4) */
+#define ADBMOUSE_TURBOMOUSE5 5 /* Turbomouse 5 (previously req. mousehack) */
+#define ADBMOUSE_MICROSPEED 6 /* Microspeed mouse (&trackball ?), MacPoint */
+#define ADBMOUSE_TRACKBALLPRO 7 /* Trackball Pro (special buttons) */
+#define ADBMOUSE_MS_A3 8 /* Mouse systems A3 trackball (handler 3) */
+#define ADBMOUSE_MACALLY2 9 /* MacAlly 2-button mouse */
+
+static void
+adbhid_keyboard_input(unsigned char *data, int nb, struct pt_regs *regs, int apoll)
+{
+ int id = (data[0] >> 4) & 0x0f;
+
+ if (!adbhid[id]) {
+ printk(KERN_ERR "ADB HID on ID %d not yet registered, packet %#02x, %#02x, %#02x, %#02x\n",
+ id, data[0], data[1], data[2], data[3]);
+ return;
+ }
+
+ /* first check this is from register 0 */
+ if (nb != 3 || (data[0] & 3) != KEYB_KEYREG)
+ return; /* ignore it */
+ kbd_pt_regs = regs;
+ adbhid_input_keycode(id, data[1], 0);
+ if (!(data[2] == 0xff || (data[2] == 0x7f && data[1] == 0x7f)))
+ adbhid_input_keycode(id, data[2], 0);
+}
+
+static void
+adbhid_input_keycode(int id, int keycode, int repeat)
+{
+ int up_flag;
+
+ up_flag = (keycode & 0x80);
+ keycode &= 0x7f;
+
+ switch (keycode) {
+ case 0x39: /* Generate down/up events for CapsLock everytime. */
+ input_report_key(&adbhid[id]->input, KEY_CAPSLOCK, 1);
+ input_report_key(&adbhid[id]->input, KEY_CAPSLOCK, 0);
+ return;
+ case 0x3f: /* ignore Powerbook Fn key */
+ return;
+ }
+
+ if (adbhid[id]->keycode[keycode])
+ input_report_key(&adbhid[id]->input,
+ adbhid[id]->keycode[keycode], !up_flag);
+ else
+ printk(KERN_INFO "Unhandled ADB key (scancode %#02x) %s.\n", keycode,
+ up_flag ? "released" : "pressed");
+}
+
+static void
+adbhid_mouse_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll)
+{
+ int id = (data[0] >> 4) & 0x0f;
+
+ if (!adbhid[id]) {
+ printk(KERN_ERR "ADB HID on ID %d not yet registered\n", id);
+ return;
+ }
+
+ /*
+ Handler 1 -- 100cpi original Apple mouse protocol.
+ Handler 2 -- 200cpi original Apple mouse protocol.
+
+ For Apple's standard one-button mouse protocol the data array will
+ contain the following values:
+
+ BITS COMMENTS
+ data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd.
+ data[1] = bxxx xxxx First button and x-axis motion.
+ data[2] = byyy yyyy Second button and y-axis motion.
+
+ Handler 4 -- Apple Extended mouse protocol.
+
+ For Apple's 3-button mouse protocol the data array will contain the
+ following values:
+
+ BITS COMMENTS
+ data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd.
+ data[1] = bxxx xxxx Left button and x-axis motion.
+ data[2] = byyy yyyy Second button and y-axis motion.
+ data[3] = byyy bxxx Third button and fourth button. Y is additional
+ high bits of y-axis motion. XY is additional
+ high bits of x-axis motion.
+
+ MacAlly 2-button mouse protocol.
+
+ For MacAlly 2-button mouse protocol the data array will contain the
+ following values:
+
+ BITS COMMENTS
+ data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd.
+ data[1] = bxxx xxxx Left button and x-axis motion.
+ data[2] = byyy yyyy Right button and y-axis motion.
+ data[3] = ???? ???? unknown
+ data[4] = ???? ???? unknown
+
+ */
+
+ /* If it's a trackpad, we alias the second button to the first.
+ NOTE: Apple sends an ADB flush command to the trackpad when
+ the first (the real) button is released. We could do
+ this here using async flush requests.
+ */
+ switch (adbhid[id]->mouse_kind)
+ {
+ case ADBMOUSE_TRACKPAD:
+ data[1] = (data[1] & 0x7f) | ((data[1] & data[2]) & 0x80);
+ data[2] = data[2] | 0x80;
+ break;
+ case ADBMOUSE_MICROSPEED:
+ data[1] = (data[1] & 0x7f) | ((data[3] & 0x01) << 7);
+ data[2] = (data[2] & 0x7f) | ((data[3] & 0x02) << 6);
+ data[3] = (data[3] & 0x77) | ((data[3] & 0x04) << 5)
+ | (data[3] & 0x08);
+ break;
+ case ADBMOUSE_TRACKBALLPRO:
+ data[1] = (data[1] & 0x7f) | (((data[3] & 0x04) << 5)
+ & ((data[3] & 0x08) << 4));
+ data[2] = (data[2] & 0x7f) | ((data[3] & 0x01) << 7);
+ data[3] = (data[3] & 0x77) | ((data[3] & 0x02) << 6);
+ break;
+ case ADBMOUSE_MS_A3:
+ data[1] = (data[1] & 0x7f) | ((data[3] & 0x01) << 7);
+ data[2] = (data[2] & 0x7f) | ((data[3] & 0x02) << 6);
+ data[3] = ((data[3] & 0x04) << 5);
+ break;
+ case ADBMOUSE_MACALLY2:
+ data[3] = (data[2] & 0x80) ? 0x80 : 0x00;
+ data[2] |= 0x80; /* Right button is mapped as button 3 */
+ nb=4;
+ break;
+ }
+
+ input_report_key(&adbhid[id]->input, BTN_LEFT, !((data[1] >> 7) & 1));
+ input_report_key(&adbhid[id]->input, BTN_MIDDLE, !((data[2] >> 7) & 1));
+
+ if (nb >= 4)
+ input_report_key(&adbhid[id]->input, BTN_RIGHT, !((data[3] >> 7) & 1));
+
+ input_report_rel(&adbhid[id]->input, REL_X,
+ ((data[2]&0x7f) < 64 ? (data[2]&0x7f) : (data[2]&0x7f)-128 ));
+ input_report_rel(&adbhid[id]->input, REL_Y,
+ ((data[1]&0x7f) < 64 ? (data[1]&0x7f) : (data[1]&0x7f)-128 ));
+}
+
+static void
+adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll)
+{
+ int id = (data[0] >> 4) & 0x0f;
+
+ if (!adbhid[id]) {
+ printk(KERN_ERR "ADB HID on ID %d not yet registered\n", id);
+ return;
+ }
+
+ switch (adbhid[id]->original_handler_id) {
+ default:
+ case 0x02: /* Adjustable keyboard button device */
+ printk(KERN_INFO "Unhandled ADB_MISC event %02x, %02x, %02x, %02x\n",
+ data[0], data[1], data[2], data[3]);
+ break;
+ case 0x1f: /* Powerbook button device */
+ {
+#ifdef CONFIG_PMAC_BACKLIGHT
+ int backlight = get_backlight_level();
+
+ /*
+ * XXX: Where is the contrast control for the passive?
+ * -- Cort
+ */
+
+ switch (data[1]) {
+ case 0x8: /* mute */
+ break;
+
+ case 0x7: /* contrast decrease */
+ break;
+
+ case 0x6: /* contrast increase */
+ break;
+
+ case 0xa: /* brightness decrease */
+ if (backlight < 0)
+ break;
+ if (backlight > BACKLIGHT_OFF)
+ set_backlight_level(backlight-1);
+ else
+ set_backlight_level(BACKLIGHT_OFF);
+ break;
+
+ case 0x9: /* brightness increase */
+ if (backlight < 0)
+ break;
+ if (backlight < BACKLIGHT_MAX)
+ set_backlight_level(backlight+1);
+ else
+ set_backlight_level(BACKLIGHT_MAX);
+ break;
+ }
+#endif /* CONFIG_PMAC_BACKLIGHT */
+ }


+ break;
+ }
+}
+

+static struct adb_request led_request;
+static int leds_pending[16];
+static int pending_devs[16];
+static int pending_led_start=0;
+static int pending_led_end=0;
+
+static void real_leds(unsigned char leds, int device)
+{
+ if (led_request.complete) {
+ adb_request(&led_request, leds_done, 0, 3,
+ ADB_WRITEREG(device, KEYB_LEDREG), 0xff,
+ ~leds);
+ } else {
+ if (!(leds_pending[device] & 0x100)) {
+ pending_devs[pending_led_end] = device;
+ pending_led_end++;
+ pending_led_end = (pending_led_end < 16) ? pending_led_end : 0;
+ }
+ leds_pending[device] = leds | 0x100;
+ }
+}
+
+/*
+ * Event callback from the input module. Events that change the state of
+ * the hardware are processed here.
+ */
+static int adbhid_kbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
+{
+ struct adbhid *adbhid = dev->private;
+ unsigned char leds;
+
+ switch (type) {
+ case EV_LED:
+ leds = (test_bit(LED_SCROLLL, dev->led) ? 4 : 0)
+ | (test_bit(LED_NUML, dev->led) ? 1 : 0)
+ | (test_bit(LED_CAPSL, dev->led) ? 2 : 0);
+ real_leds(leds, adbhid->id);


+ return 0;
+ }
+

+ return -1;
+}
+

+static void leds_done(struct adb_request *req)
+{
+ int leds,device;
+
+ if (pending_led_start != pending_led_end) {
+ device = pending_devs[pending_led_start];
+ leds = leds_pending[device] & 0xff;
+ leds_pending[device] = 0;
+ pending_led_start++;
+ pending_led_start = (pending_led_start < 16) ? pending_led_start : 0;
+ real_leds(leds,device);
+ }


+
+}
+
+static int

+adb_message_handler(struct notifier_block *this, unsigned long code, void *x)
+{


+ unsigned long flags;
+

+ switch (code) {
+ case ADB_MSG_PRE_RESET:
+ case ADB_MSG_POWERDOWN:
+ /* Stop the repeat timer. Autopoll is already off at this point */
+ save_flags(flags);
+ cli();
+ {
+ int i;
+ for (i = 1; i < 16; i++) {
+ if (adbhid[i])
+ del_timer(&adbhid[i]->input.timer);
+ }
+ }
+ restore_flags(flags);
+
+ /* Stop pending led requests */
+ while(!led_request.complete)
+ adb_poll();
+ break;
+
+ case ADB_MSG_POST_RESET:
+ adbhid_probe();
+ break;
+ }
+ return NOTIFY_DONE;
+}
+
+static void
+adbhid_input_register(int id, int default_id, int original_handler_id,
+ int current_handler_id, int mouse_kind)


+{
+ int i;
+

+ if (adbhid[id]) {
+ printk(KERN_ERR "Trying to reregister ADB HID on ID %d\n", id);
+ return;
+ }
+
+ if (!(adbhid[id] = kmalloc(sizeof(struct adbhid), GFP_KERNEL)))
+ return;
+
+ memset(adbhid[id], 0, sizeof(struct adbhid));
+
+ adbhid[id]->id = default_id;
+ adbhid[id]->original_handler_id = original_handler_id;
+ adbhid[id]->current_handler_id = current_handler_id;
+ adbhid[id]->mouse_kind = mouse_kind;
+ adbhid[id]->input.private = adbhid[id];
+ adbhid[id]->input.name = adbhid[id]->name;
+ adbhid[id]->input.idbus = BUS_ADB;
+ adbhid[id]->input.idvendor = 0x0001;
+ adbhid[id]->input.idproduct = (id << 12) | (default_id << 8) | original_handler_id;
+ adbhid[id]->input.idversion = 0x0100;
+
+ switch (default_id) {
+ case ADB_KEYBOARD:
+ if (!(adbhid[id]->keycode = kmalloc(sizeof(adb_to_linux_keycodes), GFP_KERNEL))) {
+ kfree(adbhid[id]);
+ return;
+ }
+
+ sprintf(adbhid[id]->name, "ADB keyboard on ID %d:%d.%02x",
+ id, default_id, original_handler_id);
+
+ memcpy(adbhid[id]->keycode, adb_to_linux_keycodes, sizeof(adb_to_linux_keycodes));
+
+ printk(KERN_INFO "Detected ADB keyboard, type ");
+ switch (original_handler_id) {
+ default:
+ printk("<unknown>.\n");
+ adbhid[id]->input.idversion = ADB_KEYBOARD_UNKNOWN;
+ break;
+
+ case 0x01: case 0x02: case 0x03: case 0x06: case 0x08:
+ case 0x0C: case 0x10: case 0x18: case 0x1B: case 0x1C:
+ case 0xC0: case 0xC3: case 0xC6:
+ printk("ANSI.\n");
+ adbhid[id]->input.idversion = ADB_KEYBOARD_ANSI;
+ break;
+
+ case 0x04: case 0x05: case 0x07: case 0x09: case 0x0D:
+ case 0x11: case 0x14: case 0x19: case 0x1D: case 0xC1:
+ case 0xC4: case 0xC7:
+ printk("ISO, swapping keys.\n");
+ adbhid[id]->input.idversion = ADB_KEYBOARD_ISO;
+ i = adbhid[id]->keycode[10];
+ adbhid[id]->keycode[10] = adbhid[id]->keycode[50];
+ adbhid[id]->keycode[50] = i;
+ break;
+
+ case 0x12: case 0x15: case 0x16: case 0x17: case 0x1A:
+ case 0x1E: case 0xC2: case 0xC5: case 0xC8: case 0xC9:
+ printk("JIS.\n");
+ adbhid[id]->input.idversion = ADB_KEYBOARD_JIS;
+ break;
+ }
+
+ for (i = 0; i < 128; i++)
+ if (adbhid[id]->keycode[i])
+ set_bit(adbhid[id]->keycode[i], adbhid[id]->input.keybit);
+
+ adbhid[id]->input.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
+ adbhid[id]->input.ledbit[0] = BIT(LED_SCROLLL) | BIT(LED_CAPSL) | BIT(LED_NUML);
+ adbhid[id]->input.event = adbhid_kbd_event;
+ adbhid[id]->input.keycodemax = 127;
+ adbhid[id]->input.keycodesize = 1;
+ break;
+
+ case ADB_MOUSE:
+ sprintf(adbhid[id]->name, "ADB mouse on ID %d:%d.%02x",
+ id, default_id, original_handler_id);
+
+ adbhid[id]->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+ adbhid[id]->input.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+ adbhid[id]->input.relbit[0] = BIT(REL_X) | BIT(REL_Y);
+ break;
+
+ case ADB_MISC:
+ switch (original_handler_id) {
+ case 0x02: /* Adjustable keyboard button device */
+ sprintf(adbhid[id]->name, "ADB adjustable keyboard buttons on ID %d:%d.%02x",
+ id, default_id, original_handler_id);
+ break;
+ case 0x1f: /* Powerbook button device */
+ sprintf(adbhid[id]->name, "ADB Powerbook buttons on ID %d:%d.%02x",
+ id, default_id, original_handler_id);
+ break;
+ }
+ if (adbhid[id]->name[0])
+ break;
+ /* else fall through */
+
+ default:
+ printk(KERN_INFO "Trying to register unknown ADB device to input layer.\n");
+ kfree(adbhid[id]);
+ return;
+ }
+
+ adbhid[id]->input.keycode = adbhid[id]->keycode;
+
+ input_register_device(&adbhid[id]->input);
+
+ printk(KERN_INFO "input%d: ADB HID on ID %d:%d.%02x\n",
+ adbhid[id]->input.number, id, default_id, original_handler_id);
+
+ if (default_id == ADB_KEYBOARD) {
+ /* HACK WARNING!! This should go away as soon there is an utility
+ * to control that for event devices.
+ */
+ adbhid[id]->input.rep[REP_DELAY] = HZ/2; /* input layer default: HZ/4 */
+ adbhid[id]->input.rep[REP_PERIOD] = HZ/15; /* input layer default: HZ/33 */
+ }
+}
+
+static void adbhid_input_unregister(int id)
+{
+ input_unregister_device(&adbhid[id]->input);
+ if (adbhid[id]->keycode)
+ kfree(adbhid[id]->keycode);
+ kfree(adbhid[id]);
+ adbhid[id] = 0;


+}
+
+
+static void

+adbhid_probe(void)
+{
+ struct adb_request req;
+ int i, default_id, org_handler_id, cur_handler_id;
+
+ for (i = 1; i < 16; i++) {
+ if (adbhid[i])
+ adbhid_input_unregister(i);
+ }
+
+ adb_register(ADB_MOUSE, 0, &mouse_ids, adbhid_mouse_input);
+ adb_register(ADB_KEYBOARD, 0, &keyboard_ids, adbhid_keyboard_input);
+ adb_register(ADB_MISC, 0, &buttons_ids, adbhid_buttons_input);
+
+ for (i = 0; i < keyboard_ids.nids; i++) {
+ int id = keyboard_ids.id[i];
+
+ adb_get_infos(id, &default_id, &org_handler_id);
+
+ /* turn off all leds */
+ adb_request(&req, NULL, ADBREQ_SYNC, 3,
+ ADB_WRITEREG(id, KEYB_LEDREG), 0xff, 0xff);
+
+ /* Enable full feature set of the keyboard
+ ->get it to send separate codes for left and right shift,
+ control, option keys */
+#if 0 /* handler 5 doesn't send separate codes for R modifiers */
+ if (adb_try_handler_change(id, 5))
+ printk("ADB keyboard at %d, handler set to 5\n", id);
+ else
+#endif
+ if (adb_try_handler_change(id, 3))
+ printk("ADB keyboard at %d, handler set to 3\n", id);
+ else
+ printk("ADB keyboard at %d, handler 1\n", id);
+
+ adb_get_infos(id, &default_id, &cur_handler_id);
+ adbhid_input_register(id, default_id, org_handler_id, cur_handler_id, 0);
+ }
+
+ for (i = 0; i < buttons_ids.nids; i++) {
+ int id = buttons_ids.id[i];
+
+ adb_get_infos(id, &default_id, &org_handler_id);
+ adbhid_input_register(id, default_id, org_handler_id, org_handler_id, 0);
+ }
+
+ /* Try to switch all mice to handler 4, or 2 for three-button
+ mode and full resolution. */
+ for (i = 0; i < mouse_ids.nids; i++) {
+ int id = mouse_ids.id[i];
+ int mouse_kind;
+
+ adb_get_infos(id, &default_id, &org_handler_id);
+
+ if (adb_try_handler_change(id, 4)) {
+ printk("ADB mouse at %d, handler set to 4", id);
+ mouse_kind = ADBMOUSE_EXTENDED;
+ }
+ else if (adb_try_handler_change(id, 0x2F)) {
+ printk("ADB mouse at %d, handler set to 0x2F", id);
+ mouse_kind = ADBMOUSE_MICROSPEED;
+ }
+ else if (adb_try_handler_change(id, 0x42)) {
+ printk("ADB mouse at %d, handler set to 0x42", id);
+ mouse_kind = ADBMOUSE_TRACKBALLPRO;
+ }
+ else if (adb_try_handler_change(id, 0x66)) {
+ printk("ADB mouse at %d, handler set to 0x66", id);
+ mouse_kind = ADBMOUSE_MICROSPEED;
+ }
+ else if (adb_try_handler_change(id, 0x5F)) {
+ printk("ADB mouse at %d, handler set to 0x5F", id);
+ mouse_kind = ADBMOUSE_MICROSPEED;
+ }
+ else if (adb_try_handler_change(id, 3)) {
+ printk("ADB mouse at %d, handler set to 3", id);
+ mouse_kind = ADBMOUSE_MS_A3;
+ }
+ else if (adb_try_handler_change(id, 2)) {
+ printk("ADB mouse at %d, handler set to 2", id);
+ mouse_kind = ADBMOUSE_STANDARD_200;
+ }
+ else {
+ printk("ADB mouse at %d, handler 1", id);
+ mouse_kind = ADBMOUSE_STANDARD_100;
+ }
+
+ if ((mouse_kind == ADBMOUSE_TRACKBALLPRO)
+ || (mouse_kind == ADBMOUSE_MICROSPEED)) {
+ init_microspeed(id);
+ } else if (mouse_kind == ADBMOUSE_MS_A3) {


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 052'
echo 'File patch-2.4.0-test9 is continued in part 053'
echo "053" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part053

#!/bin/sh -x
# this is part 053 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 053; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ init_ms_a3(id);
+ } else if (mouse_kind == ADBMOUSE_EXTENDED) {
+ /*
+ * Register 1 is usually used for device
+ * identification. Here, we try to identify
+ * a known device and call the appropriate
+ * init function.
+ */
+ adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
+ ADB_READREG(id, 1));
+
+ if ((req.reply_len) &&
+ (req.reply[1] == 0x9a) && ((req.reply[2] == 0x21)
+ || (req.reply[2] == 0x20))) {
+ mouse_kind = ADBMOUSE_TRACKBALL;
+ init_trackball(id);
+ }
+ else if ((req.reply_len >= 4) &&
+ (req.reply[1] == 0x74) && (req.reply[2] == 0x70) &&
+ (req.reply[3] == 0x61) && (req.reply[4] == 0x64)) {
+ mouse_kind = ADBMOUSE_TRACKPAD;
+ init_trackpad(id);
+ }
+ else if ((req.reply_len >= 4) &&
+ (req.reply[1] == 0x4b) && (req.reply[2] == 0x4d) &&
+ (req.reply[3] == 0x4c) && (req.reply[4] == 0x31)) {
+ mouse_kind = ADBMOUSE_TURBOMOUSE5;
+ init_turbomouse(id);
+ }
+ else if ((req.reply_len == 9) &&
+ (req.reply[1] == 0x4b) && (req.reply[2] == 0x4f) &&
+ (req.reply[3] == 0x49) && (req.reply[4] == 0x54)) {
+ if (adb_try_handler_change(id, 0x42)) {
+ printk("\nADB MacAlly 2-button mouse at %d, handler set to 0x42", id);
+ mouse_kind = ADBMOUSE_MACALLY2;
+ }
+ }
+ }
+ printk("\n");


+
+ adb_get_infos(id, &default_id, &cur_handler_id);
+ adbhid_input_register(id, default_id, org_handler_id,

+ cur_handler_id, mouse_kind);


+ }
+}
+
+static void

+init_trackpad(int id)


+{
+ struct adb_request req;

+ unsigned char r1_buffer[8];
+
+ printk(" (trackpad)");
+
+ adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
+ ADB_READREG(id,1));
+ if (req.reply_len < 8)
+ printk("bad length for reg. 1\n");
+ else
+ {
+ memcpy(r1_buffer, &req.reply[1], 8);
+ adb_request(&req, NULL, ADBREQ_SYNC, 9,
+ ADB_WRITEREG(id,1),
+ r1_buffer[0],
+ r1_buffer[1],
+ r1_buffer[2],
+ r1_buffer[3],
+ r1_buffer[4],
+ r1_buffer[5],
+ 0x0d, /*r1_buffer[6],*/
+ r1_buffer[7]);
+
+ adb_request(&req, NULL, ADBREQ_SYNC, 9,
+ ADB_WRITEREG(id,2),
+ 0x99,
+ 0x94,
+ 0x19,
+ 0xff,
+ 0xb2,
+ 0x8a,
+ 0x1b,
+ 0x50);
+
+ adb_request(&req, NULL, ADBREQ_SYNC, 9,
+ ADB_WRITEREG(id,1),
+ r1_buffer[0],
+ r1_buffer[1],
+ r1_buffer[2],
+ r1_buffer[3],
+ r1_buffer[4],
+ r1_buffer[5],
+ 0x03, /*r1_buffer[6],*/
+ r1_buffer[7]);


+ }
+}
+
+static void

+init_trackball(int id)


+{
+ struct adb_request req;
+

+ printk(" (trackman/mouseman)");
+


+ adb_request(&req, NULL, ADBREQ_SYNC, 3,

+ ADB_WRITEREG(id,1), 00,0x81);
+


+ adb_request(&req, NULL, ADBREQ_SYNC, 3,

+ ADB_WRITEREG(id,1), 01,0x81);
+


+ adb_request(&req, NULL, ADBREQ_SYNC, 3,

+ ADB_WRITEREG(id,1), 02,0x81);
+


+ adb_request(&req, NULL, ADBREQ_SYNC, 3,

+ ADB_WRITEREG(id,1), 03,0x38);
+


+ adb_request(&req, NULL, ADBREQ_SYNC, 3,

+ ADB_WRITEREG(id,1), 00,0x81);
+


+ adb_request(&req, NULL, ADBREQ_SYNC, 3,

+ ADB_WRITEREG(id,1), 01,0x81);
+


+ adb_request(&req, NULL, ADBREQ_SYNC, 3,

+ ADB_WRITEREG(id,1), 02,0x81);
+


+ adb_request(&req, NULL, ADBREQ_SYNC, 3,

+ ADB_WRITEREG(id,1), 03,0x38);
+}
+
+static void
+init_turbomouse(int id)


+{
+ struct adb_request req;
+

+ printk(" (TurboMouse 5)");
+
+ adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
+
+ adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(3));
+
+ adb_request(&req, NULL, ADBREQ_SYNC, 9,
+ ADB_WRITEREG(3,2),
+ 0xe7,
+ 0x8c,
+ 0,
+ 0,
+ 0,
+ 0xff,
+ 0xff,
+ 0x94);
+
+ adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(3));
+
+ adb_request(&req, NULL, ADBREQ_SYNC, 9,
+ ADB_WRITEREG(3,2),
+ 0xa5,
+ 0x14,
+ 0,
+ 0,
+ 0x69,
+ 0xff,
+ 0xff,
+ 0x27);
+}
+
+static void
+init_microspeed(int id)


+{
+ struct adb_request req;
+

+ printk(" (Microspeed/MacPoint or compatible)");
+
+ adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
+
+ /* This will initialize mice using the Microspeed, MacPoint and
+ other compatible firmware. Bit 12 enables extended protocol.
+
+ Register 1 Listen (4 Bytes)
+ 0 - 3 Button is mouse (set also for double clicking!!!)
+ 4 - 7 Button is locking (affects change speed also)
+ 8 - 11 Button changes speed
+ 12 1 = Extended mouse mode, 0 = normal mouse mode
+ 13 - 15 unused 0
+ 16 - 23 normal speed
+ 24 - 31 changed speed
+
+ Register 1 talk holds version and product identification information.
+ Register 1 Talk (4 Bytes):
+ 0 - 7 Product code
+ 8 - 23 undefined, reserved
+ 24 - 31 Version number
+
+ Speed 0 is max. 1 to 255 set speed in increments of 1/256 of max.
+ */
+ adb_request(&req, NULL, ADBREQ_SYNC, 5,
+ ADB_WRITEREG(id,1),
+ 0x20, /* alt speed = 0x20 (rather slow) */
+ 0x00, /* norm speed = 0x00 (fastest) */
+ 0x10, /* extended protocol, no speed change */
+ 0x07); /* all buttons enabled as mouse buttons, no locking */
+
+
+ adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
+}
+
+static void
+init_ms_a3(int id)


+{
+ struct adb_request req;
+

+ printk(" (Mouse Systems A3 Mouse, or compatible)");


+ adb_request(&req, NULL, ADBREQ_SYNC, 3,

+ ADB_WRITEREG(id, 0x2),
+ 0x00,
+ 0x07);
+
+ adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
+}
+
+static int __init adbhid_init(void)
+{
+ if ( (_machine != _MACH_chrp) && (_machine != _MACH_Pmac) )
+ return 0;
+
+ led_request.complete = 1;
+
+ adbhid_probe();
+
+ notifier_chain_register(&adb_client_list, &adbhid_adb_notifier);
+


+ return 0;
+}
+

+static void __exit adbhid_exit(void)
+{
+}
+
+module_init(adbhid_init);
+module_exit(adbhid_exit);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/macintosh/mac_hid.c linux/drivers/macintosh/mac_hid.c
--- v2.4.0-test8/linux/drivers/macintosh/mac_hid.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/macintosh/mac_hid.c Sun Sep 17 09:48:05 2000
@@ -0,0 +1,492 @@
+/*
+ * drivers/macintosh/mac_hid.c
+ *
+ * HID support stuff for Macintosh computers.
+ *


+ * Copyright (C) 2000 Franz Sirl.
+ *

+ * Stuff inside CONFIG_MAC_ADBKEYCODES should go away during 2.5 when all
+ * major distributions are using the Linux keycodes.
+ * Stuff inside CONFIG_MAC_EMUMOUSEBTN should really be moved to userspace.


+ */
+
+#include <linux/config.h>

+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/sysctl.h>
+#include <linux/input.h>
+
+#ifdef CONFIG_MAC_ADBKEYCODES
+#include <linux/keyboard.h>
+#include <asm/keyboard.h>
+#include <asm/machdep.h>
+#endif
+
+#ifdef CONFIG_MAC_ADBKEYCODES
+/* Simple translation table for the SysRq keys */
+
+#ifdef CONFIG_MAGIC_SYSRQ
+unsigned char mac_hid_kbd_sysrq_xlate[128] =
+ "asdfhgzxcv\000bqwer" /* 0x00 - 0x0f */
+ "yt123465=97-80o]" /* 0x10 - 0x1f */
+ "u[ip\rlj'k;\\,/nm." /* 0x20 - 0x2f */
+ "\t `\177\000\033\000\000\000\000\000\000\000\000\000\000"
+ /* 0x30 - 0x3f */
+ "\000\000\000*\000+\000\000\000\000\000/\r\000-\000"
+ /* 0x40 - 0x4f */
+ "\000\0000123456789\000\000\000" /* 0x50 - 0x5f */
+ "\205\206\207\203\210\211\000\213\000\215\000\000\000\000\000\212\000\214";
+ /* 0x60 - 0x6f */
+extern unsigned char pckbd_sysrq_xlate[128];
+#endif
+
+static u_short macplain_map[NR_KEYS] = {
+ 0xfb61, 0xfb73, 0xfb64, 0xfb66, 0xfb68, 0xfb67, 0xfb7a, 0xfb78,
+ 0xfb63, 0xfb76, 0xf200, 0xfb62, 0xfb71, 0xfb77, 0xfb65, 0xfb72,
+ 0xfb79, 0xfb74, 0xf031, 0xf032, 0xf033, 0xf034, 0xf036, 0xf035,
+ 0xf03d, 0xf039, 0xf037, 0xf02d, 0xf038, 0xf030, 0xf05d, 0xfb6f,
+ 0xfb75, 0xf05b, 0xfb69, 0xfb70, 0xf201, 0xfb6c, 0xfb6a, 0xf027,
+ 0xfb6b, 0xf03b, 0xf05c, 0xf02c, 0xf02f, 0xfb6e, 0xfb6d, 0xf02e,
+ 0xf009, 0xf020, 0xf060, 0xf07f, 0xf200, 0xf01b, 0xf702, 0xf703,
+ 0xf700, 0xf207, 0xf701, 0xf601, 0xf602, 0xf600, 0xf603, 0xf200,
+ 0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
+ 0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
+ 0xf200, 0xf200, 0xf300, 0xf301, 0xf302, 0xf303, 0xf304, 0xf305,
+ 0xf306, 0xf307, 0xf200, 0xf308, 0xf309, 0xf200, 0xf200, 0xf200,
+ 0xf104, 0xf105, 0xf106, 0xf102, 0xf107, 0xf108, 0xf200, 0xf10a,
+ 0xf200, 0xf10c, 0xf200, 0xf209, 0xf200, 0xf109, 0xf200, 0xf10b,
+ 0xf200, 0xf11d, 0xf115, 0xf114, 0xf118, 0xf116, 0xf103, 0xf117,
+ 0xf101, 0xf119, 0xf100, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
+};
+
+static u_short macshift_map[NR_KEYS] = {
+ 0xfb41, 0xfb53, 0xfb44, 0xfb46, 0xfb48, 0xfb47, 0xfb5a, 0xfb58,
+ 0xfb43, 0xfb56, 0xf200, 0xfb42, 0xfb51, 0xfb57, 0xfb45, 0xfb52,
+ 0xfb59, 0xfb54, 0xf021, 0xf040, 0xf023, 0xf024, 0xf05e, 0xf025,
+ 0xf02b, 0xf028, 0xf026, 0xf05f, 0xf02a, 0xf029, 0xf07d, 0xfb4f,
+ 0xfb55, 0xf07b, 0xfb49, 0xfb50, 0xf201, 0xfb4c, 0xfb4a, 0xf022,
+ 0xfb4b, 0xf03a, 0xf07c, 0xf03c, 0xf03f, 0xfb4e, 0xfb4d, 0xf03e,
+ 0xf009, 0xf020, 0xf07e, 0xf07f, 0xf200, 0xf01b, 0xf702, 0xf703,
+ 0xf700, 0xf207, 0xf701, 0xf601, 0xf602, 0xf600, 0xf603, 0xf200,
+ 0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
+ 0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
+ 0xf200, 0xf200, 0xf300, 0xf301, 0xf302, 0xf303, 0xf304, 0xf305,
+ 0xf306, 0xf307, 0xf200, 0xf308, 0xf309, 0xf200, 0xf200, 0xf200,
+ 0xf10e, 0xf10f, 0xf110, 0xf10c, 0xf111, 0xf112, 0xf200, 0xf10a,
+ 0xf200, 0xf10c, 0xf200, 0xf203, 0xf200, 0xf113, 0xf200, 0xf10b,
+ 0xf200, 0xf11d, 0xf115, 0xf114, 0xf20b, 0xf116, 0xf10d, 0xf117,
+ 0xf10b, 0xf20a, 0xf10a, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
+};
+
+static u_short macaltgr_map[NR_KEYS] = {
+ 0xf914, 0xfb73, 0xf917, 0xf919, 0xfb68, 0xfb67, 0xfb7a, 0xfb78,
+ 0xf916, 0xfb76, 0xf200, 0xf915, 0xfb71, 0xfb77, 0xf918, 0xfb72,
+ 0xfb79, 0xfb74, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200,
+ 0xf200, 0xf05d, 0xf07b, 0xf05c, 0xf05b, 0xf07d, 0xf07e, 0xfb6f,
+ 0xfb75, 0xf200, 0xfb69, 0xfb70, 0xf201, 0xfb6c, 0xfb6a, 0xf200,
+ 0xfb6b, 0xf200, 0xf200, 0xf200, 0xf200, 0xfb6e, 0xfb6d, 0xf200,
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf702, 0xf703,
+ 0xf700, 0xf207, 0xf701, 0xf601, 0xf602, 0xf600, 0xf603, 0xf200,
+ 0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
+ 0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
+ 0xf200, 0xf200, 0xf90a, 0xf90b, 0xf90c, 0xf90d, 0xf90e, 0xf90f,
+ 0xf910, 0xf911, 0xf200, 0xf912, 0xf913, 0xf200, 0xf200, 0xf200,
+ 0xf510, 0xf511, 0xf512, 0xf50e, 0xf513, 0xf514, 0xf200, 0xf516,
+ 0xf200, 0xf10c, 0xf200, 0xf202, 0xf200, 0xf515, 0xf200, 0xf517,
+ 0xf200, 0xf11d, 0xf115, 0xf114, 0xf118, 0xf116, 0xf50f, 0xf117,
+ 0xf50d, 0xf119, 0xf50c, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
+};
+
+static u_short macctrl_map[NR_KEYS] = {
+ 0xf001, 0xf013, 0xf004, 0xf006, 0xf008, 0xf007, 0xf01a, 0xf018,
+ 0xf003, 0xf016, 0xf200, 0xf002, 0xf011, 0xf017, 0xf005, 0xf012,
+ 0xf019, 0xf014, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01e, 0xf01d,
+ 0xf200, 0xf200, 0xf01f, 0xf01f, 0xf07f, 0xf200, 0xf01d, 0xf00f,
+ 0xf015, 0xf01b, 0xf009, 0xf010, 0xf201, 0xf00c, 0xf00a, 0xf007,
+ 0xf00b, 0xf200, 0xf01c, 0xf200, 0xf07f, 0xf00e, 0xf00d, 0xf20e,
+ 0xf200, 0xf000, 0xf000, 0xf008, 0xf200, 0xf200, 0xf702, 0xf703,
+ 0xf700, 0xf207, 0xf701, 0xf601, 0xf602, 0xf600, 0xf603, 0xf200,
+ 0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
+ 0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
+ 0xf200, 0xf200, 0xf300, 0xf301, 0xf302, 0xf303, 0xf304, 0xf305,
+ 0xf306, 0xf307, 0xf200, 0xf308, 0xf309, 0xf200, 0xf200, 0xf200,
+ 0xf104, 0xf105, 0xf106, 0xf102, 0xf107, 0xf108, 0xf200, 0xf10a,
+ 0xf200, 0xf10c, 0xf200, 0xf204, 0xf200, 0xf109, 0xf200, 0xf10b,
+ 0xf200, 0xf11d, 0xf115, 0xf114, 0xf118, 0xf116, 0xf103, 0xf117,
+ 0xf101, 0xf119, 0xf100, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
+};
+
+static u_short macshift_ctrl_map[NR_KEYS] = {
+ 0xf001, 0xf013, 0xf004, 0xf006, 0xf008, 0xf007, 0xf01a, 0xf018,
+ 0xf003, 0xf016, 0xf200, 0xf002, 0xf011, 0xf017, 0xf005, 0xf012,
+ 0xf019, 0xf014, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf200,
+ 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf200, 0xf200, 0xf00f,
+ 0xf015, 0xf200, 0xf009, 0xf010, 0xf201, 0xf00c, 0xf00a, 0xf200,
+ 0xf00b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf00e, 0xf00d, 0xf200,
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf702, 0xf703,
+ 0xf700, 0xf207, 0xf701, 0xf601, 0xf602, 0xf600, 0xf603, 0xf200,
+ 0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
+ 0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
+ 0xf200, 0xf200, 0xf300, 0xf301, 0xf302, 0xf303, 0xf304, 0xf305,
+ 0xf306, 0xf307, 0xf200, 0xf308, 0xf309, 0xf200, 0xf200, 0xf200,
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+ 0xf200, 0xf10c, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+ 0xf200, 0xf11d, 0xf115, 0xf114, 0xf118, 0xf116, 0xf200, 0xf117,
+ 0xf200, 0xf119, 0xf200, 0xf700, 0xf701, 0xf702, 0xf200, 0xf20c,
+};
+
+static u_short macalt_map[NR_KEYS] = {
+ 0xf861, 0xf873, 0xf864, 0xf866, 0xf868, 0xf867, 0xf87a, 0xf878,
+ 0xf863, 0xf876, 0xf200, 0xf862, 0xf871, 0xf877, 0xf865, 0xf872,
+ 0xf879, 0xf874, 0xf831, 0xf832, 0xf833, 0xf834, 0xf836, 0xf835,
+ 0xf83d, 0xf839, 0xf837, 0xf82d, 0xf838, 0xf830, 0xf85d, 0xf86f,
+ 0xf875, 0xf85b, 0xf869, 0xf870, 0xf80d, 0xf86c, 0xf86a, 0xf827,
+ 0xf86b, 0xf83b, 0xf85c, 0xf82c, 0xf82f, 0xf86e, 0xf86d, 0xf82e,
+ 0xf809, 0xf820, 0xf860, 0xf87f, 0xf200, 0xf81b, 0xf702, 0xf703,
+ 0xf700, 0xf207, 0xf701, 0xf210, 0xf211, 0xf600, 0xf603, 0xf200,
+ 0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
+ 0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
+ 0xf200, 0xf200, 0xf900, 0xf901, 0xf902, 0xf903, 0xf904, 0xf905,
+ 0xf906, 0xf907, 0xf200, 0xf908, 0xf909, 0xf200, 0xf200, 0xf200,
+ 0xf504, 0xf505, 0xf506, 0xf502, 0xf507, 0xf508, 0xf200, 0xf50a,
+ 0xf200, 0xf10c, 0xf200, 0xf209, 0xf200, 0xf509, 0xf200, 0xf50b,
+ 0xf200, 0xf11d, 0xf115, 0xf114, 0xf118, 0xf116, 0xf503, 0xf117,
+ 0xf501, 0xf119, 0xf500, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
+};
+
+static u_short macctrl_alt_map[NR_KEYS] = {
+ 0xf801, 0xf813, 0xf804, 0xf806, 0xf808, 0xf807, 0xf81a, 0xf818,
+ 0xf803, 0xf816, 0xf200, 0xf802, 0xf811, 0xf817, 0xf805, 0xf812,
+ 0xf819, 0xf814, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf80f,
+ 0xf815, 0xf200, 0xf809, 0xf810, 0xf201, 0xf80c, 0xf80a, 0xf200,
+ 0xf80b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf80e, 0xf80d, 0xf200,
+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf702, 0xf703,
+ 0xf700, 0xf207, 0xf701, 0xf601, 0xf602, 0xf600, 0xf603, 0xf200,
+ 0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
+ 0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
+ 0xf200, 0xf200, 0xf300, 0xf301, 0xf302, 0xf303, 0xf304, 0xf305,
+ 0xf306, 0xf307, 0xf200, 0xf308, 0xf309, 0xf200, 0xf200, 0xf200,
+ 0xf504, 0xf505, 0xf506, 0xf502, 0xf507, 0xf508, 0xf200, 0xf50a,
+ 0xf200, 0xf10c, 0xf200, 0xf200, 0xf200, 0xf509, 0xf200, 0xf50b,
+ 0xf200, 0xf11d, 0xf115, 0xf114, 0xf118, 0xf116, 0xf503, 0xf117,
+ 0xf501, 0xf119, 0xf500, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
+};
+
+static unsigned short *mac_key_maps_save[MAX_NR_KEYMAPS] = {
+ macplain_map, macshift_map, macaltgr_map, 0,
+ macctrl_map, macshift_ctrl_map, 0, 0,
+ macalt_map, 0, 0, 0,
+ macctrl_alt_map, 0
+};
+
+static unsigned short *pc_key_maps_save[MAX_NR_KEYMAPS];
+
+int mac_hid_kbd_translate(unsigned char keycode, unsigned char *keycodep,
+ char raw_mode);
+static int mac_hid_sysctl_keycodes(ctl_table *ctl, int write, struct file * filp,
+ void *buffer, size_t *lenp);
+char mac_hid_kbd_unexpected_up(unsigned char keycode);
+
+static int keyboard_lock_keycodes = 0;
+int keyboard_sends_linux_keycodes = 0;
+#else
+int keyboard_sends_linux_keycodes = 1;
+#endif
+
+
+static unsigned char e0_keys[128] = {
+ 0, 0, 0, KEY_KPCOMMA, 0, KEY_INTL3, 0, 0, /* 0x00-0x07 */
+ 0, 0, 0, 0, KEY_LANG1, KEY_LANG2, 0, 0, /* 0x08-0x0f */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x17 */
+ 0, 0, 0, 0, KEY_KPENTER, KEY_RIGHTCTRL, 0, 0, /* 0x18-0x1f */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x27 */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x28-0x2f */
+ 0, 0, 0, 0, 0, KEY_KPSLASH, 0, KEY_SYSRQ, /* 0x30-0x37 */
+ KEY_RIGHTALT, 0, 0, 0, 0, 0, 0, 0, /* 0x38-0x3f */
+ 0, 0, 0, 0, 0, 0, 0, KEY_HOME, /* 0x40-0x47 */
+ KEY_UP, KEY_PAGEUP, 0, KEY_LEFT, 0, KEY_RIGHT, 0, KEY_END, /* 0x48-0x4f */
+ KEY_DOWN, KEY_PAGEDOWN, KEY_INSERT, KEY_DELETE, 0, 0, 0, 0, /* 0x50-0x57 */
+ 0, 0, 0, KEY_LEFTMETA, KEY_RIGHTMETA, KEY_COMPOSE, 0, 0, /* 0x58-0x5f */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */
+ 0, 0, 0, 0, 0, 0, 0, KEY_MACRO, /* 0x68-0x6f */
+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77 */
+ 0, 0, 0, 0, 0, 0, 0, 0 /* 0x78-0x7f */
+};
+
+#ifdef CONFIG_MAC_EMUMOUSEBTN
+static struct input_dev emumousebtn;
+static void emumousebtn_input_register(void);
+static int mouse_emulate_buttons = 0;
+static int mouse_button2_keycode = KEY_RIGHTCTRL; /* right control key */
+static int mouse_button3_keycode = KEY_RIGHTALT; /* right option key */
+static int mouse_last_keycode = 0;
+#endif
+
+extern void pckbd_init_hw(void);
+
+#if defined CONFIG_SYSCTL && (defined(CONFIG_MAC_ADBKEYCODES) || defined(CONFIG_MAC_EMUMOUSEBTN))
+/* file(s) in /proc/sys/dev/mac_hid */
+ctl_table mac_hid_files[] =
+{
+#ifdef CONFIG_MAC_ADBKEYCODES
+ {
+ DEV_MAC_HID_KEYBOARD_SENDS_LINUX_KEYCODES,
+ "keyboard_sends_linux_keycodes", &keyboard_sends_linux_keycodes, sizeof(int),
+ 0644, NULL, &mac_hid_sysctl_keycodes
+ },
+ {
+ DEV_MAC_HID_KEYBOARD_LOCK_KEYCODES,
+ "keyboard_lock_keycodes", &keyboard_lock_keycodes, sizeof(int),
+ 0644, NULL, &proc_dointvec
+ },
+#endif
+#ifdef CONFIG_MAC_EMUMOUSEBTN
+ {
+ DEV_MAC_HID_MOUSE_BUTTON_EMULATION,
+ "mouse_button_emulation", &mouse_emulate_buttons, sizeof(int),
+ 0644, NULL, &proc_dointvec
+ },
+ {
+ DEV_MAC_HID_MOUSE_BUTTON2_KEYCODE,
+ "mouse_button2_keycode", &mouse_button2_keycode, sizeof(int),
+ 0644, NULL, &proc_dointvec
+ },
+ {
+ DEV_MAC_HID_MOUSE_BUTTON3_KEYCODE,
+ "mouse_button3_keycode", &mouse_button3_keycode, sizeof(int),
+ 0644, NULL, &proc_dointvec
+ },
+#endif
+ { 0 }
+};
+
+/* dir in /proc/sys/dev */
+ctl_table mac_hid_dir[] =
+{
+ { DEV_MAC_HID, "mac_hid", NULL, 0, 0555, mac_hid_files },
+ { 0 }
+};
+
+/* /proc/sys/dev itself, in case that is not there yet */
+ctl_table mac_hid_root_dir[] =
+{
+ { CTL_DEV, "dev", NULL, 0, 0555, mac_hid_dir },
+ { 0 }
+};
+
+static struct ctl_table_header *mac_hid_sysctl_header;
+
+#ifdef CONFIG_MAC_ADBKEYCODES
+static
+int mac_hid_sysctl_keycodes(ctl_table *ctl, int write, struct file * filp,
+ void *buffer, size_t *lenp)
+{
+ int val = keyboard_sends_linux_keycodes;
+ int ret = 0;
+
+ if (!write
+ || (write && !keyboard_lock_keycodes))
+ ret = proc_dointvec(ctl, write, filp, buffer, lenp);
+
+ if (write
+ && keyboard_sends_linux_keycodes != val) {
+ if (!keyboard_sends_linux_keycodes) {
+#ifdef CONFIG_MAGIC_SYSRQ
+ ppc_md.ppc_kbd_sysrq_xlate = mac_hid_kbd_sysrq_xlate;
+ SYSRQ_KEY = 0x69;
+#endif
+ memcpy(pc_key_maps_save, key_maps, sizeof(key_maps));
+ memcpy(key_maps, mac_key_maps_save, sizeof(key_maps));
+ } else {
+#ifdef CONFIG_MAGIC_SYSRQ
+ ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate;
+ SYSRQ_KEY = 0x54;
+#endif
+ memcpy(mac_key_maps_save, key_maps, sizeof(key_maps));
+ memcpy(key_maps, pc_key_maps_save, sizeof(key_maps));
+ }
+ }
+
+ return ret;
+}
+#endif
+#endif /* endif CONFIG_SYSCTL */
+
+int mac_hid_kbd_translate(unsigned char scancode, unsigned char *keycode,
+ char raw_mode)
+{
+#ifdef CONFIG_MAC_ADBKEYCODES
+ if (!keyboard_sends_linux_keycodes) {
+ if (!raw_mode) {
+ /*
+ * Convert R-shift/control/option to L version.
+ */
+ switch (scancode) {
+ case 0x7b: scancode = 0x38; break; /* R-shift */
+ case 0x7c: scancode = 0x3a; break; /* R-option */
+ case 0x7d: scancode = 0x36; break; /* R-control */
+ }
+ }
+ *keycode = scancode;
+ return 1;
+ } else
+#endif
+ {
+ /* This code was copied from char/pc_keyb.c and will be
+ * superflous when the input layer is fully integrated.
+ * We don't need the high_keys handling, so this part
+ * has been removed.
+ */
+ static int prev_scancode = 0;
+
+ /* special prefix scancodes.. */
+ if (scancode == 0xe0 || scancode == 0xe1) {
+ prev_scancode = scancode;


+ return 0;
+ }
+

+ scancode &= 0x7f;
+
+ if (prev_scancode) {
+ if (prev_scancode != 0xe0) {
+ if (prev_scancode == 0xe1 && scancode == 0x1d) {
+ prev_scancode = 0x100;
+ return 0;
+ } else if (prev_scancode == 0x100 && scancode == 0x45) {
+ *keycode = KEY_PAUSE;
+ prev_scancode = 0;
+ } else {
+ if (!raw_mode)
+ printk(KERN_INFO "keyboard: unknown e1 escape sequence\n");
+ prev_scancode = 0;
+ return 0;
+ }
+ } else {
+ prev_scancode = 0;
+ if (scancode == 0x2a || scancode == 0x36)
+ return 0;
+ }
+ if (e0_keys[scancode])
+ *keycode = e0_keys[scancode];
+ else {
+ if (!raw_mode)
+ printk(KERN_INFO "keyboard: unknown scancode e0 %02x\n",
+ scancode);
+ return 0;
+ }
+ } else {
+ switch (scancode) {
+ case 91: scancode = KEY_LINEFEED; break;
+ case 92: scancode = KEY_KPEQUAL; break;
+ case 125: scancode = KEY_INTL1; break;
+ }
+ *keycode = scancode;


+ }
+ return 1;
+ }
+}

+
+char mac_hid_kbd_unexpected_up(unsigned char keycode)
+{
+ if (keyboard_sends_linux_keycodes && keycode == KEY_F13)


+ return 0;
+ else

+ return 0x80;
+}
+
+#ifdef CONFIG_MAC_ADBKEYCODES
+int mac_hid_keyboard_sends_linux_keycodes(void)
+{
+ return keyboard_sends_linux_keycodes;
+}
+
+static int __init mac_hid_setup(char *str)
+{
+ int ints[2];
+
+ str = get_options(str, ARRAY_SIZE(ints), ints);
+ if (ints[0] == 1) {
+ keyboard_sends_linux_keycodes = ints[1] != 0;
+ keyboard_lock_keycodes = 1;
+ }
+ return 1;
+}
+
+__setup("keyboard_sends_linux_keycodes=", mac_hid_setup);
+
+#endif
+
+#ifdef CONFIG_MAC_EMUMOUSEBTN
+int mac_hid_mouse_emulate_buttons(int caller, unsigned int keycode, int down)
+{
+ switch (caller) {
+ case 1:
+ /* Called from keybdev.c */
+ if (mouse_emulate_buttons
+ && (keycode == mouse_button2_keycode
+ || keycode == mouse_button3_keycode)) {
+ if (mouse_emulate_buttons == 1) {
+ input_report_key(&emumousebtn,
+ keycode == mouse_button2_keycode ? BTN_MIDDLE : BTN_RIGHT,
+ down);
+ return 1;
+ }
+ mouse_last_keycode = down ? keycode : 0;
+ }


+ break;
+ case 2:

+ /* Called from mousedev.c */
+ if (mouse_emulate_buttons == 2 && keycode == 0) {
+ if (mouse_last_keycode == mouse_button2_keycode)
+ return 1; /* map to middle button */
+ if (mouse_last_keycode == mouse_button3_keycode)
+ return 2; /* map to right button */
+ }
+ return keycode; /* keep button */
+ }


+ return 0;
+}
+

+static void emumousebtn_input_register(void)
+{
+ emumousebtn.name = "Macintosh mouse button emulation";
+
+ emumousebtn.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+ emumousebtn.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+ emumousebtn.relbit[0] = BIT(REL_X) | BIT(REL_Y);
+
+ emumousebtn.idbus = BUS_ADB;
+ emumousebtn.idvendor = 0x0001;
+ emumousebtn.idproduct = 0x0001;
+ emumousebtn.idversion = 0x0100;
+
+ input_register_device(&emumousebtn);
+
+ printk(KERN_INFO "input%d: Macintosh mouse button emulation\n", emumousebtn.number);
+}
+#endif
+
+void __init mac_hid_init_hw(void)
+{
+
+#ifdef CONFIG_MAC_ADBKEYCODES
+ memcpy(pc_key_maps_save, key_maps, sizeof(key_maps));
+
+ if (!keyboard_sends_linux_keycodes)
+ memcpy(key_maps, mac_key_maps_save, sizeof(key_maps));
+#endif
+
+#ifdef CONFIG_MAC_EMUMOUSEBTN
+ emumousebtn_input_register();
+#endif
+
+#if CONFIG_PPC
+ if (_machine != _MACH_Pmac)
+ pckbd_init_hw();
+#endif
+
+#if defined(CONFIG_SYSCTL) && (defined(CONFIG_MAC_ADBKEYCODES) || defined(CONFIG_MAC_EMUMOUSEBTN))
+ mac_hid_sysctl_header = register_sysctl_table(mac_hid_root_dir, 1);
+#endif /* CONFIG_SYSCTL */
+}
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/macintosh/mac_keyb.c linux/drivers/macintosh/mac_keyb.c
--- v2.4.0-test8/linux/drivers/macintosh/mac_keyb.c Tue Jun 20 13:58:42 2000
+++ linux/drivers/macintosh/mac_keyb.c Sun Sep 17 09:48:05 2000
@@ -51,6 +51,10 @@
X #include <linux/kbd_kern.h>
X #include <linux/kbd_ll.h>
X

+#ifdef CONFIG_PMAC_BACKLIGHT
+#include <asm/backlight.h>
+#endif
+

X #define KEYB_KEYREG 0 /* register # for key up/down data */
X #define KEYB_LEDREG 2 /* register # for leds on ADB keyboard */
X #define MOUSE_DATAREG 0 /* reg# for movement/button codes from mouse */
@@ -585,68 +589,50 @@
X }
X #endif /* CONFIG_ADBMOUSE */
X
-/* XXX Needs to get rid of this, see comments in pmu.c */
-extern int backlight_level;
-
X static void
X buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int autopoll)
X {
-#ifdef CONFIG_ADB_PMU


+#ifdef CONFIG_PMAC_BACKLIGHT
+ int backlight = get_backlight_level();
+

X /*
X * XXX: Where is the contrast control for the passive?
X * -- Cort
X */
X
X /* Ignore data from register other than 0 */
-#if 0
- if ((adb_hardware != ADB_VIAPMU) || (data[0] & 0x3) || (nb < 2))
-#else
X if ((data[0] & 0x3) || (nb < 2))
-#endif
X return;
X
- switch (data[1]&0xf )
- {
- /* mute */
- case 0x8:
- /* down event */
- if ( data[1] == (data[1]&0xf) ) {
- }
- break;
- /* contrast decrease */
- case 0x7:
- /* down event */
- if ( data[1] == (data[1]&0xf) ) {
- }
- break;
- /* contrast increase */
- case 0x6:
- /* down event */
- if ( data[1] == (data[1]&0xf) ) {
- }
- break;
- /* brightness decrease */
- case 0xa:
- /* down event */
- if ( data[1] == (data[1]&0xf) ) {
- if (backlight_level > 2)
- pmu_set_brightness(backlight_level-2);
- else
- pmu_set_brightness(0);
- }


+ switch (data[1]) {
+ case 0x8: /* mute */
+ break;
+
+ case 0x7: /* contrast decrease */
+ break;
+
+ case 0x6: /* contrast increase */
+ break;
+
+ case 0xa: /* brightness decrease */
+ if (backlight < 0)

X break;
- /* brightness increase */
- case 0x9:
- /* down event */
- if ( data[1] == (data[1]&0xf) ) {
- if (backlight_level < 0x1e)
- pmu_set_brightness(backlight_level+2);
- else
- pmu_set_brightness(0x1f);
- }


+ if (backlight > BACKLIGHT_OFF)
+ set_backlight_level(backlight-1);
+ else
+ set_backlight_level(BACKLIGHT_OFF);
+ break;
+
+ case 0x9: /* brightness increase */
+ if (backlight < 0)

X break;


+ if (backlight < BACKLIGHT_MAX)
+ set_backlight_level(backlight+1);
+ else
+ set_backlight_level(BACKLIGHT_MAX);
+ break;

X }
-#endif /* CONFIG_ADB_PMU */
+#endif /* CONFIG_PMAC_BACKLIGHT */
X }
X
X /* Map led flags as defined in kbd_kern.h to bits for Apple keyboard. */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/macintosh/macio-adb.c linux/drivers/macintosh/macio-adb.c
--- v2.4.0-test8/linux/drivers/macintosh/macio-adb.c Thu Oct 7 10:17:09 1999
+++ linux/drivers/macintosh/macio-adb.c Sun Sep 17 09:48:05 2000
@@ -122,6 +122,8 @@
X out_8(&adb->autopoll.r, APE);
X out_8(&adb->intr_enb.r, DFB | TAG);
X
+ printk("adb: mac-io driver 1.0 for unified ADB\n");
+


X return 0;
X }
X

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/macintosh/macserial.c linux/drivers/macintosh/macserial.c
--- v2.4.0-test8/linux/drivers/macintosh/macserial.c Sat May 20 12:07:56 2000
+++ linux/drivers/macintosh/macserial.c Sun Sep 17 09:48:05 2000
@@ -2291,7 +2291,7 @@
X zss->irq = ch->intrs[0].line;
X zss->has_dma = 0;
X #if !defined(CONFIG_KGDB) && defined(SUPPORT_SERIAL_DMA)
- if (ch->n_addrs == 3 && ch->n_intrs == 3)
+ if (ch->n_addrs >= 3 && ch->n_intrs == 3)
X zss->has_dma = 1;
X #endif
X zss->dma_initted = 0;
@@ -2643,9 +2643,6 @@
X * ------------------------------------------------------------
X */
X #ifdef CONFIG_SERIAL_CONSOLE
-#ifdef CONFIG_SERIAL
-#error Cannot build serial console with macserial and serial drivers
-#endif
X
X /*
X * Print a string to the serial port trying not to disturb
@@ -2719,7 +2716,7 @@
X */
X static int __init serial_console_setup(struct console *co, char *options)
X {
- struct mac_serial *info = zs_soft + co->index;
+ struct mac_serial *info;
X int baud = 38400;
X int bits = 8;
X int parity = 'n';
@@ -2735,6 +2732,11 @@
X if (zs_chain == 0)
X return -1;
X
+ /* Do we have the device asked for? */
+ if (co->index >= zs_channels_found)
+ return -1;
+ info = zs_soft + co->index;
+
X set_scc_power(info, 1);
X
X /* Reset the channel */
@@ -2904,7 +2906,7 @@
X /*
X * Register console.
X */
-void __init serial_console_init(void)
+void __init mac_scc_console_init(void)
X {
X register_console(&sercons);
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/macintosh/mediabay.c linux/drivers/macintosh/mediabay.c
--- v2.4.0-test8/linux/drivers/macintosh/mediabay.c Sat May 20 12:07:56 2000
+++ linux/drivers/macintosh/mediabay.c Sun Sep 17 09:48:05 2000
@@ -472,8 +472,11 @@
X } else if (MB_IDE_READY(i)) {
X bay->timer = 0;
X bay->state = mb_up;
- if (bay->cd_index < 0)
+ if (bay->cd_index < 0) {
+ pmu_suspend();
X bay->cd_index = ide_register(bay->cd_base, 0, bay->cd_irq);
+ pmu_resume();
+ }
X if (bay->cd_index == -1) {
X /* We eventually do a retry */
X bay->cd_retry++;
@@ -605,7 +608,9 @@
X only if it did not change. Note those bozo timings,
X they seem to help the 3400 get it right.
X */
- mdelay(MB_STABLE_DELAY);
+ /* Force MB power to 0 */
+ set_mb_power(i, 0);
+ mdelay(MB_POWER_DELAY);
X if (!bay->pismo)
X out_8(&bay->addr->contents, 0x70);
X mdelay(MB_STABLE_DELAY);
@@ -615,7 +620,9 @@
X bay->last_value = bay->content_id;
X bay->value_count = MS_TO_HZ(MB_STABLE_DELAY);
X bay->timer = MS_TO_HZ(MB_POWER_DELAY);
+#ifdef CONFIG_BLK_DEV_IDE
X bay->cd_retry = 0;
+#endif
X do {
X mdelay(1000/HZ);
X media_bay_step(i);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/macintosh/nvram.c linux/drivers/macintosh/nvram.c
--- v2.4.0-test8/linux/drivers/macintosh/nvram.c Tue Jun 20 13:58:42 2000
+++ linux/drivers/macintosh/nvram.c Sun Sep 17 09:48:05 2000
@@ -14,6 +14,7 @@
X #include <linux/nvram.h>
X #include <linux/init.h>
X #include <asm/uaccess.h>
+#include <asm/nvram.h>
X
X #define NVRAM_SIZE 8192
X
@@ -70,11 +71,36 @@
X return p - buf;
X }
X
+static int nvram_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ switch(cmd) {
+ case PMAC_NVRAM_GET_OFFSET:
+ {
+ int part, offset;
+ if (copy_from_user(&part,(void*)arg,sizeof(part))!=0)
+ return -EFAULT;
+ if (part < pmac_nvram_OF || part > pmac_nvram_NR)
+ return -EINVAL;
+ offset = pmac_get_partition(part);
+ if (copy_to_user((void*)arg,&offset,sizeof(offset))!=0)
+ return -EFAULT;
+ break;
+ }
+


+ default:
+ return -EINVAL;
+ }
+

+ return 0;
+}
+

X struct file_operations nvram_fops = {
X owner: THIS_MODULE,
X llseek: nvram_llseek,
X read: read_nvram,
X write: write_nvram,
+ ioctl: nvram_ioctl,
X };
X
X static struct miscdevice nvram_dev = {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/macintosh/rtc.c linux/drivers/macintosh/rtc.c
--- v2.4.0-test8/linux/drivers/macintosh/rtc.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/macintosh/rtc.c Tue Sep 19 08:31:53 2000
@@ -0,0 +1,157 @@
+/*
+ * Linux/PowerPC Real Time Clock Driver
+ *
+ * heavily based on:
+ * Linux/SPARC Real Time Clock Driver
+ * Copyright (C) 1996 Thomas K. Dyas (td...@eden.rutgers.edu)
+ *
+ * This is a little driver that lets a user-level program access
+ * the PPC clocks chip. It is no use unless you
+ * use the modified clock utility.
+ *
+ * Get the modified clock utility from:
+ * ftp://vger.rutgers.edu/pub/linux/Sparc/userland/clock.c
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/miscdevice.h>
+#include <linux/malloc.h>
+#include <linux/fcntl.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/mc146818rtc.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/machdep.h>
+
+#include <asm/time.h>
+
+static int rtc_busy = 0;
+
+/* Retrieve the current date and time from the real time clock. */
+void get_rtc_time(struct rtc_time *t)
+{
+ unsigned long nowtime;
+
+ nowtime = (ppc_md.get_rtc_time)();
+
+ to_tm(nowtime, t);
+
+ t->tm_year -= 1900;
+ t->tm_mon -= 1;
+ t->tm_wday -= 1;
+}
+
+/* Set the current date and time in the real time clock. */
+void set_rtc_time(struct rtc_time *t)
+{
+ unsigned long nowtime;
+
+ printk(KERN_INFO "rtc.c:set_rtc_time: %04d-%02d-%02d %02d:%02d:%02d.\n", t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
+
+ nowtime = mktime(t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
+
+ printk(KERN_INFO "rtc.c:set_rtc_time: set rtc time to %ld seconds.\n", nowtime);
+
+ (ppc_md.set_rtc_time)(nowtime);
+}
+
+static loff_t rtc_lseek(struct file *file, loff_t offset, int origin)
+{
+ return -ESPIPE;
+}
+
+static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,


+ unsigned long arg)
+{

+ struct rtc_time rtc_tm;
+
+ switch (cmd)
+ {
+ case RTC_RD_TIME:
+ if (ppc_md.get_rtc_time)
+ {
+ get_rtc_time(&rtc_tm);
+
+ if (copy_to_user((struct rtc_time*)arg, &rtc_tm, sizeof(struct rtc_time)))


+ return -EFAULT;
+
+ return 0;

+ }
+ else
+ return -EINVAL;
+
+ case RTC_SET_TIME:
+ if (!capable(CAP_SYS_TIME))
+ return -EPERM;
+
+ if (ppc_md.set_rtc_time)
+ {
+ if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, sizeof(struct rtc_time)))
+ return -EFAULT;
+
+ set_rtc_time(&rtc_tm);
+
+ return 0;
+ }
+ else
+ return -EINVAL;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static int rtc_open(struct inode *inode, struct file *file)
+{
+ if (rtc_busy)
+ return -EBUSY;
+
+ rtc_busy = 1;
+
+ MOD_INC_USE_COUNT;
+


+ return 0;
+}
+

+static int rtc_release(struct inode *inode, struct file *file)
+{
+ MOD_DEC_USE_COUNT;
+ rtc_busy = 0;


+ return 0;
+}
+

+static struct file_operations rtc_fops = {
+ owner: THIS_MODULE,
+ llseek: rtc_lseek,
+ ioctl: rtc_ioctl,
+ open: rtc_open,
+ release: rtc_release
+};
+
+static struct miscdevice rtc_dev = { RTC_MINOR, "rtc", &rtc_fops };
+
+EXPORT_NO_SYMBOLS;
+
+static int __init rtc_init(void)
+{
+ int error;
+
+ error = misc_register(&rtc_dev);
+ if (error) {
+ printk(KERN_ERR "rtc: unable to get misc minor\n");
+ return error;
+ }
+


+ return 0;
+}
+

+static void __exit rtc_exit(void)
+{
+ misc_deregister(&rtc_dev);
+}
+
+module_init(rtc_init);
+module_exit(rtc_exit);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/macintosh/via-cuda.c linux/drivers/macintosh/via-cuda.c
--- v2.4.0-test8/linux/drivers/macintosh/via-cuda.c Fri Nov 12 04:29:47 1999
+++ linux/drivers/macintosh/via-cuda.c Sun Sep 17 09:48:05 2000
@@ -94,39 +94,48 @@
X #endif
X static int cuda_fully_inited = 0;
X
+#ifdef CONFIG_ADB
X static int cuda_probe(void);
X static int cuda_init(void);
+static int cuda_send_request(struct adb_request *req, int sync);
+static int cuda_adb_autopoll(int devs);
+static int cuda_reset_adb_bus(void);
+#endif /* CONFIG_ADB */
+
X static int cuda_init_via(void);
X static void cuda_start(void);
X static void cuda_interrupt(int irq, void *arg, struct pt_regs *regs);
X static void cuda_input(unsigned char *buf, int nb, struct pt_regs *regs);
-static int cuda_send_request(struct adb_request *req, int sync);
-static int cuda_adb_autopoll(int devs);
X void cuda_poll(void);
-static int cuda_reset_adb_bus(void);
X static int cuda_write(struct adb_request *req);
X
X int cuda_request(struct adb_request *req,
X void (*done)(struct adb_request *), int nbytes, ...);
X
+#ifdef CONFIG_ADB
X struct adb_driver via_cuda_driver = {
X "CUDA",
X cuda_probe,
X cuda_init,
X cuda_send_request,
- /*cuda_write,*/
X cuda_adb_autopoll,
X cuda_poll,
X cuda_reset_adb_bus
X };
+#endif /* CONFIG_ADB */
X
X #ifdef CONFIG_PPC
-void
-find_via_cuda()
+int
+find_via_cuda(void)
X {
+ int err;


+ struct adb_request req;
+

+ if (vias != 0)
+ return 1;
X vias = find_devices("via-cuda");
X if (vias == 0)
- return;
+ return 0;
X if (vias->next != 0)
X printk(KERN_WARNING "Warning: only using 1st via-cuda\n");
X
@@ -146,15 +155,54 @@
X printk(KERN_ERR "via-cuda: expecting 1 address (%d) and 1 interrupt (%d)\n",
X vias->n_addrs, vias->n_intrs);
X if (vias->n_addrs < 1 || vias->n_intrs < 1)
- return;
+ return 0;
X }
X via = (volatile unsigned char *) ioremap(vias->addrs->address, 0x2000);
X
X cuda_state = idle;
X sys_ctrler = SYS_CTRLER_CUDA;
+
+ err = cuda_init_via();
+ if (err) {
+ printk(KERN_ERR "cuda_init_via() failed\n");
+ via = NULL;


+ return 0;
+ }
+

+ /* Clear and enable interrupts, but only on PPC. On 68K it's done */
+ /* for us by the the main VIA driver in arch/m68k/mac/via.c */
+
+#ifndef CONFIG_MAC
+ via[IFR] = 0x7f; eieio(); /* clear interrupts by writing 1s */
+ via[IER] = IER_SET|SR_INT; eieio(); /* enable interrupt from SR */
+#endif
+
+ /* enable autopoll */
+ cuda_request(&req, NULL, 3, CUDA_PACKET, CUDA_AUTOPOLL, 1);
+ while (!req.complete)
+ cuda_poll();
+
+ return 1;
X }
X #endif /* CONFIG_PPC */
X
+int via_cuda_start(void)
+{
+ if (via == NULL)
+ return -ENODEV;
+
+ if (request_irq(CUDA_IRQ, cuda_interrupt, 0, "ADB", cuda_interrupt)) {
+ printk(KERN_ERR "cuda_init: can't get irq %d\n", CUDA_IRQ);


+ return -EAGAIN;
+ }
+

+ printk("Macintosh CUDA driver v0.5 for Unified ADB.\n");
+
+ cuda_fully_inited = 1;


+ return 0;
+}
+

+#ifdef CONFIG_ADB
X static int
X cuda_probe()
X {
@@ -172,46 +220,24 @@
X static int
X cuda_init(void)
X {
- int err;
-
X if (via == NULL)
X return -ENODEV;
-
- err = cuda_init_via();
- if (err) {
- printk(KERN_ERR "cuda_probe: init_via() failed\n");
- via = NULL;


- return err;
- }
-

- /* Clear and enable interrupts, but only on PPC. On 68K it's done */
- /* for us by the the main VIA driver in arch/m68k/mac/via.c */
-
-#ifndef CONFIG_MAC
- via[IFR] = 0x7f; eieio(); /* clear interrupts by writing 1s */
- via[IER] = IER_SET|SR_INT; eieio(); /* enable interrupt from SR */
+#ifndef CONFIG_PPC
+ return via_cuda_start();
X #endif
-
- if (request_irq(CUDA_IRQ, cuda_interrupt, 0, "ADB", cuda_interrupt)) {
- printk(KERN_ERR "cuda_init: can't get irq %d\n", CUDA_IRQ);
- return -EAGAIN;
- }
-
- printk("adb: CUDA driver v0.5 for Unified ADB.\n");
-
- cuda_fully_inited = 1;
X return 0;
X }
+#endif /* CONFIG_ADB */
X
-#define WAIT_FOR(cond, what) \
- do { \
- for (x = 1000; !(cond); --x) { \
- if (x == 0) { \
- printk("Timeout waiting for " what); \
- return -ENXIO; \
- } \
+#define WAIT_FOR(cond, what) \
+ do { \
+ for (x = 1000; !(cond); --x) { \
+ if (x == 0) { \
+ printk("Timeout waiting for " what "\n"); \
+ return -ENXIO; \
+ } \
X udelay(100); \
- } \
+ } \
X } while (0)
X
X static int
@@ -255,6 +281,7 @@


X return 0;
X }
X

+#ifdef CONFIG_ADB
X /* Send an ADB command */
X static int
X cuda_send_request(struct adb_request *req, int sync)
@@ -309,7 +336,7 @@
X cuda_poll();
X return 0;
X }
-
+#endif /* CONFIG_ADB */
X /* Construct and send a cuda request */
X int
X cuda_request(struct adb_request *req, void (*done)(struct adb_request *),
@@ -534,7 +561,18 @@
X
X switch (buf[0]) {
X case ADB_PACKET:
+#ifdef CONFIG_XMON
+ if (nb == 5 && buf[2] == 0x2c) {
+ extern int xmon_wants_key, xmon_adb_keycode;
+ if (xmon_wants_key) {
+ xmon_adb_keycode = buf[3];
+ return;
+ }
+ }
+#endif /* CONFIG_XMON */
+#ifdef CONFIG_ADB
X adb_input(buf+2, nb-2, regs, buf[1] & 0x40);
+#endif /* CONFIG_ADB */
X break;
X
X default:
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/macintosh/via-pmu.c linux/drivers/macintosh/via-pmu.c
--- v2.4.0-test8/linux/drivers/macintosh/via-pmu.c Wed Jul 12 21:58:42 2000
+++ linux/drivers/macintosh/via-pmu.c Sun Sep 17 09:48:05 2000
@@ -32,6 +32,7 @@
X #include <linux/pmu.h>
X #include <linux/cuda.h>
X #include <linux/smp_lock.h>
+#include <linux/spinlock.h>
X #include <asm/prom.h>
X #include <asm/machdep.h>
X #include <asm/io.h>
@@ -39,10 +40,16 @@
X #include <asm/system.h>
X #include <asm/init.h>
X #include <asm/irq.h>
+#include <asm/hardirq.h>
X #include <asm/feature.h>
X #include <asm/uaccess.h>
X #include <asm/mmu_context.h>
-#include <asm/heathrow.h>


+#ifdef CONFIG_PMAC_BACKLIGHT
+#include <asm/backlight.h>
+#endif
+

+/* Some compile options */
+#undef SUSPEND_USES_PMU
X
X /* Misc minor number allocated for /dev/pmu */
X #define PMU_MINOR 154
@@ -84,7 +91,7 @@
X #define CB2_INT 0x08
X #define CB1_INT 0x10 /* transition on CB1 input */
X
-static enum pmu_state {
+static volatile enum pmu_state {
X idle,
X sending,
X intack,
@@ -95,7 +102,7 @@
X static struct adb_request *current_req;
X static struct adb_request *last_req;
X static struct adb_request *req_awaiting_reply;
-static unsigned char interrupt_data[32];
+static unsigned char interrupt_data[256]; /* Made bigger: I've been told that might happen */
X static unsigned char *reply_ptr;
X static int data_index;
X static int data_len;
@@ -106,22 +113,27 @@
X static struct device_node *vias;
X static int pmu_kind = PMU_UNKNOWN;
X static int pmu_fully_inited = 0;
-static int pmu_has_adb, pmu_has_backlight;
+static int pmu_has_adb;
X static unsigned char *gpio_reg = NULL;
-static int gpio_irq;
+static int gpio_irq = -1;
+static volatile int pmu_suspended = 0;
+static spinlock_t pmu_lock;
X
X int asleep;
X struct notifier_block *sleep_notifier_list;
X
+#ifdef CONFIG_ADB
X static int pmu_probe(void);
X static int pmu_init(void);
+static int pmu_send_request(struct adb_request *req, int sync);
+static int pmu_adb_autopoll(int devs);
+static int pmu_adb_reset_bus(void);
+#endif /* CONFIG_ADB */
+
X static int init_pmu(void);
X static int pmu_queue_request(struct adb_request *req);
X static void pmu_start(void);
X static void via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs);
-static int pmu_send_request(struct adb_request *req, int sync);
-static int pmu_adb_autopoll(int devs);
-static int pmu_adb_reset_bus(void);
X static void send_byte(int x);
X static void recv_byte(void);
X static void pmu_sr_intr(struct pt_regs *regs);
@@ -130,20 +142,25 @@
X struct pt_regs *regs);
X static void set_volume(int level);
X static void gpio1_interrupt(int irq, void *arg, struct pt_regs *regs);
+#ifdef CONFIG_PMAC_BACKLIGHT
+static int pmu_set_backlight_level(int level, void* data);
+static int pmu_set_backlight_enable(int on, int level, void* data);
+#endif /* CONFIG_PMAC_BACKLIGHT */
X #ifdef CONFIG_PMAC_PBOOK
X static void pmu_pass_intr(unsigned char *data, int len);
X #endif
X
+#ifdef CONFIG_ADB
X struct adb_driver via_pmu_driver = {
X "PMU",
X pmu_probe,
X pmu_init,
X pmu_send_request,
- /*pmu_queue_request,*/
X pmu_adb_autopoll,
X pmu_poll,
X pmu_adb_reset_bus
X };
+#endif /* CONFIG_ADB */
X
X extern void low_sleep_handler(void);
X extern void sleep_save_intrs(int);
@@ -206,6 +223,13 @@
X "Core99"
X };
X
+#ifdef CONFIG_PMAC_BACKLIGHT
+static struct backlight_controller pmu_backlight_controller = {
+ pmu_set_backlight_enable,
+ pmu_set_backlight_level


+};
+#endif /* CONFIG_PMAC_BACKLIGHT */
+

X int __openfirmware
X find_via_pmu()
X {
@@ -216,17 +240,6 @@
X return 0;
X if (vias->next != 0)
X printk(KERN_WARNING "Warning: only using 1st via-pmu\n");
-#if 0
- { int i;
-
- printk("find_via_pmu: node = %p, addrs =", vias->node);
- for (i = 0; i < vias->n_addrs; ++i)
- printk(" %x(%x)", vias->addrs[i].address, vias->addrs[i].size);
- printk(", intrs =");
- for (i = 0; i < vias->n_intrs; ++i)
- printk(" %x", vias->intrs[i].line);
- printk("\n"); }
-#endif
X
X if (vias->n_addrs < 1 || vias->n_intrs < 1) {
X printk(KERN_ERR "via-pmu: %d addresses, %d interrupts!\n",
@@ -235,8 +248,9 @@


X return 0;
X }
X

+ spin_lock_init(&pmu_lock);
+
X pmu_has_adb = 1;
- pmu_has_backlight = 1;
X
X if (vias->parent->name && ((strcmp(vias->parent->name, "ohare") == 0)
X || device_is_compatible(vias->parent, "ohare")))
@@ -246,9 +260,18 @@
X else if (device_is_compatible(vias->parent, "heathrow"))
X pmu_kind = PMU_HEATHROW_BASED;
X else if (device_is_compatible(vias->parent, "Keylargo")) {
+ struct device_node *gpio, *gpiop;
+
X pmu_kind = PMU_KEYLARGO_BASED;
X pmu_has_adb = (find_type_devices("adb") != NULL);
- pmu_has_backlight = (find_type_devices("backlight") != NULL);
+
+ gpiop = find_devices("gpio");
+ if (gpiop && gpiop->n_addrs) {
+ gpio_reg = ioremap(gpiop->addrs->address, 0x10);
+ gpio = find_devices("extint-gpio1");
+ if (gpio && gpio->parent == gpiop && gpio->n_intrs)
+ gpio_irq = gpio->intrs[0].line;
+ }
X } else
X pmu_kind = PMU_UNKNOWN;
X
@@ -266,10 +289,13 @@
X
X printk(KERN_INFO "PMU driver initialized for %s\n",
X pbook_type[pmu_kind]);
+
X sys_ctrler = SYS_CTRLER_PMU;
+

X return 1;
X }
X

+#ifdef CONFIG_ADB
X static int __openfirmware
X pmu_probe()
X {
@@ -280,9 +306,10 @@
X pmu_init(void)
X {
X if (vias == NULL)
- return -ENXIO;
+ return -ENODEV;
X return 0;
X }
+#endif /* CONFIG_ADB */
X
X /*
X * We can't wait until pmu_init gets called, that happens too late.
@@ -291,10 +318,10 @@
X * turned us off.
X * This is called from arch/ppc/kernel/pmac_setup.c:pmac_init2().
X */
-void via_pmu_start(void)
+int via_pmu_start(void)
X {
X if (vias == NULL)


- return;
+ return -ENODEV;
X

X bright_req_1.complete = 1;
X bright_req_2.complete = 1;
@@ -304,24 +331,12 @@
X (void *)0)) {
X printk(KERN_ERR "VIA-PMU: can't get irq %d\n",
X vias->intrs[0].line);
- return;
+ return -EAGAIN;
X }
X
- if (pmu_kind == PMU_KEYLARGO_BASED) {
- struct device_node *gpio, *gpiop;
-
- gpiop = find_devices("gpio");
- if (gpiop && gpiop->n_addrs) {
- gpio_reg = ioremap(gpiop->addrs->address, 0x10);
- gpio = find_devices("extint-gpio1");
- if (gpio && gpio->parent == gpiop && gpio->n_intrs) {
- gpio_irq = gpio->intrs[0].line;
- if (request_irq(gpio_irq, gpio1_interrupt, 0,
- "GPIO1/ADB", (void *)0))
- printk(KERN_ERR "pmu: can't get irq %d (GPIO1)\n",
- gpio->intrs[0].line);
- }
- }
+ if (pmu_kind == PMU_KEYLARGO_BASED && gpio_irq != -1) {
+ if (request_irq(gpio_irq, gpio1_interrupt, 0, "GPIO1/ADB", (void *)0))
+ printk(KERN_ERR "pmu: can't get irq %d (GPIO1)\n", gpio_irq);
X }
X
X /* Enable interrupts */
@@ -329,8 +344,24 @@
X
X pmu_fully_inited = 1;
X
+#ifdef CONFIG_PMAC_BACKLIGHT
X /* Enable backlight */
- pmu_enable_backlight(1);
+ register_backlight_controller(&pmu_backlight_controller, NULL, "pmu");


+#endif /* CONFIG_PMAC_BACKLIGHT */
+

+ /* Make sure PMU settle down before continuing. This is _very_ important
+ * since the IDE probe may shut interrupts down for quite a bit of time. If
+ * a PMU communication is pending while this happens, the PMU may timeout
+ * Not that on Core99 machines, the PMU keeps sending us environement
+ * messages, we should find a way to either fix IDE or make it call
+ * pmu_suspend() before masking interrupts. This can also happens while
+ * scolling with some fbdevs.
+ */
+ do {
+ pmu_poll();
+ } while (pmu_state != idle);


+
+ return 0;
X }
X

X static int __openfirmware
@@ -342,7 +373,7 @@
X out_8(&via[B], via[B] | TREQ); /* negate TREQ */
X out_8(&via[DIRB], (via[DIRB] | TREQ) & ~TACK); /* TACK in, TREQ out */
X
- pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0xff);
+ pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0xfc);
X timeout = 100000;
X while (!req.complete) {
X if (--timeout < 0) {
@@ -367,6 +398,13 @@
X udelay(10);
X }
X
+ /* Tell PMU we are ready. Which PMU support this ? */
+ if (pmu_kind == PMU_KEYLARGO_BASED) {
+ pmu_request(&req, NULL, 2, PMU_SYSTEM_READY, 2);
+ while (!req.complete)
+ pmu_poll();
+ }
+

X return 1;
X }
X

@@ -376,6 +414,7 @@
X return pmu_kind;
X }
X
+#ifdef CONFIG_ADB
X /* Send an ADB command */
X static int __openfirmware
X pmu_send_request(struct adb_request *req, int sync)
@@ -513,6 +552,7 @@


X
X return 0;
X }

+#endif /* CONFIG_ADB */
X
X /* Construct and send a pmu request */
X int __openfirmware
@@ -568,8 +608,8 @@
X req->next = 0;
X req->sent = 0;
X req->complete = 0;
- save_flags(flags); cli();
X
+ spin_lock_irqsave(&pmu_lock, flags);
X if (current_req != 0) {
X last_req->next = req;
X last_req = req;
@@ -579,11 +619,27 @@
X if (pmu_state == idle)
X pmu_start();
X }
+ spin_unlock_irqrestore(&pmu_lock, flags);
X
- restore_flags(flags);


X return 0;
X }
X

+static void __openfirmware
+wait_for_ack(void)
+{
+ /* Sightly increased the delay, I had one occurence of the message
+ * reported
+ */
+ int timeout = 4000;
+ while ((in_8(&via[B]) & TACK) == 0) {
+ if (--timeout < 0) {
+ printk(KERN_ERR "PMU not responding (!ack)\n");
+ return;
+ }
+ udelay(10);
+ }
+}
+
X /* New PMU seems to be very sensitive to those timings, so we make sure
X * PCI is flushed immediately */
X static void __openfirmware
@@ -613,57 +669,126 @@
X static void __openfirmware
X pmu_start()
X {
- unsigned long flags;
X struct adb_request *req;
X
X /* assert pmu_state == idle */
X /* get the packet to send */
- save_flags(flags); cli();
X req = current_req;
X if (req == 0 || pmu_state != idle
- || (req->reply_expected && req_awaiting_reply))
- goto out;
+ || (/*req->reply_expected && */req_awaiting_reply))
+ return;
X
X pmu_state = sending;
X data_index = 1;
X data_len = pmu_data_len[req->data[0]][0];
X
+ /* Sounds safer to make sure ACK is high before writing. This helped
+ * kill a problem with ADB and some iBooks
+ */
+ wait_for_ack();
X /* set the shift register to shift out and send a byte */
- ++disable_poll;
X send_byte(req->data[0]);
- --disable_poll;
-
-out:
- restore_flags(flags);
X }
X
X void __openfirmware
X pmu_poll()
X {


- unsigned long flags;
-

+ if (!via)
+ return;
X if (disable_poll)
X return;
- save_flags(flags);
- cli();
- if ((via[IFR] & (SR_INT | CB1_INT)) ||
- (gpio_reg && (in_8(gpio_reg + 0x9) & 0x02) == 0))
+ /* Kicks ADB read when PMU is suspended */
+ if (pmu_suspended)
+ adb_int_pending = 1;
+ do {
+ via_pmu_interrupt(0, 0, 0);
+ } while (pmu_suspended && (adb_int_pending || pmu_state != idle
+ || req_awaiting_reply));
+}
+
+/* This function loops until the PMU is idle and prevents it from
+ * anwsering to ADB interrupts. pmu_request can still be called.
+ * This is done to avoid spurrious shutdowns when we know we'll have
+ * interrupts switched off for a long time
+ */
+void __openfirmware
+pmu_suspend(void)


+{
+ unsigned long flags;

+#ifdef SUSPEND_USES_PMU
+ struct adb_request *req;
+#endif
+ if (!via)
+ return;
+
+ spin_lock_irqsave(&pmu_lock, flags);
+ pmu_suspended++;
+ if (pmu_suspended > 1) {
+ spin_unlock_irqrestore(&pmu_lock, flags);
+ return;
+ }
+
+ do {
+ spin_unlock(&pmu_lock);
X via_pmu_interrupt(0, 0, 0);
- restore_flags(flags);
+ spin_lock(&pmu_lock);
+ if (!adb_int_pending && pmu_state == idle && !req_awaiting_reply) {
+#ifdef SUSPEND_USES_PMU
+ pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0);
+ spin_unlock_irqrestore(&pmu_lock, flags);
+ while(!req.complete)
+ pmu_poll();
+#else /* SUSPEND_USES_PMU */
+ if (gpio_irq >= 0)
+ disable_irq(gpio_irq);
+ out_8(&via[IER], CB1_INT | IER_CLR);
+ spin_unlock_irqrestore(&pmu_lock, flags);
+#endif /* SUSPEND_USES_PMU */
+ break;
+ }
+ } while (1);
+}
+
+void __openfirmware
+pmu_resume(void)


+{
+ unsigned long flags;
+

+ if (!via || (pmu_suspended < 1))
+ return;
+
+ spin_lock_irqsave(&pmu_lock, flags);
+ pmu_suspended--;
+ if (pmu_suspended > 0) {
+ spin_unlock_irqrestore(&pmu_lock, flags);
+ return;
+ }
+ adb_int_pending = 1;
+#ifdef SUSPEND_USES_PMU
+ pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0xfc);
+ spin_unlock_irqrestore(&pmu_lock, flags);
+ while(!req.complete)
+ pmu_poll();
+#else /* SUSPEND_USES_PMU */
+ if (gpio_irq >= 0)
+ enable_irq(gpio_irq);
+ out_8(&via[IER], CB1_INT | IER_SET);
+ spin_unlock_irqrestore(&pmu_lock, flags);
+ pmu_poll();
+#endif /* SUSPEND_USES_PMU */
X }
X
X static void __openfirmware
X via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs)
X {
+ unsigned long flags;
X int intr;
X int nloop = 0;
- unsigned long flags;
X
- /* Currently, we use brute-force cli() for syncing with GPIO
- * interrupt. I'll make this smarter later, along with some
- * spinlocks for SMP */
- save_flags(flags);cli();
+ /* This is a bit brutal, we can probably do better */
+ spin_lock_irqsave(&pmu_lock, flags);
X ++disable_poll;
+
X while ((intr = in_8(&via[IFR])) != 0) {
X if (++nloop > 1000) {
X printk(KERN_DEBUG "PMU: stuck in intr loop, "
@@ -681,25 +806,38 @@
X out_8(&via[IFR], intr);
X }
X }
- if (gpio_reg && (in_8(gpio_reg + 0x9) & 0x02) == 0)
+ /* This is not necessary except if synchronous ADB requests are done
+ * with interrupts off, which should not happen. Since I'm not sure
+ * this "wiring" will remain, I'm commenting it out for now. Please do
+ * not remove. -- BenH.
+ */
+#if 0
+ if (gpio_reg && !pmu_suspended && (in_8(gpio_reg + 0x9) & 0x02) == 0)
X adb_int_pending = 1;
+#endif
X
X if (pmu_state == idle) {
X if (adb_int_pending) {
X pmu_state = intack;
+ /* Sounds safer to make sure ACK is high before writing.
+ * This helped kill a problem with ADB and some iBooks
+ */
+ wait_for_ack();
X send_byte(PMU_INT_ACK);
X adb_int_pending = 0;
X } else if (current_req) {
X pmu_start();
X }
X }
+
X --disable_poll;
- restore_flags(flags);
+ spin_unlock_irqrestore(&pmu_lock, flags);
X }
X
X static void __openfirmware
X gpio1_interrupt(int irq, void *arg, struct pt_regs *regs)
X {
+ adb_int_pending = 1;
X via_pmu_interrupt(0, 0, 0);


X }
X
@@ -707,7 +845,7 @@

X pmu_sr_intr(struct pt_regs *regs)
X {
X struct adb_request *req;
- int bite, timeout;
+ int bite;
X
X if (via[B] & TREQ) {
X printk(KERN_ERR "PMU: spurious SR intr (%x)\n", via[B]);
@@ -720,26 +858,16 @@
X if (via[B] & TACK) {
X while ((in_8(&via[B]) & TACK) != 0)
X ;
-#if 0
- printk(KERN_ERR "PMU: sr_intr but ack still high! (%x)\n",
- via[B]);
-#endif
X }
X
X /* reset TREQ and wait for TACK to go high */
X out_8(&via[B], in_8(&via[B]) | TREQ);
- timeout = 3200;
- while ((in_8(&via[B]) & TACK) == 0) {
- if (--timeout < 0) {
- printk(KERN_ERR "PMU not responding (!ack)\n");
- return;
- }
- udelay(10);
- }
+ wait_for_ack();
X
X /* if reading grab the byte, and reset the interrupt */
X if (pmu_state == reading || pmu_state == reading_intr)
X bite = in_8(&via[SR]);
+
X out_8(&via[IFR], SR_INT);
X
X switch (pmu_state) {
@@ -761,8 +889,11 @@
X current_req = req->next;
X if (req->reply_expected)
X req_awaiting_reply = req;
- else
+ else {
+ spin_unlock(&pmu_lock);
X pmu_done(req);
+ spin_lock(&pmu_lock);
+ }
X } else {
X pmu_state = reading;
X data_index = 0;
@@ -795,12 +926,16 @@
X }
X
X if (pmu_state == reading_intr) {
+ spin_unlock(&pmu_lock);
X pmu_handle_data(interrupt_data, data_index, regs);
+ spin_lock(&pmu_lock);
X } else {
X req = current_req;
X current_req = req->next;
X req->reply_len += data_index;
+ spin_unlock(&pmu_lock);
X pmu_done(req);
+ spin_lock(&pmu_lock);
X }
X pmu_state = idle;
X
@@ -826,6 +961,7 @@
X {
X asleep = 0;
X if (len < 1) {
+// xmon_printk("empty ADB\n");
X adb_int_pending = 0;
X return;
X }
@@ -854,6 +990,7 @@
X }
X }
X #endif /* CONFIG_XMON */
+#ifdef CONFIG_ADB
X /*
X * XXX On the [23]400 the PMU gives us an up
X * event for keycodes 0x74 or 0x75 when the PC
@@ -864,10 +1001,13 @@
X && data[1] == 0x2c && data[3] == 0xff
X && (data[2] & ~1) == 0xf4))
X adb_input(data+1, len-1, regs, 1);
+#endif /* CONFIG_ADB */
X }
X } else if (data[0] == 0x08 && len == 3) {
X /* sound/brightness buttons pressed */
- pmu_set_brightness(data[1] >> 3);
+#ifdef CONFIG_PMAC_BACKLIGHT
+ set_backlight_level(data[1] >> 4);
+#endif
X set_volume(data[2]);
X } else {
X #ifdef CONFIG_PMAC_PBOOK
@@ -876,53 +1016,23 @@
X }
X }
X
-int backlight_level = -1;
-int backlight_enabled = 0;
-
-#define LEVEL_TO_BRIGHT(lev) ((lev) < 1? 0x7f: 0x4a - ((lev) << 1))
-
-void __openfirmware
-pmu_enable_backlight(int on)
+#ifdef CONFIG_PMAC_BACKLIGHT
+static int backlight_to_bright[] = {
+ 0x7f, 0x46, 0x42, 0x3e, 0x3a, 0x36, 0x32, 0x2e,
+ 0x2a, 0x26, 0x22, 0x1e, 0x1a, 0x16, 0x12, 0x0e
+};
+
+static int __openfirmware
+pmu_set_backlight_enable(int on, int level, void* data)
X {
X struct adb_request req;
+
+ if (vias == NULL)
+ return -ENODEV;
X
- if ((vias == NULL) || !pmu_has_backlight)
- return;
-
- /* first call: get current backlight value */
- if (on && backlight_level < 0) {
- switch (pmu_kind) {
- case PMU_OHARE_BASED:
- pmu_request(&req, NULL, 2, 0xd9, 0);
- while (!req.complete)
- pmu_poll();
- backlight_level = req.reply[1] >> 3;
- break;
- case PMU_HEATHROW_BASED:
- /* We cannot use nvram_read_byte here (not yet initialized) */
- pmu_request(&req, NULL, 3, PMU_READ_NVRAM, 0x14, 0xe);
- while (!req.complete)
- pmu_poll();
- backlight_level = req.reply[1];
- printk(KERN_DEBUG "pmu: nvram returned bright: %d\n", backlight_level);
- break;
- case PMU_PADDINGTON_BASED:
- case PMU_KEYLARGO_BASED:
- /* the G3 PB 1999 has a backlight node
- and chrp-structured nvram */
- /* XXX should read macos's "blkt" property in nvram
- for this node. For now this ensures that the
- backlight doesn't go off as soon as linux boots. */
- backlight_level = 20;
- break;
- default:
- backlight_enabled = 0;


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 053'
echo 'File patch-2.4.0-test9 is continued in part 054'
echo "054" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part054

#!/bin/sh -x
# this is part 054 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 054; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

- return;
- }
- }
X if (on) {
X pmu_request(&req, NULL, 2, PMU_BACKLIGHT_BRIGHT,
- LEVEL_TO_BRIGHT(backlight_level));
+ backlight_to_bright[level]);
X while (!req.complete)
X pmu_poll();
X }
@@ -930,35 +1040,28 @@
X PMU_POW_BACKLIGHT | (on ? PMU_POW_ON : PMU_POW_OFF));
X while (!req.complete)
X pmu_poll();
- backlight_enabled = on;


+
+ return 0;
X }
X

-void __openfirmware
-pmu_set_brightness(int level)
+static int __openfirmware
+pmu_set_backlight_level(int level, void* data)
X {
- int bright;


+ if (vias == NULL)
+ return -ENODEV;
X
- if ((vias == NULL) || !pmu_has_backlight)
- return ;

+ if (!bright_req_1.complete)
+ return -EAGAIN;
+ pmu_request(&bright_req_1, NULL, 2, PMU_BACKLIGHT_BRIGHT,
+ backlight_to_bright[level]);
+ if (!bright_req_2.complete)
+ return -EAGAIN;
+ pmu_request(&bright_req_2, NULL, 2, PMU_POWER_CTRL, PMU_POW_BACKLIGHT
+ | (level > BACKLIGHT_OFF ? PMU_POW_ON : PMU_POW_OFF));
X
- backlight_level = level;
- bright = LEVEL_TO_BRIGHT(level);
- if (!backlight_enabled)
- return;
- if (bright_req_1.complete)
- pmu_request(&bright_req_1, NULL, 2, PMU_BACKLIGHT_BRIGHT,
- bright);
- if (bright_req_2.complete)
- pmu_request(&bright_req_2, NULL, 2, PMU_POWER_CTRL,
- PMU_POW_BACKLIGHT | (bright < 0x7f ? PMU_POW_ON : PMU_POW_OFF));
-
- /* XXX nvram address is hard-coded and looks ok on wallstreet, please
- test on your machine. Note that newer MacOS system software may break
- the nvram layout. */
- if ((pmu_kind == PMU_HEATHROW_BASED) && bright_req_3.complete)
- pmu_request(&bright_req_3, NULL, 4, PMU_WRITE_NVRAM,
- 0x14, 0xe, level);
+ return 0;
X }
+#endif /* CONFIG_PMAC_BACKLIGHT */
X
X void __openfirmware
X pmu_enable_irled(int on)
@@ -967,6 +1070,8 @@


X
X if (vias == NULL)

X return ;


+ if (pmu_kind == PMU_KEYLARGO_BASED)

+ return ;
X
X pmu_request(&req, NULL, 2, PMU_POWER_CTRL, PMU_POW_IRLED |
X (on ? PMU_POW_ON : PMU_POW_OFF));
@@ -1201,17 +1306,9 @@
X {
X int ret;
X unsigned long save_l2cr;
- unsigned long save_fcr;
X unsigned long wait;
X unsigned short pmcr1;
- struct adb_request sleep_req;
- struct device_node *macio;
- unsigned long macio_base = 0;
-
- macio = find_devices("mac-io");
- if (macio != 0 && macio->n_addrs > 0)
- macio_base = (unsigned long)
- ioremap(macio->addrs[0].address, 0x40);
+ struct adb_request req;
X
X /* Notify device drivers */
X ret = broadcast_sleep(PBOOK_SLEEP_REQUEST, PBOOK_SLEEP_REJECT);
@@ -1245,14 +1342,13 @@
X /* Make sure the decrementer won't interrupt us */
X asm volatile("mtdec %0" : : "r" (0x7fffffff));
X
+ feature_prepare_for_sleep();
+
X /* For 750, save backside cache setting and disable it */
X save_l2cr = _get_L2CR(); /* (returns 0 if not 750) */
X if (save_l2cr)
X _set_L2CR(0);
X
- if (macio_base != 0)
- save_fcr = in_le32(FEATURE_CTRL(macio_base));
-
X if (current->thread.regs && (current->thread.regs->msr & MSR_FP) != 0)
X giveup_fpu(current);
X
@@ -1263,17 +1359,14 @@
X grackle_pcibios_write_config_word(0, 0, 0x70, pmcr1);
X
X /* Ask the PMU to put us to sleep */
- pmu_request(&sleep_req, NULL, 5, PMU_SLEEP, 'M', 'A', 'T', 'T');
- while (!sleep_req.complete)
+ pmu_request(&req, NULL, 5, PMU_SLEEP, 'M', 'A', 'T', 'T');
+ while (!req.complete)
X pmu_poll();
X
X cli();
X while (pmu_state != idle)
X pmu_poll();
X
- /* clear IOBUS enable */
- out_le32(FEATURE_CTRL(macio_base), save_fcr & ~HRW_IOBUS_ENABLE);
-
X /* Call low-level ASM sleep handler */
X low_sleep_handler();
X
@@ -1282,15 +1375,14 @@
X pmcr1 &= ~(GRACKLE_PM|GRACKLE_DOZE|GRACKLE_SLEEP|GRACKLE_NAP);
X grackle_pcibios_write_config_word(0, 0, 0x70, pmcr1);
X
- /* reenable IOBUS */
- out_le32(FEATURE_CTRL(macio_base), save_fcr | HRW_IOBUS_ENABLE);
-
X /* Make sure the PMU is idle */
X while (pmu_state != idle)
X pmu_poll();
X
X sti();
X
+ feature_wake_up();
+
X /* The PGD is only a placeholder until Dan finds a way to make
X * this work properly on the 8xx processors. It is only used on
X * 8xx processors, it is ignored here.
@@ -1304,6 +1396,116 @@
X /* reenable interrupts */
X sleep_restore_intrs();
X
+ /* Tell PMU we are ready */


+ pmu_request(&req, NULL, 2, PMU_SYSTEM_READY, 2);
+ while (!req.complete)
+ pmu_poll();
+

+ /* Notify drivers */
+ mdelay(10);
+ broadcast_wake();


+
+ return 0;
+}
+

+/* Not finished yet */
+int __openfirmware powerbook_sleep_Core99(void)
+{
+ int ret;
+ unsigned long save_l2cr;
+ unsigned long wait;


+ struct adb_request req;
+

+ /* Notify device drivers */
+ ret = broadcast_sleep(PBOOK_SLEEP_REQUEST, PBOOK_SLEEP_REJECT);
+ if (ret != PBOOK_SLEEP_OK) {
+ printk("pmu: sleep rejected\n");


+ return -EBUSY;
+ }
+

+ /* Sync the disks. */
+ /* XXX It would be nice to have some way to ensure that
+ * nobody is dirtying any new buffers while we wait.
+ * BenH: Moved to _after_ sleep request and changed video
+ * drivers to vmalloc() during sleep request. This way, all
+ * vmalloc's are done before actual sleep of block drivers */
+ fsync_dev(0);
+
+ /* Sleep can fail now. May not be very robust but useful for debugging */
+ ret = broadcast_sleep(PBOOK_SLEEP_NOW, PBOOK_WAKE);
+ if (ret != PBOOK_SLEEP_OK) {
+ printk("pmu: sleep failed\n");


+ return -EBUSY;
+ }
+

+ /* Give the disks a little time to actually finish writing */
+ for (wait = jiffies + (HZ/4); time_before(jiffies, wait); )
+ mb();
+
+ /* Tell PMU what events will wake us up */
+ pmu_request(&req, NULL, 4, PMU_POWER_EVENTS, PMU_PWR_CLR_WAKEUP_EVENTS,
+ 0xff, 0xff);


+ while (!req.complete)
+ pmu_poll();

+ pmu_request(&req, NULL, 4, PMU_POWER_EVENTS, PMU_PWR_SET_WAKEUP_EVENTS,
+ 0, PMU_PWR_WAKEUP_KEY | PMU_PWR_WAKEUP_LID_OPEN);


+ while (!req.complete)
+ pmu_poll();
+

+ /* Disable all interrupts except pmu */
+ sleep_save_intrs(vias->intrs[0].line);
+
+ /* Make sure the decrementer won't interrupt us */
+ asm volatile("mtdec %0" : : "r" (0x7fffffff));
+
+ /* Save the state of PCI config space for some slots */
+ pbook_pci_save();
+
+ feature_prepare_for_sleep();
+
+ /* For 750, save backside cache setting and disable it */
+ save_l2cr = _get_L2CR(); /* (returns 0 if not 750) */
+ if (save_l2cr)
+ _set_L2CR(0);
+
+ if (current->thread.regs && (current->thread.regs->msr & MSR_FP) != 0)
+ giveup_fpu(current);
+
+ /* Ask the PMU to put us to sleep */
+ pmu_request(&req, NULL, 5, PMU_SLEEP, 'M', 'A', 'T', 'T');
+ while (!req.complete)
+ mb();
+
+ cli();


+ while (pmu_state != idle)

+ pmu_poll();
+
+ /* Call low-level ASM sleep handler */
+ low_sleep_handler();
+
+ /* Make sure the PMU is idle */


+ while (pmu_state != idle)

+ pmu_poll();
+
+ sti();
+
+ feature_wake_up();
+ pbook_pci_restore();
+
+ set_context(current->mm->context, current->mm->pgd);
+
+ /* Restore L2 cache */
+ if (save_l2cr)
+ _set_L2CR(save_l2cr | 0x200000); /* set invalidate bit */
+
+ /* reenable interrupts */
+ sleep_restore_intrs();
+
+ /* Tell PMU we are ready */


+ pmu_request(&req, NULL, 2, PMU_SYSTEM_READY, 2);
+ while (!req.complete)
+ pmu_poll();
+

X /* Notify drivers */
X mdelay(10);
X broadcast_wake();
@@ -1557,7 +1759,6 @@
X u_int cmd, u_long arg)
X {
X int error;
- __u32 value;
X
X switch (cmd) {
X case PMU_IOC_SLEEP:
@@ -1569,21 +1770,33 @@
X case PMU_PADDINGTON_BASED:
X error = powerbook_sleep_G3();
X break;
+#if 0 /* Not ready yet */
+ case PMU_KEYLARGO_BASED:
+ error = powerbook_sleep_Core99();
+ break;
+#endif
X default:
X error = -ENOSYS;
X }
X return error;
+#ifdef CONFIG_PMAC_BACKLIGHT
+ /* Backlight should have its own device or go via
+ * the fbdev
+ */
X case PMU_IOC_GET_BACKLIGHT:
- if (!pmu_has_backlight)
- return -ENOSYS;
- return put_user(backlight_level, (__u32 *)arg);
+ error = get_backlight_level();
+ if (error < 0)
+ return error;
+ return put_user(error, (__u32 *)arg);
X case PMU_IOC_SET_BACKLIGHT:
- if (!pmu_has_backlight)
- return -ENOSYS;
+ {
+ __u32 value;
X error = get_user(value, (__u32 *)arg);
X if (!error)
- pmu_set_brightness(value);
+ error = set_backlight_level(value);
X return error;


+ }
+#endif /* CONFIG_PMAC_BACKLIGHT */

X case PMU_IOC_GET_MODEL:
X return put_user(pmu_kind, (__u32 *)arg);
X case PMU_IOC_HAS_ADB:
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/md/Config.in linux/drivers/md/Config.in
--- v2.4.0-test8/linux/drivers/md/Config.in Wed Dec 31 16:00:00 1969
+++ linux/drivers/md/Config.in Mon Oct 2 12:00:07 2000
@@ -0,0 +1,22 @@
+#
+# Block device driver configuration
+#
+mainmenu_option next_comment
+comment 'Multi-device support (RAID and LVM)'
+
+bool 'Multiple devices driver support (RAID and LVM)' CONFIG_MD
+
+dep_tristate ' RAID support' CONFIG_BLK_DEV_MD $CONFIG_MD
+dep_tristate ' Linear (append) mode' CONFIG_MD_LINEAR $CONFIG_BLK_DEV_MD
+dep_tristate ' RAID-0 (striping) mode' CONFIG_MD_RAID0 $CONFIG_BLK_DEV_MD
+dep_tristate ' RAID-1 (mirroring) mode' CONFIG_MD_RAID1 $CONFIG_BLK_DEV_MD
+dep_tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5 $CONFIG_BLK_DEV_MD
+if [ "$CONFIG_MD_LINEAR" = "y" -o "$CONFIG_MD_RAID0" = "y" -o "$CONFIG_MD_RAID1" = "y" -o "$CONFIG_MD_RAID5" = "y" ]; then
+ bool ' Boot support' CONFIG_MD_BOOT
+ bool ' Auto Detect support' CONFIG_AUTODETECT_RAID
+fi
+
+dep_tristate ' Logical volume manager (LVM) support' CONFIG_BLK_DEV_LVM $CONFIG_MD
+dep_mbool ' LVM information in proc filesystem' CONFIG_LVM_PROC_FS $CONFIG_BLK_DEV_LVM
+
+endmenu
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/md/Makefile linux/drivers/md/Makefile
--- v2.4.0-test8/linux/drivers/md/Makefile Wed Dec 31 16:00:00 1969
+++ linux/drivers/md/Makefile Tue Sep 19 11:05:19 2000
@@ -0,0 +1,35 @@
+#
+# Makefile for the kernel software RAID and LVM drivers.
+#
+
+O_TARGET := mddev.o
+SUB_DIRS :=
+ALL_SUB_DIRS :=
+MOD_SUB_DIRS :=
+
+export-objs := md.o xor.o
+list-multi := lvm-mod.o
+lvm-mod-objs := lvm.o lvm-snap.o
+


+obj-y :=
+obj-m :=
+obj-n :=
+obj- :=

+
+obj-$(CONFIG_BLK_DEV_MD) += md.o
+obj-$(CONFIG_MD_LINEAR) += linear.o
+obj-$(CONFIG_MD_RAID0) += raid0.o
+obj-$(CONFIG_MD_RAID1) += raid1.o
+obj-$(CONFIG_MD_RAID5) += raid5.o xor.o
+obj-$(CONFIG_BLK_DEV_LVM) += lvm-mod.o


+
+# Translate to Rules.make lists.

+O_OBJS := $(filter-out $(export-objs), $(obj-y))
+OX_OBJS := $(filter $(export-objs), $(obj-y))


+M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m)))
+MX_OBJS := $(sort $(filter $(export-objs), $(obj-m)))
+

+include $(TOPDIR)/Rules.make
+
+lvm-mod.o: $(lvm-mod-objs)
+ $(LD) -r -o $@ $(lvm-mod-objs)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/md/linear.c linux/drivers/md/linear.c
--- v2.4.0-test8/linux/drivers/md/linear.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/md/linear.c Thu Aug 10 12:35:50 2000
@@ -0,0 +1,213 @@
+/*
+ linear.c : Multiple Devices driver for Linux
+ Copyright (C) 1994-96 Marc ZYNGIER
+ <zyn...@ufr-info-p7.ibp.fr> or
+ <m...@gloups.fdn.fr>
+
+ Linear mode management functions.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ You should have received a copy of the GNU General Public License
+ (for example /usr/src/linux/COPYING); if not, write to the Free
+ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/module.h>
+
+#include <linux/raid/md.h>
+#include <linux/malloc.h>
+
+#include <linux/raid/linear.h>
+
+#define MAJOR_NR MD_MAJOR
+#define MD_DRIVER
+#define MD_PERSONALITY
+
+static int linear_run (mddev_t *mddev)
+{
+ linear_conf_t *conf;
+ struct linear_hash *table;
+ mdk_rdev_t *rdev;
+ int size, i, j, nb_zone;
+ unsigned int curr_offset;
+
+ MOD_INC_USE_COUNT;
+
+ conf = kmalloc (sizeof (*conf), GFP_KERNEL);
+ if (!conf)
+ goto out;
+ mddev->private = conf;
+
+ if (md_check_ordering(mddev)) {
+ printk("linear: disks are not ordered, aborting!\n");
+ goto out;
+ }
+ /*
+ * Find the smallest device.
+ */
+
+ conf->smallest = NULL;
+ curr_offset = 0;
+ ITERATE_RDEV_ORDERED(mddev,rdev,j) {
+ dev_info_t *disk = conf->disks + j;
+
+ disk->dev = rdev->dev;
+ disk->size = rdev->size;
+ disk->offset = curr_offset;
+
+ curr_offset += disk->size;
+
+ if (!conf->smallest || (disk->size < conf->smallest->size))
+ conf->smallest = disk;
+ }
+
+ nb_zone = conf->nr_zones =
+ md_size[mdidx(mddev)] / conf->smallest->size +
+ ((md_size[mdidx(mddev)] % conf->smallest->size) ? 1 : 0);
+
+ conf->hash_table = kmalloc (sizeof (struct linear_hash) * nb_zone,
+ GFP_KERNEL);
+ if (!conf->hash_table)
+ goto out;
+
+ /*
+ * Here we generate the linear hash table
+ */
+ table = conf->hash_table;
+ i = 0;
+ size = 0;
+ for (j = 0; j < mddev->nb_dev; j++) {
+ dev_info_t *disk = conf->disks + j;
+
+ if (size < 0) {
+ table->dev1 = disk;
+ table++;
+ }
+ size += disk->size;
+
+ while (size) {
+ table->dev0 = disk;
+ size -= conf->smallest->size;
+ if (size < 0)
+ break;
+ table->dev1 = NULL;
+ table++;
+ }
+ }
+ table->dev1 = NULL;


+
+ return 0;
+

+out:
+ if (conf)
+ kfree(conf);
+ MOD_DEC_USE_COUNT;


+ return 1;
+}
+

+static int linear_stop (mddev_t *mddev)
+{
+ linear_conf_t *conf = mddev_to_conf(mddev);
+
+ kfree(conf->hash_table);
+ kfree(conf);
+
+ MOD_DEC_USE_COUNT;


+
+ return 0;
+}
+

+static int linear_make_request (mddev_t *mddev,
+ int rw, struct buffer_head * bh)
+{
+ linear_conf_t *conf = mddev_to_conf(mddev);
+ struct linear_hash *hash;
+ dev_info_t *tmp_dev;
+ long block;
+
+ block = bh->b_rsector >> 1;
+ hash = conf->hash_table + (block / conf->smallest->size);
+
+ if (block >= (hash->dev0->size + hash->dev0->offset)) {
+ if (!hash->dev1) {
+ printk ("linear_make_request : hash->dev1==NULL for block %ld\n",
+ block);
+ return -1;
+ }
+ tmp_dev = hash->dev1;
+ } else
+ tmp_dev = hash->dev0;
+
+ if (block >= (tmp_dev->size + tmp_dev->offset)
+ || block < tmp_dev->offset) {
+ printk ("linear_make_request: Block %ld out of bounds on dev %s size %ld offset %ld\n", block, kdevname(tmp_dev->dev), tmp_dev->size, tmp_dev->offset);
+ return -1;
+ }
+ bh->b_rdev = tmp_dev->dev;
+ bh->b_rsector = bh->b_rsector - (tmp_dev->offset << 1);


+
+ return 1;
+}
+

+static int linear_status (char *page, mddev_t *mddev)
+{
+ int sz = 0;
+
+#undef MD_DEBUG
+#ifdef MD_DEBUG
+ int j;
+ linear_conf_t *conf = mddev_to_conf(mddev);
+
+ sz += sprintf(page+sz, " ");
+ for (j = 0; j < conf->nr_zones; j++)
+ {
+ sz += sprintf(page+sz, "[%s",
+ partition_name(conf->hash_table[j].dev0->dev));
+
+ if (conf->hash_table[j].dev1)
+ sz += sprintf(page+sz, "/%s] ",
+ partition_name(conf->hash_table[j].dev1->dev));
+ else
+ sz += sprintf(page+sz, "] ");
+ }
+ sz += sprintf(page+sz, "\n");
+#endif
+ sz += sprintf(page+sz, " %dk rounding", mddev->param.chunk_size/1024);
+ return sz;
+}
+
+
+static mdk_personality_t linear_personality=
+{
+ name: "linear",
+ make_request: linear_make_request,
+ run: linear_run,
+ stop: linear_stop,
+ status: linear_status,
+};
+
+#ifndef MODULE
+
+void md__init linear_init (void)
+{
+ register_md_personality (LINEAR, &linear_personality);
+}
+
+#else
+
+int init_module (void)
+{
+ return (register_md_personality (LINEAR, &linear_personality));
+}
+
+void cleanup_module (void)
+{
+ unregister_md_personality (LINEAR);
+}
+
+#endif
+
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/md/lvm-snap.c linux/drivers/md/lvm-snap.c
--- v2.4.0-test8/linux/drivers/md/lvm-snap.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/md/lvm-snap.c Sun Sep 17 09:51:57 2000
@@ -0,0 +1,436 @@
+/*
+ * kernel/lvm-snap.c
+ *
+ * Copyright (C) 2000 Andrea Arcangeli <and...@suse.de> SuSE
+ *
+ * LVM snapshot driver is free software; you can redistribute it and/or modify


+ * it under the terms of the GNU General Public License as published by

+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * LVM driver is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of


+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.

+ *
+ */
+

+#include <linux/kernel.h>
+#include <linux/vmalloc.h>
+#include <linux/blkdev.h>
+#include <linux/smp_lock.h>
+#include <linux/types.h>
+#include <linux/iobuf.h>
+#include <linux/lvm.h>
+
+
+static char *lvm_snap_version __attribute__ ((unused)) = "LVM 0.8final (15/02/2000)\n";
+
+extern const char *const lvm_name;
+extern int lvm_blocksizes[];
+
+void lvm_snapshot_release(lv_t *);
+
+#define hashfn(dev,block,mask,chunk_size) \
+ ((HASHDEV(dev)^((block)/(chunk_size))) & (mask))
+
+static inline lv_block_exception_t *
+lvm_find_exception_table(kdev_t org_dev, unsigned long org_start, lv_t * lv)
+{
+ struct list_head * hash_table = lv->lv_snapshot_hash_table, * next;
+ unsigned long mask = lv->lv_snapshot_hash_mask;
+ int chunk_size = lv->lv_chunk_size;
+ lv_block_exception_t * ret;
+ int i = 0;
+
+ hash_table = &hash_table[hashfn(org_dev, org_start, mask, chunk_size)];
+ ret = NULL;
+ for (next = hash_table->next; next != hash_table; next = next->next)
+ {
+ lv_block_exception_t * exception;
+
+ exception = list_entry(next, lv_block_exception_t, hash);
+ if (exception->rsector_org == org_start &&
+ exception->rdev_org == org_dev)
+ {
+ if (i)
+ {
+ /* fun, isn't it? :) */
+ list_del(next);
+ list_add(next, hash_table);
+ }
+ ret = exception;
+ break;
+ }
+ i++;


+ }
+ return ret;
+}
+

+static inline void lvm_hash_link(lv_block_exception_t * exception,
+ kdev_t org_dev, unsigned long org_start,
+ lv_t * lv)
+{
+ struct list_head * hash_table = lv->lv_snapshot_hash_table;
+ unsigned long mask = lv->lv_snapshot_hash_mask;
+ int chunk_size = lv->lv_chunk_size;
+
+ hash_table = &hash_table[hashfn(org_dev, org_start, mask, chunk_size)];
+ list_add(&exception->hash, hash_table);
+}
+
+int lvm_snapshot_remap_block(kdev_t * org_dev, unsigned long * org_sector,
+ unsigned long pe_start, lv_t * lv)
+{
+ int ret;
+ unsigned long pe_off, pe_adjustment, __org_start;
+ kdev_t __org_dev;
+ int chunk_size = lv->lv_chunk_size;
+ lv_block_exception_t * exception;
+
+ pe_off = pe_start % chunk_size;
+ pe_adjustment = (*org_sector-pe_off) % chunk_size;
+ __org_start = *org_sector - pe_adjustment;
+ __org_dev = *org_dev;


+
+ ret = 0;

+ exception = lvm_find_exception_table(__org_dev, __org_start, lv);
+ if (exception)
+ {
+ *org_dev = exception->rdev_new;
+ *org_sector = exception->rsector_new + pe_adjustment;
+ ret = 1;
+ }
+ return ret;
+}
+
+static void lvm_drop_snapshot(lv_t * lv_snap, const char * reason)
+{
+ kdev_t last_dev;
+ int i;
+
+ /* no exception storage space available for this snapshot
+ or error on this snapshot --> release it */
+ invalidate_buffers(lv_snap->lv_dev);
+
+ last_dev = 0;
+ for (i = 0; i < lv_snap->lv_remap_ptr; i++) {
+ if ( lv_snap->lv_block_exception[i].rdev_new != last_dev) {
+ last_dev = lv_snap->lv_block_exception[i].rdev_new;
+ invalidate_buffers(last_dev);
+ }
+ }
+
+ lvm_snapshot_release(lv_snap);
+
+ printk(KERN_INFO
+ "%s -- giving up to snapshot %s on %s due %s\n",
+ lvm_name, lv_snap->lv_snapshot_org->lv_name, lv_snap->lv_name,
+ reason);
+}
+
+static inline void lvm_snapshot_prepare_blocks(unsigned long * blocks,
+ unsigned long start,
+ int nr_sectors,
+ int blocksize)
+{
+ int i, sectors_per_block, nr_blocks;
+
+ sectors_per_block = blocksize >> 9;
+ nr_blocks = nr_sectors / sectors_per_block;
+ start /= sectors_per_block;
+
+ for (i = 0; i < nr_blocks; i++)
+ blocks[i] = start++;
+}
+
+static inline int get_blksize(kdev_t dev)
+{
+ int correct_size = BLOCK_SIZE, i, major;
+
+ major = MAJOR(dev);
+ if (blksize_size[major])
+ {
+ i = blksize_size[major][MINOR(dev)];
+ if (i)
+ correct_size = i;
+ }
+ return correct_size;
+}
+
+#ifdef DEBUG_SNAPSHOT
+static inline void invalidate_snap_cache(unsigned long start, unsigned long nr,
+ kdev_t dev)
+{


+ struct buffer_head * bh;

+ int sectors_per_block, i, blksize, minor;
+
+ minor = MINOR(dev);
+ blksize = lvm_blocksizes[minor];
+ sectors_per_block = blksize >> 9;
+ nr /= sectors_per_block;
+ start /= sectors_per_block;
+
+ for (i = 0; i < nr; i++)
+ {
+ bh = get_hash_table(dev, start++, blksize);
+ if (bh)
+ bforget(bh);
+ }
+}
+#endif
+
+/*
+ * copy on write handler for one snapshot logical volume
+ *
+ * read the original blocks and store it/them on the new one(s).
+ * if there is no exception storage space free any longer --> release snapshot.
+ *
+ * this routine gets called for each _first_ write to a physical chunk.
+ */
+int lvm_snapshot_COW(kdev_t org_phys_dev,
+ unsigned long org_phys_sector,
+ unsigned long org_pe_start,
+ unsigned long org_virt_sector,
+ lv_t * lv_snap)
+{
+ const char * reason;
+ unsigned long org_start, snap_start, virt_start, pe_off;
+ int idx = lv_snap->lv_remap_ptr, chunk_size = lv_snap->lv_chunk_size;
+ kdev_t snap_phys_dev;
+ struct kiobuf * iobuf;
+ unsigned long blocks[KIO_MAX_SECTORS];
+ int blksize_snap, blksize_org, min_blksize, max_blksize;
+ int max_sectors, nr_sectors;
+
+ /* check if we are out of snapshot space */
+ if (idx >= lv_snap->lv_remap_end)
+ goto fail_out_of_space;
+
+ /* calculate physical boundaries of source chunk */
+ pe_off = org_pe_start % chunk_size;
+ org_start = org_phys_sector - ((org_phys_sector-pe_off) % chunk_size);
+ virt_start = org_virt_sector - (org_phys_sector - org_start);
+
+ /* calculate physical boundaries of destination chunk */
+ snap_phys_dev = lv_snap->lv_block_exception[idx].rdev_new;
+ snap_start = lv_snap->lv_block_exception[idx].rsector_new;
+
+#ifdef DEBUG_SNAPSHOT
+ printk(KERN_INFO
+ "%s -- COW: "
+ "org %02d:%02d faulting %lu start %lu, "
+ "snap %02d:%02d start %lu, "
+ "size %d, pe_start %lu pe_off %lu, virt_sec %lu\n",
+ lvm_name,
+ MAJOR(org_phys_dev), MINOR(org_phys_dev), org_phys_sector,
+ org_start,
+ MAJOR(snap_phys_dev), MINOR(snap_phys_dev), snap_start,
+ chunk_size,
+ org_pe_start, pe_off,
+ org_virt_sector);
+#endif
+
+ iobuf = lv_snap->lv_iobuf;
+
+ blksize_org = get_blksize(org_phys_dev);
+ blksize_snap = get_blksize(snap_phys_dev);
+ max_blksize = max(blksize_org, blksize_snap);
+ min_blksize = min(blksize_org, blksize_snap);
+ max_sectors = KIO_MAX_SECTORS * (min_blksize>>9);
+
+ if (chunk_size % (max_blksize>>9))
+ goto fail_blksize;
+
+ while (chunk_size)
+ {
+ nr_sectors = min(chunk_size, max_sectors);
+ chunk_size -= nr_sectors;
+
+ iobuf->length = nr_sectors << 9;
+
+ lvm_snapshot_prepare_blocks(blocks, org_start,
+ nr_sectors, blksize_org);
+ if (brw_kiovec(READ, 1, &iobuf, org_phys_dev,
+ blocks, blksize_org) != (nr_sectors<<9))
+ goto fail_raw_read;
+
+ lvm_snapshot_prepare_blocks(blocks, snap_start,
+ nr_sectors, blksize_snap);
+ if (brw_kiovec(WRITE, 1, &iobuf, snap_phys_dev,
+ blocks, blksize_snap) != (nr_sectors<<9))
+ goto fail_raw_write;
+ }
+
+#ifdef DEBUG_SNAPSHOT
+ /* invalidate the logcial snapshot buffer cache */
+ invalidate_snap_cache(virt_start, lv_snap->lv_chunk_size,
+ lv_snap->lv_dev);
+#endif
+
+ /* the original chunk is now stored on the snapshot volume
+ so update the execption table */
+ lv_snap->lv_block_exception[idx].rdev_org = org_phys_dev;
+ lv_snap->lv_block_exception[idx].rsector_org = org_start;
+ lvm_hash_link(lv_snap->lv_block_exception + idx,
+ org_phys_dev, org_start, lv_snap);
+ lv_snap->lv_remap_ptr = idx + 1;
+ return 1;
+
+ /* slow path */
+ out:
+ lvm_drop_snapshot(lv_snap, reason);
+ return -1;
+
+ fail_out_of_space:
+ reason = "out of space";
+ goto out;
+ fail_raw_read:
+ reason = "read error";
+ goto out;
+ fail_raw_write:
+ reason = "write error";
+ goto out;
+ fail_blksize:
+ reason = "blocksize error";


+ goto out;
+}
+

+static int lvm_snapshot_alloc_iobuf_pages(struct kiobuf * iobuf, int sectors)
+{
+ int bytes, nr_pages, err, i;
+
+ bytes = sectors << 9;
+ nr_pages = (bytes + ~PAGE_MASK) >> PAGE_SHIFT;
+ err = expand_kiobuf(iobuf, nr_pages);
+ if (err)
+ goto out;
+
+ err = -ENOMEM;
+ iobuf->locked = 1;
+ iobuf->nr_pages = 0;
+ for (i = 0; i < nr_pages; i++)
+ {
+ struct page * page;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,27)
+ page = alloc_page(GFP_KERNEL);
+ if (!page)
+ goto out;
+#else
+ {
+ unsigned long addr = __get_free_page(GFP_USER);
+ if (!addr)
+ goto out;
+ iobuf->pagelist[i] = addr;
+ page = virt_to_page(addr);
+ }
+#endif
+
+ iobuf->maplist[i] = page;
+ /* the only point to lock the page here is to be allowed
+ to share unmap_kiobuf() in the fail-path */
+#ifndef LockPage
+#define LockPage(map) set_bit(PG_locked, &(map)->flags)
+#endif
+ LockPage(page);
+ iobuf->nr_pages++;
+ }
+ iobuf->offset = 0;
+
+ err = 0;
+ out:
+ return err;
+}
+
+static int calc_max_buckets(void)
+{
+ unsigned long mem;
+
+ mem = num_physpages << PAGE_SHIFT;
+ mem /= 100;
+ mem *= 2;
+ mem /= sizeof(struct list_head);
+
+ return mem;
+}
+
+static int lvm_snapshot_alloc_hash_table(lv_t * lv)
+{
+ int err;
+ unsigned long buckets, max_buckets, size;
+ struct list_head * hash;
+
+ buckets = lv->lv_remap_end;
+ max_buckets = calc_max_buckets();
+ buckets = min(buckets, max_buckets);
+ while (buckets & (buckets-1))
+ buckets &= (buckets-1);
+
+ size = buckets * sizeof(struct list_head);
+
+ err = -ENOMEM;
+ hash = vmalloc(size);
+ lv->lv_snapshot_hash_table = hash;
+
+ if (!hash)
+ goto out;
+
+ lv->lv_snapshot_hash_mask = buckets-1;
+ while (buckets--)
+ INIT_LIST_HEAD(hash+buckets);
+ err = 0;
+ out:
+ return err;
+}
+
+int lvm_snapshot_alloc(lv_t * lv_snap)
+{
+ int err, blocksize, max_sectors;
+
+ err = alloc_kiovec(1, &lv_snap->lv_iobuf);
+ if (err)
+ goto out;
+
+ blocksize = lvm_blocksizes[MINOR(lv_snap->lv_dev)];
+ max_sectors = KIO_MAX_SECTORS << (PAGE_SHIFT-9);
+
+ err = lvm_snapshot_alloc_iobuf_pages(lv_snap->lv_iobuf, max_sectors);
+ if (err)
+ goto out_free_kiovec;
+
+ err = lvm_snapshot_alloc_hash_table(lv_snap);
+ if (err)
+ goto out_free_kiovec;
+ out:
+ return err;
+
+ out_free_kiovec:
+ unmap_kiobuf(lv_snap->lv_iobuf);
+ free_kiovec(1, &lv_snap->lv_iobuf);


+ goto out;
+}
+

+void lvm_snapshot_release(lv_t * lv)
+{
+ if (lv->lv_block_exception)
+ {
+ vfree(lv->lv_block_exception);
+ lv->lv_block_exception = NULL;
+ }
+ if (lv->lv_snapshot_hash_table)
+ {
+ vfree(lv->lv_snapshot_hash_table);
+ lv->lv_snapshot_hash_table = NULL;
+ }
+ if (lv->lv_iobuf)
+ {
+ free_kiovec(1, &lv->lv_iobuf);
+ lv->lv_iobuf = NULL;
+ }
+}
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/md/lvm.c linux/drivers/md/lvm.c
--- v2.4.0-test8/linux/drivers/md/lvm.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/md/lvm.c Sun Sep 17 09:51:57 2000
@@ -0,0 +1,2567 @@
+/*
+ * kernel/lvm.c
+ *
+ * Copyright (C) 1997 - 2000 Heinz Mauelshagen, Germany
+ *
+ * February-November 1997
+ * April-May,July-August,November 1998
+ * January-March,May,July,September,October 1999
+ * January,February 2000
+ *
+ *
+ * LVM driver is free software; you can redistribute it and/or modify


+ * it under the terms of the GNU General Public License as published by

+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * LVM driver is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of


+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.

+ *
+ */
+

+/*
+ * Changelog
+ *
+ * 09/11/1997 - added chr ioctls VG_STATUS_GET_COUNT
+ * and VG_STATUS_GET_NAMELIST
+ * 18/01/1998 - change lvm_chr_open/close lock handling
+ * 30/04/1998 - changed LV_STATUS ioctl to LV_STATUS_BYNAME and
+ * - added LV_STATUS_BYINDEX ioctl
+ * - used lvm_status_byname_req_t and
+ * lvm_status_byindex_req_t vars
+ * 04/05/1998 - added multiple device support
+ * 08/05/1998 - added support to set/clear extendable flag in volume group
+ * 09/05/1998 - changed output of lvm_proc_get_info() because of
+ * support for free (eg. longer) logical volume names
+ * 12/05/1998 - added spin_locks (thanks to Pascal van Dam
+ * <pas...@ramoth.xs4all.nl>)
+ * 25/05/1998 - fixed handling of locked PEs in lvm_map() and lvm_chr_ioctl()
+ * 26/05/1998 - reactivated verify_area by access_ok
+ * 07/06/1998 - used vmalloc/vfree instead of kmalloc/kfree to go
+ * beyond 128/256 KB max allocation limit per call
+ * - #ifdef blocked spin_lock calls to avoid compile errors
+ * with 2.0.x
+ * 11/06/1998 - another enhancement to spinlock code in lvm_chr_open()
+ * and use of LVM_VERSION_CODE instead of my own macros
+ * (thanks to Michael Marxmeier <mi...@msede.com>)
+ * 07/07/1998 - added statistics in lvm_map()
+ * 08/07/1998 - saved statistics in lvm_do_lv_extend_reduce()
+ * 25/07/1998 - used __initfunc macro
+ * 02/08/1998 - changes for official char/block major numbers
+ * 07/08/1998 - avoided init_module() and cleanup_module() to be static
+ * 30/08/1998 - changed VG lv_open counter from sum of LV lv_open counters
+ * to sum of LVs open (no matter how often each is)
+ * 01/09/1998 - fixed lvm_gendisk.part[] index error
+ * 07/09/1998 - added copying of lv_current_pe-array
+ * in LV_STATUS_BYINDEX ioctl
+ * 17/11/1998 - added KERN_* levels to printk
+ * 13/01/1999 - fixed LV index bug in lvm_do_lv_create() which hit lvrename
+ * 07/02/1999 - fixed spinlock handling bug in case of LVM_RESET
+ * by moving spinlock code from lvm_chr_open()
+ * to lvm_chr_ioctl()
+ * - added LVM_LOCK_LVM ioctl to lvm_chr_ioctl()
+ * - allowed LVM_RESET and retrieval commands to go ahead;
+ * only other update ioctls are blocked now
+ * - fixed pv->pe to NULL for pv_status
+ * - using lv_req structure in lvm_chr_ioctl() now
+ * - fixed NULL ptr reference bug in lvm_do_lv_extend_reduce()
+ * caused by uncontiguous PV array in lvm_chr_ioctl(VG_REDUCE)
+ * 09/02/1999 - changed BLKRASET and BLKRAGET in lvm_chr_ioctl() to
+ * handle lgoical volume private read ahead sector
+ * - implemented LV read_ahead handling with lvm_blk_read()
+ * and lvm_blk_write()
+ * 10/02/1999 - implemented 2.[12].* support function lvm_hd_name()
+ * to be used in drivers/block/genhd.c by disk_name()
+ * 12/02/1999 - fixed index bug in lvm_blk_ioctl(), HDIO_GETGEO
+ * - enhanced gendisk insert/remove handling
+ * 16/02/1999 - changed to dynamic block minor number allocation to
+ * have as much as 99 volume groups with 256 logical volumes
+ * as the grand total; this allows having 1 volume group with
+ * up to 256 logical volumes in it
+ * 21/02/1999 - added LV open count information to proc filesystem
+ * - substituted redundant LVM_RESET code by calls
+ * to lvm_do_vg_remove()
+ * 22/02/1999 - used schedule_timeout() to be more responsive
+ * in case of lvm_do_vg_remove() with lots of logical volumes
+ * 19/03/1999 - fixed NULL pointer bug in module_init/lvm_init
+ * 17/05/1999 - used DECLARE_WAIT_QUEUE_HEAD macro (>2.3.0)
+ * - enhanced lvm_hd_name support
+ * 03/07/1999 - avoided use of KERNEL_VERSION macro based ifdefs and
+ * memcpy_tofs/memcpy_fromfs macro redefinitions
+ * 06/07/1999 - corrected reads/writes statistic counter copy in case
+ * of striped logical volume
+ * 28/07/1999 - implemented snapshot logical volumes
+ * - lvm_chr_ioctl
+ * - LV_STATUS_BYINDEX
+ * - LV_STATUS_BYNAME
+ * - lvm_do_lv_create
+ * - lvm_do_lv_remove
+ * - lvm_map
+ * - new lvm_snapshot_remap_block
+ * - new lvm_snapshot_remap_new_block
+ * 08/10/1999 - implemented support for multiple snapshots per
+ * original logical volume
+ * 12/10/1999 - support for 2.3.19
+ * 11/11/1999 - support for 2.3.28
+ * 21/11/1999 - changed lvm_map() interface to buffer_head based
+ * 19/12/1999 - support for 2.3.33
+ * 01/01/2000 - changed locking concept in lvm_map(),
+ * lvm_do_vg_create() and lvm_do_lv_remove()
+ * 15/01/2000 - fixed PV_FLUSH bug in lvm_chr_ioctl()
+ * 24/01/2000 - ported to 2.3.40 including Alan Cox's pointer changes etc.
+ * 29/01/2000 - used kmalloc/kfree again for all small structures
+ * 20/01/2000 - cleaned up lvm_chr_ioctl by moving code
+ * to seperated functions
+ * - avoided "/dev/" in proc filesystem output
+ * - avoided inline strings functions lvm_strlen etc.
+ * 14/02/2000 - support for 2.3.43
+ * - integrated Andrea Arcangeli's snapshot code


+ *
+ */
+
+

+static char *lvm_version = "LVM version 0.8final by Heinz Mauelshagen (15/02/2000)\n";
+static char *lvm_short_version = "version 0.8final (15/02/2000)";
+
+#define MAJOR_NR LVM_BLK_MAJOR
+#define DEVICE_OFF(device)
+
+#include <linux/config.h>
+#include <linux/version.h>
+
+#ifdef MODVERSIONS
+#undef MODULE
+#define MODULE
+#include <linux/modversions.h>
+#endif
+
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+
+#include <linux/hdreg.h>
+#include <linux/stat.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <linux/blkdev.h>
+#include <linux/genhd.h>
+#include <linux/locks.h>
+#include <linux/smp_lock.h>
+#include <asm/ioctl.h>
+#include <asm/segment.h>
+#include <asm/uaccess.h>
+
+#ifdef CONFIG_KERNELD
+#include <linux/kerneld.h>
+#endif
+
+#define LOCAL_END_REQUEST
+
+#include <linux/blk.h>
+#include <linux/blkpg.h>
+
+#include <linux/errno.h>
+#include <linux/lvm.h>
+
+#define LVM_CORRECT_READ_AHEAD(a) \
+ (((a) < LVM_MIN_READ_AHEAD || (a) > LVM_MAX_READ_AHEAD) \
+ ? LVM_MAX_READ_AHEAD : (a))
+
+#ifndef WRITEA
+# define WRITEA WRITE
+#endif
+
+/*
+ * External function prototypes
+ */
+#ifdef MODULE
+int init_module(void);
+void cleanup_module(void);
+#else
+extern int lvm_init(void);
+#endif
+
+static void lvm_dummy_device_request(request_queue_t *);
+#define DEVICE_REQUEST lvm_dummy_device_request
+
+static int lvm_make_request_fn(request_queue_t *, int, struct buffer_head*);
+static void lvm_plug_device_noop(request_queue_t *, kdev_t);
+
+static int lvm_blk_ioctl(struct inode *, struct file *, uint, ulong);
+static int lvm_blk_open(struct inode *, struct file *);
+
+static int lvm_chr_open(struct inode *, struct file *);
+
+static int lvm_chr_close(struct inode *, struct file *);
+static int lvm_blk_close(struct inode *, struct file *);
+
+static int lvm_chr_ioctl(struct inode *, struct file *, uint, ulong);
+
+#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS
+static int lvm_proc_get_info(char *, char **, off_t, int);
+static int (*lvm_proc_get_info_ptr) (char *, char **, off_t, int) =
+&lvm_proc_get_info;
+#endif
+
+#ifdef LVM_HD_NAME
+void lvm_hd_name(char *, int);
+#endif
+/* End external function prototypes */
+
+
+/*
+ * Internal function prototypes
+ */
+static void lvm_init_vars(void);
+
+/* external snapshot calls */
+int lvm_snapshot_remap_block(kdev_t *, ulong *, ulong, lv_t *);
+int lvm_snapshot_COW(kdev_t, ulong, ulong, ulong, lv_t *);
+int lvm_snapshot_alloc(lv_t *);
+void lvm_snapshot_release(lv_t *);
+
+#ifdef LVM_HD_NAME
+extern void (*lvm_hd_name_ptr) (char *, int);
+#endif
+static int lvm_map(struct buffer_head *, int);
+static int lvm_do_lock_lvm(void);
+static int lvm_do_le_remap(vg_t *, void *);
+static int lvm_do_pe_lock_unlock(vg_t *r, void *);
+static int lvm_do_vg_create(int, void *);
+static int lvm_do_vg_extend(vg_t *, void *);
+static int lvm_do_vg_reduce(vg_t *, void *);
+static int lvm_do_vg_remove(int);
+static int lvm_do_lv_create(int, char *, lv_t *);
+static int lvm_do_lv_remove(int, char *, int);
+static int lvm_do_lv_extend_reduce(int, char *, lv_t *);
+static int lvm_do_lv_status_byname(vg_t *r, void *);
+static int lvm_do_lv_status_byindex(vg_t *, void *arg);
+static int lvm_do_pv_change(vg_t*, void*);
+static int lvm_do_pv_status(vg_t *, void *);
+static void lvm_geninit(struct gendisk *);
+#ifdef LVM_GET_INODE
+static struct inode *lvm_get_inode(kdev_t);
+void lvm_clear_inode(struct inode *);
+#endif
+/* END Internal function prototypes */
+
+
+/* volume group descriptor area pointers */
+static vg_t *vg[ABS_MAX_VG];
+static pv_t *pvp = NULL;
+static lv_t *lvp = NULL;
+static pe_t *pep = NULL;
+static pe_t *pep1 = NULL;
+
+
+/* map from block minor number to VG and LV numbers */
+typedef struct {
+ int vg_number;
+ int lv_number;
+} vg_lv_map_t;
+static vg_lv_map_t vg_lv_map[ABS_MAX_LV];
+
+
+/* Request structures (lvm_chr_ioctl()) */
+static pv_change_req_t pv_change_req;
+static pv_flush_req_t pv_flush_req;
+static pv_status_req_t pv_status_req;
+static pe_lock_req_t pe_lock_req;
+static le_remap_req_t le_remap_req;
+static lv_req_t lv_req;
+
+#ifdef LVM_TOTAL_RESET
+static int lvm_reset_spindown = 0;
+#endif
+
+static char pv_name[NAME_LEN];
+/* static char rootvg[NAME_LEN] = { 0, }; */
+static uint lv_open = 0;
+const char *const lvm_name = LVM_NAME;
+static int lock = 0;
+static int loadtime = 0;
+static uint vg_count = 0;
+static long lvm_chr_open_count = 0;
+static ushort lvm_iop_version = LVM_DRIVER_IOP_VERSION;
+static DECLARE_WAIT_QUEUE_HEAD(lvm_snapshot_wait);
+static DECLARE_WAIT_QUEUE_HEAD(lvm_wait);
+static DECLARE_WAIT_QUEUE_HEAD(lvm_map_wait);
+
+static spinlock_t lvm_lock = SPIN_LOCK_UNLOCKED;
+
+static devfs_handle_t lvm_devfs_handle;
+static devfs_handle_t vg_devfs_handle[MAX_VG];
+static devfs_handle_t ch_devfs_handle[MAX_VG];
+static devfs_handle_t lv_devfs_handle[MAX_LV];
+
+static struct file_operations lvm_chr_fops =
+{
+ owner: THIS_MODULE,
+ open: lvm_chr_open,
+ release: lvm_chr_close,
+ ioctl: lvm_chr_ioctl,
+};
+
+static struct block_device_operations lvm_blk_dops =
+{
+ open: lvm_blk_open,
+ release: lvm_blk_close,
+ ioctl: lvm_blk_ioctl
+};
+
+/* gendisk structures */
+static struct hd_struct lvm_hd_struct[MAX_LV];
+static int lvm_blocksizes[MAX_LV] =
+{0,};
+static int lvm_size[MAX_LV] =
+{0,};
+static struct gendisk lvm_gendisk =
+{
+ MAJOR_NR, /* major # */
+ LVM_NAME, /* name of major */
+ 0, /* number of times minor is shifted
+ to get real minor */
+ 1, /* maximum partitions per device */
+ lvm_hd_struct, /* partition table */
+ lvm_size, /* device size in blocks, copied
+ to block_size[] */
+ MAX_LV, /* number or real devices */
+ NULL, /* internal */
+ NULL, /* pointer to next gendisk struct (internal) */
+};
+
+
+#ifdef MODULE
+/*
+ * Module initialization...
+ */
+int init_module(void)
+#else
+/*
+ * Driver initialization...
+ */
+#ifdef __initfunc
+__initfunc(int lvm_init(void))
+#else
+int __init lvm_init(void)
+#endif
+#endif /* #ifdef MODULE */
+{
+ struct gendisk *gendisk_ptr = NULL;
+
+ if (register_chrdev(LVM_CHAR_MAJOR, lvm_name, &lvm_chr_fops) < 0) {
+ printk(KERN_ERR "%s -- register_chrdev failed\n", lvm_name);
+ return -EIO;
+ }
+ if (register_blkdev(MAJOR_NR, lvm_name, &lvm_blk_dops) < 0) {
+ printk("%s -- register_blkdev failed\n", lvm_name);
+ if (unregister_chrdev(LVM_CHAR_MAJOR, lvm_name) < 0)
+ printk(KERN_ERR "%s -- unregister_chrdev failed\n", lvm_name);


+ return -EIO;
+ }
+

+ lvm_devfs_handle = devfs_register(
+ 0 , "lvm", 0, 0, LVM_CHAR_MAJOR,
+ S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,
+ &lvm_chr_fops, NULL);
+
+#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS
+ create_proc_info_entry(LVM_NAME, S_IFREG | S_IRUGO,
+ &proc_root, lvm_proc_get_info_ptr);
+#endif
+
+ lvm_init_vars();
+ lvm_geninit(&lvm_gendisk);
+
+ /* insert our gendisk at the corresponding major */
+ if (gendisk_head != NULL) {
+ gendisk_ptr = gendisk_head;
+ while (gendisk_ptr->next != NULL &&
+ gendisk_ptr->major > lvm_gendisk.major) {
+ gendisk_ptr = gendisk_ptr->next;
+ }
+ lvm_gendisk.next = gendisk_ptr->next;
+ gendisk_ptr->next = &lvm_gendisk;
+ } else {
+ gendisk_head = &lvm_gendisk;
+ lvm_gendisk.next = NULL;
+ }
+
+#ifdef LVM_HD_NAME
+ /* reference from drivers/block/genhd.c */
+ lvm_hd_name_ptr = lvm_hd_name;
+#endif
+
+ blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
+ blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR), lvm_make_request_fn);
+ blk_queue_pluggable(BLK_DEFAULT_QUEUE(MAJOR_NR), lvm_plug_device_noop);
+ /* optional read root VGDA */
+/*
+ if ( *rootvg != 0) vg_read_with_pv_and_lv ( rootvg, &vg);
+*/
+
+ printk(KERN_INFO
+ "%s%s -- "
+#ifdef MODULE
+ "Module"
+#else
+ "Driver"
+#endif
+ " successfully initialized\n",
+ lvm_version, lvm_name);
+
+ return 0;
+} /* init_module() / lvm_init() */
+
+
+#ifdef MODULE
+/*
+ * Module cleanup...
+ */
+void cleanup_module(void)
+{
+ struct gendisk *gendisk_ptr = NULL, *gendisk_ptr_prev = NULL;
+
+ devfs_unregister (lvm_devfs_handle);
+
+ if (unregister_chrdev(LVM_CHAR_MAJOR, lvm_name) < 0) {
+ printk(KERN_ERR "%s -- unregister_chrdev failed\n", lvm_name);
+ }
+ if (unregister_blkdev(MAJOR_NR, lvm_name) < 0) {
+ printk(KERN_ERR "%s -- unregister_blkdev failed\n", lvm_name);
+ }
+ blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+
+ gendisk_ptr = gendisk_ptr_prev = gendisk_head;
+ while (gendisk_ptr != NULL) {
+ if (gendisk_ptr == &lvm_gendisk)
+ break;
+ gendisk_ptr_prev = gendisk_ptr;
+ gendisk_ptr = gendisk_ptr->next;
+ }
+ /* delete our gendisk from chain */
+ if (gendisk_ptr == &lvm_gendisk)
+ gendisk_ptr_prev->next = gendisk_ptr->next;
+
+ blk_size[MAJOR_NR] = NULL;
+ blksize_size[MAJOR_NR] = NULL;
+
+#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS
+ remove_proc_entry(LVM_NAME, &proc_root);
+#endif
+
+#ifdef LVM_HD_NAME
+ /* reference from linux/drivers/block/genhd.c */
+ lvm_hd_name_ptr = NULL;
+#endif
+
+ printk(KERN_INFO "%s -- Module successfully deactivated\n", lvm_name);
+
+ return;
+} /* void cleanup_module() */
+#endif /* #ifdef MODULE */
+
+
+/*
+ * support function to initialize lvm variables
+ */
+#ifdef __initfunc
+__initfunc(void lvm_init_vars(void))
+#else
+void __init lvm_init_vars(void)
+#endif
+{
+ int v;
+
+ loadtime = CURRENT_TIME;
+
+ pe_lock_req.lock = UNLOCK_PE;
+ pe_lock_req.data.lv_dev = pe_lock_req.data.pv_dev = 0;
+ pe_lock_req.data.pv_offset = 0;
+
+ /* Initialize VG pointers */
+ for (v = 0; v < ABS_MAX_VG; v++) vg[v] = NULL;
+
+ /* Initialize LV -> VG association */
+ for (v = 0; v < ABS_MAX_LV; v++) {
+ /* index ABS_MAX_VG never used for real VG */
+ vg_lv_map[v].vg_number = ABS_MAX_VG;
+ vg_lv_map[v].lv_number = -1;
+ }
+
+ return;
+} /* lvm_init_vars() */
+
+
+/********************************************************************
+ *
+ * Character device functions
+ *
+ ********************************************************************/
+
+/*
+ * character device open routine
+ */
+static int lvm_chr_open(struct inode *inode,
+ struct file *file)
+{
+ int minor = MINOR(inode->i_rdev);
+
+#ifdef DEBUG
+ printk(KERN_DEBUG
+ "%s -- lvm_chr_open MINOR: %d VG#: %d mode: 0x%X lock: %d\n",
+ lvm_name, minor, VG_CHR(minor), file->f_mode, lock);
+#endif
+
+ /* super user validation */
+ if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+
+ /* Group special file open */
+ if (VG_CHR(minor) > MAX_VG) return -ENXIO;
+
+ lvm_chr_open_count++;
+ return 0;
+} /* lvm_chr_open() */
+
+
+/*
+ * character device i/o-control routine
+ *
+ * Only one changing process can do changing ioctl at one time,
+ * others will block.
+ *
+ */
+static int lvm_chr_ioctl(struct inode *inode, struct file *file,
+ uint command, ulong a)
+{
+ int minor = MINOR(inode->i_rdev);
+ uint extendable, l, v;
+ void *arg = (void *) a;
+ lv_t lv;
+ vg_t* vg_ptr = vg[VG_CHR(minor)];
+
+ /* otherwise cc will complain about unused variables */
+ (void) lvm_lock;
+
+
+#ifdef DEBUG_IOCTL
+ printk(KERN_DEBUG
+ "%s -- lvm_chr_ioctl: command: 0x%X MINOR: %d "
+ "VG#: %d mode: 0x%X\n",
+ lvm_name, command, minor, VG_CHR(minor), file->f_mode);
+#endif
+
+#ifdef LVM_TOTAL_RESET
+ if (lvm_reset_spindown > 0) return -EACCES;
+#endif
+
+ /* Main command switch */
+ switch (command) {
+ case LVM_LOCK_LVM:
+ /* lock the LVM */
+ return lvm_do_lock_lvm();
+
+ case LVM_GET_IOP_VERSION:
+ /* check lvm version to ensure driver/tools+lib
+ interoperability */
+ if (copy_to_user(arg, &lvm_iop_version, sizeof(ushort)) != 0)


+ return -EFAULT;
+ return 0;
+

+#ifdef LVM_TOTAL_RESET
+ case LVM_RESET:
+ /* lock reset function */
+ lvm_reset_spindown = 1;
+ for (v = 0; v < ABS_MAX_VG; v++) {
+ if (vg[v] != NULL) lvm_do_vg_remove(v);
+ }
+
+#ifdef MODULE
+ while (GET_USE_COUNT(&__this_module) < 1)
+ MOD_INC_USE_COUNT;
+ while (GET_USE_COUNT(&__this_module) > 1)
+ MOD_DEC_USE_COUNT;
+#endif /* MODULE */
+ lock = 0; /* release lock */
+ wake_up_interruptible(&lvm_wait);
+ return 0;
+#endif /* LVM_TOTAL_RESET */
+
+
+ case LE_REMAP:
+ /* remap a logical extent (after moving the physical extent) */
+ return lvm_do_le_remap(vg_ptr,arg);
+
+ case PE_LOCK_UNLOCK:
+ /* lock/unlock i/o to a physical extent to move it to another
+ physical volume (move's done in user space's pvmove) */
+ return lvm_do_pe_lock_unlock(vg_ptr,arg);
+
+ case VG_CREATE:
+ /* create a VGDA */
+ return lvm_do_vg_create(minor, arg);
+
+ case VG_REMOVE:
+ /* remove an inactive VGDA */
+ return lvm_do_vg_remove(minor);
+
+ case VG_EXTEND:
+ /* extend a volume group */
+ return lvm_do_vg_extend(vg_ptr,arg);
+
+ case VG_REDUCE:
+ /* reduce a volume group */
+ return lvm_do_vg_reduce(vg_ptr,arg);
+
+
+ case VG_SET_EXTENDABLE:
+ /* set/clear extendability flag of volume group */
+ if (vg_ptr == NULL) return -ENXIO;
+ if (copy_from_user(&extendable, arg, sizeof(extendable)) != 0)
+ return -EFAULT;
+
+ if (extendable == VG_EXTENDABLE ||
+ extendable == ~VG_EXTENDABLE) {
+ if (extendable == VG_EXTENDABLE)
+ vg_ptr->vg_status |= VG_EXTENDABLE;
+ else
+ vg_ptr->vg_status &= ~VG_EXTENDABLE;
+ } else return -EINVAL;


+ return 0;
+
+

+ case VG_STATUS:
+ /* get volume group data (only the vg_t struct) */
+ if (vg_ptr == NULL) return -ENXIO;
+ if (copy_to_user(arg, vg_ptr, sizeof(vg_t)) != 0)
+ return -EFAULT;


+ return 0;
+
+

+ case VG_STATUS_GET_COUNT:
+ /* get volume group count */
+ if (copy_to_user(arg, &vg_count, sizeof(vg_count)) != 0)
+ return -EFAULT;


+ return 0;
+
+

+ case VG_STATUS_GET_NAMELIST:
+ /* get volume group count */
+ for (l = v = 0; v < ABS_MAX_VG; v++) {
+ if (vg[v] != NULL) {
+ if (copy_to_user(arg + l++ * NAME_LEN,
+ vg[v]->vg_name,
+ NAME_LEN) != 0)


+ return -EFAULT;
+ }
+ }

+ return 0;
+
+

+ case LV_CREATE:
+ case LV_REMOVE:
+ case LV_EXTEND:
+ case LV_REDUCE:
+ /* create, remove, extend or reduce a logical volume */
+ if (vg_ptr == NULL) return -ENXIO;
+ if (copy_from_user(&lv_req, arg, sizeof(lv_req)) != 0)
+ return -EFAULT;
+
+ if (command != LV_REMOVE) {
+ if (copy_from_user(&lv, lv_req.lv, sizeof(lv_t)) != 0)
+ return -EFAULT;
+ }
+ switch (command) {
+ case LV_CREATE:
+ return lvm_do_lv_create(minor, lv_req.lv_name, &lv);
+
+ case LV_REMOVE:
+ return lvm_do_lv_remove(minor, lv_req.lv_name, -1);
+
+ case LV_EXTEND:
+ case LV_REDUCE:
+ return lvm_do_lv_extend_reduce(minor, lv_req.lv_name, &lv);
+ }
+
+
+ case LV_STATUS_BYNAME:
+ /* get status of a logical volume by name */
+ return lvm_do_lv_status_byname(vg_ptr,arg);
+
+ case LV_STATUS_BYINDEX:
+ /* get status of a logical volume by index */
+ return lvm_do_lv_status_byindex(vg_ptr,arg);
+
+ case PV_CHANGE:
+ /* change a physical volume */
+ return lvm_do_pv_change(vg_ptr,arg);
+
+ case PV_STATUS:
+ /* get physical volume data (pv_t structure only) */
+ return lvm_do_pv_status(vg_ptr,arg);
+
+ case PV_FLUSH:
+ /* physical volume buffer flush/invalidate */
+ if (copy_from_user(&pv_flush_req, arg,
+ sizeof(pv_flush_req)) != 0)
+ return -EFAULT;
+
+ for ( v = 0; v < ABS_MAX_VG; v++) {
+ unsigned int p;
+ if ( vg[v] == NULL) continue;
+ for ( p = 0; p < vg[v]->pv_max; p++) {
+ if ( vg[v]->pv[p] != NULL &&
+ strcmp ( vg[v]->pv[p]->pv_name,
+ pv_flush_req.pv_name) == 0) {
+ fsync_dev ( vg[v]->pv[p]->pv_dev);
+ invalidate_buffers ( vg[v]->pv[p]->pv_dev);


+ return 0;
+ }
+ }
+ }

+ return 0;
+
+ default:
+ printk(KERN_WARNING
+ "%s -- lvm_chr_ioctl: unknown command %x\n",
+ lvm_name, command);


+ return -EINVAL;
+ }
+
+ return 0;

+} /* lvm_chr_ioctl */
+
+
+/*
+ * character device close routine
+ */
+static int lvm_chr_close(struct inode *inode, struct file *file)
+{
+#ifdef DEBUG
+ int minor = MINOR(inode->i_rdev);
+ printk(KERN_DEBUG
+ "%s -- lvm_chr_close VG#: %d\n", lvm_name, VG_CHR(minor));
+#endif
+
+ lock_kernel();
+#ifdef LVM_TOTAL_RESET
+ if (lvm_reset_spindown > 0) {
+ lvm_reset_spindown = 0;
+ lvm_chr_open_count = 1;
+ }
+#endif
+
+ if (lvm_chr_open_count > 0) lvm_chr_open_count--;
+ if (lock == current->pid) {
+ lock = 0; /* release lock */
+ wake_up_interruptible(&lvm_wait);
+ }
+ unlock_kernel();
+
+ return 0;
+} /* lvm_chr_close() */
+
+
+
+/********************************************************************
+ *
+ * Block device functions
+ *
+ ********************************************************************/
+
+/*
+ * block device open routine
+ */
+static int lvm_blk_open(struct inode *inode, struct file *file)
+{
+ int minor = MINOR(inode->i_rdev);
+ lv_t *lv_ptr;
+ vg_t *vg_ptr = vg[VG_BLK(minor)];
+
+#ifdef DEBUG_LVM_BLK_OPEN
+ printk(KERN_DEBUG
+ "%s -- lvm_blk_open MINOR: %d VG#: %d LV#: %d mode: 0x%X\n",
+ lvm_name, minor, VG_BLK(minor), LV_BLK(minor), file->f_mode);
+#endif
+
+#ifdef LVM_TOTAL_RESET
+ if (lvm_reset_spindown > 0)
+ return -EPERM;
+#endif
+
+ if (vg_ptr != NULL &&
+ (vg_ptr->vg_status & VG_ACTIVE) &&
+ (lv_ptr = vg_ptr->lv[LV_BLK(minor)]) != NULL &&
+ LV_BLK(minor) >= 0 &&
+ LV_BLK(minor) < vg_ptr->lv_max) {
+
+ /* Check parallel LV spindown (LV remove) */
+ if (lv_ptr->lv_status & LV_SPINDOWN) return -EPERM;
+
+ /* Check inactive LV and open for read/write */
+ if (file->f_mode & O_RDWR) {
+ if (!(lv_ptr->lv_status & LV_ACTIVE)) return -EPERM;
+ if (!(lv_ptr->lv_access & LV_WRITE)) return -EACCES;
+ }
+
+ /* be sure to increment VG counter */
+ if (lv_ptr->lv_open == 0) vg_ptr->lv_open++;
+ lv_ptr->lv_open++;
+
+ MOD_INC_USE_COUNT;
+
+#ifdef DEBUG_LVM_BLK_OPEN
+ printk(KERN_DEBUG
+ "%s -- lvm_blk_open MINOR: %d VG#: %d LV#: %d size: %d\n",
+ lvm_name, minor, VG_BLK(minor), LV_BLK(minor),
+ lv_ptr->lv_size);
+#endif


+
+ return 0;
+ }

+ return -ENXIO;
+} /* lvm_blk_open() */
+
+
+/*
+ * block device i/o-control routine
+ */
+static int lvm_blk_ioctl(struct inode *inode, struct file *file,
+ uint command, ulong a)
+{
+ int minor = MINOR(inode->i_rdev);
+ vg_t *vg_ptr = vg[VG_BLK(minor)];
+ lv_t *lv_ptr = vg_ptr->lv[LV_BLK(minor)];
+ void *arg = (void *) a;
+ struct hd_geometry *hd = (struct hd_geometry *) a;
+
+#ifdef DEBUG_IOCTL
+ printk(KERN_DEBUG
+ "%s -- lvm_blk_ioctl MINOR: %d command: 0x%X arg: %X "
+ "VG#: %dl LV#: %d\n",
+ lvm_name, minor, command, (ulong) arg,
+ VG_BLK(minor), LV_BLK(minor));
+#endif
+
+ switch (command) {
+ case BLKGETSIZE:
+ /* return device size */
+#ifdef DEBUG_IOCTL
+ printk(KERN_DEBUG
+ "%s -- lvm_blk_ioctl -- BLKGETSIZE: %u\n",
+ lvm_name, lv_ptr->lv_size);
+#endif
+ if (put_user(lv_ptr->lv_size, (long *)arg))


+ return -EFAULT;
+ break;
+
+

+ case BLKFLSBUF:
+ /* flush buffer cache */
+ if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+
+#ifdef DEBUG_IOCTL
+ printk(KERN_DEBUG
+ "%s -- lvm_blk_ioctl -- BLKFLSBUF\n", lvm_name);
+#endif
+ fsync_dev(inode->i_rdev);
+ invalidate_buffers(inode->i_rdev);
+ break;
+
+
+ case BLKRASET:
+ /* set read ahead for block device */
+ if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+
+#ifdef DEBUG_IOCTL
+ printk(KERN_DEBUG
+ "%s -- lvm_blk_ioctl -- BLKRASET: %d sectors for %02X:%02X\n",
+ lvm_name, (long) arg, MAJOR(inode->i_rdev), minor);
+#endif
+ if ((long) arg < LVM_MIN_READ_AHEAD ||
+ (long) arg > LVM_MAX_READ_AHEAD)
+ return -EINVAL;
+ read_ahead[MAJOR_NR] = lv_ptr->lv_read_ahead = (long) arg;
+ break;
+
+
+ case BLKRAGET:
+ /* get current read ahead setting */
+#ifdef DEBUG_IOCTL
+ printk(KERN_DEBUG
+ "%s -- lvm_blk_ioctl -- BLKRAGET\n", lvm_name);
+#endif
+ if (put_user(lv_ptr->lv_read_ahead, (long *)arg))


+ return -EFAULT;
+ break;
+
+

+ case HDIO_GETGEO:
+ /* get disk geometry */
+#ifdef DEBUG_IOCTL
+ printk(KERN_DEBUG
+ "%s -- lvm_blk_ioctl -- HDIO_GETGEO\n", lvm_name);
+#endif
+ if (hd == NULL)
+ return -EINVAL;
+ {
+ unsigned char heads = 64;
+ unsigned char sectors = 32;
+ long start = 0;
+ short cylinders = lv_ptr->lv_size / heads / sectors;
+
+ if (copy_to_user((char *) &hd->heads, &heads,
+ sizeof(heads)) != 0 ||
+ copy_to_user((char *) &hd->sectors, &sectors,
+ sizeof(sectors)) != 0 ||
+ copy_to_user((short *) &hd->cylinders,
+ &cylinders, sizeof(cylinders)) != 0 ||
+ copy_to_user((long *) &hd->start, &start,
+ sizeof(start)) != 0)


+ return -EFAULT;
+ }
+

+#ifdef DEBUG_IOCTL
+ printk(KERN_DEBUG
+ "%s -- lvm_blk_ioctl -- cylinders: %d\n",
+ lvm_name, lv_ptr->lv_size / heads / sectors);
+#endif
+ break;
+
+
+ case LV_SET_ACCESS:
+ /* set access flags of a logical volume */
+ if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+ lv_ptr->lv_access = (ulong) arg;
+ break;
+
+
+ case LV_SET_STATUS:
+ /* set status flags of a logical volume */
+ if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+ if (!((ulong) arg & LV_ACTIVE) && lv_ptr->lv_open > 1)
+ return -EPERM;
+ lv_ptr->lv_status = (ulong) arg;
+ break;
+
+
+ case LV_SET_ALLOCATION:
+ /* set allocation flags of a logical volume */
+ if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+ lv_ptr->lv_allocation = (ulong) arg;


+ break;
+
+
+ default:

+ printk(KERN_WARNING
+ "%s -- lvm_blk_ioctl: unknown command %d\n",
+ lvm_name, command);


+ return -EINVAL;
+ }
+
+ return 0;

+} /* lvm_blk_ioctl() */
+
+
+/*
+ * block device close routine
+ */
+static int lvm_blk_close(struct inode *inode, struct file *file)
+{
+ int minor = MINOR(inode->i_rdev);
+ vg_t *vg_ptr = vg[VG_BLK(minor)];
+ lv_t *lv_ptr = vg_ptr->lv[LV_BLK(minor)];
+
+#ifdef DEBUG
+ printk(KERN_DEBUG
+ "%s -- lvm_blk_close MINOR: %d VG#: %d LV#: %d\n",
+ lvm_name, minor, VG_BLK(minor), LV_BLK(minor));
+#endif
+
+ sync_dev(inode->i_rdev);
+ if (lv_ptr->lv_open == 1) vg_ptr->lv_open--;
+ lv_ptr->lv_open--;
+
+ MOD_DEC_USE_COUNT;
+
+ return 0;
+} /* lvm_blk_close() */
+
+
+#if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS
+/*
+ * Support function /proc-Filesystem
+ */
+#define LVM_PROC_BUF ( i == 0 ? dummy_buf : &buf[sz])
+
+static int lvm_proc_get_info(char *page, char **start, off_t pos, int count)
+{
+ int c, i, l, p, v, vg_counter, pv_counter, lv_counter, lv_open_counter,
+ lv_open_total, pe_t_bytes, lv_block_exception_t_bytes, seconds;
+ static off_t sz;
+ off_t sz_last;
+ char allocation_flag, inactive_flag, rw_flag, stripes_flag;
+ char *lv_name, *pv_name;
+ static char *buf = NULL;
+ static char dummy_buf[160]; /* sized for 2 lines */
+ vg_t *vg_ptr;
+ lv_t *lv_ptr;
+ pv_t *pv_ptr;
+
+
+#ifdef DEBUG_LVM_PROC_GET_INFO
+ printk(KERN_DEBUG
+ "%s - lvm_proc_get_info CALLED pos: %lu count: %d whence: %d\n",
+ lvm_name, pos, count, whence);
+#endif
+
+ if (pos == 0 || buf == NULL) {
+ sz_last = vg_counter = pv_counter = lv_counter = lv_open_counter = \
+ lv_open_total = pe_t_bytes = lv_block_exception_t_bytes = 0;
+
+ /* search for activity */
+ for (v = 0; v < ABS_MAX_VG; v++) {
+ if ((vg_ptr = vg[v]) != NULL) {
+ vg_counter++;
+ pv_counter += vg_ptr->pv_cur;
+ lv_counter += vg_ptr->lv_cur;
+ if (vg_ptr->lv_cur > 0) {
+ for (l = 0; l < vg[v]->lv_max; l++) {
+ if ((lv_ptr = vg_ptr->lv[l]) != NULL) {
+ pe_t_bytes += lv_ptr->lv_allocated_le;
+ if (lv_ptr->lv_block_exception != NULL)
+ lv_block_exception_t_bytes += lv_ptr->lv_remap_end;
+ if (lv_ptr->lv_open > 0) {
+ lv_open_counter++;
+ lv_open_total += lv_ptr->lv_open;


+ }
+ }
+ }
+ }
+ }

+ }
+ pe_t_bytes *= sizeof(pe_t);
+ lv_block_exception_t_bytes *= sizeof(lv_block_exception_t);
+
+ if (buf != NULL) {
+#ifdef DEBUG_KFREE
+ printk(KERN_DEBUG
+ "%s -- kfree %d\n", lvm_name, __LINE__);
+#endif
+ kfree(buf);
+ buf = NULL;
+ }
+ /* 2 times: first to get size to allocate buffer,
+ 2nd to fill the malloced buffer */
+ for (i = 0; i < 2; i++) {
+ sz = 0;
+ sz += sprintf(LVM_PROC_BUF,


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 054'
echo 'File patch-2.4.0-test9 is continued in part 055'
echo "055" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part057

#!/bin/sh -x
# this is part 057 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 057; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ serialize = 1;
+ break;
+ }
+ }
+ if (serialize) {
+ interruptible_sleep_on(&resync_wait);
+ if (md_signal_pending(current)) {
+ md_flush_signals();
+ err = -EINTR;
+ goto out;
+ }
+ goto recheck;
+ }
+
+ mddev->curr_resync = 1;
+
+ max_blocks = mddev->sb->size;
+
+ printk(KERN_INFO "md: syncing RAID array md%d\n", mdidx(mddev));
+ printk(KERN_INFO "md: minimum _guaranteed_ reconstruction speed: %d KB/sec/disc.\n",
+ sysctl_speed_limit_min);
+ printk(KERN_INFO "md: using maximum available idle IO bandwith (but not more than %d KB/sec) for reconstruction.\n", sysctl_speed_limit_max);
+
+ /*
+ * Resync has low priority.
+ */
+ current->nice = 19;
+
+ is_mddev_idle(mddev); /* this also initializes IO event counters */
+ for (m = 0; m < SYNC_MARKS; m++) {
+ mark[m] = jiffies;
+ mark_cnt[m] = 0;
+ }
+ last_mark = 0;
+ mddev->resync_mark = mark[last_mark];
+ mddev->resync_mark_cnt = mark_cnt[last_mark];
+
+ /*
+ * Tune reconstruction:
+ */
+ window = MAX_READAHEAD*(PAGE_SIZE/1024);
+ printk(KERN_INFO "md: using %dk window, over a total of %d blocks.\n",window,max_blocks);
+
+ atomic_set(&mddev->recovery_active, 0);
+ init_waitqueue_head(&mddev->recovery_wait);
+ last_check = 0;
+ for (j = 0; j < max_blocks;) {
+ int blocks;
+
+ blocks = mddev->pers->sync_request(mddev, j);
+
+ if (blocks < 0) {
+ err = blocks;
+ goto out;
+ }
+ atomic_add(blocks, &mddev->recovery_active);
+ j += blocks;
+ mddev->curr_resync = j;
+
+ if (last_check + window > j)
+ continue;
+
+ run_task_queue(&tq_disk); //??
+
+ if (jiffies >= mark[last_mark] + SYNC_MARK_STEP ) {
+ /* step marks */
+ int next = (last_mark+1) % SYNC_MARKS;
+
+ mddev->resync_mark = mark[next];
+ mddev->resync_mark_cnt = mark_cnt[next];
+ mark[next] = jiffies;
+ mark_cnt[next] = j - atomic_read(&mddev->recovery_active);
+ last_mark = next;
+ }
+
+
+ if (md_signal_pending(current)) {
+ /*
+ * got a signal, exit.
+ */
+ mddev->curr_resync = 0;
+ printk("md_do_sync() got signal ... exiting\n");
+ md_flush_signals();
+ err = -EINTR;


+ goto out;
+ }
+

+ /*
+ * this loop exits only if either when we are slower than
+ * the 'hard' speed limit, or the system was IO-idle for
+ * a jiffy.
+ * the system might be non-idle CPU-wise, but we only care
+ * about not overloading the IO subsystem. (things like an
+ * e2fsck being done on the RAID array should execute fast)
+ */
+repeat:
+ if (md_need_resched(current))
+ schedule();
+
+ currspeed = (j-mddev->resync_mark_cnt)/((jiffies-mddev->resync_mark)/HZ +1) +1;
+
+ if (currspeed > sysctl_speed_limit_min) {
+ current->nice = 19;
+
+ if ((currspeed > sysctl_speed_limit_max) ||
+ !is_mddev_idle(mddev)) {


+ current->state = TASK_INTERRUPTIBLE;

+ md_schedule_timeout(HZ/4);
+ if (!md_signal_pending(current))
+ goto repeat;
+ }
+ } else
+ current->nice = -20;
+ }
+ fsync_dev(read_disk);
+ printk(KERN_INFO "md: md%d: sync done.\n",mdidx(mddev));
+ err = 0;
+ /*
+ * this also signals 'finished resyncing' to md_stop
+ */
+out:
+ wait_event(mddev->recovery_wait, atomic_read(&mddev->recovery_active)==0);
+ up(&mddev->resync_sem);
+out_nolock:
+ mddev->curr_resync = 0;
+ wake_up(&resync_wait);


+ return err;
+}
+
+

+/*
+ * This is a kernel thread which syncs a spare disk with the active array
+ *
+ * the amount of foolproofing might seem to be a tad excessive, but an
+ * early (not so error-safe) version of raid1syncd synced the first 0.5 gigs
+ * of my root partition with the first 0.5 gigs of my /home partition ... so
+ * i'm a bit nervous ;)
+ */
+void md_do_recovery (void *data)
+{
+ int err;
+ mddev_t *mddev;
+ mdp_super_t *sb;
+ mdp_disk_t *spare;
+ struct md_list_head *tmp;
+
+ printk(KERN_INFO "md: recovery thread got woken up ...\n");
+restart:
+ ITERATE_MDDEV(mddev,tmp) {
+ sb = mddev->sb;
+ if (!sb)
+ continue;
+ if (mddev->recovery_running)
+ continue;
+ if (sb->active_disks == sb->raid_disks)
+ continue;
+ if (!sb->spare_disks) {
+ printk(KERN_ERR "md%d: no spare disk to reconstruct array! -- continuing in degraded mode\n", mdidx(mddev));
+ continue;
+ }
+ /*
+ * now here we get the spare and resync it.
+ */
+ if ((spare = get_spare(mddev)) == NULL)
+ continue;
+ printk(KERN_INFO "md%d: resyncing spare disk %s to replace failed disk\n", mdidx(mddev), partition_name(MKDEV(spare->major,spare->minor)));
+ if (!mddev->pers->diskop)
+ continue;
+ if (mddev->pers->diskop(mddev, &spare, DISKOP_SPARE_WRITE))
+ continue;
+ down(&mddev->recovery_sem);
+ mddev->recovery_running = 1;
+ err = md_do_sync(mddev, spare);
+ if (err == -EIO) {
+ printk(KERN_INFO "md%d: spare disk %s failed, skipping to next spare.\n", mdidx(mddev), partition_name(MKDEV(spare->major,spare->minor)));
+ if (!disk_faulty(spare)) {
+ mddev->pers->diskop(mddev,&spare,DISKOP_SPARE_INACTIVE);
+ mark_disk_faulty(spare);
+ mark_disk_nonsync(spare);
+ mark_disk_inactive(spare);
+ sb->spare_disks--;
+ sb->working_disks--;
+ sb->failed_disks++;
+ }
+ } else
+ if (disk_faulty(spare))
+ mddev->pers->diskop(mddev, &spare,
+ DISKOP_SPARE_INACTIVE);
+ if (err == -EINTR || err == -ENOMEM) {
+ /*
+ * Recovery got interrupted, or ran out of mem ...
+ * signal back that we have finished using the array.
+ */
+ mddev->pers->diskop(mddev, &spare,
+ DISKOP_SPARE_INACTIVE);
+ up(&mddev->recovery_sem);
+ mddev->recovery_running = 0;
+ continue;
+ } else {
+ mddev->recovery_running = 0;
+ up(&mddev->recovery_sem);
+ }
+ if (!disk_faulty(spare)) {
+ /*
+ * the SPARE_ACTIVE diskop possibly changes the
+ * pointer too
+ */
+ mddev->pers->diskop(mddev, &spare, DISKOP_SPARE_ACTIVE);
+ mark_disk_sync(spare);
+ mark_disk_active(spare);
+ sb->active_disks++;
+ sb->spare_disks--;
+ }
+ mddev->sb_dirty = 1;
+ md_update_sb(mddev);
+ goto restart;
+ }
+ printk(KERN_INFO "md: recovery thread finished ...\n");
+
+}
+
+int md_notify_reboot(struct notifier_block *this,
+ unsigned long code, void *x)
+{
+ struct md_list_head *tmp;
+ mddev_t *mddev;
+
+ if ((code == MD_SYS_DOWN) || (code == MD_SYS_HALT)
+ || (code == MD_SYS_POWER_OFF)) {
+
+ printk(KERN_INFO "stopping all md devices.\n");
+
+ ITERATE_MDDEV(mddev,tmp)
+ do_md_stop (mddev, 1);
+ /*
+ * certain more exotic SCSI devices are known to be
+ * volatile wrt too early system reboots. While the
+ * right place to handle this issue is the given
+ * driver, we do want to have a safe RAID driver ...
+ */
+ md_mdelay(1000*1);


+ }
+ return NOTIFY_DONE;
+}
+

+struct notifier_block md_notifier = {
+ md_notify_reboot,
+ NULL,
+ 0
+};
+#ifndef MODULE
+static int md__init raid_setup(char *str)
+{
+ int len, pos;
+
+ len = strlen(str) + 1;
+ pos = 0;
+
+ while (pos < len) {
+ char *comma = strchr(str+pos, ',');
+ int wlen;
+ if (comma)
+ wlen = (comma-str)-pos;
+ else wlen = (len-1)-pos;
+
+ if (strncmp(str, "noautodetect", wlen) == 0)
+ raid_setup_args.noautodetect = 1;
+ pos += wlen+1;
+ }
+ raid_setup_args.set = 1;
+ return 1;
+}
+__setup("raid=", raid_setup);
+#endif
+static void md_geninit (void)
+{
+ int i;
+
+ for(i = 0; i < MAX_MD_DEVS; i++) {
+ md_blocksizes[i] = 1024;
+ md_size[i] = 0;
+ md_hardsect_sizes[i] = 512;
+ md_maxreadahead[i] = MD_READAHEAD;
+ register_disk(&md_gendisk, MKDEV(MAJOR_NR,i), 1, &md_fops, 0);
+ }
+ blksize_size[MAJOR_NR] = md_blocksizes;
+ blk_size[MAJOR_NR] = md_size;
+ max_readahead[MAJOR_NR] = md_maxreadahead;
+ hardsect_size[MAJOR_NR] = md_hardsect_sizes;
+
+ printk("md.c: sizeof(mdp_super_t) = %d\n", (int)sizeof(mdp_super_t));
+
+#ifdef CONFIG_PROC_FS
+ create_proc_read_entry("mdstat", 0, NULL, md_status_read_proc, NULL);
+#endif
+}
+void hsm_init (void);
+void translucent_init (void);
+void linear_init (void);
+void raid0_init (void);
+void raid1_init (void);
+void raid5_init (void);
+
+int md__init md_init (void)
+{
+ static char * name = "mdrecoveryd";
+
+ printk (KERN_INFO "md driver %d.%d.%d MAX_MD_DEVS=%d, MAX_REAL=%d\n",
+ MD_MAJOR_VERSION, MD_MINOR_VERSION,
+ MD_PATCHLEVEL_VERSION, MAX_MD_DEVS, MAX_REAL);
+
+ if (devfs_register_blkdev (MAJOR_NR, "md", &md_fops))
+ {
+ printk (KERN_ALERT "Unable to get major %d for md\n", MAJOR_NR);
+ return (-1);
+ }
+ devfs_handle = devfs_mk_dir (NULL, "md", NULL);
+ devfs_register_series (devfs_handle, "%u",MAX_MD_DEVS,DEVFS_FL_DEFAULT,
+ MAJOR_NR, 0, S_IFBLK | S_IRUSR | S_IWUSR,
+ &md_fops, NULL);
+
+ /* forward all md request to md_make_request */
+ blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR), md_make_request);
+
+
+ read_ahead[MAJOR_NR] = INT_MAX;
+ md_gendisk.next = gendisk_head;
+
+ gendisk_head = &md_gendisk;
+
+ md_recovery_thread = md_register_thread(md_do_recovery, NULL, name);
+ if (!md_recovery_thread)
+ printk(KERN_ALERT "bug: couldn't allocate md_recovery_thread\n");
+
+ md_register_reboot_notifier(&md_notifier);
+ raid_table_header = register_sysctl_table(raid_root_table, 1);
+
+#ifdef CONFIG_MD_LINEAR
+ linear_init ();
+#endif
+#ifdef CONFIG_MD_RAID0
+ raid0_init ();
+#endif
+#ifdef CONFIG_MD_RAID1
+ raid1_init ();
+#endif
+#ifdef CONFIG_MD_RAID5
+ raid5_init ();
+#endif
+ md_geninit();
+ return (0);
+}
+
+#ifdef CONFIG_MD_BOOT
+#define MAX_MD_BOOT_DEVS 8
+struct {
+ unsigned long set;
+ int pers[MAX_MD_BOOT_DEVS];
+ int chunk[MAX_MD_BOOT_DEVS];
+ kdev_t devices[MAX_MD_BOOT_DEVS][MAX_REAL];
+} md_setup_args md__initdata;
+
+/*
+ * Parse the command-line parameters given our kernel, but do not
+ * actually try to invoke the MD device now; that is handled by
+ * md_setup_drive after the low-level disk drivers have initialised.
+ *
+ * 27/11/1999: Fixed to work correctly with the 2.3 kernel (which
+ * assigns the task of parsing integer arguments to the
+ * invoked program now). Added ability to initialise all
+ * the MD devices (by specifying multiple "md=" lines)
+ * instead of just one. -- KTK
+ * 18May2000: Added support for persistant-superblock arrays:
+ * md=n,0,factor,fault,device-list uses RAID0 for device n
+ * md=n,-1,factor,fault,device-list uses LINEAR for device n
+ * md=n,device-list reads a RAID superblock from the devices
+ * elements in device-list are read by name_to_kdev_t so can be
+ * a hex number or something like /dev/hda1 /dev/sdb
+ */
+extern kdev_t name_to_kdev_t(char *line) md__init;
+static int md__init md_setup(char *str)
+{
+ int minor, level, factor, fault, i=0;
+ kdev_t device;
+ char *devnames, *pername = "";
+
+ if(get_option(&str, &minor) != 2) { /* MD Number */
+ printk("md: Too few arguments supplied to md=.\n");
+ return 0;
+ }
+ if (minor >= MAX_MD_BOOT_DEVS) {
+ printk ("md: Minor device number too high.\n");
+ return 0;
+ } else if (md_setup_args.set & (1 << minor)) {
+ printk ("md: Warning - md=%d,... has been specified twice;\n"
+ " will discard the first definition.\n", minor);
+ }
+ switch(get_option(&str, &level)) { /* RAID Personality */
+ case 2: /* could be 0 or -1.. */
+ if (level == 0 || level == -1) {
+ if (get_option(&str, &factor) != 2 || /* Chunk Size */
+ get_option(&str, &fault) != 2) {
+ printk("md: Too few arguments supplied to md=.\n");
+ return 0;
+ }
+ md_setup_args.pers[minor] = level;
+ md_setup_args.chunk[minor] = 1 << (factor+12);
+ switch(level) {
+ case -1:
+ level = LINEAR;
+ pername = "linear";
+ break;
+ case 0:
+ level = RAID0;
+ pername = "raid0";
+ break;
+ default:
+ printk ("md: The kernel has not been configured for raid%d"
+ " support!\n", level);
+ return 0;
+ }
+ md_setup_args.pers[minor] = level;
+ break;
+ }
+ /* FALL THROUGH */
+ case 1: /* the first device is numeric */
+ md_setup_args.devices[minor][i++] = level;
+ /* FALL THROUGH */
+ case 0:
+ md_setup_args.pers[minor] = 0;
+ pername="super-block";
+ }
+ devnames = str;
+ for (; i<MAX_REAL && str; i++) {
+ if ((device = name_to_kdev_t(str))) {
+ md_setup_args.devices[minor][i] = device;
+ } else {
+ printk ("md: Unknown device name, %s.\n", str);
+ return 0;
+ }
+ if ((str = strchr(str, ',')) != NULL)
+ str++;
+ }
+ if (!i) {
+ printk ("md: No devices specified for md%d?\n", minor);


+ return 0;
+ }
+

+ printk ("md: Will configure md%d (%s) from %s, below.\n",
+ minor, pername, devnames);
+ md_setup_args.devices[minor][i] = (kdev_t) 0;
+ md_setup_args.set |= (1 << minor);


+ return 1;
+}
+

+void md__init md_setup_drive(void)
+{
+ int minor, i;
+ kdev_t dev;
+ mddev_t*mddev;
+
+ for (minor = 0; minor < MAX_MD_BOOT_DEVS; minor++) {
+ mdu_disk_info_t dinfo;
+ int err=0;
+ if (!(md_setup_args.set & (1 << minor)))
+ continue;
+ printk("md: Loading md%d.\n", minor);
+ if (mddev_map[minor].mddev) {
+ printk(".. md%d already autodetected - use raid=noautodetect\n", minor);
+ continue;
+ }
+ mddev = alloc_mddev(MKDEV(MD_MAJOR,minor));
+ if (md_setup_args.pers[minor]) {
+ /* non-persistent */
+ mdu_array_info_t ainfo;
+ ainfo.level = pers_to_level(md_setup_args.pers[minor]);
+ ainfo.size = 0;
+ ainfo.nr_disks =0;
+ ainfo.raid_disks =0;
+ ainfo.md_minor =minor;
+ ainfo.not_persistent = 1;
+
+ ainfo.state = MD_SB_CLEAN;
+ ainfo.active_disks = 0;
+ ainfo.working_disks = 0;
+ ainfo.failed_disks = 0;
+ ainfo.spare_disks = 0;
+ ainfo.layout = 0;
+ ainfo.chunk_size = md_setup_args.chunk[minor];
+ err = set_array_info(mddev, &ainfo);
+ for (i=0; !err && (dev = md_setup_args.devices[minor][i]); i++) {
+ dinfo.number = i;
+ dinfo.raid_disk = i;
+ dinfo.state = (1<<MD_DISK_ACTIVE)|(1<<MD_DISK_SYNC);
+ dinfo.major = MAJOR(dev);
+ dinfo.minor = MINOR(dev);
+ mddev->sb->nr_disks++;
+ mddev->sb->raid_disks++;
+ mddev->sb->active_disks++;
+ mddev->sb->working_disks++;
+ err = add_new_disk (mddev, &dinfo);
+ }
+ } else {
+ /* persistent */
+ for (i = 0; (dev = md_setup_args.devices[minor][i]); i++) {
+ dinfo.major = MAJOR(dev);
+ dinfo.minor = MINOR(dev);
+ add_new_disk (mddev, &dinfo);
+ }
+ }
+ if (!err)
+ err = do_md_run(mddev);
+ if (err) {
+ mddev->sb_dirty = 0;
+ do_md_stop(mddev, 0);
+ printk("md: starting md%d failed\n", minor);
+ }
+ }
+}
+
+__setup("md=", md_setup);
+#endif
+
+#ifdef MODULE
+int init_module (void)
+{
+ return md_init();
+}
+
+static void free_device_names(void)
+{
+ while (device_names.next != &device_names) {
+ struct list_head *tmp = device_names.next;
+ list_del(tmp);
+ kfree(tmp);
+ }
+}


+
+
+void cleanup_module (void)
+{

+ struct gendisk **gendisk_ptr;
+
+ md_unregister_thread(md_recovery_thread);
+ devfs_unregister(devfs_handle);
+
+ devfs_unregister_blkdev(MAJOR_NR,"md");
+ unregister_reboot_notifier(&md_notifier);
+ unregister_sysctl_table(raid_table_header);
+#ifdef CONFIG_PROC_FS
+ remove_proc_entry("mdstat", NULL);
+#endif
+
+ gendisk_ptr = &gendisk_head;
+ while (*gendisk_ptr) {
+ if (*gendisk_ptr == &md_gendisk) {
+ *gendisk_ptr = md_gendisk.next;
+ break;
+ }
+ gendisk_ptr = & (*gendisk_ptr)->next;
+ }
+ blk_dev[MAJOR_NR].queue = NULL;


+ blksize_size[MAJOR_NR] = NULL;
+ blk_size[MAJOR_NR] = NULL;

+ max_readahead[MAJOR_NR] = NULL;
+ hardsect_size[MAJOR_NR] = NULL;
+
+ free_device_names();
+
+}
+#endif
+
+__initcall(md_init);
+#ifdef CONFIG_AUTODETECT_RAID
+__initcall(md_run_setup);
+#endif
+
+MD_EXPORT_SYMBOL(md_size);
+MD_EXPORT_SYMBOL(register_md_personality);
+MD_EXPORT_SYMBOL(unregister_md_personality);
+MD_EXPORT_SYMBOL(partition_name);
+MD_EXPORT_SYMBOL(md_error);
+MD_EXPORT_SYMBOL(md_do_sync);
+MD_EXPORT_SYMBOL(md_sync_acct);
+MD_EXPORT_SYMBOL(md_done_sync);
+MD_EXPORT_SYMBOL(md_recover_arrays);
+MD_EXPORT_SYMBOL(md_register_thread);
+MD_EXPORT_SYMBOL(md_unregister_thread);
+MD_EXPORT_SYMBOL(md_update_sb);
+MD_EXPORT_SYMBOL(md_wakeup_thread);
+MD_EXPORT_SYMBOL(md_print_devices);
+MD_EXPORT_SYMBOL(find_rdev_nr);
+MD_EXPORT_SYMBOL(md_interrupt_thread);
+MD_EXPORT_SYMBOL(mddev_map);
+MD_EXPORT_SYMBOL(md_check_ordering);
+
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/md/raid0.c linux/drivers/md/raid0.c
--- v2.4.0-test8/linux/drivers/md/raid0.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/md/raid0.c Thu Aug 10 12:35:50 2000
@@ -0,0 +1,356 @@
+/*
+ raid0.c : Multiple Devices driver for Linux


+ Copyright (C) 1994-96 Marc ZYNGIER
+ <zyn...@ufr-info-p7.ibp.fr> or
+ <m...@gloups.fdn.fr>

+ Copyright (C) 1999, 2000 Ingo Molnar, Red Hat
+
+
+ RAID-0 management functions.


+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ You should have received a copy of the GNU General Public License
+ (for example /usr/src/linux/COPYING); if not, write to the Free
+ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/module.h>

+#include <linux/raid/raid0.h>


+
+#define MAJOR_NR MD_MAJOR
+#define MD_DRIVER
+#define MD_PERSONALITY
+

+static int create_strip_zones (mddev_t *mddev)
+{
+ int i, c, j, j1, j2;
+ unsigned long current_offset, curr_zone_offset;
+ raid0_conf_t *conf = mddev_to_conf(mddev);
+ mdk_rdev_t *smallest, *rdev1, *rdev2, *rdev;
+
+ /*
+ * The number of 'same size groups'
+ */
+ conf->nr_strip_zones = 0;
+
+ ITERATE_RDEV_ORDERED(mddev,rdev1,j1) {
+ printk("raid0: looking at %s\n", partition_name(rdev1->dev));
+ c = 0;
+ ITERATE_RDEV_ORDERED(mddev,rdev2,j2) {
+ printk("raid0: comparing %s(%ld) with %s(%ld)\n", partition_name(rdev1->dev), rdev1->size, partition_name(rdev2->dev), rdev2->size);
+ if (rdev2 == rdev1) {
+ printk("raid0: END\n");
+ break;
+ }
+ if (rdev2->size == rdev1->size)
+ {
+ /*
+ * Not unique, dont count it as a new
+ * group
+ */
+ printk("raid0: EQUAL\n");
+ c = 1;
+ break;
+ }
+ printk("raid0: NOT EQUAL\n");
+ }
+ if (!c) {
+ printk("raid0: ==> UNIQUE\n");
+ conf->nr_strip_zones++;
+ printk("raid0: %d zones\n", conf->nr_strip_zones);
+ }
+ }
+ printk("raid0: FINAL %d zones\n", conf->nr_strip_zones);
+
+ conf->strip_zone = vmalloc(sizeof(struct strip_zone)*
+ conf->nr_strip_zones);
+ if (!conf->strip_zone)


+ return 1;
+
+

+ conf->smallest = NULL;

+ current_offset = 0;
+ curr_zone_offset = 0;
+
+ for (i = 0; i < conf->nr_strip_zones; i++)
+ {
+ struct strip_zone *zone = conf->strip_zone + i;
+
+ printk("zone %d\n", i);
+ zone->dev_offset = current_offset;
+ smallest = NULL;


+ c = 0;
+

+ ITERATE_RDEV_ORDERED(mddev,rdev,j) {
+
+ printk(" checking %s ...", partition_name(rdev->dev));
+ if (rdev->size > current_offset)
+ {
+ printk(" contained as device %d\n", c);
+ zone->dev[c] = rdev;
+ c++;
+ if (!smallest || (rdev->size <smallest->size)) {
+ smallest = rdev;
+ printk(" (%ld) is smallest!.\n", rdev->size);
+ }
+ } else
+ printk(" nope.\n");
+ }
+
+ zone->nb_dev = c;
+ zone->size = (smallest->size - current_offset) * c;
+ printk(" zone->nb_dev: %d, size: %ld\n",zone->nb_dev,zone->size);
+
+ if (!conf->smallest || (zone->size < conf->smallest->size))
+ conf->smallest = zone;
+
+ zone->zone_offset = curr_zone_offset;
+ curr_zone_offset += zone->size;
+
+ current_offset = smallest->size;
+ printk("current zone offset: %ld\n", current_offset);
+ }
+ printk("done.\n");


+ return 0;
+}
+

+static int raid0_run (mddev_t *mddev)
+{
+ unsigned long cur=0, i=0, size, zone0_size, nb_zone;
+ raid0_conf_t *conf;
+
+ MOD_INC_USE_COUNT;
+
+ conf = vmalloc(sizeof (raid0_conf_t));


+ if (!conf)
+ goto out;

+ mddev->private = (void *)conf;
+
+ if (md_check_ordering(mddev)) {
+ printk("raid0: disks are not ordered, aborting!\n");
+ goto out_free_conf;
+ }
+
+ if (create_strip_zones (mddev))
+ goto out_free_conf;
+
+ printk("raid0 : md_size is %d blocks.\n", md_size[mdidx(mddev)]);
+ printk("raid0 : conf->smallest->size is %ld blocks.\n", conf->smallest->size);
+ nb_zone = md_size[mdidx(mddev)]/conf->smallest->size +
+ (md_size[mdidx(mddev)] % conf->smallest->size ? 1 : 0);
+ printk("raid0 : nb_zone is %ld.\n", nb_zone);
+ conf->nr_zones = nb_zone;
+
+ printk("raid0 : Allocating %ld bytes for hash.\n",
+ nb_zone*sizeof(struct raid0_hash));
+
+ conf->hash_table = vmalloc (sizeof (struct raid0_hash)*nb_zone);
+ if (!conf->hash_table)
+ goto out_free_zone_conf;
+ size = conf->strip_zone[cur].size;
+
+ i = 0;
+ while (cur < conf->nr_strip_zones) {
+ conf->hash_table[i].zone0 = conf->strip_zone + cur;
+
+ /*
+ * If we completely fill the slot
+ */
+ if (size >= conf->smallest->size) {
+ conf->hash_table[i++].zone1 = NULL;


+ size -= conf->smallest->size;
+

+ if (!size) {
+ if (++cur == conf->nr_strip_zones)
+ continue;
+ size = conf->strip_zone[cur].size;
+ }
+ continue;
+ }
+ if (++cur == conf->nr_strip_zones) {
+ /*
+ * Last dev, set unit1 as NULL
+ */
+ conf->hash_table[i].zone1=NULL;
+ continue;
+ }
+
+ /*
+ * Here we use a 2nd dev to fill the slot
+ */
+ zone0_size = size;
+ size = conf->strip_zone[cur].size;
+ conf->hash_table[i++].zone1 = conf->strip_zone + cur;
+ size -= (conf->smallest->size - zone0_size);


+ }
+ return 0;
+

+out_free_zone_conf:
+ vfree(conf->strip_zone);
+ conf->strip_zone = NULL;
+
+out_free_conf:
+ vfree(conf);
+ mddev->private = NULL;
+out:


+ MOD_DEC_USE_COUNT;
+ return 1;
+}
+

+static int raid0_stop (mddev_t *mddev)
+{
+ raid0_conf_t *conf = mddev_to_conf(mddev);
+
+ vfree (conf->hash_table);
+ conf->hash_table = NULL;
+ vfree (conf->strip_zone);
+ conf->strip_zone = NULL;
+ vfree (conf);
+ mddev->private = NULL;
+
+ MOD_DEC_USE_COUNT;


+ return 0;
+}
+
+/*

+ * FIXME - We assume some things here :
+ * - requested buffers NEVER bigger than chunk size,
+ * - requested buffers NEVER cross stripes limits.
+ * Of course, those facts may not be valid anymore (and surely won't...)
+ * Hey guys, there's some work out there ;-)
+ */
+static int raid0_make_request (mddev_t *mddev,


+ int rw, struct buffer_head * bh)
+{

+ unsigned int sect_in_chunk, chunksize_bits, chunk_size;
+ raid0_conf_t *conf = mddev_to_conf(mddev);
+ struct raid0_hash *hash;
+ struct strip_zone *zone;
+ mdk_rdev_t *tmp_dev;
+ unsigned long chunk, block, rsect;
+
+ chunk_size = mddev->param.chunk_size >> 10;
+ chunksize_bits = ffz(~chunk_size);


+ block = bh->b_rsector >> 1;

+ hash = conf->hash_table + block / conf->smallest->size;
+
+ /* Sanity check */
+ if (chunk_size < (block % chunk_size) + (bh->b_size >> 10))
+ goto bad_map;
+
+ if (!hash)
+ goto bad_hash;
+
+ if (!hash->zone0)
+ goto bad_zone0;
+
+ if (block >= (hash->zone0->size + hash->zone0->zone_offset)) {
+ if (!hash->zone1)
+ goto bad_zone1;
+ zone = hash->zone1;
+ } else
+ zone = hash->zone0;
+
+ sect_in_chunk = bh->b_rsector & ((chunk_size<<1) -1);
+ chunk = (block - zone->zone_offset) / (zone->nb_dev << chunksize_bits);
+ tmp_dev = zone->dev[(block >> chunksize_bits) % zone->nb_dev];
+ rsect = (((chunk << chunksize_bits) + zone->dev_offset)<<1)
+ + sect_in_chunk;
+
+ /*
+ * The new BH_Lock semantics in ll_rw_blk.c guarantee that this
+ * is the only IO operation happening on this bh.
+ */


+ bh->b_rdev = tmp_dev->dev;

+ bh->b_rsector = rsect;
+
+ /*
+ * Let the main block layer submit the IO and resolve recursion:
+ */
+ return 1;
+
+bad_map:
+ printk ("raid0_make_request bug: can't convert block across chunks or bigger than %dk %ld %d\n", chunk_size, bh->b_rsector, bh->b_size >> 10);
+ return -1;
+bad_hash:
+ printk("raid0_make_request bug: hash==NULL for block %ld\n", block);
+ return -1;
+bad_zone0:
+ printk ("raid0_make_request bug: hash->zone0==NULL for block %ld\n", block);
+ return -1;
+bad_zone1:
+ printk ("raid0_make_request bug: hash->zone1==NULL for block %ld\n", block);


+ return -1;
+}
+

+static int raid0_status (char *page, mddev_t *mddev)


+{
+ int sz = 0;

+#undef MD_DEBUG
+#ifdef MD_DEBUG
+ int j, k;
+ raid0_conf_t *conf = mddev_to_conf(mddev);
+
+ sz += sprintf(page + sz, " ");


+ for (j = 0; j < conf->nr_zones; j++) {

+ sz += sprintf(page + sz, "[z%d",
+ conf->hash_table[j].zone0 - conf->strip_zone);
+ if (conf->hash_table[j].zone1)
+ sz += sprintf(page+sz, "/z%d] ",
+ conf->hash_table[j].zone1 - conf->strip_zone);


+ else
+ sz += sprintf(page+sz, "] ");
+ }
+

+ sz += sprintf(page + sz, "\n");
+
+ for (j = 0; j < conf->nr_strip_zones; j++) {
+ sz += sprintf(page + sz, " z%d=[", j);
+ for (k = 0; k < conf->strip_zone[j].nb_dev; k++)
+ sz += sprintf (page+sz, "%s/", partition_name(
+ conf->strip_zone[j].dev[k]->dev));
+ sz--;
+ sz += sprintf (page+sz, "] zo=%d do=%d s=%d\n",
+ conf->strip_zone[j].zone_offset,
+ conf->strip_zone[j].dev_offset,
+ conf->strip_zone[j].size);
+ }
+#endif
+ sz += sprintf(page + sz, " %dk chunks", mddev->param.chunk_size/1024);


+ return sz;
+}
+

+static mdk_personality_t raid0_personality=
+{
+ name: "raid0",
+ make_request: raid0_make_request,
+ run: raid0_run,
+ stop: raid0_stop,
+ status: raid0_status,


+};
+
+#ifndef MODULE
+

+void raid0_init (void)
+{
+ register_md_personality (RAID0, &raid0_personality);


+}
+
+#else
+
+int init_module (void)
+{

+ return (register_md_personality (RAID0, &raid0_personality));


+}
+
+void cleanup_module (void)
+{

+ unregister_md_personality (RAID0);
+}
+
+#endif
+
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/md/raid1.c linux/drivers/md/raid1.c
--- v2.4.0-test8/linux/drivers/md/raid1.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/md/raid1.c Mon Aug 14 08:26:34 2000
@@ -0,0 +1,1897 @@
+/*
+ * raid1.c : Multiple Devices driver for Linux
+ *
+ * Copyright (C) 1999, 2000 Ingo Molnar, Red Hat
+ *
+ * Copyright (C) 1996, 1997, 1998 Ingo Molnar, Miguel de Icaza, Gadi Oxman
+ *
+ * RAID-1 management functions.
+ *
+ * Better read-balancing code written by Mika Kuoppala <mi...@iki.fi>, 2000
+ *
+ * Fixes to reconstruction by Jakob Řstergaard" <ja...@ostenfeld.dk>
+ * Various fixes by Neil Brown <ne...@cse.unsw.edu.au>
+ *
+ * This program is free software; you can redistribute it and/or modify


+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *

+ * You should have received a copy of the GNU General Public License

+ * (for example /usr/src/linux/COPYING); if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.


+ */
+
+#include <linux/module.h>

+#include <linux/malloc.h>
+#include <linux/raid/raid1.h>
+#include <asm/atomic.h>


+
+#define MAJOR_NR MD_MAJOR
+#define MD_DRIVER
+#define MD_PERSONALITY
+

+#define MAX_WORK_PER_DISK 128
+
+/*
+ * The following can be used to debug the driver
+ */
+#define RAID1_DEBUG 0
+
+#if RAID1_DEBUG
+#define PRINTK(x...) printk(x)
+#define inline
+#define __inline__
+#else
+#define PRINTK(x...) do { } while (0)
+#endif
+
+
+static mdk_personality_t raid1_personality;
+static md_spinlock_t retry_list_lock = MD_SPIN_LOCK_UNLOCKED;
+struct raid1_bh *raid1_retry_list = NULL, **raid1_retry_tail;
+
+static struct buffer_head *raid1_alloc_bh(raid1_conf_t *conf, int cnt)
+{
+ /* return a linked list of "cnt" struct buffer_heads.
+ * don't take any off the free list unless we know we can
+ * get all we need, otherwise we could deadlock
+ */
+ struct buffer_head *bh=NULL;
+
+ while(cnt) {
+ struct buffer_head *t;
+ md_spin_lock_irq(&conf->device_lock);
+ if (conf->freebh_cnt >= cnt)
+ while (cnt) {
+ t = conf->freebh;
+ conf->freebh = t->b_next;
+ t->b_next = bh;
+ bh = t;
+ t->b_state = 0;
+ conf->freebh_cnt--;
+ cnt--;
+ }
+ md_spin_unlock_irq(&conf->device_lock);
+ if (cnt == 0)
+ break;
+ t = (struct buffer_head *)kmalloc(sizeof(struct buffer_head), GFP_BUFFER);
+ if (t) {
+ memset(t, 0, sizeof(*t));
+ t->b_next = bh;
+ bh = t;
+ cnt--;
+ } else {
+ PRINTK("waiting for %d bh\n", cnt);
+ wait_event(conf->wait_buffer, conf->freebh_cnt >= cnt);
+ }
+ }
+ return bh;
+}
+
+static inline void raid1_free_bh(raid1_conf_t *conf, struct buffer_head *bh)
+{
+ md_spin_lock_irq(&conf->device_lock);
+ while (bh) {
+ struct buffer_head *t = bh;
+ bh=bh->b_next;
+ if (t->b_pprev == NULL)
+ kfree(t);
+ else {
+ t->b_next= conf->freebh;
+ conf->freebh = t;
+ conf->freebh_cnt++;
+ }
+ }
+ md_spin_unlock_irq(&conf->device_lock);
+ wake_up(&conf->wait_buffer);
+}
+
+static int raid1_grow_bh(raid1_conf_t *conf, int cnt)
+{
+ /* allocate cnt buffer_heads, possibly less if kalloc fails */


+ int i = 0;
+

+ while (i < cnt) {
+ struct buffer_head *bh;
+ bh = kmalloc(sizeof(*bh), GFP_KERNEL);
+ if (!bh) break;
+ memset(bh, 0, sizeof(*bh));
+
+ md_spin_lock_irq(&conf->device_lock);
+ bh->b_pprev = &conf->freebh;
+ bh->b_next = conf->freebh;
+ conf->freebh = bh;
+ conf->freebh_cnt++;
+ md_spin_unlock_irq(&conf->device_lock);
+
+ i++;
+ }
+ return i;
+}
+
+static int raid1_shrink_bh(raid1_conf_t *conf, int cnt)
+{
+ /* discard cnt buffer_heads, if we can find them */


+ int i = 0;
+

+ md_spin_lock_irq(&conf->device_lock);
+ while ((i < cnt) && conf->freebh) {
+ struct buffer_head *bh = conf->freebh;
+ conf->freebh = bh->b_next;
+ kfree(bh);
+ i++;
+ conf->freebh_cnt--;
+ }
+ md_spin_unlock_irq(&conf->device_lock);
+ return i;
+}
+
+
+static struct raid1_bh *raid1_alloc_r1bh(raid1_conf_t *conf)
+{
+ struct raid1_bh *r1_bh = NULL;
+
+ do {
+ md_spin_lock_irq(&conf->device_lock);
+ if (conf->freer1) {
+ r1_bh = conf->freer1;
+ conf->freer1 = r1_bh->next_r1;
+ r1_bh->next_r1 = NULL;
+ r1_bh->state = 0;
+ r1_bh->bh_req.b_state = 0;
+ }
+ md_spin_unlock_irq(&conf->device_lock);
+ if (r1_bh)
+ return r1_bh;
+ r1_bh = (struct raid1_bh *) kmalloc(sizeof(struct raid1_bh),
+ GFP_BUFFER);
+ if (r1_bh) {
+ memset(r1_bh, 0, sizeof(*r1_bh));
+ return r1_bh;
+ }
+ wait_event(conf->wait_buffer, conf->freer1);
+ } while (1);
+}
+
+static inline void raid1_free_r1bh(struct raid1_bh *r1_bh)
+{
+ struct buffer_head *bh = r1_bh->mirror_bh_list;
+ raid1_conf_t *conf = mddev_to_conf(r1_bh->mddev);
+
+ r1_bh->mirror_bh_list = NULL;
+
+ if (test_bit(R1BH_PreAlloc, &r1_bh->state)) {
+ md_spin_lock_irq(&conf->device_lock);
+ r1_bh->next_r1 = conf->freer1;
+ conf->freer1 = r1_bh;
+ md_spin_unlock_irq(&conf->device_lock);
+ } else {
+ kfree(r1_bh);
+ }
+ raid1_free_bh(conf, bh);
+}
+
+static int raid1_grow_r1bh (raid1_conf_t *conf, int cnt)
+{


+ int i = 0;
+

+ while (i < cnt) {
+ struct raid1_bh *r1_bh;
+ r1_bh = (struct raid1_bh*)kmalloc(sizeof(*r1_bh), GFP_KERNEL);
+ if (!r1_bh)
+ break;
+ memset(r1_bh, 0, sizeof(*r1_bh));
+
+ md_spin_lock_irq(&conf->device_lock);
+ set_bit(R1BH_PreAlloc, &r1_bh->state);
+ r1_bh->next_r1 = conf->freer1;
+ conf->freer1 = r1_bh;
+ md_spin_unlock_irq(&conf->device_lock);
+
+ i++;
+ }
+ return i;
+}
+
+static void raid1_shrink_r1bh(raid1_conf_t *conf)
+{
+ md_spin_lock_irq(&conf->device_lock);
+ while (conf->freer1) {
+ struct raid1_bh *r1_bh = conf->freer1;
+ conf->freer1 = r1_bh->next_r1;
+ kfree(r1_bh);
+ }
+ md_spin_unlock_irq(&conf->device_lock);
+}
+
+
+
+static inline void raid1_free_buf(struct raid1_bh *r1_bh)
+{
+ struct buffer_head *bh = r1_bh->mirror_bh_list;
+ raid1_conf_t *conf = mddev_to_conf(r1_bh->mddev);
+ r1_bh->mirror_bh_list = NULL;
+
+ md_spin_lock_irq(&conf->device_lock);
+ r1_bh->next_r1 = conf->freebuf;
+ conf->freebuf = r1_bh;
+ md_spin_unlock_irq(&conf->device_lock);
+ raid1_free_bh(conf, bh);
+}
+
+static struct raid1_bh *raid1_alloc_buf(raid1_conf_t *conf)
+{
+ struct raid1_bh *r1_bh;
+
+ md_spin_lock_irq(&conf->device_lock);
+ wait_event_lock_irq(conf->wait_buffer, conf->freebuf, conf->device_lock);
+ r1_bh = conf->freebuf;
+ conf->freebuf = r1_bh->next_r1;
+ r1_bh->next_r1= NULL;
+ md_spin_unlock_irq(&conf->device_lock);
+
+ return r1_bh;
+}
+
+static int raid1_grow_buffers (raid1_conf_t *conf, int cnt)
+{


+ int i = 0;
+

+ md_spin_lock_irq(&conf->device_lock);
+ while (i < cnt) {
+ struct raid1_bh *r1_bh;
+ struct page *page;
+


+ page = alloc_page(GFP_KERNEL);
+ if (!page)

+ break;
+
+ r1_bh = (struct raid1_bh *) kmalloc(sizeof(*r1_bh), GFP_KERNEL);
+ if (!r1_bh) {
+ __free_page(page);
+ break;
+ }
+ memset(r1_bh, 0, sizeof(*r1_bh));
+ r1_bh->bh_req.b_page = page;
+ r1_bh->bh_req.b_data = page_address(page);
+ r1_bh->next_r1 = conf->freebuf;
+ conf->freebuf = r1_bh;
+ i++;
+ }
+ md_spin_unlock_irq(&conf->device_lock);
+ return i;
+}
+
+static void raid1_shrink_buffers (raid1_conf_t *conf)
+{
+ md_spin_lock_irq(&conf->device_lock);
+ while (conf->freebuf) {
+ struct raid1_bh *r1_bh = conf->freebuf;
+ conf->freebuf = r1_bh->next_r1;
+ __free_page(r1_bh->bh_req.b_page);
+ kfree(r1_bh);
+ }
+ md_spin_unlock_irq(&conf->device_lock);
+}
+
+static int raid1_map (mddev_t *mddev, kdev_t *rdev, unsigned long size)
+{
+ raid1_conf_t *conf = mddev_to_conf(mddev);
+ int i, disks = MD_SB_DISKS;
+
+ /*
+ * Later we do read balancing on the read side
+ * now we use the first available disk.
+ */
+
+ for (i = 0; i < disks; i++) {
+ if (conf->mirrors[i].operational) {
+ *rdev = conf->mirrors[i].dev;
+ return (0);
+ }
+ }
+
+ printk (KERN_ERR "raid1_map(): huh, no more operational devices?\n");


+ return (-1);
+}
+

+static void raid1_reschedule_retry (struct raid1_bh *r1_bh)


+{
+ unsigned long flags;

+ mddev_t *mddev = r1_bh->mddev;
+ raid1_conf_t *conf = mddev_to_conf(mddev);
+
+ md_spin_lock_irqsave(&retry_list_lock, flags);
+ if (raid1_retry_list == NULL)
+ raid1_retry_tail = &raid1_retry_list;
+ *raid1_retry_tail = r1_bh;
+ raid1_retry_tail = &r1_bh->next_r1;
+ r1_bh->next_r1 = NULL;
+ md_spin_unlock_irqrestore(&retry_list_lock, flags);
+ md_wakeup_thread(conf->thread);
+}
+
+
+static void inline io_request_done(unsigned long sector, raid1_conf_t *conf, int phase)


+{
+ unsigned long flags;

+ spin_lock_irqsave(&conf->segment_lock, flags);
+ if (sector < conf->start_active)
+ conf->cnt_done--;
+ else if (sector >= conf->start_future && conf->phase == phase)
+ conf->cnt_future--;
+ else if (!--conf->cnt_pending)
+ wake_up(&conf->wait_ready);
+
+ spin_unlock_irqrestore(&conf->segment_lock, flags);
+}
+
+static void inline sync_request_done (unsigned long sector, raid1_conf_t *conf)


+{
+ unsigned long flags;

+ spin_lock_irqsave(&conf->segment_lock, flags);
+ if (sector >= conf->start_ready)
+ --conf->cnt_ready;
+ else if (sector >= conf->start_active) {
+ if (!--conf->cnt_active) {
+ conf->start_active = conf->start_ready;
+ wake_up(&conf->wait_done);
+ }
+ }
+ spin_unlock_irqrestore(&conf->segment_lock, flags);
+}
+
+/*
+ * raid1_end_bh_io() is called when we have finished servicing a mirrored
+ * operation and are ready to return a success/failure code to the buffer
+ * cache layer.
+ */
+static void raid1_end_bh_io (struct raid1_bh *r1_bh, int uptodate)
+{
+ struct buffer_head *bh = r1_bh->master_bh;
+
+ io_request_done(bh->b_rsector, mddev_to_conf(r1_bh->mddev),
+ test_bit(R1BH_SyncPhase, &r1_bh->state));
+
+ bh->b_end_io(bh, uptodate);
+ raid1_free_r1bh(r1_bh);
+}
+void raid1_end_request (struct buffer_head *bh, int uptodate)
+{
+ struct raid1_bh * r1_bh = (struct raid1_bh *)(bh->b_private);
+
+ /*
+ * this branch is our 'one mirror IO has finished' event handler:
+ */
+ if (!uptodate)
+ md_error (mddev_to_kdev(r1_bh->mddev), bh->b_dev);
+ else
+ /*
+ * Set R1BH_Uptodate in our master buffer_head, so that
+ * we will return a good error code for to the higher
+ * levels even if IO on some other mirrored buffer fails.
+ *
+ * The 'master' represents the complex operation to
+ * user-side. So if something waits for IO, then it will
+ * wait for the 'master' buffer_head.
+ */
+ set_bit (R1BH_Uptodate, &r1_bh->state);
+
+ /*
+ * We split up the read and write side, imho they are
+ * conceptually different.
+ */
+
+ if ( (r1_bh->cmd == READ) || (r1_bh->cmd == READA) ) {
+ /*
+ * we have only one buffer_head on the read side
+ */
+
+ if (uptodate) {
+ raid1_end_bh_io(r1_bh, uptodate);
+ return;
+ }
+ /*
+ * oops, read error:
+ */
+ printk(KERN_ERR "raid1: %s: rescheduling block %lu\n",
+ partition_name(bh->b_dev), bh->b_blocknr);
+ raid1_reschedule_retry(r1_bh);
+ return;
+ }
+
+ /*
+ * WRITE:
+ *
+ * Let's see if all mirrored write operations have finished
+ * already.
+ */
+
+ if (atomic_dec_and_test(&r1_bh->remaining))
+ raid1_end_bh_io(r1_bh, test_bit(R1BH_Uptodate, &r1_bh->state));
+}
+
+/*
+ * This routine returns the disk from which the requested read should
+ * be done. It bookkeeps the last read position for every disk
+ * in array and when new read requests come, the disk which last
+ * position is nearest to the request, is chosen.
+ *
+ * TODO: now if there are 2 mirrors in the same 2 devices, performance
+ * degrades dramatically because position is mirror, not device based.
+ * This should be changed to be device based. Also atomic sequential
+ * reads should be somehow balanced.
+ */
+
+static int raid1_read_balance (raid1_conf_t *conf, struct buffer_head *bh)
+{
+ int new_disk = conf->last_used;
+ const int sectors = bh->b_size >> 9;
+ const unsigned long this_sector = bh->b_rsector;
+ int disk = new_disk;
+ unsigned long new_distance;
+ unsigned long current_distance;
+
+ /*
+ * Check if it is sane at all to balance
+ */
+
+ if (conf->resync_mirrors)
+ goto rb_out;
+
+ if (conf->working_disks < 2) {


+ int i = 0;
+

+ while( !conf->mirrors[new_disk].operational &&
+ (i < MD_SB_DISKS) ) {
+ new_disk = conf->mirrors[new_disk].next;
+ i++;
+ }
+
+ if (i >= MD_SB_DISKS) {
+ /*
+ * This means no working disk was found
+ * Nothing much to do, lets not change anything
+ * and hope for the best...
+ */
+
+ new_disk = conf->last_used;
+ }
+
+ goto rb_out;
+ }
+
+ /*
+ * Don't touch anything for sequential reads.
+ */
+
+ if (this_sector == conf->mirrors[new_disk].head_position)
+ goto rb_out;
+
+ /*
+ * If reads have been done only on a single disk
+ * for a time, lets give another disk a change.
+ * This is for kicking those idling disks so that
+ * they would find work near some hotspot.
+ */
+
+ if (conf->sect_count >= conf->mirrors[new_disk].sect_limit) {
+ conf->sect_count = 0;
+
+ while( new_disk != conf->mirrors[new_disk].next ) {
+ if ((conf->mirrors[new_disk].write_only) ||
+ (!conf->mirrors[new_disk].operational) )
+ continue;
+
+ new_disk = conf->mirrors[new_disk].next;
+ break;
+ }
+
+ goto rb_out;
+ }
+
+ current_distance = abs(this_sector -
+ conf->mirrors[disk].head_position);
+
+ /* Find the disk which is closest */
+
+ while( conf->mirrors[disk].next != conf->last_used ) {
+ disk = conf->mirrors[disk].next;
+
+ if ((conf->mirrors[disk].write_only) ||
+ (!conf->mirrors[disk].operational))
+ continue;
+
+ new_distance = abs(this_sector -
+ conf->mirrors[disk].head_position);
+
+ if (new_distance < current_distance) {
+ conf->sect_count = 0;
+ current_distance = new_distance;
+ new_disk = disk;
+ }
+ }
+
+rb_out:
+ conf->mirrors[new_disk].head_position = this_sector + sectors;
+
+ conf->last_used = new_disk;
+ conf->sect_count += sectors;
+
+ return new_disk;
+}
+
+static int raid1_make_request (mddev_t *mddev, int rw,
+ struct buffer_head * bh)
+{
+ raid1_conf_t *conf = mddev_to_conf(mddev);
+ struct buffer_head *bh_req, *bhl;
+ struct raid1_bh * r1_bh;
+ int disks = MD_SB_DISKS;
+ int i, sum_bhs = 0, sectors;
+ struct mirror_info *mirror;
+
+ if (!buffer_locked(bh))
+ BUG();
+
+/*
+ * make_request() can abort the operation when READA is being
+ * used and no empty request is available.
+ *
+ * Currently, just replace the command with READ/WRITE.
+ */
+ if (rw == READA)
+ rw = READ;
+
+ r1_bh = raid1_alloc_r1bh (conf);
+
+ spin_lock_irq(&conf->segment_lock);
+ wait_event_lock_irq(conf->wait_done,
+ bh->b_rsector < conf->start_active ||
+ bh->b_rsector >= conf->start_future,
+ conf->segment_lock);
+ if (bh->b_rsector < conf->start_active)
+ conf->cnt_done++;
+ else {
+ conf->cnt_future++;
+ if (conf->phase)
+ set_bit(R1BH_SyncPhase, &r1_bh->state);
+ }
+ spin_unlock_irq(&conf->segment_lock);
+
+ /*
+ * i think the read and write branch should be separated completely,
+ * since we want to do read balancing on the read side for example.
+ * Alternative implementations? :) --mingo
+ */
+
+ r1_bh->master_bh = bh;
+ r1_bh->mddev = mddev;
+ r1_bh->cmd = rw;
+
+ sectors = bh->b_size >> 9;
+ if (rw == READ) {
+ /*
+ * read balancing logic:
+ */
+ mirror = conf->mirrors + raid1_read_balance(conf, bh);
+
+ bh_req = &r1_bh->bh_req;
+ memcpy(bh_req, bh, sizeof(*bh));
+ bh_req->b_blocknr = bh->b_rsector * sectors;
+ bh_req->b_dev = mirror->dev;
+ bh_req->b_rdev = mirror->dev;
+ /* bh_req->b_rsector = bh->n_rsector; */
+ bh_req->b_end_io = raid1_end_request;
+ bh_req->b_private = r1_bh;
+ generic_make_request (rw, bh_req);


+ return 0;
+ }
+

+ /*
+ * WRITE:
+ */
+
+ bhl = raid1_alloc_bh(conf, conf->raid_disks);
+ for (i = 0; i < disks; i++) {
+ struct buffer_head *mbh;
+ if (!conf->mirrors[i].operational)
+ continue;
+
+ /*
+ * We should use a private pool (size depending on NR_REQUEST),
+ * to avoid writes filling up the memory with bhs
+ *
+ * Such pools are much faster than kmalloc anyways (so we waste
+ * almost nothing by not using the master bh when writing and
+ * win alot of cleanness) but for now we are cool enough. --mingo
+ *
+ * It's safe to sleep here, buffer heads cannot be used in a shared
+ * manner in the write branch. Look how we lock the buffer at the
+ * beginning of this function to grok the difference ;)
+ */
+ mbh = bhl;
+ if (mbh == NULL) {
+ MD_BUG();
+ break;
+ }
+ bhl = mbh->b_next;
+ mbh->b_next = NULL;
+ mbh->b_this_page = (struct buffer_head *)1;
+
+ /*
+ * prepare mirrored mbh (fields ordered for max mem throughput):
+ */
+ mbh->b_blocknr = bh->b_rsector * sectors;
+ mbh->b_dev = conf->mirrors[i].dev;
+ mbh->b_rdev = conf->mirrors[i].dev;
+ mbh->b_rsector = bh->b_rsector;
+ mbh->b_state = (1<<BH_Req) | (1<<BH_Dirty) |
+ (1<<BH_Mapped) | (1<<BH_Lock);
+
+ atomic_set(&mbh->b_count, 1);
+ mbh->b_size = bh->b_size;
+ mbh->b_page = bh->b_page;
+ mbh->b_data = bh->b_data;
+ mbh->b_list = BUF_LOCKED;
+ mbh->b_end_io = raid1_end_request;
+ mbh->b_private = r1_bh;
+
+ mbh->b_next = r1_bh->mirror_bh_list;
+ r1_bh->mirror_bh_list = mbh;
+ sum_bhs++;
+ }
+ if (bhl) raid1_free_bh(conf,bhl);
+ md_atomic_set(&r1_bh->remaining, sum_bhs);
+
+ /*
+ * We have to be a bit careful about the semaphore above, thats
+ * why we start the requests separately. Since kmalloc() could
+ * fail, sleep and make_request() can sleep too, this is the
+ * safer solution. Imagine, end_request decreasing the semaphore
+ * before we could have set it up ... We could play tricks with
+ * the semaphore (presetting it and correcting at the end if
+ * sum_bhs is not 'n' but we have to do end_request by hand if
+ * all requests finish until we had a chance to set up the
+ * semaphore correctly ... lots of races).
+ */
+ bh = r1_bh->mirror_bh_list;
+ while(bh) {
+ struct buffer_head *bh2 = bh;
+ bh = bh->b_next;
+ generic_make_request(rw, bh2);
+ }
+ return (0);
+}
+
+static int raid1_status (char *page, mddev_t *mddev)
+{
+ raid1_conf_t *conf = mddev_to_conf(mddev);
+ int sz = 0, i;
+
+ sz += sprintf (page+sz, " [%d/%d] [", conf->raid_disks,
+ conf->working_disks);
+ for (i = 0; i < conf->raid_disks; i++)
+ sz += sprintf (page+sz, "%s",
+ conf->mirrors[i].operational ? "U" : "_");
+ sz += sprintf (page+sz, "]");


+ return sz;
+}
+

+static void unlink_disk (raid1_conf_t *conf, int target)
+{
+ int disks = MD_SB_DISKS;
+ int i;
+
+ for (i = 0; i < disks; i++)
+ if (conf->mirrors[i].next == target)
+ conf->mirrors[i].next = conf->mirrors[target].next;
+}
+
+#define LAST_DISK KERN_ALERT \
+"raid1: only one disk left and IO error.\n"
+
+#define NO_SPARE_DISK KERN_ALERT \
+"raid1: no spare disk left, degrading mirror level by one.\n"
+
+#define DISK_FAILED KERN_ALERT \
+"raid1: Disk failure on %s, disabling device. \n" \
+" Operation continuing on %d devices\n"
+
+#define START_SYNCING KERN_ALERT \
+"raid1: start syncing spare disk.\n"
+
+#define ALREADY_SYNCING KERN_INFO \
+"raid1: syncing already in progress.\n"
+
+static void mark_disk_bad (mddev_t *mddev, int failed)
+{
+ raid1_conf_t *conf = mddev_to_conf(mddev);
+ struct mirror_info *mirror = conf->mirrors+failed;
+ mdp_super_t *sb = mddev->sb;
+
+ mirror->operational = 0;
+ unlink_disk(conf, failed);
+ mark_disk_faulty(sb->disks+mirror->number);
+ mark_disk_nonsync(sb->disks+mirror->number);
+ mark_disk_inactive(sb->disks+mirror->number);
+ sb->active_disks--;
+ sb->working_disks--;
+ sb->failed_disks++;
+ mddev->sb_dirty = 1;
+ md_wakeup_thread(conf->thread);
+ conf->working_disks--;
+ printk (DISK_FAILED, partition_name (mirror->dev),
+ conf->working_disks);
+}
+
+static int raid1_error (mddev_t *mddev, kdev_t dev)
+{
+ raid1_conf_t *conf = mddev_to_conf(mddev);
+ struct mirror_info * mirrors = conf->mirrors;
+ int disks = MD_SB_DISKS;
+ int i;
+
+ if (conf->working_disks == 1) {
+ /*
+ * Uh oh, we can do nothing if this is our last disk, but
+ * first check if this is a queued request for a device
+ * which has just failed.
+ */
+ for (i = 0; i < disks; i++) {
+ if (mirrors[i].dev==dev && !mirrors[i].operational)
+ return 0;
+ }
+ printk (LAST_DISK);
+ } else {
+ /*
+ * Mark disk as unusable
+ */
+ for (i = 0; i < disks; i++) {
+ if (mirrors[i].dev==dev && mirrors[i].operational) {
+ mark_disk_bad(mddev, i);


+ break;
+ }
+ }
+ }

+ return 0;
+}
+

+#undef LAST_DISK
+#undef NO_SPARE_DISK
+#undef DISK_FAILED
+#undef START_SYNCING
+
+/*
+ * Insert the spare disk into the drive-ring
+ */
+static void link_disk(raid1_conf_t *conf, struct mirror_info *mirror)
+{
+ int j, next;
+ int disks = MD_SB_DISKS;
+ struct mirror_info *p = conf->mirrors;
+
+ for (j = 0; j < disks; j++, p++)
+ if (p->operational && !p->write_only) {
+ next = p->next;
+ p->next = mirror->raid_disk;
+ mirror->next = next;
+ return;
+ }
+
+ printk("raid1: bug: no read-operational devices\n");
+}
+
+static void print_raid1_conf (raid1_conf_t *conf)
+{
+ int i;
+ struct mirror_info *tmp;
+
+ printk("RAID1 conf printout:\n");
+ if (!conf) {
+ printk("(conf==NULL)\n");
+ return;
+ }
+ printk(" --- wd:%d rd:%d nd:%d\n", conf->working_disks,
+ conf->raid_disks, conf->nr_disks);
+
+ for (i = 0; i < MD_SB_DISKS; i++) {
+ tmp = conf->mirrors + i;
+ printk(" disk %d, s:%d, o:%d, n:%d rd:%d us:%d dev:%s\n",
+ i, tmp->spare,tmp->operational,
+ tmp->number,tmp->raid_disk,tmp->used_slot,
+ partition_name(tmp->dev));
+ }
+}
+
+static int raid1_diskop(mddev_t *mddev, mdp_disk_t **d, int state)
+{
+ int err = 0;
+ int i, failed_disk=-1, spare_disk=-1, removed_disk=-1, added_disk=-1;
+ raid1_conf_t *conf = mddev->private;
+ struct mirror_info *tmp, *sdisk, *fdisk, *rdisk, *adisk;
+ mdp_super_t *sb = mddev->sb;
+ mdp_disk_t *failed_desc, *spare_desc, *added_desc;
+
+ print_raid1_conf(conf);
+ md_spin_lock_irq(&conf->device_lock);
+ /*
+ * find the disk ...
+ */
+ switch (state) {
+
+ case DISKOP_SPARE_ACTIVE:
+
+ /*
+ * Find the failed disk within the RAID1 configuration ...
+ * (this can only be in the first conf->working_disks part)
+ */
+ for (i = 0; i < conf->raid_disks; i++) {
+ tmp = conf->mirrors + i;
+ if ((!tmp->operational && !tmp->spare) ||
+ !tmp->used_slot) {
+ failed_disk = i;
+ break;
+ }
+ }
+ /*
+ * When we activate a spare disk we _must_ have a disk in
+ * the lower (active) part of the array to replace.
+ */
+ if ((failed_disk == -1) || (failed_disk >= conf->raid_disks)) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+ /* fall through */
+
+ case DISKOP_SPARE_WRITE:
+ case DISKOP_SPARE_INACTIVE:
+
+ /*
+ * Find the spare disk ... (can only be in the 'high'
+ * area of the array)
+ */
+ for (i = conf->raid_disks; i < MD_SB_DISKS; i++) {
+ tmp = conf->mirrors + i;
+ if (tmp->spare && tmp->number == (*d)->number) {
+ spare_disk = i;
+ break;
+ }
+ }
+ if (spare_disk == -1) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+ break;
+
+ case DISKOP_HOT_REMOVE_DISK:
+
+ for (i = 0; i < MD_SB_DISKS; i++) {
+ tmp = conf->mirrors + i;
+ if (tmp->used_slot && (tmp->number == (*d)->number)) {
+ if (tmp->operational) {
+ err = -EBUSY;
+ goto abort;
+ }
+ removed_disk = i;
+ break;
+ }
+ }
+ if (removed_disk == -1) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+ break;
+
+ case DISKOP_HOT_ADD_DISK:
+
+ for (i = conf->raid_disks; i < MD_SB_DISKS; i++) {
+ tmp = conf->mirrors + i;
+ if (!tmp->used_slot) {
+ added_disk = i;
+ break;
+ }
+ }
+ if (added_disk == -1) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+ break;
+ }
+
+ switch (state) {
+ /*
+ * Switch the spare disk to write-only mode:
+ */
+ case DISKOP_SPARE_WRITE:
+ sdisk = conf->mirrors + spare_disk;
+ sdisk->operational = 1;
+ sdisk->write_only = 1;
+ break;
+ /*
+ * Deactivate a spare disk:
+ */
+ case DISKOP_SPARE_INACTIVE:
+ sdisk = conf->mirrors + spare_disk;
+ sdisk->operational = 0;
+ sdisk->write_only = 0;
+ break;
+ /*
+ * Activate (mark read-write) the (now sync) spare disk,
+ * which means we switch it's 'raid position' (->raid_disk)
+ * with the failed disk. (only the first 'conf->nr_disks'
+ * slots are used for 'real' disks and we must preserve this
+ * property)
+ */
+ case DISKOP_SPARE_ACTIVE:
+
+ sdisk = conf->mirrors + spare_disk;
+ fdisk = conf->mirrors + failed_disk;
+
+ spare_desc = &sb->disks[sdisk->number];
+ failed_desc = &sb->disks[fdisk->number];
+
+ if (spare_desc != *d) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+
+ if (spare_desc->raid_disk != sdisk->raid_disk) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+
+ if (sdisk->raid_disk != spare_disk) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+
+ if (failed_desc->raid_disk != fdisk->raid_disk) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+
+ if (fdisk->raid_disk != failed_disk) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+
+ /*
+ * do the switch finally
+ */
+ xchg_values(*spare_desc, *failed_desc);
+ xchg_values(*fdisk, *sdisk);
+
+ /*
+ * (careful, 'failed' and 'spare' are switched from now on)
+ *
+ * we want to preserve linear numbering and we want to
+ * give the proper raid_disk number to the now activated
+ * disk. (this means we switch back these values)
+ */
+
+ xchg_values(spare_desc->raid_disk, failed_desc->raid_disk);
+ xchg_values(sdisk->raid_disk, fdisk->raid_disk);
+ xchg_values(spare_desc->number, failed_desc->number);
+ xchg_values(sdisk->number, fdisk->number);
+
+ *d = failed_desc;
+
+ if (sdisk->dev == MKDEV(0,0))
+ sdisk->used_slot = 0;
+ /*
+ * this really activates the spare.
+ */
+ fdisk->spare = 0;
+ fdisk->write_only = 0;
+ link_disk(conf, fdisk);
+
+ /*
+ * if we activate a spare, we definitely replace a
+ * non-operational disk slot in the 'low' area of
+ * the disk array.
+ */
+
+ conf->working_disks++;
+
+ break;
+
+ case DISKOP_HOT_REMOVE_DISK:
+ rdisk = conf->mirrors + removed_disk;
+
+ if (rdisk->spare && (removed_disk < conf->raid_disks)) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+ rdisk->dev = MKDEV(0,0);
+ rdisk->used_slot = 0;
+ conf->nr_disks--;
+ break;
+
+ case DISKOP_HOT_ADD_DISK:
+ adisk = conf->mirrors + added_disk;
+ added_desc = *d;
+
+ if (added_disk != added_desc->number) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+
+ adisk->number = added_desc->number;
+ adisk->raid_disk = added_desc->raid_disk;
+ adisk->dev = MKDEV(added_desc->major,added_desc->minor);
+
+ adisk->operational = 0;
+ adisk->write_only = 0;
+ adisk->spare = 1;
+ adisk->used_slot = 1;
+ adisk->head_position = 0;
+ conf->nr_disks++;
+
+ break;
+
+ default:
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+abort:
+ md_spin_unlock_irq(&conf->device_lock);
+ if (state == DISKOP_SPARE_ACTIVE || state == DISKOP_SPARE_INACTIVE)
+ /* should move to "END_REBUILD" when such exists */
+ raid1_shrink_buffers(conf);
+
+ print_raid1_conf(conf);


+ return err;
+}
+
+

+#define IO_ERROR KERN_ALERT \
+"raid1: %s: unrecoverable I/O read error for block %lu\n"
+
+#define REDIRECT_SECTOR KERN_ERR \
+"raid1: %s: redirecting sector %lu to another mirror\n"
+
+/*
+ * This is a kernel thread which:
+ *
+ * 1. Retries failed read operations on working mirrors.
+ * 2. Updates the raid superblock when problems encounter.
+ * 3. Performs writes following reads for array syncronising.
+ */
+static void end_sync_write(struct buffer_head *bh, int uptodate);
+static void end_sync_read(struct buffer_head *bh, int uptodate);
+
+static void raid1d (void *data)
+{
+ struct raid1_bh *r1_bh;
+ struct buffer_head *bh;
+ unsigned long flags;
+ mddev_t *mddev;
+ kdev_t dev;
+
+
+ for (;;) {
+ md_spin_lock_irqsave(&retry_list_lock, flags);
+ r1_bh = raid1_retry_list;
+ if (!r1_bh)
+ break;
+ raid1_retry_list = r1_bh->next_r1;
+ md_spin_unlock_irqrestore(&retry_list_lock, flags);
+
+ mddev = r1_bh->mddev;
+ if (mddev->sb_dirty) {
+ printk(KERN_INFO "dirty sb detected, updating.\n");
+ mddev->sb_dirty = 0;
+ md_update_sb(mddev);
+ }
+ bh = &r1_bh->bh_req;
+ switch(r1_bh->cmd) {
+ case SPECIAL:
+ /* have to allocate lots of bh structures and
+ * schedule writes
+ */
+ if (test_bit(R1BH_Uptodate, &r1_bh->state)) {
+ int i, sum_bhs = 0;
+ int disks = MD_SB_DISKS;
+ struct buffer_head *bhl, *mbh;
+ raid1_conf_t *conf;
+ int sectors = bh->b_size >> 9;
+
+ conf = mddev_to_conf(mddev);
+ bhl = raid1_alloc_bh(conf, conf->raid_disks); /* don't really need this many */
+ for (i = 0; i < disks ; i++) {
+ if (!conf->mirrors[i].operational)
+ continue;
+ if (i==conf->last_used)
+ /* we read from here, no need to write */
+ continue;
+ if (i < conf->raid_disks
+ && !conf->resync_mirrors)
+ /* don't need to write this,
+ * we are just rebuilding */
+ continue;
+ mbh = bhl;
+ if (!mbh) {
+ MD_BUG();
+ break;
+ }
+ bhl = mbh->b_next;
+ mbh->b_this_page = (struct buffer_head *)1;
+
+
+ /*
+ * prepare mirrored bh (fields ordered for max mem throughput):
+ */
+ mbh->b_blocknr = bh->b_blocknr;
+ mbh->b_dev = conf->mirrors[i].dev;
+ mbh->b_rdev = conf->mirrors[i].dev;
+ mbh->b_rsector = bh->b_blocknr * sectors;
+ mbh->b_state = (1<<BH_Req) | (1<<BH_Dirty) |
+ (1<<BH_Mapped) | (1<<BH_Lock);
+ atomic_set(&mbh->b_count, 1);
+ mbh->b_size = bh->b_size;
+ mbh->b_page = bh->b_page;
+ mbh->b_data = bh->b_data;
+ mbh->b_list = BUF_LOCKED;
+ mbh->b_end_io = end_sync_write;
+ mbh->b_private = r1_bh;
+
+ mbh->b_next = r1_bh->mirror_bh_list;
+ r1_bh->mirror_bh_list = mbh;
+
+ sum_bhs++;
+ }
+ md_atomic_set(&r1_bh->remaining, sum_bhs);
+ if (bhl) raid1_free_bh(conf, bhl);
+ mbh = r1_bh->mirror_bh_list;
+ while (mbh) {
+ struct buffer_head *bh1 = mbh;
+ mbh = mbh->b_next;
+ generic_make_request(WRITE, bh1);
+ md_sync_acct(bh1->b_rdev, bh1->b_size/512);
+ }
+ } else {
+ dev = bh->b_dev;
+ raid1_map (mddev, &bh->b_dev, bh->b_size >> 9);
+ if (bh->b_dev == dev) {
+ printk (IO_ERROR, partition_name(bh->b_dev), bh->b_blocknr);
+ md_done_sync(mddev, bh->b_size>>10, 0);
+ } else {
+ printk (REDIRECT_SECTOR,
+ partition_name(bh->b_dev), bh->b_blocknr);
+ bh->b_rdev = bh->b_dev;
+ generic_make_request(READ, bh);
+ }
+ }
+
+ break;
+ case READ:
+ case READA:
+ dev = bh->b_dev;
+
+ raid1_map (mddev, &bh->b_dev, bh->b_size >> 9);
+ if (bh->b_dev == dev) {
+ printk (IO_ERROR, partition_name(bh->b_dev), bh->b_blocknr);
+ raid1_end_bh_io(r1_bh, 0);
+ } else {
+ printk (REDIRECT_SECTOR,
+ partition_name(bh->b_dev), bh->b_blocknr);
+ bh->b_rdev = bh->b_dev;
+ generic_make_request (r1_bh->cmd, bh);
+ }
+ break;
+ }
+ }
+ md_spin_unlock_irqrestore(&retry_list_lock, flags);
+}
+#undef IO_ERROR
+#undef REDIRECT_SECTOR
+
+/*
+ * Private kernel thread to reconstruct mirrors after an unclean
+ * shutdown.
+ */
+static void raid1syncd (void *data)
+{
+ raid1_conf_t *conf = data;
+ mddev_t *mddev = conf->mddev;
+
+ if (!conf->resync_mirrors)
+ return;
+ if (conf->resync_mirrors == 2)
+ return;
+ down(&mddev->recovery_sem);
+ if (!md_do_sync(mddev, NULL)) {
+ /*
+ * Only if everything went Ok.
+ */
+ conf->resync_mirrors = 0;
+ }
+
+ /* If reconstruction was interrupted, we need to close the "active" and "pending"
+ * holes.
+ * we know that there are no active rebuild requests, os cnt_active == cnt_ready ==0
+ */
+ /* this is really needed when recovery stops too... */
+ spin_lock_irq(&conf->segment_lock);
+ conf->start_active = conf->start_pending;
+ conf->start_ready = conf->start_pending;
+ wait_event_lock_irq(conf->wait_ready, !conf->cnt_pending, conf->segment_lock);
+ conf->start_active =conf->start_ready = conf->start_pending = conf->start_future;
+ conf->start_future = mddev->sb->size+1;
+ conf->cnt_pending = conf->cnt_future;
+ conf->cnt_future = 0;
+ conf->phase = conf->phase ^1;
+ wait_event_lock_irq(conf->wait_ready, !conf->cnt_pending, conf->segment_lock);
+ conf->start_active = conf->start_ready = conf->start_pending = conf->start_future = 0;
+ conf->phase = 0;
+ conf->cnt_future = conf->cnt_done;;
+ conf->cnt_done = 0;
+ spin_unlock_irq(&conf->segment_lock);
+ wake_up(&conf->wait_done);
+
+ up(&mddev->recovery_sem);
+ raid1_shrink_buffers(conf);
+}
+
+/*
+ * perform a "sync" on one "block"


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 057'
echo 'File patch-2.4.0-test9 is continued in part 058'
echo "058" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part055

#!/bin/sh -x
# this is part 055 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 055; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ "LVM "
+#ifdef MODULE
+ "module"
+#else
+ "driver"
+#endif
+ " %s\n\n"
+ "Total: %d VG%s %d PV%s %d LV%s ",
+ lvm_short_version,
+ vg_counter, vg_counter == 1 ? "" : "s",
+ pv_counter, pv_counter == 1 ? "" : "s",
+ lv_counter, lv_counter == 1 ? "" : "s");
+ sz += sprintf(LVM_PROC_BUF,
+ "(%d LV%s open",
+ lv_open_counter,
+ lv_open_counter == 1 ? "" : "s");
+ if (lv_open_total > 0)
+ sz += sprintf(LVM_PROC_BUF,
+ " %d times)\n",
+ lv_open_total);
+ else
+ sz += sprintf(LVM_PROC_BUF, ")");
+ sz += sprintf(LVM_PROC_BUF,
+ "\nGlobal: %lu bytes malloced IOP version: %d ",
+ vg_counter * sizeof(vg_t) +
+ pv_counter * sizeof(pv_t) +
+ lv_counter * sizeof(lv_t) +
+ pe_t_bytes + lv_block_exception_t_bytes + sz_last,
+ lvm_iop_version);
+
+ seconds = CURRENT_TIME - loadtime;
+ if (seconds < 0)
+ loadtime = CURRENT_TIME + seconds;
+ if (seconds / 86400 > 0) {
+ sz += sprintf(LVM_PROC_BUF, "%d day%s ",
+ seconds / 86400,
+ seconds / 86400 == 0 ||
+ seconds / 86400 > 1 ? "s" : "");
+ }
+ sz += sprintf(LVM_PROC_BUF, "%d:%02d:%02d active\n",
+ (seconds % 86400) / 3600,
+ (seconds % 3600) / 60,
+ seconds % 60);
+
+ if (vg_counter > 0) {


+ for (v = 0; v < ABS_MAX_VG; v++) {

+ /* volume group */


+ if ((vg_ptr = vg[v]) != NULL) {

+ inactive_flag = ' ';
+ if (!(vg_ptr->vg_status & VG_ACTIVE)) inactive_flag = 'I';
+ sz += sprintf(LVM_PROC_BUF,
+ "\nVG: %c%s [%d PV, %d LV/%d open] "
+ " PE Size: %d KB\n"
+ " Usage [KB/PE]: %d /%d total "
+ "%d /%d used %d /%d free",
+ inactive_flag,
+ vg_ptr->vg_name,
+ vg_ptr->pv_cur,
+ vg_ptr->lv_cur,
+ vg_ptr->lv_open,
+ vg_ptr->pe_size >> 1,
+ vg_ptr->pe_size * vg_ptr->pe_total >> 1,
+ vg_ptr->pe_total,
+ vg_ptr->pe_allocated * vg_ptr->pe_size >> 1,
+ vg_ptr->pe_allocated,
+ (vg_ptr->pe_total - vg_ptr->pe_allocated) *
+ vg_ptr->pe_size >> 1,
+ vg_ptr->pe_total - vg_ptr->pe_allocated);
+
+ /* physical volumes */
+ sz += sprintf(LVM_PROC_BUF,
+ "\n PV%s ",
+ vg_ptr->pv_cur == 1 ? ": " : "s:");
+ c = 0;
+ for (p = 0; p < vg_ptr->pv_max; p++) {
+ if ((pv_ptr = vg_ptr->pv[p]) != NULL) {
+ inactive_flag = 'A';
+ if (!(pv_ptr->pv_status & PV_ACTIVE))
+ inactive_flag = 'I';
+ allocation_flag = 'A';
+ if (!(pv_ptr->pv_allocatable & PV_ALLOCATABLE))
+ allocation_flag = 'N';
+ pv_name = strchr(pv_ptr->pv_name+1,'/');
+ if ( pv_name == 0) pv_name = pv_ptr->pv_name;
+ else pv_name++;
+ sz += sprintf(LVM_PROC_BUF,
+ "[%c%c] %-21s %8d /%-6d "
+ "%8d /%-6d %8d /%-6d",
+ inactive_flag,
+ allocation_flag,
+ pv_name,
+ pv_ptr->pe_total *
+ pv_ptr->pe_size >> 1,
+ pv_ptr->pe_total,
+ pv_ptr->pe_allocated *
+ pv_ptr->pe_size >> 1,
+ pv_ptr->pe_allocated,
+ (pv_ptr->pe_total -
+ pv_ptr->pe_allocated) *
+ pv_ptr->pe_size >> 1,
+ pv_ptr->pe_total -
+ pv_ptr->pe_allocated);
+ c++;
+ if (c < vg_ptr->pv_cur)
+ sz += sprintf(LVM_PROC_BUF,
+ "\n ");
+ }
+ }
+
+ /* logical volumes */
+ sz += sprintf(LVM_PROC_BUF,
+ "\n LV%s ",
+ vg_ptr->lv_cur == 1 ? ": " : "s:");
+ c = 0;


+ for (l = 0; l < vg[v]->lv_max; l++) {
+ if ((lv_ptr = vg_ptr->lv[l]) != NULL) {

+ inactive_flag = 'A';


+ if (!(lv_ptr->lv_status & LV_ACTIVE))

+ inactive_flag = 'I';
+ rw_flag = 'R';
+ if (lv_ptr->lv_access & LV_WRITE)
+ rw_flag = 'W';
+ allocation_flag = 'D';
+ if (lv_ptr->lv_allocation & LV_CONTIGUOUS)
+ allocation_flag = 'C';
+ stripes_flag = 'L';
+ if (lv_ptr->lv_stripes > 1)
+ stripes_flag = 'S';
+ sz += sprintf(LVM_PROC_BUF,
+ "[%c%c%c%c",
+ inactive_flag,
+ rw_flag,
+ allocation_flag,
+ stripes_flag);
+ if (lv_ptr->lv_stripes > 1)
+ sz += sprintf(LVM_PROC_BUF, "%-2d",
+ lv_ptr->lv_stripes);
+ else
+ sz += sprintf(LVM_PROC_BUF, " ");
+ lv_name = strrchr(lv_ptr->lv_name, '/');
+ if ( lv_name == 0) lv_name = lv_ptr->lv_name;
+ else lv_name++;
+ sz += sprintf(LVM_PROC_BUF, "] %-25s", lv_name);
+ if (strlen(lv_name) > 25)
+ sz += sprintf(LVM_PROC_BUF,
+ "\n ");
+ sz += sprintf(LVM_PROC_BUF, "%9d /%-6d ",
+ lv_ptr->lv_size >> 1,
+ lv_ptr->lv_size / vg[v]->pe_size);
+


+ if (lv_ptr->lv_open == 0)

+ sz += sprintf(LVM_PROC_BUF, "close");
+ else
+ sz += sprintf(LVM_PROC_BUF, "%dx open",
+ lv_ptr->lv_open);
+ c++;
+ if (c < vg_ptr->lv_cur)
+ sz += sprintf(LVM_PROC_BUF,
+ "\n ");
+ }
+ }
+ if (vg_ptr->lv_cur == 0) sz += sprintf(LVM_PROC_BUF, "none");
+ sz += sprintf(LVM_PROC_BUF, "\n");
+ }
+ }
+ }
+ if (buf == NULL) {
+ if ((buf = vmalloc(sz)) == NULL) {
+ sz = 0;
+ return sprintf(page, "%s - vmalloc error at line %d\n",
+ lvm_name, __LINE__);
+ }
+ }
+ sz_last = sz;
+ }
+ }
+ if (pos > sz - 1) {
+ vfree(buf);
+ buf = NULL;
+ return 0;
+ }
+ *start = &buf[pos];
+ if (sz - pos < count)
+ return sz - pos;
+ else
+ return count;
+} /* lvm_proc_get_info() */
+#endif /* #if defined CONFIG_LVM_PROC_FS && defined CONFIG_PROC_FS */
+
+
+/*
+ * block device support function for /usr/src/linux/drivers/block/ll_rw_blk.c
+ * (see init_module/lvm_init)
+ */
+static int lvm_map(struct buffer_head *bh, int rw)
+{
+ int minor = MINOR(bh->b_rdev);
+ ulong index;
+ ulong pe_start;
+ ulong size = bh->b_size >> 9;
+ ulong rsector_tmp = bh->b_rsector;
+ ulong rsector_sav;
+ kdev_t rdev_tmp = bh->b_rdev;
+ kdev_t rdev_sav;
+ lv_t *lv = vg[VG_BLK(minor)]->lv[LV_BLK(minor)];
+
+
+ if (!(lv->lv_status & LV_ACTIVE)) {
+ printk(KERN_ALERT
+ "%s - lvm_map: ll_rw_blk for inactive LV %s\n",
+ lvm_name, lv->lv_name);
+ goto error;
+ }
+/*
+ if ( lv->lv_access & LV_SNAPSHOT)
+ printk ( "%s -- %02d:%02d block: %lu rw: %d\n", lvm_name, MAJOR ( bh->b_dev), MINOR ( bh->b_dev), bh->b_blocknr, rw);
+ */
+
+ /* take care of snapshot chunk writes before
+ check for writable logical volume */
+ if ((lv->lv_access & LV_SNAPSHOT) &&
+ MAJOR(bh->b_rdev) != 0 &&
+ MAJOR(bh->b_rdev) != MAJOR_NR &&
+ (rw == WRITEA || rw == WRITE))
+ {
+ printk ( "%s -- doing snapshot write for %02d:%02d[%02d:%02d] b_blocknr: %lu b_rsector: %lu\n", lvm_name, MAJOR ( bh->b_dev), MINOR ( bh->b_dev), MAJOR ( bh->b_rdev), MINOR ( bh->b_rdev), bh->b_blocknr, bh->b_rsector);
+ goto error;
+ }
+
+ if ((rw == WRITE || rw == WRITEA) &&
+ !(lv->lv_access & LV_WRITE)) {
+ printk(KERN_CRIT
+ "%s - lvm_map: ll_rw_blk write for readonly LV %s\n",
+ lvm_name, lv->lv_name);
+ goto error;
+ }
+#ifdef DEBUG_MAP
+ printk(KERN_DEBUG
+ "%s - lvm_map minor:%d *rdev: %02d:%02d *rsector: %lu "
+ "size:%lu\n",
+ lvm_name, minor,
+ MAJOR(rdev_tmp),
+ MINOR(rdev_tmp),
+ rsector_tmp, size);
+#endif
+
+ if (rsector_tmp + size > lv->lv_size) {
+ printk(KERN_ALERT
+ "%s - lvm_map *rsector: %lu or size: %lu wrong for"
+ " minor: %2d\n", lvm_name, rsector_tmp, size, minor);
+ goto error;
+ }
+ rsector_sav = rsector_tmp;
+ rdev_sav = rdev_tmp;
+
+lvm_second_remap:
+ /* linear mapping */
+ if (lv->lv_stripes < 2) {
+ /* get the index */
+ index = rsector_tmp / vg[VG_BLK(minor)]->pe_size;
+ pe_start = lv->lv_current_pe[index].pe;
+ rsector_tmp = lv->lv_current_pe[index].pe +
+ (rsector_tmp % vg[VG_BLK(minor)]->pe_size);
+ rdev_tmp = lv->lv_current_pe[index].dev;
+
+#ifdef DEBUG_MAP
+ printk(KERN_DEBUG
+ "lv_current_pe[%ld].pe: %ld rdev: %02d:%02d rsector:%ld\n",
+ index,
+ lv->lv_current_pe[index].pe,
+ MAJOR(rdev_tmp),
+ MINOR(rdev_tmp),
+ rsector_tmp);
+#endif
+
+ /* striped mapping */
+ } else {
+ ulong stripe_index;
+ ulong stripe_length;
+
+ stripe_length = vg[VG_BLK(minor)]->pe_size * lv->lv_stripes;
+ stripe_index = (rsector_tmp % stripe_length) / lv->lv_stripesize;
+ index = rsector_tmp / stripe_length +
+ (stripe_index % lv->lv_stripes) *
+ (lv->lv_allocated_le / lv->lv_stripes);
+ pe_start = lv->lv_current_pe[index].pe;
+ rsector_tmp = lv->lv_current_pe[index].pe +
+ (rsector_tmp % stripe_length) -
+ (stripe_index % lv->lv_stripes) * lv->lv_stripesize -
+ stripe_index / lv->lv_stripes *
+ (lv->lv_stripes - 1) * lv->lv_stripesize;
+ rdev_tmp = lv->lv_current_pe[index].dev;
+ }
+
+#ifdef DEBUG_MAP
+ printk(KERN_DEBUG
+ "lv_current_pe[%ld].pe: %ld rdev: %02d:%02d rsector:%ld\n"
+ "stripe_length: %ld stripe_index: %ld\n",
+ index,
+ lv->lv_current_pe[index].pe,
+ MAJOR(rdev_tmp),
+ MINOR(rdev_tmp),
+ rsector_tmp,
+ stripe_length,
+ stripe_index);
+#endif
+
+ /* handle physical extents on the move */
+ if (pe_lock_req.lock == LOCK_PE) {
+ if (rdev_tmp == pe_lock_req.data.pv_dev &&
+ rsector_tmp >= pe_lock_req.data.pv_offset &&
+ rsector_tmp < (pe_lock_req.data.pv_offset +
+ vg[VG_BLK(minor)]->pe_size)) {
+ sleep_on(&lvm_map_wait);
+ rsector_tmp = rsector_sav;
+ rdev_tmp = rdev_sav;
+ goto lvm_second_remap;
+ }
+ }
+ /* statistic */
+ if (rw == WRITE || rw == WRITEA)
+ lv->lv_current_pe[index].writes++;
+ else
+ lv->lv_current_pe[index].reads++;
+
+ /* snapshot volume exception handling on physical device address base */
+ if (lv->lv_access & (LV_SNAPSHOT | LV_SNAPSHOT_ORG)) {
+ /* original logical volume */
+ if (lv->lv_access & LV_SNAPSHOT_ORG) {
+ if (rw == WRITE || rw == WRITEA)
+ {
+ lv_t *lv_ptr;
+
+ /* start with first snapshot and loop thrugh all of them */
+ for (lv_ptr = lv->lv_snapshot_next;
+ lv_ptr != NULL;
+ lv_ptr = lv_ptr->lv_snapshot_next) {
+ down(&lv->lv_snapshot_org->lv_snapshot_sem);
+ /* do we still have exception storage for this snapshot free? */


+ if (lv_ptr->lv_block_exception != NULL) {

+ rdev_sav = rdev_tmp;
+ rsector_sav = rsector_tmp;
+ if (!lvm_snapshot_remap_block(&rdev_tmp,
+ &rsector_tmp,
+ pe_start,
+ lv_ptr)) {
+ /* create a new mapping */
+ lvm_snapshot_COW(rdev_tmp,
+ rsector_tmp,
+ pe_start,
+ rsector_sav,
+ lv_ptr);
+ }
+ rdev_tmp = rdev_sav;
+ rsector_tmp = rsector_sav;
+ }
+ up(&lv->lv_snapshot_org->lv_snapshot_sem);
+ }
+ }
+ } else {
+ /* remap snapshot logical volume */
+ down(&lv->lv_snapshot_sem);
+ if (lv->lv_block_exception != NULL)
+ lvm_snapshot_remap_block(&rdev_tmp, &rsector_tmp, pe_start, lv);
+ up(&lv->lv_snapshot_sem);
+ }
+ }
+ bh->b_rdev = rdev_tmp;
+ bh->b_rsector = rsector_tmp;


+
+ return 1;
+

+ error:
+ buffer_IO_error(bh);
+ return -1;
+} /* lvm_map() */
+
+
+/*
+ * internal support functions
+ */
+
+#ifdef LVM_HD_NAME
+/*
+ * generate "hard disk" name
+ */
+void lvm_hd_name(char *buf, int minor)
+{
+ int len = 0;
+ lv_t *lv_ptr;
+
+ if (vg[VG_BLK(minor)] == NULL ||
+ (lv_ptr = vg[VG_BLK(minor)]->lv[LV_BLK(minor)]) == NULL)
+ return;
+ len = strlen(lv_ptr->lv_name) - 5;
+ memcpy(buf, &lv_ptr->lv_name[5], len);
+ buf[len] = 0;
+ return;
+}
+#endif
+
+
+/*
+ * this one never should be called...
+ */
+static void lvm_dummy_device_request(request_queue_t * t)
+{
+ printk(KERN_EMERG
+ "%s -- oops, got lvm request for %02d:%02d [sector: %lu]\n",
+ lvm_name,
+ MAJOR(CURRENT->rq_dev),
+ MINOR(CURRENT->rq_dev),
+ CURRENT->sector);
+ return;
+}
+
+
+/*
+ * make request function
+ */
+static int lvm_make_request_fn(request_queue_t *q, int rw, struct buffer_head *bh)
+{
+ lvm_map(bh, rw);


+ return 1;
+}
+

+/*
+ * plug device function is a noop because plugging has to happen
+ * in the queue of the physical blockdevice to allow the
+ * elevator to do a better job.
+ */
+static void lvm_plug_device_noop(request_queue_t *q, kdev_t dev) { }
+
+/********************************************************************
+ *
+ * Character device support functions
+ *
+ ********************************************************************/
+/*
+ * character device support function logical volume manager lock
+ */
+static int lvm_do_lock_lvm(void)
+{
+lock_try_again:
+ spin_lock(&lvm_lock);
+ if (lock != 0 && lock != current->pid) {
+#ifdef DEBUG_IOCTL
+ printk(KERN_INFO "lvm_do_lock_lvm: %s is locked by pid %d ...\n",
+ lvm_name, lock);
+#endif
+ spin_unlock(&lvm_lock);
+ interruptible_sleep_on(&lvm_wait);
+ if (current->sigpending != 0)
+ return -EINTR;


+#ifdef LVM_TOTAL_RESET
+ if (lvm_reset_spindown > 0)

+ return -EACCES;
+#endif
+ goto lock_try_again;
+ }
+ lock = current->pid;
+ spin_unlock(&lvm_lock);
+ return 0;
+} /* lvm_do_lock_lvm */
+
+
+/*
+ * character device support function lock/unlock physical extend
+ */
+static int lvm_do_pe_lock_unlock(vg_t *vg_ptr, void *arg)
+{
+ uint p;
+


+ if (vg_ptr == NULL) return -ENXIO;

+ if (copy_from_user(&pe_lock_req, arg,
+ sizeof(pe_lock_req_t)) != 0) return -EFAULT;
+
+ switch (pe_lock_req.lock) {
+ case LOCK_PE:
+ for (p = 0; p < vg_ptr->pv_max; p++) {
+ if (vg_ptr->pv[p] != NULL &&
+ pe_lock_req.data.pv_dev ==
+ vg_ptr->pv[p]->pv_dev)
+ break;
+ }
+ if (p == vg_ptr->pv_max) return -ENXIO;


+
+ pe_lock_req.lock = UNLOCK_PE;

+ fsync_dev(pe_lock_req.data.lv_dev);
+ pe_lock_req.lock = LOCK_PE;
+ break;
+
+ case UNLOCK_PE:


+ pe_lock_req.lock = UNLOCK_PE;
+ pe_lock_req.data.lv_dev = pe_lock_req.data.pv_dev = 0;
+ pe_lock_req.data.pv_offset = 0;

+ wake_up(&lvm_map_wait);


+ break;
+
+ default:

+ return -EINVAL;
+ }


+ return 0;
+}
+
+

+/*
+ * character device support function logical extend remap
+ */
+static int lvm_do_le_remap(vg_t *vg_ptr, void *arg)
+{
+ uint l, le;
+ lv_t *lv_ptr;
+


+ if (vg_ptr == NULL) return -ENXIO;

+ if (copy_from_user(&le_remap_req, arg,
+ sizeof(le_remap_req_t)) != 0)
+ return -EFAULT;
+
+ for (l = 0; l < vg_ptr->lv_max; l++) {
+ lv_ptr = vg_ptr->lv[l];
+ if (lv_ptr != NULL &&
+ strcmp(lv_ptr->lv_name,
+ le_remap_req.lv_name) == 0) {
+ for (le = 0; le < lv_ptr->lv_allocated_le;
+ le++) {
+ if (lv_ptr->lv_current_pe[le].dev ==
+ le_remap_req.old_dev &&
+ lv_ptr->lv_current_pe[le].pe ==
+ le_remap_req.old_pe) {
+ lv_ptr->lv_current_pe[le].dev =
+ le_remap_req.new_dev;
+ lv_ptr->lv_current_pe[le].pe =
+ le_remap_req.new_pe;


+ return 0;
+ }
+ }

+ return -EINVAL;
+ }
+ }

+ return -ENXIO;
+} /* lvm_do_le_remap() */
+
+
+/*
+ * character device support function VGDA create
+ */
+int lvm_do_vg_create(int minor, void *arg)
+{
+ int snaporg_minor = 0;
+ ulong l, p;
+ lv_t lv;
+ vg_t *vg_ptr;
+ pv_t *pv_ptr;
+ lv_t *lv_ptr;
+
+ if (vg[VG_CHR(minor)] != NULL) return -EPERM;
+
+ if ((vg_ptr = kmalloc(sizeof(vg_t),GFP_KERNEL)) == NULL) {
+ printk(KERN_CRIT
+ "%s -- VG_CREATE: kmalloc error VG at line %d\n",
+ lvm_name, __LINE__);
+ return -ENOMEM;
+ }
+ /* get the volume group structure */
+ if (copy_from_user(vg_ptr, arg, sizeof(vg_t)) != 0) {
+ kfree(vg_ptr);


+ return -EFAULT;
+ }
+

+ vg_devfs_handle[vg_ptr->vg_number] = devfs_mk_dir(0, vg_ptr->vg_name, NULL);
+ ch_devfs_handle[vg_ptr->vg_number] = devfs_register(
+ vg_devfs_handle[vg_ptr->vg_number] , "group",
+ DEVFS_FL_DEFAULT, LVM_CHAR_MAJOR, vg_ptr->vg_number,


+ S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,
+ &lvm_chr_fops, NULL);
+

+ /* we are not that active so far... */
+ vg_ptr->vg_status &= ~VG_ACTIVE;
+ vg[VG_CHR(minor)] = vg_ptr;
+
+ vg[VG_CHR(minor)]->pe_allocated = 0;
+ if (vg_ptr->pv_max > ABS_MAX_PV) {
+ printk(KERN_WARNING
+ "%s -- Can't activate VG: ABS_MAX_PV too small\n",
+ lvm_name);
+ kfree(vg_ptr);
+ vg[VG_CHR(minor)] = NULL;
+ return -EPERM;
+ }
+ if (vg_ptr->lv_max > ABS_MAX_LV) {
+ printk(KERN_WARNING
+ "%s -- Can't activate VG: ABS_MAX_LV too small for %u\n",
+ lvm_name, vg_ptr->lv_max);
+ kfree(vg_ptr);
+ vg_ptr = NULL;
+ return -EPERM;
+ }
+ /* get the physical volume structures */
+ vg_ptr->pv_act = vg_ptr->pv_cur = 0;
+ for (p = 0; p < vg_ptr->pv_max; p++) {
+ /* user space address */
+ if ((pvp = vg_ptr->pv[p]) != NULL) {
+ pv_ptr = vg_ptr->pv[p] = kmalloc(sizeof(pv_t),GFP_KERNEL);
+ if (pv_ptr == NULL) {
+ printk(KERN_CRIT
+ "%s -- VG_CREATE: kmalloc error PV at line %d\n",
+ lvm_name, __LINE__);
+ lvm_do_vg_remove(minor);
+ return -ENOMEM;
+ }
+ if (copy_from_user(pv_ptr, pvp, sizeof(pv_t)) != 0) {
+ lvm_do_vg_remove(minor);
+ return -EFAULT;
+ }
+ /* We don't need the PE list
+ in kernel space as with LVs pe_t list (see below) */
+ pv_ptr->pe = NULL;
+ pv_ptr->pe_allocated = 0;
+ pv_ptr->pv_status = PV_ACTIVE;
+ vg_ptr->pv_act++;
+ vg_ptr->pv_cur++;
+
+#ifdef LVM_GET_INODE
+ /* insert a dummy inode for fs_may_mount */
+ pv_ptr->inode = lvm_get_inode(pv_ptr->pv_dev);
+#endif
+ }
+ }
+
+ /* get the logical volume structures */
+ vg_ptr->lv_cur = 0;
+ for (l = 0; l < vg_ptr->lv_max; l++) {
+ /* user space address */
+ if ((lvp = vg_ptr->lv[l]) != NULL) {
+ if (copy_from_user(&lv, lvp, sizeof(lv_t)) != 0) {
+ lvm_do_vg_remove(minor);
+ return -EFAULT;
+ }
+ vg_ptr->lv[l] = NULL;
+ if (lvm_do_lv_create(minor, lv.lv_name, &lv) != 0) {
+ lvm_do_vg_remove(minor);


+ return -EFAULT;
+ }
+ }
+ }

+
+ /* Second path to correct snapshot logical volumes which are not
+ in place during first path above */
+ for (l = 0; l < vg_ptr->lv_max; l++) {
+ if ((lv_ptr = vg_ptr->lv[l]) != NULL &&
+ vg_ptr->lv[l]->lv_access & LV_SNAPSHOT) {
+ snaporg_minor = lv_ptr->lv_snapshot_minor;
+ if (vg_ptr->lv[LV_BLK(snaporg_minor)] != NULL) {
+ /* get pointer to original logical volume */
+ lv_ptr = vg_ptr->lv[l]->lv_snapshot_org =
+ vg_ptr->lv[LV_BLK(snaporg_minor)];
+
+ /* set necessary fields of original logical volume */
+ lv_ptr->lv_access |= LV_SNAPSHOT_ORG;
+ lv_ptr->lv_snapshot_minor = 0;
+ lv_ptr->lv_snapshot_org = lv_ptr;
+ lv_ptr->lv_snapshot_prev = NULL;
+
+ /* find last snapshot logical volume in the chain */
+ while (lv_ptr->lv_snapshot_next != NULL)
+ lv_ptr = lv_ptr->lv_snapshot_next;
+
+ /* set back pointer to this last one in our new logical volume */
+ vg_ptr->lv[l]->lv_snapshot_prev = lv_ptr;
+
+ /* last logical volume now points to our new snapshot volume */
+ lv_ptr->lv_snapshot_next = vg_ptr->lv[l];
+
+ /* now point to the new one */
+ lv_ptr = lv_ptr->lv_snapshot_next;
+
+ /* set necessary fields of new snapshot logical volume */
+ lv_ptr->lv_snapshot_next = NULL;
+ lv_ptr->lv_current_pe =
+ vg_ptr->lv[LV_BLK(snaporg_minor)]->lv_current_pe;
+ lv_ptr->lv_allocated_le =
+ vg_ptr->lv[LV_BLK(snaporg_minor)]->lv_allocated_le;
+ lv_ptr->lv_current_le =
+ vg_ptr->lv[LV_BLK(snaporg_minor)]->lv_current_le;
+ lv_ptr->lv_size =
+ vg_ptr->lv[LV_BLK(snaporg_minor)]->lv_size;
+ }
+ }
+ }
+
+ vg_count++;
+
+ /* let's go active */
+ vg_ptr->vg_status |= VG_ACTIVE;
+
+ MOD_INC_USE_COUNT;
+
+ return 0;
+} /* lvm_do_vg_create() */
+
+
+/*
+ * character device support function VGDA extend
+ */
+static int lvm_do_vg_extend(vg_t *vg_ptr, void *arg)
+{
+ uint p;
+ pv_t *pv_ptr;
+


+ if (vg_ptr == NULL) return -ENXIO;

+ if (vg_ptr->pv_cur < vg_ptr->pv_max) {
+ for (p = 0; p < vg_ptr->pv_max; p++) {
+ if (vg_ptr->pv[p] == NULL) {
+ if ((pv_ptr = vg_ptr->pv[p] = kmalloc(sizeof(pv_t),GFP_KERNEL)) == NULL) {
+ printk(KERN_CRIT
+ "%s -- VG_EXTEND: kmalloc error PV at line %d\n",
+ lvm_name, __LINE__);
+ return -ENOMEM;
+ }
+ if (copy_from_user(pv_ptr, arg, sizeof(pv_t)) != 0) {
+ kfree(pv_ptr);
+ vg_ptr->pv[p] = NULL;


+ return -EFAULT;
+ }
+

+ pv_ptr->pv_status = PV_ACTIVE;
+ /* We don't need the PE list
+ in kernel space like LVs pe_t list */
+ pv_ptr->pe = NULL;
+ vg_ptr->pv_cur++;
+ vg_ptr->pv_act++;
+ vg_ptr->pe_total +=
+ pv_ptr->pe_total;
+#ifdef LVM_GET_INODE
+ /* insert a dummy inode for fs_may_mount */
+ pv_ptr->inode = lvm_get_inode(pv_ptr->pv_dev);
+#endif


+ return 0;
+ }
+ }
+ }

+return -EPERM;
+} /* lvm_do_vg_extend() */
+
+
+/*
+ * character device support function VGDA reduce
+ */
+static int lvm_do_vg_reduce(vg_t *vg_ptr, void *arg)
+{
+ uint p;
+ pv_t *pv_ptr;
+


+ if (vg_ptr == NULL) return -ENXIO;

+ if (copy_from_user(pv_name, arg, sizeof(pv_name)) != 0)
+ return -EFAULT;
+
+ for (p = 0; p < vg_ptr->pv_max; p++) {
+ pv_ptr = vg_ptr->pv[p];
+ if (pv_ptr != NULL &&
+ strcmp(pv_ptr->pv_name,
+ pv_name) == 0) {
+ if (pv_ptr->lv_cur > 0) return -EPERM;
+ vg_ptr->pe_total -=
+ pv_ptr->pe_total;
+ vg_ptr->pv_cur--;
+ vg_ptr->pv_act--;
+#ifdef LVM_GET_INODE
+ lvm_clear_inode(pv_ptr->inode);
+#endif
+ kfree(pv_ptr);
+ /* Make PV pointer array contiguous */
+ for (; p < vg_ptr->pv_max - 1; p++)
+ vg_ptr->pv[p] = vg_ptr->pv[p + 1];
+ vg_ptr->pv[p + 1] = NULL;


+ return 0;
+ }
+ }

+ return -ENXIO;
+} /* lvm_do_vg_reduce */
+
+
+/*
+ * character device support function VGDA remove
+ */
+static int lvm_do_vg_remove(int minor)
+{
+ int i;


+ vg_t *vg_ptr = vg[VG_CHR(minor)];

+ pv_t *pv_ptr;
+


+ if (vg_ptr == NULL) return -ENXIO;
+

+#ifdef LVM_TOTAL_RESET
+ if (vg_ptr->lv_open > 0 && lvm_reset_spindown == 0)
+#else
+ if (vg_ptr->lv_open > 0)
+#endif
+ return -EPERM;
+
+ /* let's go inactive */
+ vg_ptr->vg_status &= ~VG_ACTIVE;
+
+ devfs_unregister (ch_devfs_handle[vg_ptr->vg_number]);
+ devfs_unregister (vg_devfs_handle[vg_ptr->vg_number]);
+
+ /* free LVs */
+ /* first free snapshot logical volumes */
+ for (i = 0; i < vg_ptr->lv_max; i++) {
+ if (vg_ptr->lv[i] != NULL &&
+ vg_ptr->lv[i]->lv_access & LV_SNAPSHOT) {
+ lvm_do_lv_remove(minor, NULL, i);
+ current->state = TASK_UNINTERRUPTIBLE;
+ schedule_timeout(1);
+ }
+ }
+ /* then free the rest of the LVs */
+ for (i = 0; i < vg_ptr->lv_max; i++) {
+ if (vg_ptr->lv[i] != NULL) {
+ lvm_do_lv_remove(minor, NULL, i);
+ current->state = TASK_UNINTERRUPTIBLE;
+ schedule_timeout(1);
+ }
+ }
+
+ /* free PVs */
+ for (i = 0; i < vg_ptr->pv_max; i++) {
+ if ((pv_ptr = vg_ptr->pv[i]) != NULL) {


+#ifdef DEBUG_KFREE
+ printk(KERN_DEBUG
+ "%s -- kfree %d\n", lvm_name, __LINE__);
+#endif

+#ifdef LVM_GET_INODE
+ lvm_clear_inode(pv_ptr->inode);
+#endif
+ kfree(pv_ptr);
+ vg[VG_CHR(minor)]->pv[i] = NULL;
+ }
+ }
+
+#ifdef DEBUG_KFREE
+ printk(KERN_DEBUG "%s -- kfree %d\n", lvm_name, __LINE__);
+#endif
+ kfree(vg_ptr);
+ vg[VG_CHR(minor)] = NULL;
+
+ vg_count--;


+
+ MOD_DEC_USE_COUNT;
+
+ return 0;

+} /* lvm_do_vg_remove() */
+
+
+/*
+ * character device support function logical volume create
+ */
+static int lvm_do_lv_create(int minor, char *lv_name, lv_t *lv)
+{
+ int l, le, l_new, p, size;
+ ulong lv_status_save;
+ char *lv_tmp, *lv_buf;
+ lv_block_exception_t *lvbe = lv->lv_block_exception;


+ vg_t *vg_ptr = vg[VG_CHR(minor)];

+ lv_t *lv_ptr = NULL;
+
+ if ((pep = lv->lv_current_pe) == NULL) return -EINVAL;
+ if (lv->lv_chunk_size > LVM_SNAPSHOT_MAX_CHUNK)
+ return -EINVAL;
+
+ for (l = 0; l < vg_ptr->lv_max; l++) {
+ if (vg_ptr->lv[l] != NULL &&
+ strcmp(vg_ptr->lv[l]->lv_name, lv_name) == 0)
+ return -EEXIST;
+ }
+
+ /* in case of lv_remove(), lv_create() pair; for eg. lvrename does this */
+ l_new = -1;
+ if (vg_ptr->lv[lv->lv_number] == NULL)
+ l_new = lv->lv_number;
+ else {
+ for (l = 0; l < vg_ptr->lv_max; l++) {
+ if (vg_ptr->lv[l] == NULL)
+ if (l_new == -1) l_new = l;
+ }
+ }
+ if (l_new == -1) return -EPERM;
+ else l = l_new;
+
+ if ((lv_ptr = kmalloc(sizeof(lv_t),GFP_KERNEL)) == NULL) {;
+ printk(KERN_CRIT "%s -- LV_CREATE: kmalloc error LV at line %d\n",
+ lvm_name, __LINE__);
+ return -ENOMEM;
+ }
+ /* copy preloaded LV */
+ memcpy((char *) lv_ptr, (char *) lv, sizeof(lv_t));
+
+ lv_status_save = lv_ptr->lv_status;
+ lv_ptr->lv_status &= ~LV_ACTIVE;
+ lv_ptr->lv_snapshot_org = \
+ lv_ptr->lv_snapshot_prev = \
+ lv_ptr->lv_snapshot_next = NULL;
+ lv_ptr->lv_block_exception = NULL;
+ init_MUTEX(&lv_ptr->lv_snapshot_sem);
+ vg_ptr->lv[l] = lv_ptr;
+
+ /* get the PE structures from user space if this
+ is no snapshot logical volume */
+ if (!(lv_ptr->lv_access & LV_SNAPSHOT)) {
+ size = lv_ptr->lv_allocated_le * sizeof(pe_t);
+ if ((lv_ptr->lv_current_pe = vmalloc(size)) == NULL) {
+ printk(KERN_CRIT
+ "%s -- LV_CREATE: vmalloc error LV_CURRENT_PE of %d Byte "
+ "at line %d\n",
+ lvm_name, size, __LINE__);
+#ifdef DEBUG_KFREE
+ printk(KERN_DEBUG "%s -- kfree %d\n", lvm_name, __LINE__);
+#endif
+ kfree(lv_ptr);
+ vg[VG_CHR(minor)]->lv[l] = NULL;
+ return -ENOMEM;
+ }
+ if (copy_from_user(lv_ptr->lv_current_pe, pep, size)) {
+ vfree(lv_ptr->lv_current_pe);
+ kfree(lv_ptr);
+ vg_ptr->lv[l] = NULL;
+ return -EFAULT;
+ }
+ /* correct the PE count in PVs */
+ for (le = 0; le < lv_ptr->lv_allocated_le; le++) {
+ vg_ptr->pe_allocated++;
+ for (p = 0; p < vg_ptr->pv_cur; p++) {
+ if (vg_ptr->pv[p]->pv_dev ==
+ lv_ptr->lv_current_pe[le].dev)
+ vg_ptr->pv[p]->pe_allocated++;
+ }
+ }
+ } else {
+ /* Get snapshot exception data and block list */
+ if (lvbe != NULL) {
+ lv_ptr->lv_snapshot_org =
+ vg_ptr->lv[LV_BLK(lv_ptr->lv_snapshot_minor)];
+ if (lv_ptr->lv_snapshot_org != NULL) {
+ size = lv_ptr->lv_remap_end * sizeof(lv_block_exception_t);
+ if ((lv_ptr->lv_block_exception = vmalloc(size)) == NULL) {
+ printk(KERN_CRIT
+ "%s -- lvm_do_lv_create: vmalloc error LV_BLOCK_EXCEPTION "
+ "of %d byte at line %d\n",
+ lvm_name, size, __LINE__);
+#ifdef DEBUG_KFREE
+ printk(KERN_DEBUG "%s -- kfree %d\n", lvm_name, __LINE__);
+#endif
+ kfree(lv_ptr);
+ vg_ptr->lv[l] = NULL;
+ return -ENOMEM;
+ }
+ if (copy_from_user(lv_ptr->lv_block_exception, lvbe, size)) {
+ vfree(lv_ptr->lv_block_exception);
+ kfree(lv_ptr);
+ vg[VG_CHR(minor)]->lv[l] = NULL;
+ return -EFAULT;
+ }
+ /* get pointer to original logical volume */
+ lv_ptr = lv_ptr->lv_snapshot_org;
+
+ lv_ptr->lv_snapshot_minor = 0;
+ lv_ptr->lv_snapshot_org = lv_ptr;
+ lv_ptr->lv_snapshot_prev = NULL;
+ /* walk thrugh the snapshot list */
+ while (lv_ptr->lv_snapshot_next != NULL)
+ lv_ptr = lv_ptr->lv_snapshot_next;
+ /* now lv_ptr points to the last existing snapshot in the chain */
+ vg_ptr->lv[l]->lv_snapshot_prev = lv_ptr;
+ /* our new one now back points to the previous last in the chain */
+ lv_ptr = vg_ptr->lv[l];
+ /* now lv_ptr points to our new last snapshot logical volume */
+ lv_ptr->lv_snapshot_org = lv_ptr->lv_snapshot_prev->lv_snapshot_org;
+ lv_ptr->lv_snapshot_next = NULL;
+ lv_ptr->lv_current_pe = lv_ptr->lv_snapshot_org->lv_current_pe;
+ lv_ptr->lv_allocated_le = lv_ptr->lv_snapshot_org->lv_allocated_le;
+ lv_ptr->lv_current_le = lv_ptr->lv_snapshot_org->lv_current_le;
+ lv_ptr->lv_size = lv_ptr->lv_snapshot_org->lv_size;
+ lv_ptr->lv_stripes = lv_ptr->lv_snapshot_org->lv_stripes;
+ lv_ptr->lv_stripesize = lv_ptr->lv_snapshot_org->lv_stripesize;
+ {
+ int err = lvm_snapshot_alloc(lv_ptr);
+ if (err)
+ {
+ vfree(lv_ptr->lv_block_exception);
+ kfree(lv_ptr);
+ vg[VG_CHR(minor)]->lv[l] = NULL;


+ return err;
+ }
+ }

+ } else {
+ vfree(lv_ptr->lv_block_exception);
+ kfree(lv_ptr);
+ vg_ptr->lv[l] = NULL;
+ return -EFAULT;
+ }
+ } else {
+ kfree(vg_ptr->lv[l]);
+ vg_ptr->lv[l] = NULL;
+ return -EINVAL;
+ }
+ } /* if ( vg[VG_CHR(minor)]->lv[l]->lv_access & LV_SNAPSHOT) */
+
+ lv_ptr = vg_ptr->lv[l];
+ lvm_gendisk.part[MINOR(lv_ptr->lv_dev)].start_sect = 0;
+ lvm_gendisk.part[MINOR(lv_ptr->lv_dev)].nr_sects = lv_ptr->lv_size;
+ lvm_size[MINOR(lv_ptr->lv_dev)] = lv_ptr->lv_size >> 1;
+ vg_lv_map[MINOR(lv_ptr->lv_dev)].vg_number = vg_ptr->vg_number;
+ vg_lv_map[MINOR(lv_ptr->lv_dev)].lv_number = lv_ptr->lv_number;
+ read_ahead[MAJOR_NR] = lv_ptr->lv_read_ahead = LVM_CORRECT_READ_AHEAD(lv_ptr->lv_read_ahead);
+ vg_ptr->lv_cur++;
+ lv_ptr->lv_status = lv_status_save;
+
+ strtok(lv->lv_name, "/"); /* /dev */
+
+ while((lv_tmp = strtok(NULL, "/")) != NULL)
+ lv_buf = lv_tmp;
+
+ lv_devfs_handle[lv->lv_number] = devfs_register(
+ vg_devfs_handle[vg_ptr->vg_number], lv_buf,
+ DEVFS_FL_DEFAULT, LVM_BLK_MAJOR, lv->lv_number,
+ S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP,
+ &lvm_blk_dops, NULL);
+
+ /* optionally add our new snapshot LV */
+ if (lv_ptr->lv_access & LV_SNAPSHOT) {
+ /* sync the original logical volume */
+ fsync_dev(lv_ptr->lv_snapshot_org->lv_dev);
+ /* put ourselve into the chain */
+ lv_ptr->lv_snapshot_prev->lv_snapshot_next = lv_ptr;
+ lv_ptr->lv_snapshot_org->lv_access |= LV_SNAPSHOT_ORG;
+ }
+ return 0;
+} /* lvm_do_lv_create() */
+
+
+/*
+ * character device support function logical volume remove
+ */
+static int lvm_do_lv_remove(int minor, char *lv_name, int l)
+{
+ uint le, p;


+ vg_t *vg_ptr = vg[VG_CHR(minor)];

+ lv_t *lv_ptr;
+
+ if (l == -1) {
+ for (l = 0; l < vg_ptr->lv_max; l++) {
+ if (vg_ptr->lv[l] != NULL &&
+ strcmp(vg_ptr->lv[l]->lv_name, lv_name) == 0) {


+ break;
+ }
+ }
+ }

+ if (l == vg_ptr->lv_max) return -ENXIO;
+
+ lv_ptr = vg_ptr->lv[l];
+#ifdef LVM_TOTAL_RESET
+ if (lv_ptr->lv_open > 0 && lvm_reset_spindown == 0)
+#else


+ if (lv_ptr->lv_open > 0)

+#endif
+ return -EBUSY;
+
+ /* check for deletion of snapshot source while
+ snapshot volume still exists */
+ if ((lv_ptr->lv_access & LV_SNAPSHOT_ORG) &&
+ lv_ptr->lv_snapshot_next != NULL)
+ return -EPERM;
+
+ lv_ptr->lv_status |= LV_SPINDOWN;
+
+ /* sync the buffers */
+ fsync_dev(lv_ptr->lv_dev);
+
+ lv_ptr->lv_status &= ~LV_ACTIVE;
+
+ /* invalidate the buffers */
+ invalidate_buffers(lv_ptr->lv_dev);
+
+ /* reset generic hd */
+ lvm_gendisk.part[MINOR(lv_ptr->lv_dev)].start_sect = -1;
+ lvm_gendisk.part[MINOR(lv_ptr->lv_dev)].nr_sects = 0;
+ lvm_size[MINOR(lv_ptr->lv_dev)] = 0;
+
+ /* reset VG/LV mapping */
+ vg_lv_map[MINOR(lv_ptr->lv_dev)].vg_number = ABS_MAX_VG;
+ vg_lv_map[MINOR(lv_ptr->lv_dev)].lv_number = -1;
+
+ /* correct the PE count in PVs if this is no snapshot logical volume */
+ if (!(lv_ptr->lv_access & LV_SNAPSHOT)) {
+ /* only if this is no snapshot logical volume because
+ we share the lv_current_pe[] structs with the
+ original logical volume */
+ for (le = 0; le < lv_ptr->lv_allocated_le; le++) {
+ vg_ptr->pe_allocated--;
+ for (p = 0; p < vg_ptr->pv_cur; p++) {
+ if (vg_ptr->pv[p]->pv_dev ==
+ lv_ptr->lv_current_pe[le].dev)
+ vg_ptr->pv[p]->pe_allocated--;
+ }
+ }
+ vfree(lv_ptr->lv_current_pe);
+ /* LV_SNAPSHOT */
+ } else {
+ /* remove this snapshot logical volume from the chain */
+ lv_ptr->lv_snapshot_prev->lv_snapshot_next = lv_ptr->lv_snapshot_next;
+ if (lv_ptr->lv_snapshot_next != NULL) {
+ lv_ptr->lv_snapshot_next->lv_snapshot_prev =
+ lv_ptr->lv_snapshot_prev;
+ }
+ /* no more snapshots? */
+ if (lv_ptr->lv_snapshot_org->lv_snapshot_next == NULL)
+ lv_ptr->lv_snapshot_org->lv_access &= ~LV_SNAPSHOT_ORG;
+ lvm_snapshot_release(lv_ptr);
+ }
+
+ devfs_unregister(lv_devfs_handle[lv_ptr->lv_number]);
+
+#ifdef DEBUG_KFREE
+ printk(KERN_DEBUG "%s -- kfree %d\n", lvm_name, __LINE__);
+#endif
+ kfree(lv_ptr);
+ vg_ptr->lv[l] = NULL;
+ vg_ptr->lv_cur--;
+ return 0;
+} /* lvm_do_lv_remove() */
+
+
+/*
+ * character device support function logical volume extend / reduce
+ */
+static int lvm_do_lv_extend_reduce(int minor, char *lv_name, lv_t *lv)
+{
+ int l, le, p, size, old_allocated_le;
+ uint32_t end, lv_status_save;


+ vg_t *vg_ptr = vg[VG_CHR(minor)];

+ lv_t *lv_ptr;
+ pe_t *pe;
+
+ if ((pep = lv->lv_current_pe) == NULL) return -EINVAL;
+
+ for (l = 0; l < vg_ptr->lv_max; l++) {
+ if (vg_ptr->lv[l] != NULL &&
+ strcmp(vg_ptr->lv[l]->lv_name, lv_name) == 0)
+ break;
+ }
+ if (l == vg_ptr->lv_max) return -ENXIO;
+ lv_ptr = vg_ptr->lv[l];
+
+ /* check for active snapshot */
+ if (lv->lv_access & (LV_SNAPSHOT | LV_SNAPSHOT_ORG)) return -EPERM;
+
+ if ((pe = vmalloc(size = lv->lv_current_le * sizeof(pe_t))) == NULL) {
+ printk(KERN_CRIT
+ "%s -- lvm_do_lv_extend_reduce: vmalloc error LV_CURRENT_PE "
+ "of %d Byte at line %d\n",
+ lvm_name, size, __LINE__);
+ return -ENOMEM;
+ }
+ /* get the PE structures from user space */
+ if (copy_from_user(pe, pep, size)) {
+ vfree(pe);


+ return -EFAULT;
+ }
+

+#ifdef DEBUG
+ printk(KERN_DEBUG
+ "%s -- fsync_dev and "
+ "invalidate_buffers for %s [%s] in %s\n",
+ lvm_name, lv_ptr->lv_name,
+ kdevname(lv_ptr->lv_dev),
+ vg_ptr->vg_name);
+#endif
+
+ lv_ptr->lv_status |= LV_SPINDOWN;
+ fsync_dev(lv_ptr->lv_dev);
+ lv_ptr->lv_status &= ~LV_ACTIVE;
+ invalidate_buffers(lv_ptr->lv_dev);
+
+ /* reduce allocation counters on PV(s) */
+ for (le = 0; le < lv_ptr->lv_allocated_le; le++) {
+ vg_ptr->pe_allocated--;
+ for (p = 0; p < vg_ptr->pv_cur; p++) {
+ if (vg_ptr->pv[p]->pv_dev ==
+ lv_ptr->lv_current_pe[le].dev) {
+ vg_ptr->pv[p]->pe_allocated--;


+ break;
+ }
+ }
+ }

+
+
+ /* save pointer to "old" lv/pe pointer array */
+ pep1 = lv_ptr->lv_current_pe;
+ end = lv_ptr->lv_current_le;
+
+ /* save open counter */
+ lv_open = lv_ptr->lv_open;
+
+ /* save # of old allocated logical extents */
+ old_allocated_le = lv_ptr->lv_allocated_le;
+
+ /* copy preloaded LV */
+ lv_status_save = lv->lv_status;
+ lv->lv_status |= LV_SPINDOWN;
+ lv->lv_status &= ~LV_ACTIVE;
+ memcpy((char *) lv_ptr, (char *) lv, sizeof(lv_t));
+ lv_ptr->lv_current_pe = pe;
+ lv_ptr->lv_open = lv_open;
+
+ /* save availiable i/o statistic data */
+ /* linear logical volume */
+ if (lv_ptr->lv_stripes < 2) {
+ /* Check what last LE shall be used */
+ if (end > lv_ptr->lv_current_le) end = lv_ptr->lv_current_le;
+ for (le = 0; le < end; le++) {
+ lv_ptr->lv_current_pe[le].reads = pep1[le].reads;
+ lv_ptr->lv_current_pe[le].writes = pep1[le].writes;
+ }
+ /* striped logical volume */
+ } else {
+ uint i, j, source, dest, end, old_stripe_size, new_stripe_size;
+
+ old_stripe_size = old_allocated_le / lv_ptr->lv_stripes;
+ new_stripe_size = lv_ptr->lv_allocated_le / lv_ptr->lv_stripes;
+ end = old_stripe_size;
+ if (end > new_stripe_size) end = new_stripe_size;
+ for (i = source = dest = 0;
+ i < lv_ptr->lv_stripes; i++) {
+ for (j = 0; j < end; j++) {
+ lv_ptr->lv_current_pe[dest + j].reads =
+ pep1[source + j].reads;
+ lv_ptr->lv_current_pe[dest + j].writes =
+ pep1[source + j].writes;
+ }
+ source += old_stripe_size;
+ dest += new_stripe_size;
+ }
+ }
+ vfree(pep1);
+ pep1 = NULL;
+
+
+ /* extend the PE count in PVs */
+ for (le = 0; le < lv_ptr->lv_allocated_le; le++) {
+ vg_ptr->pe_allocated++;
+ for (p = 0; p < vg_ptr->pv_cur; p++) {
+ if (vg_ptr->pv[p]->pv_dev ==
+ vg_ptr->lv[l]->lv_current_pe[le].dev) {
+ vg_ptr->pv[p]->pe_allocated++;


+ break;
+ }
+ }
+ }

+
+ lvm_gendisk.part[MINOR(lv_ptr->lv_dev)].start_sect = 0;
+ lvm_gendisk.part[MINOR(lv_ptr->lv_dev)].nr_sects = lv_ptr->lv_size;
+ lvm_size[MINOR(lv_ptr->lv_dev)] = lv_ptr->lv_size >> 1;
+ /* vg_lv_map array doesn't have to be changed here */
+
+ read_ahead[MAJOR_NR] = lv_ptr->lv_read_ahead = LVM_CORRECT_READ_AHEAD(lv_ptr->lv_read_ahead);
+ lv_ptr->lv_status = lv_status_save;
+
+ return 0;
+} /* lvm_do_lv_extend_reduce() */
+
+
+/*
+ * character device support function logical volume status by name
+ */
+static int lvm_do_lv_status_byname(vg_t *vg_ptr, void *arg)
+{
+ uint l;
+ ulong size;
+ lv_t lv;
+ lv_t *lv_ptr;
+ lv_status_byname_req_t lv_status_byname_req;
+


+ if (vg_ptr == NULL) return -ENXIO;

+ if (copy_from_user(&lv_status_byname_req, arg,
+ sizeof(lv_status_byname_req_t)) != 0)
+ return -EFAULT;
+
+ if (lv_status_byname_req.lv == NULL) return -EINVAL;
+ if (copy_from_user(&lv, lv_status_byname_req.lv,
+ sizeof(lv_t)) != 0)
+ return -EFAULT;
+
+ for (l = 0; l < vg_ptr->lv_max; l++) {
+ lv_ptr = vg_ptr->lv[l];
+ if (lv_ptr != NULL &&
+ strcmp(lv_ptr->lv_name,
+ lv_status_byname_req.lv_name) == 0) {
+ if (copy_to_user(lv_status_byname_req.lv,
+ lv_ptr,
+ sizeof(lv_t)) != 0)
+ return -EFAULT;
+
+ if (lv.lv_current_pe != NULL) {
+ size = lv_ptr->lv_allocated_le *
+ sizeof(pe_t);
+ if (copy_to_user(lv.lv_current_pe,
+ lv_ptr->lv_current_pe,
+ size) != 0)
+ return -EFAULT;
+ }


+ return 0;
+ }
+ }

+ return -ENXIO;
+} /* lvm_do_lv_status_byname() */
+
+
+/*
+ * character device support function logical volume status by index
+ */
+static int lvm_do_lv_status_byindex(vg_t *vg_ptr,void *arg)
+{
+ ulong size;
+ lv_t lv;
+ lv_t *lv_ptr;
+ lv_status_byindex_req_t lv_status_byindex_req;
+


+ if (vg_ptr == NULL) return -ENXIO;

+ if (copy_from_user(&lv_status_byindex_req, arg,
+ sizeof(lv_status_byindex_req)) != 0)
+ return -EFAULT;
+
+ if ((lvp = lv_status_byindex_req.lv) == NULL)
+ return -EINVAL;
+ if ( ( lv_ptr = vg_ptr->lv[lv_status_byindex_req.lv_index]) == NULL)
+ return -ENXIO;
+
+ if (copy_from_user(&lv, lvp, sizeof(lv_t)) != 0)
+ return -EFAULT;
+
+ if (copy_to_user(lvp, lv_ptr, sizeof(lv_t)) != 0)
+ return -EFAULT;
+
+ if (lv.lv_current_pe != NULL) {
+ size = lv_ptr->lv_allocated_le * sizeof(pe_t);
+ if (copy_to_user(lv.lv_current_pe,
+ lv_ptr->lv_current_pe,
+ size) != 0)
+ return -EFAULT;
+ }
+ return 0;
+} /* lvm_do_lv_status_byindex() */
+
+
+/*
+ * character device support function physical volume change
+ */
+static int lvm_do_pv_change(vg_t *vg_ptr, void *arg)
+{
+ uint p;
+ pv_t *pv_ptr;
+#ifdef LVM_GET_INODE
+ struct inode *inode_sav;
+#endif
+


+ if (vg_ptr == NULL) return -ENXIO;

+ if (copy_from_user(&pv_change_req, arg,
+ sizeof(pv_change_req)) != 0)
+ return -EFAULT;
+
+ for (p = 0; p < vg_ptr->pv_max; p++) {
+ pv_ptr = vg_ptr->pv[p];
+ if (pv_ptr != NULL &&
+ strcmp(pv_ptr->pv_name,
+ pv_change_req.pv_name) == 0) {
+#ifdef LVM_GET_INODE
+ inode_sav = pv_ptr->inode;
+#endif
+ if (copy_from_user(pv_ptr,
+ pv_change_req.pv,
+ sizeof(pv_t)) != 0)
+ return -EFAULT;
+
+ /* We don't need the PE list
+ in kernel space as with LVs pe_t list */
+ pv_ptr->pe = NULL;
+#ifdef LVM_GET_INODE
+ pv_ptr->inode = inode_sav;
+#endif


+ return 0;
+ }
+ }

+ return -ENXIO;
+} /* lvm_do_pv_change() */
+
+/*
+ * character device support function get physical volume status
+ */
+static int lvm_do_pv_status(vg_t *vg_ptr, void *arg)
+{
+ uint p;
+ pv_t *pv_ptr;
+


+ if (vg_ptr == NULL) return -ENXIO;

+ if (copy_from_user(&pv_status_req, arg,
+ sizeof(pv_status_req)) != 0)
+ return -EFAULT;
+
+ for (p = 0; p < vg_ptr->pv_max; p++) {
+ pv_ptr = vg_ptr->pv[p];
+ if (pv_ptr != NULL &&
+ strcmp(pv_ptr->pv_name,
+ pv_status_req.pv_name) == 0) {
+ if (copy_to_user(pv_status_req.pv,
+ pv_ptr,
+ sizeof(pv_t)) != 0)


+ return -EFAULT;
+ return 0;
+ }
+ }

+ return -ENXIO;
+} /* lvm_do_pv_status() */
+
+
+/*
+ * support function initialize gendisk variables
+ */
+#ifdef __initfunc
+__initfunc(void lvm_geninit(struct gendisk *lvm_gdisk))
+#else
+void __init
+ lvm_geninit(struct gendisk *lvm_gdisk)
+#endif
+{


+ int i = 0;
+

+#ifdef DEBUG_GENDISK
+ printk(KERN_DEBUG "%s -- lvm_gendisk\n", lvm_name);
+#endif
+
+ for (i = 0; i < MAX_LV; i++) {
+ lvm_gendisk.part[i].start_sect = -1; /* avoid partition check */
+ lvm_size[i] = lvm_gendisk.part[i].nr_sects = 0;
+ lvm_blocksizes[i] = BLOCK_SIZE;
+ }
+
+ blksize_size[MAJOR_NR] = lvm_blocksizes;
+ blk_size[MAJOR_NR] = lvm_size;
+
+ return;
+} /* lvm_gen_init() */
+
+
+#ifdef LVM_GET_INODE
+/*
+ * support function to get an empty inode
+ *
+ * Gets an empty inode to be inserted into the inode hash,
+ * so that a physical volume can't be mounted.
+ * This is analog to drivers/block/md.c
+ *
+ * Is this the real thing?
+ *
+ * No, it's bollocks. md.c tries to do a bit different thing that might
+ * _somewhat_ work eons ago. Neither does any good these days. mount() couldn't
+ * care less for icache (it cares only for ->s_root->d_count and if we want
+ * loopback mounts even that will stop). BTW, with the form used here mount()
+ * would have to scan the _whole_ icache to detect the attempt - how on the
+ * Earth could it guess the i_ino of your dummy inode? Official line on the
+ * exclusion between mount()/swapon()/open()/etc. is Just Don't Do It(tm).
+ * If you can convince Linus that it's worth changing - fine, then you'll need
+ * to do blkdev_get()/blkdev_put(). Until then...
+ */
+struct inode *lvm_get_inode(kdev_t dev)
+{
+ struct inode *inode_this = NULL;
+
+ /* Lock the device by inserting a dummy inode. */
+ inode_this = get_empty_inode();
+ inode_this->i_dev = dev;
+ insert_inode_hash(inode_this);
+ return inode_this;
+}
+
+
+/*
+ * support function to clear an inode
+ *
+ */
+void lvm_clear_inode(struct inode *inode)
+{
+#ifdef I_FREEING
+ inode->i_state |= I_FREEING;
+#endif
+ clear_inode(inode);
+ return;
+}
+#endif /* #ifdef LVM_GET_INODE */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/md/md.c linux/drivers/md/md.c
--- v2.4.0-test8/linux/drivers/md/md.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/md/md.c Wed Sep 27 13:55:04 2000
@@ -0,0 +1,3878 @@
+/*
+ md.c : Multiple Devices driver for Linux
+ Copyright (C) 1998, 1999, 2000 Ingo Molnar
+
+ completely rewritten, based on the MD driver code from Marc Zyngier
+
+ Changes:
+
+ - RAID-1/RAID-5 extensions by Miguel de Icaza, Gadi Oxman, Ingo Molnar
+ - boot support for linear and striped mode by Harald Hoyer <Har...@Royal.Net>
+ - kerneld support by Boris Tobotras <bo...@xtalk.msk.su>
+ - kmod support by: Cyrus Durgin
+ - RAID0 bugfixes: Mark Anthony Lisher <mar...@iname.com>
+ - Devfs support by Richard Gooch <rgo...@atnf.csiro.au>
+
+ - lots of fixes and improvements to the RAID1/RAID5 and generic
+ RAID code (such as request based resynchronization):
+
+ Neil Brown <ne...@cse.unsw.edu.au>.


+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ You should have received a copy of the GNU General Public License
+ (for example /usr/src/linux/COPYING); if not, write to the Free
+ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/module.h>

+#include <linux/config.h>
+#include <linux/raid/md.h>
+#include <linux/raid/xor.h>
+#include <linux/devfs_fs_kernel.h>
+
+#include <linux/init.h>
+
+#ifdef CONFIG_KMOD
+#include <linux/kmod.h>
+#endif
+
+#define __KERNEL_SYSCALLS__
+#include <linux/unistd.h>
+
+#include <asm/unaligned.h>
+
+extern asmlinkage int sys_sched_yield(void);
+extern asmlinkage long sys_setsid(void);


+
+#define MAJOR_NR MD_MAJOR
+#define MD_DRIVER
+

+#include <linux/blk.h>
+
+#define DEBUG 0
+#if DEBUG
+# define dprintk(x...) printk(x)
+#else
+# define dprintk(x...) do { } while(0)
+#endif
+
+static mdk_personality_t *pers[MAX_PERSONALITY] = {NULL, };
+
+/*
+ * Current RAID-1,4,5 parallel reconstruction 'guaranteed speed limit'
+ * is 100 KB/sec, so the extra system load does not show up that much.
+ * Increase it if you want to have more _guaranteed_ speed. Note that
+ * the RAID driver will use the maximum available bandwith if the IO
+ * subsystem is idle. There is also an 'absolute maximum' reconstruction
+ * speed limit - in case reconstruction slows down your system despite
+ * idle IO detection.
+ *
+ * you can change it via /proc/sys/dev/raid/speed_limit_min and _max.
+ */
+
+static int sysctl_speed_limit_min = 100;
+static int sysctl_speed_limit_max = 100000;
+
+static struct ctl_table_header *raid_table_header;
+
+static ctl_table raid_table[] = {
+ {DEV_RAID_SPEED_LIMIT_MIN, "speed_limit_min",
+ &sysctl_speed_limit_min, sizeof(int), 0644, NULL, &proc_dointvec},
+ {DEV_RAID_SPEED_LIMIT_MAX, "speed_limit_max",
+ &sysctl_speed_limit_max, sizeof(int), 0644, NULL, &proc_dointvec},
+ {0}
+};
+
+static ctl_table raid_dir_table[] = {
+ {DEV_RAID, "raid", NULL, 0, 0555, raid_table},
+ {0}
+};
+
+static ctl_table raid_root_table[] = {
+ {CTL_DEV, "dev", NULL, 0, 0555, raid_dir_table},
+ {0}
+};
+
+/*
+ * these have to be allocated separately because external
+ * subsystems want to have a pre-defined structure
+ */
+struct hd_struct md_hd_struct[MAX_MD_DEVS];
+static int md_blocksizes[MAX_MD_DEVS];
+static int md_hardsect_sizes[MAX_MD_DEVS];
+static int md_maxreadahead[MAX_MD_DEVS];
+static mdk_thread_t *md_recovery_thread = NULL;
+
+int md_size[MAX_MD_DEVS] = {0, };
+
+extern struct block_device_operations md_fops;
+static devfs_handle_t devfs_handle = NULL;
+
+static struct gendisk md_gendisk=
+{
+ major: MD_MAJOR,
+ major_name: "md",
+ minor_shift: 0,
+ max_p: 1,
+ part: md_hd_struct,
+ sizes: md_size,
+ nr_real: MAX_MD_DEVS,
+ real_devices: NULL,
+ next: NULL,
+ fops: &md_fops,
+};
+
+/*
+ * Enables to iterate over all existing md arrays
+ */
+static MD_LIST_HEAD(all_mddevs);
+
+/*
+ * The mapping between kdev and mddev is not necessary a simple
+ * one! Eg. HSM uses several sub-devices to implement Logical
+ * Volumes. All these sub-devices map to the same mddev.
+ */
+dev_mapping_t mddev_map [MAX_MD_DEVS] = { {NULL, 0}, };
+
+void add_mddev_mapping (mddev_t * mddev, kdev_t dev, void *data)
+{
+ unsigned int minor = MINOR(dev);
+
+ if (MAJOR(dev) != MD_MAJOR) {
+ MD_BUG();
+ return;
+ }
+ if (mddev_map[minor].mddev != NULL) {
+ MD_BUG();
+ return;
+ }
+ mddev_map[minor].mddev = mddev;
+ mddev_map[minor].data = data;
+}
+
+void del_mddev_mapping (mddev_t * mddev, kdev_t dev)
+{
+ unsigned int minor = MINOR(dev);
+
+ if (MAJOR(dev) != MD_MAJOR) {
+ MD_BUG();
+ return;
+ }
+ if (mddev_map[minor].mddev != mddev) {
+ MD_BUG();
+ return;
+ }
+ mddev_map[minor].mddev = NULL;
+ mddev_map[minor].data = NULL;
+}
+
+static int md_make_request (request_queue_t *q, int rw, struct buffer_head * bh)
+{
+ mddev_t *mddev = kdev_to_mddev(bh->b_rdev);
+
+ if (mddev && mddev->pers)
+ return mddev->pers->make_request(mddev, rw, bh);
+ else {
+ buffer_IO_error(bh);


+ return -1;
+ }
+}

+
+static mddev_t * alloc_mddev (kdev_t dev)
+{
+ mddev_t *mddev;
+
+ if (MAJOR(dev) != MD_MAJOR) {
+ MD_BUG();
+ return 0;
+ }
+ mddev = (mddev_t *) kmalloc(sizeof(*mddev), GFP_KERNEL);
+ if (!mddev)
+ return NULL;
+
+ memset(mddev, 0, sizeof(*mddev));
+
+ mddev->__minor = MINOR(dev);
+ init_MUTEX(&mddev->reconfig_sem);
+ init_MUTEX(&mddev->recovery_sem);
+ init_MUTEX(&mddev->resync_sem);
+ MD_INIT_LIST_HEAD(&mddev->disks);
+ MD_INIT_LIST_HEAD(&mddev->all_mddevs);
+
+ /*
+ * The 'base' mddev is the one with data NULL.
+ * personalities can create additional mddevs
+ * if necessary.
+ */
+ add_mddev_mapping(mddev, dev, 0);
+ md_list_add(&mddev->all_mddevs, &all_mddevs);
+
+ MOD_INC_USE_COUNT;
+
+ return mddev;
+}
+
+struct gendisk * find_gendisk (kdev_t dev)
+{
+ struct gendisk *tmp = gendisk_head;
+
+ while (tmp != NULL) {
+ if (tmp->major == MAJOR(dev))
+ return (tmp);
+ tmp = tmp->next;
+ }


+ return (NULL);
+}
+

+mdk_rdev_t * find_rdev_nr(mddev_t *mddev, int nr)
+{
+ mdk_rdev_t * rdev;


+ struct md_list_head *tmp;
+

+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->desc_nr == nr)
+ return rdev;
+ }


+ return NULL;
+}
+

+mdk_rdev_t * find_rdev(mddev_t * mddev, kdev_t dev)
+{
+ struct md_list_head *tmp;
+ mdk_rdev_t *rdev;
+
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->dev == dev)
+ return rdev;
+ }


+ return NULL;
+}
+

+static MD_LIST_HEAD(device_names);
+
+char * partition_name (kdev_t dev)
+{
+ struct gendisk *hd;
+ static char nomem [] = "<nomem>";
+ dev_name_t *dname;
+ struct md_list_head *tmp = device_names.next;
+
+ while (tmp != &device_names) {
+ dname = md_list_entry(tmp, dev_name_t, list);
+ if (dname->dev == dev)
+ return dname->name;
+ tmp = tmp->next;
+ }
+
+ dname = (dev_name_t *) kmalloc(sizeof(*dname), GFP_KERNEL);
+
+ if (!dname)
+ return nomem;
+ /*
+ * ok, add this new device name to the list
+ */
+ hd = find_gendisk (dev);
+ dname->name = NULL;
+ if (hd)
+ dname->name = disk_name (hd, MINOR(dev), dname->namebuf);
+ if (!dname->name) {
+ sprintf (dname->namebuf, "[dev %s]", kdevname(dev));
+ dname->name = dname->namebuf;
+ }
+
+ dname->dev = dev;
+ MD_INIT_LIST_HEAD(&dname->list);
+ md_list_add(&dname->list, &device_names);
+
+ return dname->name;
+}
+
+static unsigned int calc_dev_sboffset (kdev_t dev, mddev_t *mddev,
+ int persistent)
+{
+ unsigned int size = 0;
+
+ if (blk_size[MAJOR(dev)])
+ size = blk_size[MAJOR(dev)][MINOR(dev)];
+ if (persistent)
+ size = MD_NEW_SIZE_BLOCKS(size);
+ return size;
+}
+
+static unsigned int calc_dev_size (kdev_t dev, mddev_t *mddev, int persistent)
+{
+ unsigned int size;
+
+ size = calc_dev_sboffset(dev, mddev, persistent);
+ if (!mddev->sb) {
+ MD_BUG();
+ return size;
+ }
+ if (mddev->sb->chunk_size)
+ size &= ~(mddev->sb->chunk_size/1024 - 1);
+ return size;
+}
+
+static unsigned int zoned_raid_size (mddev_t *mddev)
+{
+ unsigned int mask;
+ mdk_rdev_t * rdev;


+ struct md_list_head *tmp;
+

+ if (!mddev->sb) {
+ MD_BUG();
+ return -EINVAL;
+ }
+ /*
+ * do size and offset calculations.
+ */
+ mask = ~(mddev->sb->chunk_size/1024 - 1);
+
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ rdev->size &= mask;
+ md_size[mdidx(mddev)] += rdev->size;


+ }
+ return 0;
+}
+
+/*

+ * We check wether all devices are numbered from 0 to nb_dev-1. The
+ * order is guaranteed even after device name changes.
+ *
+ * Some personalities (raid0, linear) use this. Personalities that
+ * provide data have to be able to deal with loss of individual
+ * disks, so they do their checking themselves.
+ */
+int md_check_ordering (mddev_t *mddev)
+{
+ int i, c;
+ mdk_rdev_t *rdev;
+ struct md_list_head *tmp;
+
+ /*
+ * First, all devices must be fully functional
+ */
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->faulty) {
+ printk("md: md%d's device %s faulty, aborting.\n",
+ mdidx(mddev), partition_name(rdev->dev));


+ goto abort;
+ }
+ }
+

+ c = 0;
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ c++;
+ }
+ if (c != mddev->nb_dev) {
+ MD_BUG();
+ goto abort;
+ }
+ if (mddev->nb_dev != mddev->sb->raid_disks) {
+ printk("md: md%d, array needs %d disks, has %d, aborting.\n",
+ mdidx(mddev), mddev->sb->raid_disks, mddev->nb_dev);
+ goto abort;
+ }
+ /*
+ * Now the numbering check
+ */
+ for (i = 0; i < mddev->nb_dev; i++) {
+ c = 0;
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->desc_nr == i)
+ c++;
+ }
+ if (!c) {
+ printk("md: md%d, missing disk #%d, aborting.\n",
+ mdidx(mddev), i);
+ goto abort;
+ }
+ if (c > 1) {
+ printk("md: md%d, too many disks #%d, aborting.\n",
+ mdidx(mddev), i);
+ goto abort;


+ }
+ }
+ return 0;

+abort:


+ return 1;
+}
+

+static void remove_descriptor (mdp_disk_t *disk, mdp_super_t *sb)
+{
+ if (disk_active(disk)) {
+ sb->working_disks--;
+ } else {
+ if (disk_spare(disk)) {


+ sb->spare_disks--;
+ sb->working_disks--;

+ } else {
+ sb->failed_disks--;
+ }
+ }
+ sb->nr_disks--;
+ disk->major = 0;
+ disk->minor = 0;
+ mark_disk_removed(disk);
+}
+
+#define BAD_MAGIC KERN_ERR \
+"md: invalid raid superblock magic on %s\n"
+
+#define BAD_MINOR KERN_ERR \
+"md: %s: invalid raid minor (%x)\n"
+
+#define OUT_OF_MEM KERN_ALERT \
+"md: out of memory.\n"
+
+#define NO_SB KERN_ERR \
+"md: disabled device %s, could not read superblock.\n"
+
+#define BAD_CSUM KERN_WARNING \
+"md: invalid superblock checksum on %s\n"
+
+static int alloc_array_sb (mddev_t * mddev)
+{
+ if (mddev->sb) {
+ MD_BUG();


+ return 0;
+ }
+

+ mddev->sb = (mdp_super_t *) __get_free_page (GFP_KERNEL);
+ if (!mddev->sb)
+ return -ENOMEM;
+ md_clear_page(mddev->sb);


+ return 0;
+}
+

+static int alloc_disk_sb (mdk_rdev_t * rdev)
+{
+ if (rdev->sb)
+ MD_BUG();
+
+ rdev->sb = (mdp_super_t *) __get_free_page(GFP_KERNEL);
+ if (!rdev->sb) {
+ printk (OUT_OF_MEM);
+ return -EINVAL;
+ }
+ md_clear_page(rdev->sb);


+
+ return 0;
+}
+

+static void free_disk_sb (mdk_rdev_t * rdev)
+{
+ if (rdev->sb) {
+ free_page((unsigned long) rdev->sb);
+ rdev->sb = NULL;
+ rdev->sb_offset = 0;
+ rdev->size = 0;
+ } else {
+ if (!rdev->faulty)
+ MD_BUG();
+ }
+}
+
+static void mark_rdev_faulty (mdk_rdev_t * rdev)
+{
+ if (!rdev) {
+ MD_BUG();
+ return;
+ }
+ free_disk_sb(rdev);
+ rdev->faulty = 1;
+}
+
+static int read_disk_sb (mdk_rdev_t * rdev)
+{
+ int ret = -EINVAL;
+ struct buffer_head *bh = NULL;
+ kdev_t dev = rdev->dev;
+ mdp_super_t *sb;
+ unsigned long sb_offset;
+
+ if (!rdev->sb) {
+ MD_BUG();
+ goto abort;
+ }
+
+ /*
+ * Calculate the position of the superblock,
+ * it's at the end of the disk
+ */
+ sb_offset = calc_dev_sboffset(rdev->dev, rdev->mddev, 1);
+ rdev->sb_offset = sb_offset;
+ printk("(read) %s's sb offset: %ld", partition_name(dev), sb_offset);
+ fsync_dev(dev);
+ set_blocksize (dev, MD_SB_BYTES);
+ bh = bread (dev, sb_offset / MD_SB_BLOCKS, MD_SB_BYTES);
+
+ if (bh) {
+ sb = (mdp_super_t *) bh->b_data;
+ memcpy (rdev->sb, sb, MD_SB_BYTES);
+ } else {
+ printk (NO_SB,partition_name(rdev->dev));
+ goto abort;
+ }
+ printk(" [events: %08lx]\n", (unsigned long)rdev->sb->events_lo);
+ ret = 0;
+abort:
+ if (bh)
+ brelse (bh);


+ return ret;
+}
+

+static unsigned int calc_sb_csum (mdp_super_t * sb)
+{
+ unsigned int disk_csum, csum;
+
+ disk_csum = sb->sb_csum;
+ sb->sb_csum = 0;
+ csum = csum_partial((void *)sb, MD_SB_BYTES, 0);
+ sb->sb_csum = disk_csum;
+ return csum;
+}
+
+/*
+ * Check one RAID superblock for generic plausibility
+ */
+
+static int check_disk_sb (mdk_rdev_t * rdev)
+{
+ mdp_super_t *sb;
+ int ret = -EINVAL;
+
+ sb = rdev->sb;
+ if (!sb) {
+ MD_BUG();


+ goto abort;
+ }
+

+ if (sb->md_magic != MD_SB_MAGIC) {
+ printk (BAD_MAGIC, partition_name(rdev->dev));


+ goto abort;
+ }
+

+ if (sb->md_minor >= MAX_MD_DEVS) {
+ printk (BAD_MINOR, partition_name(rdev->dev),
+ sb->md_minor);


+ goto abort;
+ }
+

+ if (calc_sb_csum(sb) != sb->sb_csum)
+ printk(BAD_CSUM, partition_name(rdev->dev));
+ ret = 0;
+abort:


+ return ret;
+}
+

+static kdev_t dev_unit(kdev_t dev)
+{
+ unsigned int mask;
+ struct gendisk *hd = find_gendisk(dev);
+
+ if (!hd)
+ return 0;
+ mask = ~((1 << hd->minor_shift) - 1);
+
+ return MKDEV(MAJOR(dev), MINOR(dev) & mask);
+}
+
+static mdk_rdev_t * match_dev_unit(mddev_t *mddev, kdev_t dev)
+{
+ struct md_list_head *tmp;
+ mdk_rdev_t *rdev;
+
+ ITERATE_RDEV(mddev,rdev,tmp)
+ if (dev_unit(rdev->dev) == dev_unit(dev))
+ return rdev;
+


+ return NULL;
+}
+

+static int match_mddev_units(mddev_t *mddev1, mddev_t *mddev2)


+{
+ struct md_list_head *tmp;

+ mdk_rdev_t *rdev;
+
+ ITERATE_RDEV(mddev1,rdev,tmp)
+ if (match_dev_unit(mddev2, rdev->dev))
+ return 1;
+


+ return 0;
+}
+

+static MD_LIST_HEAD(all_raid_disks);
+static MD_LIST_HEAD(pending_raid_disks);
+
+static void bind_rdev_to_array (mdk_rdev_t * rdev, mddev_t * mddev)
+{
+ mdk_rdev_t *same_pdev;
+
+ if (rdev->mddev) {
+ MD_BUG();
+ return;
+ }
+ same_pdev = match_dev_unit(mddev, rdev->dev);
+ if (same_pdev)
+ printk( KERN_WARNING
+"md%d: WARNING: %s appears to be on the same physical disk as %s. True\n"
+" protection against single-disk failure might be compromised.\n",
+ mdidx(mddev), partition_name(rdev->dev),
+ partition_name(same_pdev->dev));
+
+ md_list_add(&rdev->same_set, &mddev->disks);
+ rdev->mddev = mddev;
+ mddev->nb_dev++;
+ printk("bind<%s,%d>\n", partition_name(rdev->dev), mddev->nb_dev);
+}
+
+static void unbind_rdev_from_array (mdk_rdev_t * rdev)
+{
+ if (!rdev->mddev) {
+ MD_BUG();
+ return;
+ }
+ md_list_del(&rdev->same_set);
+ MD_INIT_LIST_HEAD(&rdev->same_set);
+ rdev->mddev->nb_dev--;
+ printk("unbind<%s,%d>\n", partition_name(rdev->dev),
+ rdev->mddev->nb_dev);
+ rdev->mddev = NULL;
+}
+
+/*
+ * prevent the device from being mounted, repartitioned or
+ * otherwise reused by a RAID array (or any other kernel
+ * subsystem), by opening the device. [simply getting an
+ * inode is not enough, the SCSI module usage code needs
+ * an explicit open() on the device]
+ */
+static int lock_rdev (mdk_rdev_t *rdev)
+{
+ int err = 0;
+
+ /*
+ * First insert a dummy inode.
+ */
+ if (rdev->inode)
+ MD_BUG();
+ rdev->inode = get_empty_inode();
+ if (!rdev->inode)
+ return -ENOMEM;
+ /*
+ * we dont care about any other fields
+ */
+ rdev->inode->i_dev = rdev->inode->i_rdev = rdev->dev;
+ insert_inode_hash(rdev->inode);
+
+ memset(&rdev->filp, 0, sizeof(rdev->filp));
+ rdev->filp.f_mode = 3; /* read write */


+ return err;
+}
+

+static void unlock_rdev (mdk_rdev_t *rdev)
+{
+ if (!rdev->inode)
+ MD_BUG();
+ iput(rdev->inode);
+ rdev->inode = NULL;
+}
+
+static void export_rdev (mdk_rdev_t * rdev)
+{
+ printk("export_rdev(%s)\n",partition_name(rdev->dev));
+ if (rdev->mddev)
+ MD_BUG();
+ unlock_rdev(rdev);
+ free_disk_sb(rdev);
+ md_list_del(&rdev->all);
+ MD_INIT_LIST_HEAD(&rdev->all);


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 055'
echo 'File patch-2.4.0-test9 is continued in part 056'
echo "056" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part056

#!/bin/sh -x
# this is part 056 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 056; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ if (rdev->pending.next != &rdev->pending) {
+ printk("(%s was pending)\n",partition_name(rdev->dev));
+ md_list_del(&rdev->pending);
+ MD_INIT_LIST_HEAD(&rdev->pending);
+ }
+ rdev->dev = 0;
+ rdev->faulty = 0;
+ kfree(rdev);
+}
+
+static void kick_rdev_from_array (mdk_rdev_t * rdev)
+{
+ unbind_rdev_from_array(rdev);
+ export_rdev(rdev);
+}
+
+static void export_array (mddev_t *mddev)


+{
+ struct md_list_head *tmp;
+ mdk_rdev_t *rdev;

+ mdp_super_t *sb = mddev->sb;

+
+ if (mddev->sb) {

+ mddev->sb = NULL;
+ free_page((unsigned long) sb);
+ }
+
+ ITERATE_RDEV(mddev,rdev,tmp) {


+ if (!rdev->mddev) {
+ MD_BUG();

+ continue;
+ }
+ kick_rdev_from_array(rdev);
+ }
+ if (mddev->nb_dev)
+ MD_BUG();
+}
+
+static void free_mddev (mddev_t *mddev)
+{
+ if (!mddev) {


+ MD_BUG();
+ return;
+ }
+

+ export_array(mddev);
+ md_size[mdidx(mddev)] = 0;
+ md_hd_struct[mdidx(mddev)].nr_sects = 0;
+
+ /*
+ * Make sure nobody else is using this mddev
+ * (careful, we rely on the global kernel lock here)
+ */
+ while (md_atomic_read(&mddev->resync_sem.count) != 1)
+ schedule();
+ while (md_atomic_read(&mddev->recovery_sem.count) != 1)
+ schedule();
+
+ del_mddev_mapping(mddev, MKDEV(MD_MAJOR, mdidx(mddev)));
+ md_list_del(&mddev->all_mddevs);
+ MD_INIT_LIST_HEAD(&mddev->all_mddevs);
+ kfree(mddev);
+ MOD_DEC_USE_COUNT;
+}
+
+#undef BAD_CSUM
+#undef BAD_MAGIC
+#undef OUT_OF_MEM
+#undef NO_SB
+
+static void print_desc(mdp_disk_t *desc)
+{
+ printk(" DISK<N:%d,%s(%d,%d),R:%d,S:%d>\n", desc->number,
+ partition_name(MKDEV(desc->major,desc->minor)),
+ desc->major,desc->minor,desc->raid_disk,desc->state);
+}
+
+static void print_sb(mdp_super_t *sb)


+{
+ int i;
+

+ printk(" SB: (V:%d.%d.%d) ID:<%08x.%08x.%08x.%08x> CT:%08x\n",
+ sb->major_version, sb->minor_version, sb->patch_version,
+ sb->set_uuid0, sb->set_uuid1, sb->set_uuid2, sb->set_uuid3,
+ sb->ctime);
+ printk(" L%d S%08d ND:%d RD:%d md%d LO:%d CS:%d\n", sb->level,
+ sb->size, sb->nr_disks, sb->raid_disks, sb->md_minor,
+ sb->layout, sb->chunk_size);
+ printk(" UT:%08x ST:%d AD:%d WD:%d FD:%d SD:%d CSUM:%08x E:%08lx\n",
+ sb->utime, sb->state, sb->active_disks, sb->working_disks,
+ sb->failed_disks, sb->spare_disks,
+ sb->sb_csum, (unsigned long)sb->events_lo);
+
+ for (i = 0; i < MD_SB_DISKS; i++) {
+ mdp_disk_t *desc;
+
+ desc = sb->disks + i;
+ printk(" D %2d: ", i);
+ print_desc(desc);
+ }
+ printk(" THIS: ");
+ print_desc(&sb->this_disk);
+
+}
+
+static void print_rdev(mdk_rdev_t *rdev)
+{
+ printk(" rdev %s: O:%s, SZ:%08ld F:%d DN:%d ",
+ partition_name(rdev->dev), partition_name(rdev->old_dev),
+ rdev->size, rdev->faulty, rdev->desc_nr);
+ if (rdev->sb) {
+ printk("rdev superblock:\n");
+ print_sb(rdev->sb);
+ } else
+ printk("no rdev superblock!\n");
+}
+
+void md_print_devices (void)
+{
+ struct md_list_head *tmp, *tmp2;
+ mdk_rdev_t *rdev;
+ mddev_t *mddev;
+
+ printk("\n");
+ printk(" **********************************\n");
+ printk(" * <COMPLETE RAID STATE PRINTOUT> *\n");
+ printk(" **********************************\n");
+ ITERATE_MDDEV(mddev,tmp) {
+ printk("md%d: ", mdidx(mddev));
+
+ ITERATE_RDEV(mddev,rdev,tmp2)
+ printk("<%s>", partition_name(rdev->dev));


+
+ if (mddev->sb) {

+ printk(" array superblock:\n");
+ print_sb(mddev->sb);
+ } else
+ printk(" no array superblock.\n");
+
+ ITERATE_RDEV(mddev,rdev,tmp2)
+ print_rdev(rdev);
+ }
+ printk(" **********************************\n");
+ printk("\n");
+}
+
+static int sb_equal ( mdp_super_t *sb1, mdp_super_t *sb2)
+{
+ int ret;
+ mdp_super_t *tmp1, *tmp2;
+
+ tmp1 = kmalloc(sizeof(*tmp1),GFP_KERNEL);
+ tmp2 = kmalloc(sizeof(*tmp2),GFP_KERNEL);
+
+ if (!tmp1 || !tmp2) {
+ ret = 0;


+ goto abort;
+ }
+

+ *tmp1 = *sb1;
+ *tmp2 = *sb2;
+
+ /*
+ * nr_disks is not constant
+ */
+ tmp1->nr_disks = 0;
+ tmp2->nr_disks = 0;
+
+ if (memcmp(tmp1, tmp2, MD_SB_GENERIC_CONSTANT_WORDS * 4))
+ ret = 0;
+ else
+ ret = 1;
+
+abort:
+ if (tmp1)
+ kfree(tmp1);
+ if (tmp2)
+ kfree(tmp2);
+


+ return ret;
+}
+

+static int uuid_equal(mdk_rdev_t *rdev1, mdk_rdev_t *rdev2)
+{
+ if ( (rdev1->sb->set_uuid0 == rdev2->sb->set_uuid0) &&
+ (rdev1->sb->set_uuid1 == rdev2->sb->set_uuid1) &&
+ (rdev1->sb->set_uuid2 == rdev2->sb->set_uuid2) &&
+ (rdev1->sb->set_uuid3 == rdev2->sb->set_uuid3))


+
+ return 1;
+

+ return 0;
+}
+

+static mdk_rdev_t * find_rdev_all (kdev_t dev)
+{


+ struct md_list_head *tmp;
+ mdk_rdev_t *rdev;
+

+ tmp = all_raid_disks.next;
+ while (tmp != &all_raid_disks) {
+ rdev = md_list_entry(tmp, mdk_rdev_t, all);


+ if (rdev->dev == dev)
+ return rdev;

+ tmp = tmp->next;
+ }

+ return NULL;
+}
+
+#define GETBLK_FAILED KERN_ERR \
+"md: getblk failed for device %s\n"
+
+static int write_disk_sb(mdk_rdev_t * rdev)
+{
+ struct buffer_head *bh;
+ kdev_t dev;
+ unsigned long sb_offset, size;
+ mdp_super_t *sb;


+
+ if (!rdev->sb) {
+ MD_BUG();

+ return -1;
+ }
+ if (rdev->faulty) {
+ MD_BUG();
+ return -1;
+ }
+ if (rdev->sb->md_magic != MD_SB_MAGIC) {
+ MD_BUG();


+ return -1;
+ }
+

+ dev = rdev->dev;
+ sb_offset = calc_dev_sboffset(dev, rdev->mddev, 1);
+ if (rdev->sb_offset != sb_offset) {
+ printk("%s's sb offset has changed from %ld to %ld, skipping\n", partition_name(dev), rdev->sb_offset, sb_offset);
+ goto skip;
+ }
+ /*
+ * If the disk went offline meanwhile and it's just a spare, then
+ * it's size has changed to zero silently, and the MD code does
+ * not yet know that it's faulty.
+ */
+ size = calc_dev_size(dev, rdev->mddev, 1);
+ if (size != rdev->size) {
+ printk("%s's size has changed from %ld to %ld since import, skipping\n", partition_name(dev), rdev->size, size);
+ goto skip;
+ }
+
+ printk("(write) %s's sb offset: %ld\n", partition_name(dev), sb_offset);


+ fsync_dev(dev);
+ set_blocksize(dev, MD_SB_BYTES);

+ bh = getblk(dev, sb_offset / MD_SB_BLOCKS, MD_SB_BYTES);
+ if (!bh) {
+ printk(GETBLK_FAILED, partition_name(dev));
+ return 1;
+ }
+ memset(bh->b_data,0,bh->b_size);


+ sb = (mdp_super_t *) bh->b_data;

+ memcpy(sb, rdev->sb, MD_SB_BYTES);
+
+ mark_buffer_uptodate(bh, 1);
+ mark_buffer_dirty(bh);
+ ll_rw_block(WRITE, 1, &bh);
+ wait_on_buffer(bh);
+ brelse(bh);
+ fsync_dev(dev);
+skip:
+ return 0;
+}
+#undef GETBLK_FAILED
+
+static void set_this_disk(mddev_t *mddev, mdk_rdev_t *rdev)
+{
+ int i, ok = 0;
+ mdp_disk_t *desc;
+
+ for (i = 0; i < MD_SB_DISKS; i++) {
+ desc = mddev->sb->disks + i;
+#if 0
+ if (disk_faulty(desc)) {
+ if (MKDEV(desc->major,desc->minor) == rdev->dev)
+ ok = 1;
+ continue;
+ }
+#endif
+ if (MKDEV(desc->major,desc->minor) == rdev->dev) {
+ rdev->sb->this_disk = *desc;
+ rdev->desc_nr = desc->number;
+ ok = 1;


+ break;
+ }
+ }
+

+ if (!ok) {


+ MD_BUG();
+ }
+}
+

+static int sync_sbs(mddev_t * mddev)
+{
+ mdk_rdev_t *rdev;
+ mdp_super_t *sb;


+ struct md_list_head *tmp;
+
+ ITERATE_RDEV(mddev,rdev,tmp) {

+ if (rdev->faulty)
+ continue;


+ sb = rdev->sb;

+ *sb = *mddev->sb;
+ set_this_disk(mddev, rdev);
+ sb->sb_csum = calc_sb_csum(sb);


+ }
+ return 0;
+}
+

+int md_update_sb(mddev_t * mddev)
+{
+ int first, err, count = 100;


+ struct md_list_head *tmp;
+ mdk_rdev_t *rdev;
+

+repeat:
+ mddev->sb->utime = CURRENT_TIME;
+ if ((++mddev->sb->events_lo)==0)
+ ++mddev->sb->events_hi;
+
+ if ((mddev->sb->events_lo|mddev->sb->events_hi)==0) {
+ /*
+ * oops, this 64-bit counter should never wrap.
+ * Either we are in around ~1 trillion A.C., assuming
+ * 1 reboot per second, or we have a bug:
+ */
+ MD_BUG();
+ mddev->sb->events_lo = mddev->sb->events_hi = 0xffffffff;
+ }
+ sync_sbs(mddev);
+
+ /*
+ * do not write anything to disk if using
+ * nonpersistent superblocks
+ */
+ if (mddev->sb->not_persistent)
+ return 0;
+
+ printk(KERN_INFO "md: updating md%d RAID superblock on device\n",
+ mdidx(mddev));
+
+ first = 1;
+ err = 0;
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (!first) {
+ first = 0;
+ printk(", ");
+ }
+ if (rdev->faulty)
+ printk("(skipping faulty ");
+ printk("%s ", partition_name(rdev->dev));
+ if (!rdev->faulty) {
+ printk("[events: %08lx]",
+ (unsigned long)rdev->sb->events_lo);
+ err += write_disk_sb(rdev);
+ } else
+ printk(")\n");
+ }
+ printk(".\n");
+ if (err) {
+ printk("errors occured during superblock update, repeating\n");
+ if (--count)
+ goto repeat;
+ printk("excessive errors occured during superblock update, exiting\n");


+ }
+ return 0;
+}
+
+/*

+ * Import a device. If 'on_disk', then sanity check the superblock
+ *
+ * mark the device faulty if:
+ *
+ * - the device is nonexistent (zero size)
+ * - the device has no valid superblock
+ *
+ * a faulty rdev _never_ has rdev->sb set.
+ */
+static int md_import_device (kdev_t newdev, int on_disk)
+{
+ int err;
+ mdk_rdev_t *rdev;


+ unsigned int size;
+

+ if (find_rdev_all(newdev))
+ return -EEXIST;
+
+ rdev = (mdk_rdev_t *) kmalloc(sizeof(*rdev), GFP_KERNEL);
+ if (!rdev) {
+ printk("could not alloc mem for %s!\n", partition_name(newdev));
+ return -ENOMEM;
+ }
+ memset(rdev, 0, sizeof(*rdev));
+
+ if (get_super(newdev)) {
+ printk("md: can not import %s, has active inodes!\n",
+ partition_name(newdev));
+ err = -EBUSY;
+ goto abort_free;
+ }
+
+ if ((err = alloc_disk_sb(rdev)))
+ goto abort_free;
+
+ rdev->dev = newdev;
+ if (lock_rdev(rdev)) {
+ printk("md: could not lock %s, zero-size? Marking faulty.\n",
+ partition_name(newdev));
+ err = -EINVAL;
+ goto abort_free;
+ }
+ rdev->desc_nr = -1;
+ rdev->faulty = 0;
+
+ size = 0;
+ if (blk_size[MAJOR(newdev)])
+ size = blk_size[MAJOR(newdev)][MINOR(newdev)];
+ if (!size) {
+ printk("md: %s has zero size, marking faulty!\n",
+ partition_name(newdev));
+ err = -EINVAL;
+ goto abort_free;
+ }
+
+ if (on_disk) {
+ if ((err = read_disk_sb(rdev))) {
+ printk("md: could not read %s's sb, not importing!\n",
+ partition_name(newdev));
+ goto abort_free;
+ }
+ if ((err = check_disk_sb(rdev))) {
+ printk("md: %s has invalid sb, not importing!\n",
+ partition_name(newdev));
+ goto abort_free;
+ }
+
+ rdev->old_dev = MKDEV(rdev->sb->this_disk.major,
+ rdev->sb->this_disk.minor);
+ rdev->desc_nr = rdev->sb->this_disk.number;
+ }
+ md_list_add(&rdev->all, &all_raid_disks);
+ MD_INIT_LIST_HEAD(&rdev->pending);
+
+ if (rdev->faulty && rdev->sb)
+ free_disk_sb(rdev);
+ return 0;
+
+abort_free:
+ if (rdev->sb) {
+ if (rdev->inode)


+ unlock_rdev(rdev);
+ free_disk_sb(rdev);
+ }

+ kfree(rdev);


+ return err;
+}
+

+/*
+ * Check a full RAID array for plausibility
+ */
+
+#define INCONSISTENT KERN_ERR \
+"md: fatal superblock inconsistency in %s -- removing from array\n"
+
+#define OUT_OF_DATE KERN_ERR \
+"md: superblock update time inconsistency -- using the most recent one\n"
+
+#define OLD_VERSION KERN_ALERT \
+"md: md%d: unsupported raid array version %d.%d.%d\n"
+
+#define NOT_CLEAN_IGNORE KERN_ERR \
+"md: md%d: raid array is not clean -- starting background reconstruction\n"
+
+#define UNKNOWN_LEVEL KERN_ERR \
+"md: md%d: unsupported raid level %d\n"
+
+static int analyze_sbs (mddev_t * mddev)
+{
+ int out_of_date = 0, i;
+ struct md_list_head *tmp, *tmp2;
+ mdk_rdev_t *rdev, *rdev2, *freshest;
+ mdp_super_t *sb;
+
+ /*
+ * Verify the RAID superblock on each real device


+ */
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->faulty) {

+ MD_BUG();
+ goto abort;
+ }

+ if (!rdev->sb) {
+ MD_BUG();
+ goto abort;
+ }

+ if (check_disk_sb(rdev))


+ goto abort;
+ }
+
+ /*

+ * The superblock constant part has to be the same
+ * for all disks in the array.
+ */
+ sb = NULL;
+
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (!sb) {


+ sb = rdev->sb;

+ continue;
+ }
+ if (!sb_equal(sb, rdev->sb)) {
+ printk (INCONSISTENT, partition_name(rdev->dev));
+ kick_rdev_from_array(rdev);
+ continue;


+ }
+ }
+
+ /*

+ * OK, we have all disks and the array is ready to run. Let's
+ * find the freshest superblock, that one will be the superblock
+ * that represents the whole array.
+ */
+ if (!mddev->sb)
+ if (alloc_array_sb(mddev))
+ goto abort;


+ sb = mddev->sb;

+ freshest = NULL;
+
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ __u64 ev1, ev2;
+ /*
+ * if the checksum is invalid, use the superblock
+ * only as a last resort. (decrease it's age by
+ * one event)
+ */
+ if (calc_sb_csum(rdev->sb) != rdev->sb->sb_csum) {
+ if (rdev->sb->events_lo || rdev->sb->events_hi)
+ if ((rdev->sb->events_lo--)==0)
+ rdev->sb->events_hi--;
+ }
+
+ printk("%s's event counter: %08lx\n", partition_name(rdev->dev),
+ (unsigned long)rdev->sb->events_lo);
+ if (!freshest) {
+ freshest = rdev;
+ continue;
+ }
+ /*
+ * Find the newest superblock version
+ */
+ ev1 = md_event(rdev->sb);
+ ev2 = md_event(freshest->sb);
+ if (ev1 != ev2) {
+ out_of_date = 1;
+ if (ev1 > ev2)
+ freshest = rdev;
+ }
+ }
+ if (out_of_date) {
+ printk(OUT_OF_DATE);
+ printk("freshest: %s\n", partition_name(freshest->dev));
+ }
+ memcpy (sb, freshest->sb, sizeof(*sb));
+
+ /*
+ * at this point we have picked the 'best' superblock
+ * from all available superblocks.
+ * now we validate this superblock and kick out possibly
+ * failed disks.
+ */
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ /*
+ * Kick all non-fresh devices faulty
+ */
+ __u64 ev1, ev2;
+ ev1 = md_event(rdev->sb);
+ ev2 = md_event(sb);
+ ++ev1;
+ if (ev1 < ev2) {
+ printk("md: kicking non-fresh %s from array!\n",
+ partition_name(rdev->dev));
+ kick_rdev_from_array(rdev);
+ continue;


+ }
+ }
+
+ /*

+ * Fix up changed device names ... but only if this disk has a
+ * recent update time. Use faulty checksum ones too.
+ */
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ __u64 ev1, ev2, ev3;
+ if (rdev->faulty) { /* REMOVEME */


+ MD_BUG();
+ goto abort;
+ }

+ ev1 = md_event(rdev->sb);
+ ev2 = md_event(sb);
+ ev3 = ev2;
+ --ev3;
+ if ((rdev->dev != rdev->old_dev) &&
+ ((ev1 == ev2) || (ev1 == ev3))) {
+ mdp_disk_t *desc;
+
+ printk("md: device name has changed from %s to %s since last import!\n", partition_name(rdev->old_dev), partition_name(rdev->dev));
+ if (rdev->desc_nr == -1) {


+ MD_BUG();
+ goto abort;
+ }

+ desc = &sb->disks[rdev->desc_nr];
+ if (rdev->old_dev != MKDEV(desc->major, desc->minor)) {


+ MD_BUG();
+ goto abort;
+ }

+ desc->major = MAJOR(rdev->dev);
+ desc->minor = MINOR(rdev->dev);
+ desc = &rdev->sb->this_disk;
+ desc->major = MAJOR(rdev->dev);
+ desc->minor = MINOR(rdev->dev);


+ }
+ }
+
+ /*

+ * Remove unavailable and faulty devices ...
+ *
+ * note that if an array becomes completely unrunnable due to
+ * missing devices, we do not write the superblock back, so the
+ * administrator has a chance to fix things up. The removal thus
+ * only happens if it's nonfatal to the contents of the array.
+ */
+ for (i = 0; i < MD_SB_DISKS; i++) {
+ int found;
+ mdp_disk_t *desc;
+ kdev_t dev;
+
+ desc = sb->disks + i;
+ dev = MKDEV(desc->major, desc->minor);
+
+ /*
+ * We kick faulty devices/descriptors immediately.
+ */
+ if (disk_faulty(desc)) {
+ found = 0;
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->desc_nr != desc->number)
+ continue;
+ printk("md%d: kicking faulty %s!\n",
+ mdidx(mddev),partition_name(rdev->dev));
+ kick_rdev_from_array(rdev);
+ found = 1;
+ break;
+ }
+ if (!found) {
+ if (dev == MKDEV(0,0))
+ continue;
+ printk("md%d: removing former faulty %s!\n",
+ mdidx(mddev), partition_name(dev));
+ }
+ remove_descriptor(desc, sb);
+ continue;
+ }
+
+ if (dev == MKDEV(0,0))
+ continue;
+ /*
+ * Is this device present in the rdev ring?
+ */
+ found = 0;
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->desc_nr == desc->number) {
+ found = 1;
+ break;
+ }
+ }
+ if (found)
+ continue;
+
+ printk("md%d: former device %s is unavailable, removing from array!\n", mdidx(mddev), partition_name(dev));
+ remove_descriptor(desc, sb);
+ }
+
+ /*
+ * Double check wether all devices mentioned in the
+ * superblock are in the rdev ring.
+ */
+ for (i = 0; i < MD_SB_DISKS; i++) {
+ mdp_disk_t *desc;
+ kdev_t dev;
+
+ desc = sb->disks + i;
+ dev = MKDEV(desc->major, desc->minor);
+
+ if (dev == MKDEV(0,0))
+ continue;
+
+ if (disk_faulty(desc)) {


+ MD_BUG();
+ goto abort;
+ }
+

+ rdev = find_rdev(mddev, dev);


+ if (!rdev) {
+ MD_BUG();

+ goto abort;
+ }
+ }
+

+ /*
+ * Do a final reality check.
+ */
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->desc_nr == -1) {


+ MD_BUG();
+ goto abort;
+ }

+ /*
+ * is the desc_nr unique?
+ */
+ ITERATE_RDEV(mddev,rdev2,tmp2) {
+ if ((rdev2 != rdev) &&
+ (rdev2->desc_nr == rdev->desc_nr)) {


+ MD_BUG();
+ goto abort;
+ }
+ }
+ /*

+ * is the device unique?
+ */
+ ITERATE_RDEV(mddev,rdev2,tmp2) {
+ if ((rdev2 != rdev) &&
+ (rdev2->dev == rdev->dev)) {


+ MD_BUG();
+ goto abort;
+ }
+ }
+ }

+
+ /*
+ * Check if we can support this RAID array
+ */
+ if (sb->major_version != MD_MAJOR_VERSION ||
+ sb->minor_version > MD_MINOR_VERSION) {
+
+ printk (OLD_VERSION, mdidx(mddev), sb->major_version,
+ sb->minor_version, sb->patch_version);


+ goto abort;
+ }
+

+ if ((sb->state != (1 << MD_SB_CLEAN)) && ((sb->level == 1) ||
+ (sb->level == 4) || (sb->level == 5)))
+ printk (NOT_CLEAN_IGNORE, mdidx(mddev));


+
+ return 0;
+abort:
+ return 1;
+}
+

+#undef INCONSISTENT
+#undef OUT_OF_DATE
+#undef OLD_VERSION
+#undef OLD_LEVEL
+
+static int device_size_calculation (mddev_t * mddev)
+{
+ int data_disks = 0, persistent;
+ unsigned int readahead;


+ mdp_super_t *sb = mddev->sb;

+ struct md_list_head *tmp;
+ mdk_rdev_t *rdev;
+

+ /*
+ * Do device size calculation. Bail out if too small.
+ * (we have to do this after having validated chunk_size,
+ * because device size has to be modulo chunk_size)
+ */
+ persistent = !mddev->sb->not_persistent;


+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->faulty)

+ continue;
+ if (rdev->size) {
+ MD_BUG();
+ continue;
+ }
+ rdev->size = calc_dev_size(rdev->dev, mddev, persistent);
+ if (rdev->size < sb->chunk_size / 1024) {
+ printk (KERN_WARNING
+ "Dev %s smaller than chunk_size: %ldk < %dk\n",
+ partition_name(rdev->dev),
+ rdev->size, sb->chunk_size / 1024);


+ return -EINVAL;
+ }
+ }
+

+ switch (sb->level) {
+ case -3:
+ data_disks = 1;
+ break;
+ case -2:
+ data_disks = 1;
+ break;
+ case -1:
+ zoned_raid_size(mddev);
+ data_disks = 1;
+ break;
+ case 0:
+ zoned_raid_size(mddev);
+ data_disks = sb->raid_disks;


+ break;
+ case 1:

+ data_disks = 1;
+ break;
+ case 4:
+ case 5:
+ data_disks = sb->raid_disks-1;
+ break;
+ default:
+ printk (UNKNOWN_LEVEL, mdidx(mddev), sb->level);
+ goto abort;
+ }
+ if (!md_size[mdidx(mddev)])
+ md_size[mdidx(mddev)] = sb->size * data_disks;
+
+ readahead = MD_READAHEAD;
+ if ((sb->level == 0) || (sb->level == 4) || (sb->level == 5)) {
+ readahead = (mddev->sb->chunk_size>>PAGE_SHIFT) * 4 * data_disks;
+ if (readahead < data_disks * (MAX_SECTORS>>(PAGE_SHIFT-9))*2)
+ readahead = data_disks * (MAX_SECTORS>>(PAGE_SHIFT-9))*2;
+ } else {
+ if (sb->level == -3)
+ readahead = 0;
+ }
+ md_maxreadahead[mdidx(mddev)] = readahead;
+
+ printk(KERN_INFO "md%d: max total readahead window set to %ldk\n",
+ mdidx(mddev), readahead*(PAGE_SIZE/1024));
+
+ printk(KERN_INFO
+ "md%d: %d data-disks, max readahead per data-disk: %ldk\n",
+ mdidx(mddev), data_disks, readahead/data_disks*(PAGE_SIZE/1024));


+ return 0;
+abort:
+ return 1;
+}
+
+

+#define TOO_BIG_CHUNKSIZE KERN_ERR \
+"too big chunk_size: %d > %d\n"
+
+#define TOO_SMALL_CHUNKSIZE KERN_ERR \
+"too small chunk_size: %d < %ld\n"
+
+#define BAD_CHUNKSIZE KERN_ERR \
+"no chunksize specified, see 'man raidtab'\n"
+
+static int do_md_run (mddev_t * mddev)
+{
+ int pnum, err;
+ int chunk_size;


+ struct md_list_head *tmp;
+ mdk_rdev_t *rdev;
+
+

+ if (!mddev->nb_dev) {


+ MD_BUG();
+ return -EINVAL;
+ }
+

+ if (mddev->pers)


+ return -EBUSY;
+
+ /*

+ * Resize disks to align partitions size on a given
+ * chunk size.
+ */
+ md_size[mdidx(mddev)] = 0;
+
+ /*
+ * Analyze all RAID superblock(s)
+ */
+ if (analyze_sbs(mddev)) {


+ MD_BUG();
+ return -EINVAL;
+ }
+

+ chunk_size = mddev->sb->chunk_size;
+ pnum = level_to_pers(mddev->sb->level);
+
+ mddev->param.chunk_size = chunk_size;
+ mddev->param.personality = pnum;
+
+ if (chunk_size > MAX_CHUNK_SIZE) {
+ printk(TOO_BIG_CHUNKSIZE, chunk_size, MAX_CHUNK_SIZE);


+ return -EINVAL;
+ }
+ /*

+ * chunk-size has to be a power of 2 and multiples of PAGE_SIZE
+ */
+ if ( (1 << ffz(~chunk_size)) != chunk_size) {


+ MD_BUG();
+ return -EINVAL;
+ }

+ if (chunk_size < PAGE_SIZE) {
+ printk(TOO_SMALL_CHUNKSIZE, chunk_size, PAGE_SIZE);


+ return -EINVAL;
+ }
+

+ if (pnum >= MAX_PERSONALITY) {


+ MD_BUG();
+ return -EINVAL;
+ }
+

+ if ((pnum != RAID1) && (pnum != LINEAR) && !chunk_size) {
+ /*
+ * 'default chunksize' in the old md code used to
+ * be PAGE_SIZE, baaad.
+ * we abort here to be on the safe side. We dont
+ * want to continue the bad practice.
+ */
+ printk(BAD_CHUNKSIZE);


+ return -EINVAL;
+ }
+

+ if (!pers[pnum])
+ {
+#ifdef CONFIG_KMOD
+ char module_name[80];
+ sprintf (module_name, "md-personality-%d", pnum);
+ request_module (module_name);
+ if (!pers[pnum])
+#endif


+ return -EINVAL;
+ }
+

+ if (device_size_calculation(mddev))


+ return -EINVAL;
+
+ /*

+ * Drop all container device buffers, from now on
+ * the only valid external interface is through the md
+ * device.
+ * Also find largest hardsector size
+ */
+ md_hardsect_sizes[mdidx(mddev)] = 512;


+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->faulty)

+ continue;
+ fsync_dev(rdev->dev);
+ invalidate_buffers(rdev->dev);
+ if (get_hardsect_size(rdev->dev)
+ > md_hardsect_sizes[mdidx(mddev)])
+ md_hardsect_sizes[mdidx(mddev)] =
+ get_hardsect_size(rdev->dev);
+ }
+ md_blocksizes[mdidx(mddev)] = 1024;
+ if (md_blocksizes[mdidx(mddev)] < md_hardsect_sizes[mdidx(mddev)])
+ md_blocksizes[mdidx(mddev)] = md_hardsect_sizes[mdidx(mddev)];
+ mddev->pers = pers[pnum];
+
+ err = mddev->pers->run(mddev);
+ if (err) {
+ printk("pers->run() failed ...\n");
+ mddev->pers = NULL;


+ return -EINVAL;
+ }
+

+ mddev->sb->state &= ~(1 << MD_SB_CLEAN);
+ md_update_sb(mddev);
+
+ /*
+ * md_size has units of 1K blocks, which are
+ * twice as large as sectors.
+ */
+ md_hd_struct[mdidx(mddev)].start_sect = 0;
+ md_hd_struct[mdidx(mddev)].nr_sects = md_size[mdidx(mddev)] << 1;
+
+ read_ahead[MD_MAJOR] = 1024;


+ return (0);
+}
+

+#undef TOO_BIG_CHUNKSIZE
+#undef BAD_CHUNKSIZE
+
+#define OUT(x) do { err = (x); goto out; } while (0)
+
+static int restart_array (mddev_t *mddev)
+{


+ int err = 0;
+
+ /*

+ * Complain if it has no devices
+ */
+ if (!mddev->nb_dev)
+ OUT(-ENXIO);
+
+ if (mddev->pers) {
+ if (!mddev->ro)
+ OUT(-EBUSY);
+
+ mddev->ro = 0;
+ set_device_ro(mddev_to_kdev(mddev), 0);
+
+ printk (KERN_INFO
+ "md%d switched to read-write mode.\n", mdidx(mddev));
+ /*
+ * Kick recovery or resync if necessary
+ */
+ md_recover_arrays();
+ if (mddev->pers->restart_resync)
+ mddev->pers->restart_resync(mddev);
+ } else
+ err = -EINVAL;
+
+out:


+ return err;
+}
+

+#define STILL_MOUNTED KERN_WARNING \
+"md: md%d still mounted.\n"
+
+static int do_md_stop (mddev_t * mddev, int ro)
+{
+ int err = 0, resync_interrupted = 0;
+ kdev_t dev = mddev_to_kdev(mddev);
+
+ if (!ro && get_super(dev)) {
+ printk (STILL_MOUNTED, mdidx(mddev));
+ OUT(-EBUSY);
+ }
+
+ if (mddev->pers) {
+ /*
+ * It is safe to call stop here, it only frees private
+ * data. Also, it tells us if a device is unstoppable
+ * (eg. resyncing is in progress)
+ */
+ if (mddev->pers->stop_resync)
+ if (mddev->pers->stop_resync(mddev))
+ resync_interrupted = 1;
+
+ if (mddev->recovery_running)
+ md_interrupt_thread(md_recovery_thread);
+
+ /*
+ * This synchronizes with signal delivery to the
+ * resync or reconstruction thread. It also nicely
+ * hangs the process if some reconstruction has not
+ * finished.
+ */
+ down(&mddev->recovery_sem);
+ up(&mddev->recovery_sem);
+
+ /*
+ * sync and invalidate buffers because we cannot kill the
+ * main thread with valid IO transfers still around.
+ * the kernel lock protects us from new requests being
+ * added after invalidate_buffers().
+ */
+ fsync_dev (mddev_to_kdev(mddev));
+ fsync_dev (dev);
+ invalidate_buffers (dev);
+
+ if (ro) {
+ if (mddev->ro)
+ OUT(-ENXIO);
+ mddev->ro = 1;
+ } else {
+ if (mddev->ro)
+ set_device_ro(dev, 0);
+ if (mddev->pers->stop(mddev)) {
+ if (mddev->ro)
+ set_device_ro(dev, 1);
+ OUT(-EBUSY);
+ }
+ if (mddev->ro)
+ mddev->ro = 0;
+ }
+ if (mddev->sb) {
+ /*
+ * mark it clean only if there was no resync
+ * interrupted.
+ */
+ if (!mddev->recovery_running && !resync_interrupted) {
+ printk("marking sb clean...\n");
+ mddev->sb->state |= 1 << MD_SB_CLEAN;
+ }
+ md_update_sb(mddev);
+ }
+ if (ro)
+ set_device_ro(dev, 1);
+ }
+
+ /*
+ * Free resources if final stop
+ */
+ if (!ro) {
+ printk (KERN_INFO "md%d stopped.\n", mdidx(mddev));
+ free_mddev(mddev);
+
+ } else
+ printk (KERN_INFO
+ "md%d switched to read-only mode.\n", mdidx(mddev));
+out:


+ return err;
+}
+

+#undef OUT
+
+/*
+ * We have to safely support old arrays too.
+ */
+int detect_old_array (mdp_super_t *sb)
+{
+ if (sb->major_version > 0)
+ return 0;
+ if (sb->minor_version >= 90)
+ return 0;
+


+ return -EINVAL;
+}
+
+

+static void autorun_array (mddev_t *mddev)
+{


+ mdk_rdev_t *rdev;
+ struct md_list_head *tmp;

+ int err;
+
+ if (mddev->disks.prev == &mddev->disks) {


+ MD_BUG();
+ return;
+ }
+

+ printk("running: ");
+
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ printk("<%s>", partition_name(rdev->dev));
+ }
+ printk("\nnow!\n");
+
+ err = do_md_run (mddev);
+ if (err) {
+ printk("do_md_run() returned %d\n", err);
+ /*
+ * prevent the writeback of an unrunnable array
+ */


+ mddev->sb_dirty = 0;
+ do_md_stop (mddev, 0);

+ }
+}
+
+/*
+ * lets try to run arrays based on all disks that have arrived
+ * until now. (those are in the ->pending list)
+ *
+ * the method: pick the first pending disk, collect all disks with
+ * the same UUID, remove all from the pending list and put them into
+ * the 'same_array' list. Then order this list based on superblock
+ * update time (freshest comes first), kick out 'old' disks and
+ * compare superblocks. If everything's fine then run it.
+ */
+static void autorun_devices (void)
+{
+ struct md_list_head candidates;
+ struct md_list_head *tmp;
+ mdk_rdev_t *rdev0, *rdev;
+ mddev_t *mddev;
+ kdev_t md_kdev;
+
+
+ printk("autorun ...\n");
+ while (pending_raid_disks.next != &pending_raid_disks) {
+ rdev0 = md_list_entry(pending_raid_disks.next,
+ mdk_rdev_t, pending);
+
+ printk("considering %s ...\n", partition_name(rdev0->dev));
+ MD_INIT_LIST_HEAD(&candidates);
+ ITERATE_RDEV_PENDING(rdev,tmp) {
+ if (uuid_equal(rdev0, rdev)) {
+ if (!sb_equal(rdev0->sb, rdev->sb)) {
+ printk("%s has same UUID as %s, but superblocks differ ...\n", partition_name(rdev->dev), partition_name(rdev0->dev));
+ continue;
+ }
+ printk(" adding %s ...\n", partition_name(rdev->dev));
+ md_list_del(&rdev->pending);
+ md_list_add(&rdev->pending, &candidates);
+ }
+ }
+ /*
+ * now we have a set of devices, with all of them having
+ * mostly sane superblocks. It's time to allocate the
+ * mddev.
+ */
+ md_kdev = MKDEV(MD_MAJOR, rdev0->sb->md_minor);
+ mddev = kdev_to_mddev(md_kdev);
+ if (mddev) {
+ printk("md%d already running, cannot run %s\n",
+ mdidx(mddev), partition_name(rdev0->dev));
+ ITERATE_RDEV_GENERIC(candidates,pending,rdev,tmp)
+ export_rdev(rdev);
+ continue;
+ }
+ mddev = alloc_mddev(md_kdev);
+ printk("created md%d\n", mdidx(mddev));
+ ITERATE_RDEV_GENERIC(candidates,pending,rdev,tmp) {
+ bind_rdev_to_array(rdev, mddev);
+ md_list_del(&rdev->pending);
+ MD_INIT_LIST_HEAD(&rdev->pending);
+ }
+ autorun_array(mddev);
+ }
+ printk("... autorun DONE.\n");
+}
+
+/*
+ * import RAID devices based on one partition
+ * if possible, the array gets run as well.
+ */
+
+#define BAD_VERSION KERN_ERR \
+"md: %s has RAID superblock version 0.%d, autodetect needs v0.90 or higher\n"


+
+#define OUT_OF_MEM KERN_ALERT \
+"md: out of memory.\n"
+

+#define NO_DEVICE KERN_ERR \
+"md: disabled device %s\n"
+
+#define AUTOADD_FAILED KERN_ERR \
+"md: auto-adding devices to md%d FAILED (error %d).\n"
+
+#define AUTOADD_FAILED_USED KERN_ERR \
+"md: cannot auto-add device %s to md%d, already used.\n"
+
+#define AUTORUN_FAILED KERN_ERR \
+"md: auto-running md%d FAILED (error %d).\n"
+
+#define MDDEV_BUSY KERN_ERR \
+"md: cannot auto-add to md%d, already running.\n"
+
+#define AUTOADDING KERN_INFO \
+"md: auto-adding devices to md%d, based on %s's superblock.\n"
+
+#define AUTORUNNING KERN_INFO \
+"md: auto-running md%d.\n"
+
+static int autostart_array (kdev_t startdev)
+{
+ int err = -EINVAL, i;
+ mdp_super_t *sb = NULL;
+ mdk_rdev_t *start_rdev = NULL, *rdev;
+
+ if (md_import_device(startdev, 1)) {
+ printk("could not import %s!\n", partition_name(startdev));


+ goto abort;
+ }
+

+ start_rdev = find_rdev_all(startdev);
+ if (!start_rdev) {


+ MD_BUG();
+ goto abort;
+ }

+ if (start_rdev->faulty) {
+ printk("can not autostart based on faulty %s!\n",
+ partition_name(startdev));
+ goto abort;
+ }
+ md_list_add(&start_rdev->pending, &pending_raid_disks);
+
+ sb = start_rdev->sb;
+
+ err = detect_old_array(sb);
+ if (err) {
+ printk("array version is too old to be autostarted, use raidtools 0.90 mkraid --upgrade\nto upgrade the array without data loss!\n");


+ goto abort;
+ }
+

+ for (i = 0; i < MD_SB_DISKS; i++) {
+ mdp_disk_t *desc;
+ kdev_t dev;
+
+ desc = sb->disks + i;
+ dev = MKDEV(desc->major, desc->minor);
+
+ if (dev == MKDEV(0,0))
+ continue;
+ if (dev == startdev)
+ continue;
+ if (md_import_device(dev, 1)) {
+ printk("could not import %s, trying to run array nevertheless.\n", partition_name(dev));
+ continue;
+ }
+ rdev = find_rdev_all(dev);


+ if (!rdev) {
+ MD_BUG();

+ goto abort;
+ }
+ md_list_add(&rdev->pending, &pending_raid_disks);
+ }
+
+ /*
+ * possibly return codes
+ */
+ autorun_devices();
+ return 0;
+
+abort:
+ if (start_rdev)
+ export_rdev(start_rdev);


+ return err;
+}
+

+#undef BAD_VERSION
+#undef OUT_OF_MEM
+#undef NO_DEVICE
+#undef AUTOADD_FAILED_USED
+#undef AUTOADD_FAILED
+#undef AUTORUN_FAILED
+#undef AUTOADDING
+#undef AUTORUNNING
+
+struct {
+ int set;
+ int noautodetect;
+
+} raid_setup_args md__initdata = { 0, 0 };
+
+void md_setup_drive(void) md__init;
+
+/*
+ * Searches all registered partitions for autorun RAID arrays
+ * at boot time.
+ */
+#ifdef CONFIG_AUTODETECT_RAID
+static int detected_devices[128] md__initdata;
+static int dev_cnt=0;
+void md_autodetect_dev(kdev_t dev)
+{
+ if (dev_cnt >= 0 && dev_cnt < 127)
+ detected_devices[dev_cnt++] = dev;
+}
+#endif
+
+int md__init md_run_setup(void)
+{
+#ifdef CONFIG_AUTODETECT_RAID
+ mdk_rdev_t *rdev;
+ int i;
+
+ if (raid_setup_args.noautodetect)
+ printk(KERN_INFO "skipping autodetection of RAID arrays\n");
+ else {
+
+ printk(KERN_INFO "autodetecting RAID arrays\n");
+
+ for (i=0; i<dev_cnt; i++) {
+ kdev_t dev = detected_devices[i];
+
+ if (md_import_device(dev,1)) {
+ printk(KERN_ALERT "could not import %s!\n",
+ partition_name(dev));
+ continue;
+ }
+ /*
+ * Sanity checks:
+ */
+ rdev = find_rdev_all(dev);


+ if (!rdev) {
+ MD_BUG();

+ continue;
+ }
+ if (rdev->faulty) {
+ MD_BUG();
+ continue;
+ }
+ md_list_add(&rdev->pending, &pending_raid_disks);
+ }
+
+ autorun_devices();
+ }
+
+ dev_cnt = -1; /* make sure further calls to md_autodetect_dev are ignored */
+#endif
+#ifdef CONFIG_MD_BOOT
+ md_setup_drive();


+#endif
+ return 0;
+}
+

+static int get_version (void * arg)
+{
+ mdu_version_t ver;
+
+ ver.major = MD_MAJOR_VERSION;
+ ver.minor = MD_MINOR_VERSION;
+ ver.patchlevel = MD_PATCHLEVEL_VERSION;
+
+ if (md_copy_to_user(arg, &ver, sizeof(ver)))


+ return -EFAULT;
+
+ return 0;
+}
+

+#define SET_FROM_SB(x) info.x = mddev->sb->x
+static int get_array_info (mddev_t * mddev, void * arg)
+{
+ mdu_array_info_t info;


+
+ if (!mddev->sb)

+ return -EINVAL;
+
+ SET_FROM_SB(major_version);
+ SET_FROM_SB(minor_version);
+ SET_FROM_SB(patch_version);
+ SET_FROM_SB(ctime);
+ SET_FROM_SB(level);
+ SET_FROM_SB(size);
+ SET_FROM_SB(nr_disks);
+ SET_FROM_SB(raid_disks);
+ SET_FROM_SB(md_minor);
+ SET_FROM_SB(not_persistent);
+
+ SET_FROM_SB(utime);
+ SET_FROM_SB(state);
+ SET_FROM_SB(active_disks);
+ SET_FROM_SB(working_disks);
+ SET_FROM_SB(failed_disks);
+ SET_FROM_SB(spare_disks);
+
+ SET_FROM_SB(layout);
+ SET_FROM_SB(chunk_size);
+
+ if (md_copy_to_user(arg, &info, sizeof(info)))


+ return -EFAULT;
+
+ return 0;
+}

+#undef SET_FROM_SB
+
+#define SET_FROM_SB(x) info.x = mddev->sb->disks[nr].x
+static int get_disk_info (mddev_t * mddev, void * arg)
+{
+ mdu_disk_info_t info;
+ unsigned int nr;


+
+ if (!mddev->sb)

+ return -EINVAL;
+
+ if (md_copy_from_user(&info, arg, sizeof(info)))
+ return -EFAULT;
+
+ nr = info.number;
+ if (nr >= mddev->sb->nr_disks)
+ return -EINVAL;
+
+ SET_FROM_SB(major);
+ SET_FROM_SB(minor);
+ SET_FROM_SB(raid_disk);
+ SET_FROM_SB(state);
+
+ if (md_copy_to_user(arg, &info, sizeof(info)))


+ return -EFAULT;
+
+ return 0;
+}

+#undef SET_FROM_SB
+
+#define SET_SB(x) mddev->sb->disks[nr].x = info->x
+
+static int add_new_disk (mddev_t * mddev, mdu_disk_info_t *info)
+{
+ int err, size, persistent;
+ mdk_rdev_t *rdev;
+ unsigned int nr;
+ kdev_t dev;
+ dev = MKDEV(info->major,info->minor);
+
+ if (find_rdev_all(dev)) {
+ printk("device %s already used in a RAID array!\n",
+ partition_name(dev));
+ return -EBUSY;
+ }
+ if (!mddev->sb) {
+ /* expecting a device which has a superblock */
+ err = md_import_device(dev, 1);
+ if (err) {
+ printk("md error, md_import_device returned %d\n", err);
+ return -EINVAL;
+ }
+ rdev = find_rdev_all(dev);


+ if (!rdev) {
+ MD_BUG();

+ return -EINVAL;
+ }
+ if (mddev->nb_dev) {
+ mdk_rdev_t *rdev0 = md_list_entry(mddev->disks.next,
+ mdk_rdev_t, same_set);
+ if (!uuid_equal(rdev0, rdev)) {
+ printk("md: %s has different UUID to %s\n", partition_name(rdev->dev), partition_name(rdev0->dev));
+ export_rdev(rdev);
+ return -EINVAL;
+ }
+ if (!sb_equal(rdev0->sb, rdev->sb)) {
+ printk("md: %s has same UUID but different superblock to %s\n", partition_name(rdev->dev), partition_name(rdev0->dev));
+ export_rdev(rdev);


+ return -EINVAL;
+ }
+ }

+ bind_rdev_to_array(rdev, mddev);


+ return 0;
+ }
+

+ nr = info->number;
+ if (nr >= mddev->sb->nr_disks)
+ return -EINVAL;
+
+ SET_SB(number);
+ SET_SB(major);
+ SET_SB(minor);
+ SET_SB(raid_disk);
+ SET_SB(state);
+
+ if ((info->state & (1<<MD_DISK_FAULTY))==0) {
+ err = md_import_device (dev, 0);
+ if (err) {
+ printk("md: error, md_import_device() returned %d\n", err);
+ return -EINVAL;
+ }
+ rdev = find_rdev_all(dev);


+ if (!rdev) {
+ MD_BUG();

+ return -EINVAL;
+ }
+
+ rdev->old_dev = dev;
+ rdev->desc_nr = info->number;
+
+ bind_rdev_to_array(rdev, mddev);
+
+ persistent = !mddev->sb->not_persistent;
+ if (!persistent)
+ printk("nonpersistent superblock ...\n");
+ if (!mddev->sb->chunk_size)
+ printk("no chunksize?\n");
+
+ size = calc_dev_size(dev, mddev, persistent);
+ rdev->sb_offset = calc_dev_sboffset(dev, mddev, persistent);
+
+ if (!mddev->sb->size || (mddev->sb->size > size))
+ mddev->sb->size = size;
+ }
+
+ /*
+ * sync all other superblocks with the main superblock
+ */
+ sync_sbs(mddev);


+
+ return 0;
+}

+#undef SET_SB
+
+static int hot_remove_disk (mddev_t * mddev, kdev_t dev)
+{
+ int err;
+ mdk_rdev_t *rdev;
+ mdp_disk_t *disk;
+
+ if (!mddev->pers)
+ return -ENODEV;
+
+ printk("trying to remove %s from md%d ... \n",
+ partition_name(dev), mdidx(mddev));
+


+ if (!mddev->pers->diskop) {

+ printk("md%d: personality does not support diskops!\n",
+ mdidx(mddev));


+ return -EINVAL;
+ }
+

+ rdev = find_rdev(mddev, dev);
+ if (!rdev)
+ return -ENXIO;
+
+ if (rdev->desc_nr == -1) {


+ MD_BUG();
+ return -EINVAL;
+ }

+ disk = &mddev->sb->disks[rdev->desc_nr];
+ if (disk_active(disk))
+ goto busy;
+ if (disk_removed(disk)) {


+ MD_BUG();
+ return -EINVAL;
+ }
+

+ err = mddev->pers->diskop(mddev, &disk, DISKOP_HOT_REMOVE_DISK);
+ if (err == -EBUSY)
+ goto busy;
+ if (err) {


+ MD_BUG();
+ return -EINVAL;
+ }
+

+ remove_descriptor(disk, mddev->sb);
+ kick_rdev_from_array(rdev);


+ mddev->sb_dirty = 1;
+ md_update_sb(mddev);
+

+ return 0;
+busy:
+ printk("cannot remove active disk %s from md%d ... \n",
+ partition_name(dev), mdidx(mddev));


+ return -EBUSY;
+}
+

+static int hot_add_disk (mddev_t * mddev, kdev_t dev)
+{
+ int i, err, persistent;
+ unsigned int size;
+ mdk_rdev_t *rdev;
+ mdp_disk_t *disk;
+
+ if (!mddev->pers)
+ return -ENODEV;
+
+ printk("trying to hot-add %s to md%d ... \n",
+ partition_name(dev), mdidx(mddev));
+


+ if (!mddev->pers->diskop) {

+ printk("md%d: personality does not support diskops!\n",
+ mdidx(mddev));


+ return -EINVAL;
+ }
+

+ persistent = !mddev->sb->not_persistent;
+ size = calc_dev_size(dev, mddev, persistent);
+
+ if (size < mddev->sb->size) {
+ printk("md%d: disk size %d blocks < array size %d\n",
+ mdidx(mddev), size, mddev->sb->size);
+ return -ENOSPC;
+ }
+
+ rdev = find_rdev(mddev, dev);
+ if (rdev)
+ return -EBUSY;
+
+ err = md_import_device (dev, 0);
+ if (err) {
+ printk("md: error, md_import_device() returned %d\n", err);
+ return -EINVAL;
+ }
+ rdev = find_rdev_all(dev);


+ if (!rdev) {
+ MD_BUG();

+ return -EINVAL;
+ }
+ if (rdev->faulty) {
+ printk("md: can not hot-add faulty %s disk to md%d!\n",
+ partition_name(dev), mdidx(mddev));
+ err = -EINVAL;
+ goto abort_export;
+ }
+ bind_rdev_to_array(rdev, mddev);
+
+ /*
+ * The rest should better be atomic, we can have disk failures
+ * noticed in interrupt contexts ...
+ */
+ rdev->old_dev = dev;
+ rdev->size = size;
+ rdev->sb_offset = calc_dev_sboffset(dev, mddev, persistent);
+
+ disk = mddev->sb->disks + mddev->sb->raid_disks;
+ for (i = mddev->sb->raid_disks; i < MD_SB_DISKS; i++) {
+ disk = mddev->sb->disks + i;
+
+ if (!disk->major && !disk->minor)
+ break;
+ if (disk_removed(disk))
+ break;
+ }
+ if (i == MD_SB_DISKS) {
+ printk("md%d: can not hot-add to full array!\n", mdidx(mddev));
+ err = -EBUSY;
+ goto abort_unbind_export;
+ }
+
+ if (disk_removed(disk)) {
+ /*
+ * reuse slot
+ */
+ if (disk->number != i) {
+ MD_BUG();
+ err = -EINVAL;
+ goto abort_unbind_export;
+ }
+ } else {
+ disk->number = i;
+ }
+
+ disk->raid_disk = disk->number;
+ disk->major = MAJOR(dev);
+ disk->minor = MINOR(dev);
+
+ if (mddev->pers->diskop(mddev, &disk, DISKOP_HOT_ADD_DISK)) {
+ MD_BUG();
+ err = -EINVAL;
+ goto abort_unbind_export;
+ }
+
+ mark_disk_spare(disk);
+ mddev->sb->nr_disks++;
+ mddev->sb->spare_disks++;


+ mddev->sb->working_disks++;
+

+ mddev->sb_dirty = 1;
+

+ md_update_sb(mddev);
+
+ /*
+ * Kick recovery, maybe this spare has to be added to the
+ * array immediately.
+ */
+ md_recover_arrays();


+
+ return 0;
+

+abort_unbind_export:
+ unbind_rdev_from_array(rdev);
+
+abort_export:
+ export_rdev(rdev);


+ return err;
+}
+

+#define SET_SB(x) mddev->sb->x = info->x
+static int set_array_info (mddev_t * mddev, mdu_array_info_t *info)
+{
+
+ if (alloc_array_sb(mddev))
+ return -ENOMEM;
+
+ mddev->sb->major_version = MD_MAJOR_VERSION;
+ mddev->sb->minor_version = MD_MINOR_VERSION;
+ mddev->sb->patch_version = MD_PATCHLEVEL_VERSION;
+ mddev->sb->ctime = CURRENT_TIME;
+
+ SET_SB(level);
+ SET_SB(size);
+ SET_SB(nr_disks);
+ SET_SB(raid_disks);
+ SET_SB(md_minor);
+ SET_SB(not_persistent);
+
+ SET_SB(state);
+ SET_SB(active_disks);
+ SET_SB(working_disks);
+ SET_SB(failed_disks);
+ SET_SB(spare_disks);
+
+ SET_SB(layout);
+ SET_SB(chunk_size);
+
+ mddev->sb->md_magic = MD_SB_MAGIC;
+
+ /*
+ * Generate a 128 bit UUID
+ */
+ get_random_bytes(&mddev->sb->set_uuid0, 4);
+ get_random_bytes(&mddev->sb->set_uuid1, 4);
+ get_random_bytes(&mddev->sb->set_uuid2, 4);
+ get_random_bytes(&mddev->sb->set_uuid3, 4);


+
+ return 0;
+}

+#undef SET_SB
+
+static int set_disk_info (mddev_t * mddev, void * arg)
+{
+ printk("not yet");


+ return -EINVAL;
+}
+

+static int clear_array (mddev_t * mddev)
+{
+ printk("not yet");


+ return -EINVAL;
+}
+

+static int write_raid_info (mddev_t * mddev)
+{
+ printk("not yet");


+ return -EINVAL;
+}
+

+static int protect_array (mddev_t * mddev)
+{
+ printk("not yet");


+ return -EINVAL;
+}
+

+static int unprotect_array (mddev_t * mddev)
+{
+ printk("not yet");


+ return -EINVAL;
+}
+

+static int set_disk_faulty (mddev_t *mddev, kdev_t dev)
+{
+ int ret;
+
+ fsync_dev(mddev_to_kdev(mddev));
+ ret = md_error(mddev_to_kdev(mddev), dev);


+ return ret;
+}
+

+static int md_ioctl (struct inode *inode, struct file *file,


+ unsigned int cmd, unsigned long arg)

+{
+ unsigned int minor;


+ int err = 0;

+ struct hd_geometry *loc = (struct hd_geometry *) arg;
+ mddev_t *mddev = NULL;
+ kdev_t dev;
+
+ if (!md_capable_admin())
+ return -EACCES;
+
+ dev = inode->i_rdev;
+ minor = MINOR(dev);
+ if (minor >= MAX_MD_DEVS)


+ return -EINVAL;
+
+ /*

+ * Commands dealing with the RAID driver but not any
+ * particular array:
+ */
+ switch (cmd)
+ {
+ case RAID_VERSION:
+ err = get_version((void *)arg);
+ goto done;
+
+ case PRINT_RAID_DEBUG:
+ err = 0;
+ md_print_devices();
+ goto done_unlock;
+
+ case BLKGETSIZE: /* Return device size */
+ if (!arg) {
+ err = -EINVAL;
+ goto abort;
+ }
+ err = md_put_user(md_hd_struct[minor].nr_sects,
+ (long *) arg);
+ goto done;
+
+ case BLKFLSBUF:
+ fsync_dev(dev);
+ invalidate_buffers(dev);
+ goto done;
+
+ case BLKRASET:
+ if (arg > 0xff) {
+ err = -EINVAL;
+ goto abort;
+ }
+ read_ahead[MAJOR(dev)] = arg;
+ goto done;
+
+ case BLKRAGET:
+ if (!arg) {
+ err = -EINVAL;
+ goto abort;
+ }
+ err = md_put_user (read_ahead[
+ MAJOR(dev)], (long *) arg);
+ goto done;
+ default:
+ }
+
+ /*
+ * Commands creating/starting a new array:
+ */
+
+ mddev = kdev_to_mddev(dev);


+
+ switch (cmd)
+ {

+ case SET_ARRAY_INFO:
+ case START_ARRAY:
+ if (mddev) {
+ printk("array md%d already exists!\n",
+ mdidx(mddev));
+ err = -EEXIST;
+ goto abort;
+ }
+ default:


+ }
+ switch (cmd)
+ {

+ case SET_ARRAY_INFO:
+ mddev = alloc_mddev(dev);
+ if (!mddev) {
+ err = -ENOMEM;


+ goto abort;
+ }
+ /*

+ * alloc_mddev() should possibly self-lock.
+ */
+ err = lock_mddev(mddev);
+ if (err) {
+ printk("ioctl, reason %d, cmd %d\n", err, cmd);


+ goto abort;
+ }
+

+ if (mddev->sb) {
+ printk("array md%d already has a superblock!\n",
+ mdidx(mddev));
+ err = -EBUSY;
+ goto abort_unlock;
+ }
+ if (arg) {
+ mdu_array_info_t info;
+ if (md_copy_from_user(&info, (void*)arg, sizeof(info))) {
+ err = -EFAULT;
+ goto abort_unlock;
+ }
+ err = set_array_info(mddev, &info);
+ if (err) {
+ printk("couldnt set array info. %d\n", err);
+ goto abort_unlock;
+ }
+ }
+ goto done_unlock;
+
+ case START_ARRAY:
+ /*
+ * possibly make it lock the array ...
+ */
+ err = autostart_array((kdev_t)arg);
+ if (err) {
+ printk("autostart %s failed!\n",
+ partition_name((kdev_t)arg));
+ goto abort;
+ }
+ goto done;
+
+ default:
+ }
+
+ /*
+ * Commands querying/configuring an existing array:
+ */
+
+ if (!mddev) {
+ err = -ENODEV;
+ goto abort;
+ }
+ err = lock_mddev(mddev);
+ if (err) {
+ printk("ioctl lock interrupted, reason %d, cmd %d\n",err, cmd);
+ goto abort;
+ }
+ /* if we don't have a superblock yet, only ADD_NEW_DISK or STOP_ARRAY is allowed */
+ if (!mddev->sb && cmd != ADD_NEW_DISK && cmd != STOP_ARRAY && cmd != RUN_ARRAY) {
+ err = -ENODEV;
+ goto abort_unlock;
+ }
+
+ /*
+ * Commands even a read-only array can execute:
+ */
+ switch (cmd)
+ {
+ case GET_ARRAY_INFO:
+ err = get_array_info(mddev, (void *)arg);
+ goto done_unlock;
+
+ case GET_DISK_INFO:
+ err = get_disk_info(mddev, (void *)arg);
+ goto done_unlock;
+
+ case RESTART_ARRAY_RW:
+ err = restart_array(mddev);
+ goto done_unlock;
+
+ case STOP_ARRAY:
+ if (!(err = do_md_stop (mddev, 0)))
+ mddev = NULL;
+ goto done_unlock;
+
+ case STOP_ARRAY_RO:
+ err = do_md_stop (mddev, 1);
+ goto done_unlock;
+
+ /*
+ * We have a problem here : there is no easy way to give a CHS
+ * virtual geometry. We currently pretend that we have a 2 heads
+ * 4 sectors (with a BIG number of cylinders...). This drives
+ * dosfs just mad... ;-)
+ */
+ case HDIO_GETGEO:
+ if (!loc) {
+ err = -EINVAL;
+ goto abort_unlock;
+ }
+ err = md_put_user (2, (char *) &loc->heads);
+ if (err)
+ goto abort_unlock;
+ err = md_put_user (4, (char *) &loc->sectors);
+ if (err)
+ goto abort_unlock;
+ err = md_put_user (md_hd_struct[mdidx(mddev)].nr_sects/8,
+ (short *) &loc->cylinders);
+ if (err)
+ goto abort_unlock;
+ err = md_put_user (md_hd_struct[minor].start_sect,
+ (long *) &loc->start);
+ goto done_unlock;
+ }
+
+ /*
+ * The remaining ioctls are changing the state of the
+ * superblock, so we do not allow read-only arrays
+ * here:
+ */
+ if (mddev->ro) {
+ err = -EROFS;
+ goto abort_unlock;
+ }


+
+ switch (cmd)
+ {

+ case CLEAR_ARRAY:
+ err = clear_array(mddev);
+ goto done_unlock;
+
+ case ADD_NEW_DISK:
+ {
+ mdu_disk_info_t info;
+ if (md_copy_from_user(&info, (void*)arg, sizeof(info)))
+ err = -EFAULT;
+ else
+ err = add_new_disk(mddev, &info);
+ goto done_unlock;
+ }
+ case HOT_REMOVE_DISK:
+ err = hot_remove_disk(mddev, (kdev_t)arg);
+ goto done_unlock;
+
+ case HOT_ADD_DISK:
+ err = hot_add_disk(mddev, (kdev_t)arg);
+ goto done_unlock;
+
+ case SET_DISK_INFO:
+ err = set_disk_info(mddev, (void *)arg);
+ goto done_unlock;
+
+ case WRITE_RAID_INFO:
+ err = write_raid_info(mddev);
+ goto done_unlock;
+
+ case UNPROTECT_ARRAY:
+ err = unprotect_array(mddev);
+ goto done_unlock;
+
+ case PROTECT_ARRAY:
+ err = protect_array(mddev);
+ goto done_unlock;
+
+ case SET_DISK_FAULTY:
+ err = set_disk_faulty(mddev, (kdev_t)arg);
+ goto done_unlock;
+
+ case RUN_ARRAY:
+ {
+/* The data is never used....
+ mdu_param_t param;
+ err = md_copy_from_user(&param, (mdu_param_t *)arg,
+ sizeof(param));
+ if (err)
+ goto abort_unlock;
+*/
+ err = do_md_run (mddev);
+ /*
+ * we have to clean up the mess if
+ * the array cannot be run for some
+ * reason ...
+ */


+ if (err) {
+ mddev->sb_dirty = 0;

+ if (!do_md_stop (mddev, 0))
+ mddev = NULL;
+ }
+ goto done_unlock;
+ }
+
+ default:
+ printk(KERN_WARNING "%s(pid %d) used obsolete MD ioctl, upgrade your software to use new ictls.\n", current->comm, current->pid);
+ err = -EINVAL;
+ goto abort_unlock;
+ }
+
+done_unlock:
+abort_unlock:
+ if (mddev)
+ unlock_mddev(mddev);
+
+ return err;
+done:
+ if (err)
+ printk("huh12?\n");
+abort:


+ return err;
+}
+

+static int md_open (struct inode *inode, struct file *file)
+{
+ /*
+ * Always succeed
+ */


+ return (0);
+}
+

+static struct block_device_operations md_fops=
+{
+ open: md_open,
+ ioctl: md_ioctl,
+};
+
+
+int md_thread(void * arg)
+{
+ mdk_thread_t *thread = arg;
+
+ md_lock_kernel();
+ exit_mm(current);
+ exit_files(current);
+ exit_fs(current);
+
+ /*
+ * Detach thread
+ */
+ daemonize();
+ sprintf(current->comm, thread->name);
+ md_init_signals();
+ md_flush_signals();
+ thread->tsk = current;
+
+ /*
+ * md_thread is a 'system-thread', it's priority should be very
+ * high. We avoid resource deadlocks individually in each
+ * raid personality. (RAID5 does preallocation) We also use RR and
+ * the very same RT priority as kswapd, thus we will never get
+ * into a priority inversion deadlock.
+ *
+ * we definitely have to have equal or higher priority than
+ * bdflush, otherwise bdflush will deadlock if there are too
+ * many dirty RAID5 blocks.
+ */
+ current->policy = SCHED_OTHER;


+ current->nice = -20;

+// md_unlock_kernel();
+
+ up(thread->sem);


+
+ for (;;) {

+ DECLARE_WAITQUEUE(wait, current);
+
+ add_wait_queue(&thread->wqueue, &wait);
+ set_task_state(current, TASK_INTERRUPTIBLE);
+ if (!test_bit(THREAD_WAKEUP, &thread->flags)) {
+ dprintk("thread %p went to sleep.\n", thread);
+ schedule();
+ dprintk("thread %p woke up.\n", thread);
+ }


+ current->state = TASK_RUNNING;

+ remove_wait_queue(&thread->wqueue, &wait);
+ clear_bit(THREAD_WAKEUP, &thread->flags);
+
+ if (thread->run) {
+ thread->run(thread->data);
+ run_task_queue(&tq_disk);
+ } else
+ break;
+ if (md_signal_pending(current)) {
+ printk("%8s(%d) flushing signals.\n", current->comm,
+ current->pid);
+ md_flush_signals();
+ }
+ }
+ up(thread->sem);


+ return 0;
+}
+

+void md_wakeup_thread(mdk_thread_t *thread)
+{
+ dprintk("waking up MD thread %p.\n", thread);
+ set_bit(THREAD_WAKEUP, &thread->flags);
+ wake_up(&thread->wqueue);
+}
+
+mdk_thread_t *md_register_thread (void (*run) (void *),
+ void *data, const char *name)
+{
+ mdk_thread_t *thread;
+ int ret;
+ DECLARE_MUTEX_LOCKED(sem);
+
+ thread = (mdk_thread_t *) kmalloc
+ (sizeof(mdk_thread_t), GFP_KERNEL);
+ if (!thread)
+ return NULL;
+
+ memset(thread, 0, sizeof(mdk_thread_t));
+ md_init_waitqueue_head(&thread->wqueue);
+
+ thread->sem = &sem;
+ thread->run = run;
+ thread->data = data;
+ thread->name = name;
+ ret = kernel_thread(md_thread, thread, 0);
+ if (ret < 0) {
+ kfree(thread);
+ return NULL;
+ }
+ down(&sem);
+ return thread;
+}
+
+void md_interrupt_thread (mdk_thread_t *thread)
+{
+ if (!thread->tsk) {


+ MD_BUG();
+ return;
+ }

+ printk("interrupting MD-thread pid %d\n", thread->tsk->pid);
+ send_sig(SIGKILL, thread->tsk, 1);
+}
+
+void md_unregister_thread (mdk_thread_t *thread)
+{
+ DECLARE_MUTEX_LOCKED(sem);
+
+ thread->sem = &sem;
+ thread->run = NULL;
+ thread->name = NULL;
+ if (!thread->tsk) {


+ MD_BUG();
+ return;
+ }

+ md_interrupt_thread(thread);
+ down(&sem);
+}
+
+void md_recover_arrays (void)
+{
+ if (!md_recovery_thread) {


+ MD_BUG();
+ return;
+ }

+ md_wakeup_thread(md_recovery_thread);
+}
+
+
+int md_error (kdev_t dev, kdev_t rdev)
+{
+ mddev_t *mddev;
+ mdk_rdev_t * rrdev;
+ int rc;
+
+ mddev = kdev_to_mddev(dev);
+/* printk("md_error dev:(%d:%d), rdev:(%d:%d), (caller: %p,%p,%p,%p).\n",MAJOR(dev),MINOR(dev),MAJOR(rdev),MINOR(rdev), __builtin_return_address(0),__builtin_return_address(1),__builtin_return_address(2),__builtin_return_address(3));
+ */
+ if (!mddev) {


+ MD_BUG();
+ return 0;
+ }

+ rrdev = find_rdev(mddev, rdev);
+ mark_rdev_faulty(rrdev);
+ /*
+ * if recovery was running, stop it now.
+ */
+ if (mddev->pers->stop_resync)
+ mddev->pers->stop_resync(mddev);
+ if (mddev->recovery_running)
+ md_interrupt_thread(md_recovery_thread);
+ if (mddev->pers->error_handler) {
+ rc = mddev->pers->error_handler(mddev, rdev);
+ md_recover_arrays();
+ return rc;


+ }
+ return 0;
+}
+

+static int status_unused (char * page)
+{
+ int sz = 0, i = 0;


+ mdk_rdev_t *rdev;
+ struct md_list_head *tmp;
+

+ sz += sprintf(page + sz, "unused devices: ");
+
+ ITERATE_RDEV_ALL(rdev,tmp) {
+ if (!rdev->same_set.next && !rdev->same_set.prev) {
+ /*
+ * The device is not yet used by any array.
+ */
+ i++;
+ sz += sprintf(page + sz, "%s ",
+ partition_name(rdev->dev));
+ }
+ }
+ if (!i)
+ sz += sprintf(page + sz, "<none>");
+


+ sz += sprintf(page + sz, "\n");

+ return sz;
+}
+
+
+static int status_resync (char * page, mddev_t * mddev)
+{


+ int sz = 0;

+ unsigned long max_blocks, resync, res, dt, db, rt;
+
+ resync = mddev->curr_resync - atomic_read(&mddev->recovery_active);


+ max_blocks = mddev->sb->size;

+
+ /*
+ * Should not happen.
+ */
+ if (!max_blocks) {


+ MD_BUG();
+ return 0;
+ }

+ res = (resync/1024)*1000/(max_blocks/1024 + 1);
+ {
+ int i, x = res/50, y = 20-x;


+ sz += sprintf(page + sz, "[");

+ for (i = 0; i < x; i++)
+ sz += sprintf(page + sz, "=");


+ sz += sprintf(page + sz, ">");

+ for (i = 0; i < y; i++)
+ sz += sprintf(page + sz, ".");


+ sz += sprintf(page + sz, "] ");
+ }

+ if (!mddev->recovery_running)
+ /*
+ * true resync
+ */
+ sz += sprintf(page + sz, " resync =%3lu.%lu%% (%lu/%lu)",
+ res/10, res % 10, resync, max_blocks);
+ else
+ /*
+ * recovery ...
+ */
+ sz += sprintf(page + sz, " recovery =%3lu.%lu%% (%lu/%lu)",
+ res/10, res % 10, resync, max_blocks);
+
+ /*
+ * We do not want to overflow, so the order of operands and
+ * the * 100 / 100 trick are important. We do a +1 to be
+ * safe against division by zero. We only estimate anyway.
+ *
+ * dt: time from mark until now
+ * db: blocks written from mark until now
+ * rt: remaining time
+ */
+ dt = ((jiffies - mddev->resync_mark) / HZ);
+ if (!dt) dt++;
+ db = resync - mddev->resync_mark_cnt;
+ rt = (dt * ((max_blocks-resync) / (db/100+1)))/100;
+
+ sz += sprintf(page + sz, " finish=%lu.%lumin", rt / 60, (rt % 60)/6);
+
+ sz += sprintf(page + sz, " speed=%ldK/sec", db/dt);
+


+ return sz;
+}
+

+static int md_status_read_proc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int sz = 0, j, size;
+ struct md_list_head *tmp, *tmp2;
+ mdk_rdev_t *rdev;
+ mddev_t *mddev;
+
+ sz += sprintf(page + sz, "Personalities : ");
+ for (j = 0; j < MAX_PERSONALITY; j++)
+ if (pers[j])
+ sz += sprintf(page+sz, "[%s] ", pers[j]->name);
+
+ sz += sprintf(page+sz, "\n");
+
+
+ sz += sprintf(page+sz, "read_ahead ");
+ if (read_ahead[MD_MAJOR] == INT_MAX)
+ sz += sprintf(page+sz, "not set\n");
+ else
+ sz += sprintf(page+sz, "%d sectors\n", read_ahead[MD_MAJOR]);
+
+ ITERATE_MDDEV(mddev,tmp) {
+ sz += sprintf(page + sz, "md%d : %sactive", mdidx(mddev),
+ mddev->pers ? "" : "in");
+ if (mddev->pers) {
+ if (mddev->ro)
+ sz += sprintf(page + sz, " (read-only)");
+ sz += sprintf(page + sz, " %s", mddev->pers->name);
+ }
+
+ size = 0;
+ ITERATE_RDEV(mddev,rdev,tmp2) {
+ sz += sprintf(page + sz, " %s[%d]",
+ partition_name(rdev->dev), rdev->desc_nr);
+ if (rdev->faulty) {
+ sz += sprintf(page + sz, "(F)");
+ continue;
+ }
+ size += rdev->size;
+ }
+
+ if (mddev->nb_dev) {
+ if (mddev->pers)
+ sz += sprintf(page + sz, "\n %d blocks",
+ md_size[mdidx(mddev)]);
+ else
+ sz += sprintf(page + sz, "\n %d blocks", size);
+ }
+
+ if (!mddev->pers) {
+ sz += sprintf(page+sz, "\n");
+ continue;
+ }
+
+ sz += mddev->pers->status (page+sz, mddev);


+
+ sz += sprintf(page+sz, "\n ");

+ if (mddev->curr_resync) {
+ sz += status_resync (page+sz, mddev);
+ } else {
+ if (md_atomic_read(&mddev->resync_sem.count) != 1)
+ sz += sprintf(page + sz, " resync=DELAYED");
+ }
+ sz += sprintf(page + sz, "\n");
+ }
+ sz += status_unused (page + sz);
+


+ return sz;
+}
+

+int register_md_personality (int pnum, mdk_personality_t *p)
+{
+ if (pnum >= MAX_PERSONALITY)
+ return -EINVAL;
+
+ if (pers[pnum])
+ return -EBUSY;
+
+ pers[pnum] = p;
+ printk(KERN_INFO "%s personality registered\n", p->name);


+ return 0;
+}
+

+int unregister_md_personality (int pnum)
+{
+ if (pnum >= MAX_PERSONALITY)
+ return -EINVAL;
+
+ printk(KERN_INFO "%s personality unregistered\n", pers[pnum]->name);
+ pers[pnum] = NULL;


+ return 0;
+}
+

+static mdp_disk_t *get_spare(mddev_t *mddev)
+{


+ mdp_super_t *sb = mddev->sb;

+ mdp_disk_t *disk;


+ mdk_rdev_t *rdev;
+ struct md_list_head *tmp;
+

+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->faulty)

+ continue;


+ if (!rdev->sb) {
+ MD_BUG();

+ continue;
+ }
+ disk = &sb->disks[rdev->desc_nr];
+ if (disk_faulty(disk)) {
+ MD_BUG();
+ continue;
+ }
+ if (disk_active(disk))
+ continue;
+ return disk;


+ }
+ return NULL;
+}
+

+static unsigned int sync_io[DK_MAX_MAJOR][DK_MAX_DISK];
+void md_sync_acct(kdev_t dev, unsigned long nr_sectors)
+{
+ unsigned int major = MAJOR(dev);
+ unsigned int index;
+
+ index = disk_index(dev);
+ if ((index >= DK_MAX_DISK) || (major >= DK_MAX_MAJOR))
+ return;
+
+ sync_io[major][index] += nr_sectors;
+}
+
+static int is_mddev_idle (mddev_t *mddev)


+{
+ mdk_rdev_t * rdev;
+ struct md_list_head *tmp;

+ int idle;
+ unsigned long curr_events;
+
+ idle = 1;
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ int major = MAJOR(rdev->dev);
+ int idx = disk_index(rdev->dev);
+
+ if ((idx >= DK_MAX_DISK) || (major >= DK_MAX_MAJOR))
+ continue;
+
+ curr_events = kstat.dk_drive_rblk[major][idx] +
+ kstat.dk_drive_wblk[major][idx] ;
+ curr_events -= sync_io[major][idx];
+// printk("events(major: %d, idx: %d): %ld\n", major, idx, curr_events);
+ if (curr_events != rdev->last_events) {
+// printk("!I(%ld)", curr_events - rdev->last_events);
+ rdev->last_events = curr_events;
+ idle = 0;
+ }
+ }
+ return idle;
+}
+
+MD_DECLARE_WAIT_QUEUE_HEAD(resync_wait);
+
+void md_done_sync(mddev_t *mddev, int blocks, int ok)
+{
+ /* another "blocks" (1K) blocks have been synced */
+ atomic_sub(blocks, &mddev->recovery_active);
+ wake_up(&mddev->recovery_wait);
+ if (!ok) {
+ // stop recovery, signal do_sync ....
+ }
+}
+
+#define SYNC_MARKS 10
+#define SYNC_MARK_STEP (3*HZ)
+int md_do_sync(mddev_t *mddev, mdp_disk_t *spare)
+{
+ mddev_t *mddev2;
+ unsigned int max_blocks, currspeed,
+ j, window, err, serialize;
+ kdev_t read_disk = mddev_to_kdev(mddev);
+ unsigned long mark[SYNC_MARKS];
+ unsigned long mark_cnt[SYNC_MARKS];
+ int last_mark,m;
+ struct md_list_head *tmp;
+ unsigned long last_check;
+
+
+ err = down_interruptible(&mddev->resync_sem);
+ if (err)
+ goto out_nolock;
+
+recheck:
+ serialize = 0;
+ ITERATE_MDDEV(mddev2,tmp) {
+ if (mddev2 == mddev)
+ continue;
+ if (mddev2->curr_resync && match_mddev_units(mddev,mddev2)) {
+ printk(KERN_INFO "md: serializing resync, md%d has overlapping physical units with md%d!\n", mdidx(mddev), mdidx(mddev2));


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 056'
echo 'File patch-2.4.0-test9 is continued in part 057'
echo "057" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part061

#!/bin/sh -x
# this is part 061 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 061; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

- if (vortex_debug > 2)
- printk(KERN_DEBUG "reset DMA to 0x%08x\n", inl(ioaddr + DownListPtr));
- outw(DownUnstall, ioaddr + EL3_CMD);
-
- /*
- * Here we make a single attempt to prevent a timeout by
- * restarting the timer if we think that the ISR has a good
- * chance of unjamming things.
- */
- if (vp->tx_reset_resume == 0 && vp->tx_full) {
- vp->tx_reset_resume = 1;
- dev->trans_start = jiffies;
- }
- } else {
- wait_for_completion(dev, TxReset);
- outw(TxEnable, ioaddr + EL3_CMD);
+ wait_for_completion(dev, TxReset|reset_mask);
+ outw(TxEnable, ioaddr + EL3_CMD);
+ if (!vp->full_bus_master_tx)
X netif_wake_queue(dev);
- }
X }
X }
X
@@ -1785,7 +1772,6 @@
X /* netif_start_queue (dev); */ /* AKPM: redundant? */
X }
X outw(DownUnstall, ioaddr + EL3_CMD);
- vp->tx_reset_resume = 0;
X spin_unlock_irqrestore(&vp->lock, flags);
X dev->trans_start = jiffies;
X return 0;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/8139too.c linux/drivers/net/8139too.c
--- v2.4.0-test8/linux/drivers/net/8139too.c Fri Sep 8 12:37:34 2000
+++ linux/drivers/net/8139too.c Sun Sep 17 09:41:28 2000
@@ -2,8 +2,37 @@
X
X 8139too.c: A RealTek RTL-8139 Fast Ethernet driver for Linux.
X
- Copyright 2000 Jeff Garzik <jga...@mandrakesoft.com>
- Originally: Written 1997-1999 by Donald Becker.
+ Maintained by Jeff Garzik <jga...@mandrakesoft.com>
+
+ Much code comes from Donald Becker's rtl8139.c driver,
+ versions 1.11 and older. This driver was originally based
+ on rtl8139.c version 1.07. Header of rtl8139.c version 1.11:
+
+ -----<snip>-----
+
+ Written 1997-2000 by Donald Becker.
+ This software may be used and distributed according to the
+ terms of the GNU General Public License (GPL), incorporated
+ herein by reference. Drivers based on or derived from this
+ code fall under the GPL and must retain the authorship,
+ copyright and license notice. This file is not a complete
+ program and may only be used when the entire operating
+ system is licensed under the GPL.
+
+ This driver is for boards based on the RTL8129 and RTL8139


+ PCI ethernet chips.
+

+ The author may be reached as bec...@scyld.com, or C/O Scyld
+ Computing Corporation 410 Severn Ave., Suite 210 Annapolis
+ MD 21403
+
+ Support and updates available at
+ http://www.scyld.com/network/rtl8139.html
+
+ Twister-tuning table provided by Kinston
+ <sha...@realtek.com.tw>.
+
+ -----<snip>-----
X
X This software may be used and distributed according to the terms
X of the GNU Public License, incorporated herein by reference.
@@ -16,7 +45,7 @@
X Tigran Aivazian - bug fixes, skbuff free cleanup
X
X Martin Mares - suggestions for PCI cleanup
-
+
X David S. Miller - PCI DMA and softnet updates
X
X Ernst Gill - fixes ported from BSD driver
@@ -24,7 +53,22 @@
X Daniel Kobras - identified specific locations of
X posted MMIO write bugginess
X
- Gerard Sharp - bug fix
+ Gerard Sharp - bug fix, testing and feedback
+
+ David Ford - Rx ring wrap fix
+
+ Dan DeMaggio - swapped RTL8139 cards with me, and allowed me
+ to find and fix a crucial bug on older chipsets.
+
+ Donald Becker/Chris Butterworth/Marcus Westergren -
+ Noticed various Rx packet size-related buglets.
+
+ Santiago Garcia Mantinan - testing and feedback
+
+ Jens David - 2.2.x kernel backports
+
+ Martin Dennett - incredibly helpful insight on undocumented
+ features of the 8139 chips
X
X Submitting bug reports:
X
@@ -73,7 +117,7 @@
X IVb. References
X
X http://www.realtek.com.tw/cn/cn.html
-http://cesdis.gsfc.nasa.gov/linux/misc/NWay.html
+http://www.scyld.com/expert/NWay.html
X
X IVc. Errata
X
@@ -97,25 +141,33 @@
X #include <asm/io.h>
X
X
-#define RTL8139_VERSION "0.9.8"
+#define RTL8139_VERSION "0.9.10"
X #define RTL8139_MODULE_NAME "8139too"
X #define RTL8139_DRIVER_NAME RTL8139_MODULE_NAME " Fast Ethernet driver " RTL8139_VERSION
X #define PFX RTL8139_MODULE_NAME ": "
X
-#undef RTL8139_DEBUG /* define to 1 to enable copious debugging info */
+
+/* define to 1 to enable PIO instead of MMIO */
+#undef USE_IO_OPS
+
+/* define to 1 to enable copious debugging info */
+#undef RTL8139_DEBUG
+
+/* define to 1 to disable lightweight runtime debugging checks */
+#undef RTL8139_NDEBUG
+
X
X #ifdef RTL8139_DEBUG
X /* note: prints function name for you */
-#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+# define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
X #else
-#define DPRINTK(fmt, args...)
+# define DPRINTK(fmt, args...)
X #endif
X
-#undef RTL8139_NDEBUG /* define to 1 to disable lightweight runtime checks */
X #ifdef RTL8139_NDEBUG
-#define assert(expr)
+# define assert(expr) do {} while (0)
X #else
-#define assert(expr) \
+# define assert(expr) \
X if(!(expr)) { \
X printk( "Assertion failed! %s,%s,%s,line=%d\n", \
X #expr,__FILE__,__FUNCTION__,__LINE__); \
@@ -125,12 +177,6 @@
X #define arraysize(x) (sizeof(x)/sizeof(*(x)))
X
X
-#ifndef PCI_GET_DRIVER_DATA
- #define PCI_GET_DRIVER_DATA(pdev) ((pdev)->driver_data)
- #define PCI_SET_DRIVER_DATA(pdev,data) (((pdev)->driver_data) = (data))
-#endif /* PCI_GET_DRIVER_DATA */
-
-
X /* A few user-configurable values. */
X /* media options */
X static int media[] = {-1, -1, -1, -1, -1, -1, -1, -1};
@@ -146,7 +192,8 @@
X #define RX_BUF_LEN_IDX 2 /* 0==8K, 1==16K, 2==32K, 3==64K */
X #define RX_BUF_LEN (8192 << RX_BUF_LEN_IDX)
X #define RX_BUF_PAD 16
-#define RX_BUF_TOT_LEN (RX_BUF_LEN + RX_BUF_PAD)
+#define RX_BUF_WRAP_PAD 2048 /* spare padding to handle lack of packet wrap */
+#define RX_BUF_TOT_LEN (RX_BUF_LEN + RX_BUF_PAD + RX_BUF_WRAP_PAD)
X
X /* Number of Tx descriptor registers. */
X #define NUM_TX_DESC 4
@@ -160,9 +207,9 @@
X #define TX_FIFO_THRESH 256 /* In bytes, rounded down to 32 byte units. */
X
X /* The following settings are log_2(bytes)-4: 0 == 16 bytes .. 6==1024, 7==end of packet. */
-#define RX_FIFO_THRESH 4 /* Rx buffer level before first PCI xfer. */
-#define RX_DMA_BURST 4 /* Maximum PCI burst, '7' is unlimited */
-#define TX_DMA_BURST 4 /* Maximum PCI burst, '4' is 256 */
+#define RX_FIFO_THRESH 6 /* Rx buffer level before first PCI xfer. */
+#define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
+#define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
X
X
X /* Operational parameters that usually are not changed. */
@@ -321,6 +368,7 @@
X TxLoopBack = (1 << 18) | (1 << 17), /* enable loopback test mode */
X TxCRC = (1 << 16), /* DISABLE appending CRC to end of Tx packets */
X TxClearAbt = (1 << 0), /* Clear abort (WO) */
+ TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */
X
X TxVersionMask = 0x7C800000, /* mask out version bits 30-26, 23 */
X };
@@ -341,7 +389,7 @@
X /* Early Rx threshold, none or X/16 */
X RxCfgEarlyRxNone = 0,
X RxCfgEarlyRxShift = 24,
-
+
X /* rx fifo threshold */
X RxCfgFIFOShift = 13,
X RxCfgFIFONone = (7 << RxCfgFIFOShift),
@@ -355,6 +403,9 @@
X RxCfgRcv16K = (1 << 11),
X RxCfgRcv32K = (1 << 12),
X RxCfgRcv64K = (1 << 11) | (1 << 12),
+
+ /* Disable packet wrap at end of Rx buffer */
+ RxNoWrap = (1 << 7),
X };
X
X
@@ -411,17 +462,17 @@
X 0x40,
X 0xf0fe0040, /* XXX copied from RTL8139A, verify */
X },
-
+
X { "RTL-8139 rev K",
X 0x60,
- 0xf0fe0040, /* XXX copied from RTL8139A, verify */
+ 0xf0fe0040,
X },
-
+
X { "RTL-8139A",
X 0x70,
X 0xf0fe0040,
X },
-
+
X { "RTL-8139B",
X 0x78,
X 0xf0fc0040
@@ -497,6 +548,32 @@
X static void rtl8139_hw_start (struct net_device *dev);
X
X
+#ifdef USE_IO_OPS
+
+#define RTL_R8(reg) inb (((unsigned long)ioaddr) + (reg))
+#define RTL_R16(reg) inw (((unsigned long)ioaddr) + (reg))
+#define RTL_R32(reg) inl (((unsigned long)ioaddr) + (reg))
+#define RTL_W8(reg, val8) outb ((val8), ((unsigned long)ioaddr) + (reg))
+#define RTL_W16(reg, val16) outw ((val16), ((unsigned long)ioaddr) + (reg))
+#define RTL_W32(reg, val32) outl ((val32), ((unsigned long)ioaddr) + (reg))
+#define RTL_W8_F RTL_W8
+#define RTL_W16_F RTL_W16
+#define RTL_W32_F RTL_W32
+#undef readb
+#undef readw
+#undef readl
+#undef writeb
+#undef writew
+#undef writel
+#define readb(addr) inb((unsigned long)(addr))
+#define readw(addr) inw((unsigned long)(addr))
+#define readl(addr) inl((unsigned long)(addr))
+#define writeb(val,addr) outb((val),(unsigned long)(addr))
+#define writew(val,addr) outw((val),(unsigned long)(addr))
+#define writel(val,addr) outl((val),(unsigned long)(addr))
+
+#else
+
X /* write MMIO register, with flush */
X /* Flush avoids rtl8139 bug w/ posted MMIO writes */
X #define RTL_W8_F(reg, val8) do { writeb ((val8), ioaddr + (reg)); readb (ioaddr + (reg)); } while (0)
@@ -525,13 +602,17 @@
X #define RTL_R16(reg) readw (ioaddr + (reg))
X #define RTL_R32(reg) readl (ioaddr + (reg))
X
+#endif /* USE_IO_OPS */
X
-static const u16 rtl8139_intr_mask =
+
+static const u16 rtl8139_intr_mask =
X PCIErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver |
X TxErr | TxOK | RxErr | RxOK;
X
X static const unsigned int rtl8139_rx_config =
- RxCfgEarlyRxNone | RxCfgFIFONone | RxCfgRcv32K | RxCfgDMAUnlimited;
+ RxCfgEarlyRxNone | RxCfgRcv32K | RxNoWrap |
+ (RX_FIFO_THRESH << RxCfgFIFOShift) |
+ (RX_DMA_BURST << RxCfgDMAShift);
X
X
X static int __devinit rtl8139_init_board (struct pci_dev *pdev,
@@ -577,7 +658,7 @@
X /* set this immediately, we need to know before
X * we talk to the chip directly */
X DPRINTK("PIO region size == 0x%02X\n", pio_len);
- DPRINTK("MMIO region size == 0x%02X\n", mmio_len);
+ DPRINTK("MMIO region size == 0x%02lX\n", mmio_len);
X if (pio_len == RTL8139B_IO_SIZE)
X tp->chipset = CH_8139B;
X
@@ -587,14 +668,14 @@
X rc = -ENODEV;
X goto err_out;
X }
-
+
X /* make sure PCI base addr 1 is MMIO */
X if (!(mmio_flags & IORESOURCE_MEM)) {
X printk (KERN_ERR PFX "region #1 not an MMIO resource, aborting\n");
X rc = -ENODEV;
X goto err_out;
X }
-
+
X /* check for weird/broken PCI region reporting */
X if ((pio_len != mmio_len) ||
X (pio_len < RTL_MIN_IO_SIZE) ||
@@ -610,14 +691,14 @@
X rc = -EBUSY;
X goto err_out;
X }
-
+
X /* make sure our MMIO region in PCI space is available */
X if (!request_mem_region (mmio_start, mmio_len, dev->name)) {
X printk (KERN_ERR PFX "no mem resource available, aborting\n");
X rc = -EBUSY;
X goto err_out_free_pio;
X }
-
+
X /* enable device (incl. PCI PM wakeup), and bus-mastering */
X rc = pci_enable_device (pdev);
X if (rc)


@@ -625,6 +706,9 @@
X

X pci_set_master (pdev);
X
+#ifdef USE_IO_OPS
+ ioaddr = (void *) pio_start;
+#else
X /* ioremap MMIO region */
X ioaddr = ioremap (mmio_start, mmio_len);
X if (ioaddr == NULL) {
@@ -632,6 +716,7 @@
X rc = -EIO;
X goto err_out_free_mmio;
X }
+#endif /* USE_IO_OPS */
X
X /* Soft reset the chip. */
X RTL_W8 (ChipCmd, (RTL_R8 (ChipCmd) & ChipCmdClear) | CmdReset);
@@ -653,12 +738,14 @@
X RTL_W8 (Config1, 0);
X }
X
+#ifndef USE_IO_OPS
X /* sanity checks -- ensure PIO and MMIO registers agree */
X assert (inb (pio_start+Config0) == readb (ioaddr+Config0));
X assert (inb (pio_start+Config1) == readb (ioaddr+Config1));
X assert (inb (pio_start+TxConfig) == readb (ioaddr+TxConfig));
X assert (inb (pio_start+RxConfig) == readb (ioaddr+RxConfig));
-
+#endif /* !USE_IO_OPS */
+
X /* make sure chip thinks PIO and MMIO are enabled */
X tmp8 = RTL_R8 (Config1);
X if ((tmp8 & Cfg1_PIO) == 0) {
@@ -671,7 +758,7 @@
X rc = -EIO;
X goto err_out_iounmap;
X }
-
+
X /* identify chip attached to board */
X tmp = RTL_R8 (ChipVersion);
X for (i = arraysize (rtl_chip_info) - 1; i >= 0; i--)
@@ -691,15 +778,17 @@
X tmp,
X tp->chipset,
X rtl_chip_info[tp->chipset].name);
-

+
X DPRINTK ("EXIT, returning 0\n");

X *ioaddr_out = ioaddr;
X *dev_out = dev;
- return 0;
+ return 0;
X
X err_out_iounmap:
X assert (ioaddr > 0);
+#ifndef USE_IO_OPS
X iounmap (ioaddr);
+#endif /* !USE_IO_OPS */
X err_out_free_mmio:
X release_mem_region (mmio_start, mmio_len);
X err_out_free_pio:
@@ -720,14 +809,11 @@
X int i, addr_len, option;
X void *ioaddr = NULL;
X static int board_idx = -1;
- u8 tmp;
-
-#ifndef RTL8139_NDEBUG
X static int printed_version = 0;
-#endif /* RTL8139_NDEBUG */
+ u8 tmp;


X
X DPRINTK ("ENTER\n");

-
+
X assert (pdev != NULL);
X assert (ent != NULL);
X
@@ -743,9 +829,9 @@
X DPRINTK ("EXIT, returning %d\n", i);
X return i;
X }
-
+
X tp = dev->priv;
-
+
X assert (ioaddr != NULL);
X assert (dev != NULL);
X assert (tp != NULL);
@@ -766,7 +852,7 @@
X dev->watchdog_timeo = TX_TIMEOUT;
X
X dev->irq = pdev->irq;
- dev->base_addr = pci_resource_start (pdev, 1);
+ dev->base_addr = (unsigned long) ioaddr;
X
X /* dev->priv/tp zeroed and aligned in init_etherdev */
X tp = dev->priv;
@@ -779,24 +865,23 @@
X tp->mmio_addr = ioaddr;
X tp->lock = SPIN_LOCK_UNLOCKED;
X
- PCI_SET_DRIVER_DATA (pdev, dev);
+ pdev->driver_data = dev;
X
X tp->phys[0] = 32;
X
- printk (KERN_INFO "%s: %s board found at 0x%lx, IRQ %d\n",
- dev->name, board_info[ent->driver_data].name,
- dev->base_addr, dev->irq);
-
- printk (KERN_INFO "%s: Chip is '%s'\n",
- dev->name,
- rtl_chip_info[tp->chipset].name);
-
- printk (KERN_INFO "%s: MAC address "
- "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n",
+ printk (KERN_INFO "%s: %s at 0x%lx, "
+ "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
+ "IRQ %d\n",
X dev->name,
+ board_info[ent->driver_data].name,
+ dev->base_addr,
X dev->dev_addr[0], dev->dev_addr[1],
X dev->dev_addr[2], dev->dev_addr[3],
- dev->dev_addr[4], dev->dev_addr[5]);
+ dev->dev_addr[4], dev->dev_addr[5],
+ dev->irq);
+
+ printk (KERN_DEBUG "%s: Identified 8139 chip type '%s'\n",
+ dev->name, rtl_chip_info[tp->chipset].name);
X
X /* Put the chip into low-power mode. */
X RTL_W8_F (Cfg9346, Cfg9346_Unlock);
@@ -831,7 +916,7 @@
X
X static void __devexit rtl8139_remove_one (struct pci_dev *pdev)
X {
- struct net_device *dev = PCI_GET_DRIVER_DATA (pdev);
+ struct net_device *dev = pdev->driver_data;
X struct rtl8139_private *np;


X
X DPRINTK ("ENTER\n");

@@ -843,7 +928,10 @@
X
X unregister_netdev (dev);
X
+#ifndef USE_IO_OPS
X iounmap (np->mmio_addr);
+#endif /* !USE_IO_OPS */
+
X release_region (pci_resource_start (pdev, 0),
X pci_resource_len (pdev, 0));
X release_mem_region (pci_resource_start (pdev, 1),
@@ -857,7 +945,9 @@
X #endif /* RTL8139_NDEBUG */
X
X kfree (dev);
-
+
+ pdev->driver_data = NULL;
+


X DPRINTK ("EXIT\n");
X }

X
@@ -1094,9 +1184,9 @@
X DPRINTK ("EXIT, returning -ENOMEM\n");
X MOD_DEC_USE_COUNT;
X return -ENOMEM;
-
+
X }
-
+
X tp->full_duplex = tp->duplex_lock;
X tp->tx_flag = (TX_FIFO_THRESH << 11) & 0x003f0000;


X
@@ -1131,7 +1221,7 @@

X u8 tmp;


X
X DPRINTK ("ENTER\n");

-
+
X /* Soft reset the chip. */
X RTL_W8 (ChipCmd, (RTL_R8 (ChipCmd) & ChipCmdClear) | CmdReset);
X udelay (100);
@@ -1154,7 +1244,7 @@
X RTL_W32_F (RxConfig, i);
X
X /* Check this value: the documentation for IFG contradicts ifself. */
- RTL_W32 (TxConfig, (TX_DMA_BURST << 8));
+ RTL_W32 (TxConfig, (TX_DMA_BURST << TxDMAShift));
X
X /* unlock Config[01234] and BMCR register writes */
X RTL_W8_F (Cfg9346, Cfg9346_Unlock);
@@ -1175,9 +1265,9 @@
X if (tp->chipset >= CH_8139B) {
X tmp = RTL_R8 (Config4) & ~(1<<2);
X /* chip will clear Rx FIFO overflow automatically */
- tmp |= (1<<7);
+ tmp |= (1<<7);
X RTL_W8 (Config4, tmp);
-
+
X /* disable magic packet scanning, which is enabled
X * when PM is enabled above (Config1) */
X RTL_W8 (Config3, RTL_R8 (Config3) & ~(1<<5));
@@ -1334,15 +1424,13 @@
X {
X struct net_device *dev = (struct net_device *) data;
X struct rtl8139_private *tp = (struct rtl8139_private *) dev->priv;
+ void *ioaddr = tp->mmio_addr;
X int next_tick = 60 * HZ;
X int mii_reg5;
X
- spin_lock_irq (&tp->lock);
-
X mii_reg5 = mdio_read (dev, tp->phys[0], 5);
X
X if (!tp->duplex_lock && mii_reg5 != 0xffff) {
- void *ioaddr = tp->mmio_addr;
X int duplex = (mii_reg5 & 0x0100)
X || (mii_reg5 & 0x01C0) == 0x0040;
X if (tp->full_duplex != duplex) {
@@ -1371,8 +1459,6 @@
X dev->name, RTL_R8 (Config0),
X RTL_R8 (Config1));
X
- spin_unlock_irq (&tp->lock);
-
X tp->timer.expires = jiffies + next_tick;
X add_timer (&tp->timer);
X }
@@ -1383,6 +1469,7 @@
X struct rtl8139_private *tp = (struct rtl8139_private *) dev->priv;
X void *ioaddr = tp->mmio_addr;
X int i;


+ unsigned long flags;
X

X DPRINTK ("%s: Transmit timeout, status %2.2x %4.4x "
X "media %2.2x.\n", dev->name,
@@ -1390,25 +1477,20 @@
X RTL_R16 (IntrStatus),
X RTL_R8 (MediaStatus));
X
- spin_lock_irq (&tp->lock);
-
X /* Disable interrupts by clearing the interrupt mask. */
X RTL_W16 (IntrMask, 0x0000);
X
- spin_unlock_irq (&tp->lock);
-
X /* Emit info to figure out what went wrong. */
- printk (KERN_DEBUG
- "%s: Tx queue start entry %d dirty entry %d.\n",
+ printk (KERN_DEBUG "%s: Tx queue start entry %d dirty entry %d.\n",
X dev->name, atomic_read (&tp->cur_tx),
X atomic_read (&tp->dirty_tx));
X for (i = 0; i < NUM_TX_DESC; i++)
X printk (KERN_DEBUG "%s: Tx descriptor %d is %8.8x.%s\n",
X dev->name, i, RTL_R32 (TxStatus0 + (i * 4)),
- i ==
- atomic_read (&tp->dirty_tx) % NUM_TX_DESC ? " (queue head)" : "");
+ i == atomic_read (&tp->dirty_tx) % NUM_TX_DESC ?
+ " (queue head)" : "");
X
- spin_lock_irq (&tp->lock);
+ spin_lock_irqsave (&tp->lock, flags);
X
X /* Stop a shared interrupt from scavenging while we are. */
X atomic_set (&tp->cur_tx, 0);
@@ -1418,7 +1500,8 @@
X for (i = 0; i < NUM_TX_DESC; i++) {
X struct ring_info *rp = &tp->tx_info[i];
X if (rp->mapping != 0) {
- pci_unmap_single (tp->pci_dev, rp->mapping, rp->skb->len, PCI_DMA_TODEVICE);
+ pci_unmap_single (tp->pci_dev, rp->mapping,
+ rp->skb->len, PCI_DMA_TODEVICE);
X rp->mapping = 0;
X }
X if (rp->skb) {
@@ -1427,9 +1510,10 @@
X tp->stats.tx_dropped++;
X }
X }
-
- spin_unlock_irq (&tp->lock);
X
+ spin_unlock_irqrestore (&tp->lock, flags);
+
+ /* ...and finally, reset everything */
X rtl8139_hw_start (dev);
X }
X
@@ -1444,18 +1528,17 @@
X /* Calculate the next Tx descriptor entry. */
X entry = atomic_read (&tp->cur_tx) % NUM_TX_DESC;
X
+ assert (tp->tx_info[entry].skb == NULL);
+ assert (tp->tx_info[entry].mapping == 0);
+
X tp->tx_info[entry].skb = skb;
- tp->tx_info[entry].mapping = 0;
+ /* tp->tx_info[entry].mapping = 0; */
X memcpy (tp->tx_buf[entry], skb->data, skb->len);
X
- spin_lock_irq (&tp->lock);
-
X /* Note: the chip doesn't have auto-pad! */
X RTL_W32 (TxStatus0 + (entry * sizeof(u32)),
X tp->tx_flag | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN));
X
- spin_unlock_irq (&tp->lock);
-
X dev->trans_start = jiffies;
X atomic_inc (&tp->cur_tx);
X if ((atomic_read (&tp->cur_tx) - atomic_read (&tp->dirty_tx)) >= NUM_TX_DESC)
@@ -1477,20 +1560,15 @@
X assert (dev != NULL);
X assert (tp != NULL);
X assert (ioaddr != NULL);
-
- /* drop lock held in rtl8139_interrupt */
- spin_unlock (&tp->lock);
-
+
X dirty_tx = atomic_read (&tp->dirty_tx);
X
X while ((atomic_read (&tp->cur_tx) - dirty_tx) > 0) {
X int entry = dirty_tx % NUM_TX_DESC;
X int txstatus;
X
- spin_lock (&tp->lock);
- txstatus = RTL_R32 (TxStatus0 + (entry * 4));
- spin_unlock (&tp->lock);
-
+ txstatus = RTL_R32 (TxStatus0 + (entry * sizeof (u32)));
+
X if (!(txstatus & (TxStatOK | TxUnderrun | TxAborted)))
X break; /* It still hasn't been Txed */
X
@@ -1502,9 +1580,7 @@
X tp->stats.tx_errors++;
X if (txstatus & TxAborted) {
X tp->stats.tx_aborted_errors++;
- spin_lock (&tp->lock);
- RTL_W32 (TxConfig, (TX_DMA_BURST << 8));
- spin_unlock (&tp->lock);
+ RTL_W32 (TxConfig, TxClearAbt | (TX_DMA_BURST << TxDMAShift));
X }
X if (txstatus & TxCarrierLost)
X tp->stats.tx_carrier_errors++;
@@ -1551,17 +1627,63 @@
X #endif /* RTL8139_NDEBUG */
X
X atomic_set (&tp->dirty_tx, dirty_tx);
-
- /* obtain lock need for rtl8139_interrupt */
- spin_lock (&tp->lock);
+}
+
+
+/* TODO: clean this up! Rx reset need not be this intensive */
+static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
+ struct rtl8139_private *tp, void *ioaddr)
+{
+ u8 tmp8;
+ int tmp_work = 1000;
+
+ DPRINTK ("%s: Ethernet frame had errors, status %8.8x.\n",
+ dev->name, rx_status);
+ if (rx_status & RxTooLong) {
+ DPRINTK ("%s: Oversized Ethernet frame, status %4.4x!\n",
+ dev->name, rx_status);
+ /* A.C.: The chip hangs here. */
+ }
+ tp->stats.rx_errors++;
+ if (rx_status & (RxBadSymbol | RxBadAlign))
+ tp->stats.rx_frame_errors++;
+ if (rx_status & (RxRunt | RxTooLong))
+ tp->stats.rx_length_errors++;
+ if (rx_status & RxCRCErr)
+ tp->stats.rx_crc_errors++;
+ /* Reset the receiver, based on RealTek recommendation. (Bug?) */
+ tp->cur_rx = 0;
+
+ /* disable receive */
+ tmp8 = RTL_R8 (ChipCmd) & ChipCmdClear;
+ RTL_W8_F (ChipCmd, tmp8 | CmdTxEnb);
+
+ /* A.C.: Reset the multicast list. */
+ rtl8139_set_rx_mode (dev);
+
+ /* XXX potentially temporary hack to
+ * restart hung receiver */
+ while (--tmp_work > 0) {
+ tmp8 = RTL_R8 (ChipCmd);
+ if ((tmp8 & CmdRxEnb) && (tmp8 & CmdTxEnb))
+ break;
+ RTL_W8_F (ChipCmd,
+ (tmp8 & ChipCmdClear) | CmdRxEnb | CmdTxEnb);
+ }
+
+ /* G.S.: Re-enable receiver */
+ /* XXX temporary hack to work around receiver hang */
+ rtl8139_set_rx_mode (dev);
+
+ if (tmp_work <= 0)
+ printk (KERN_WARNING PFX "tx/rx enable wait too long\n");
X }
X
X
X /* The data sheet doesn't describe the Rx ring at all, so I'm guessing at the
X field alignments and semantics. */
X static void rtl8139_rx_interrupt (struct net_device *dev,
- struct rtl8139_private *tp,
- void *ioaddr)
+ struct rtl8139_private *tp, void *ioaddr)
X {
X unsigned char *rx_ring;
X u16 cur_rx;
@@ -1569,31 +1691,33 @@
X assert (dev != NULL);
X assert (tp != NULL);
X assert (ioaddr != NULL);
-
+
X rx_ring = tp->rx_ring;
X cur_rx = tp->cur_rx;
X
X DPRINTK ("%s: In rtl8139_rx(), current %4.4x BufAddr %4.4x,"
- " free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx,
- RTL_R16 (RxBufAddr),
- RTL_R16 (RxBufPtr),
- RTL_R8 (ChipCmd));
+ " free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx,
+ RTL_R16 (RxBufAddr),
+ RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
X
X while ((RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
X int ring_offset = cur_rx % RX_BUF_LEN;
X u32 rx_status = le32_to_cpu (*(u32 *) (rx_ring + ring_offset));
X int rx_size = rx_status >> 16;
+ struct sk_buff *skb;
+ int pkt_size = rx_size - 4;
X
X DPRINTK ("%s: rtl8139_rx() status %4.4x, size %4.4x,"
- " cur %4.4x.\n", dev->name, rx_status,
- rx_size, cur_rx);
+ " cur %4.4x.\n", dev->name, rx_status,
+ rx_size, cur_rx);
X #if RTL8139_DEBUG > 2
X {
- int i;
- DPRINTK ("%s: Frame contents ", dev->name);
- for (i = 0; i < 70; i++)
- printk (" %2.2x", rx_ring[ring_offset + i]);
- printk (".\n");
+ int i;
+ DPRINTK ("%s: Frame contents ", dev->name);
+ for (i = 0; i < 70; i++)
+ printk (" %2.2x",
+ rx_ring[ring_offset + i]);
+ printk (".\n");
X }
X #endif
X
@@ -1609,128 +1733,68 @@
X if (rx_size == 0xfff0)
X break;
X
+ /* if Rx err received, Rx process gets reset, so
+ * we abort any further Rx processing
+ */
X if (rx_status &
- (RxBadSymbol | RxRunt | RxTooLong | RxCRCErr |
- RxBadAlign)) {
- u8 tmp8;
- int tmp_work = 1000;
-
- DPRINTK ("%s: Ethernet frame had errors,"
- " status %8.8x.\n", dev->name,
- rx_status);
- if (rx_status & RxTooLong) {
- DPRINTK ("%s: Oversized Ethernet frame, status %4.4x!\n",
- dev->name, rx_status);
- /* A.C.: The chip hangs here. */
- }
- tp->stats.rx_errors++;
- if (rx_status & (RxBadSymbol | RxBadAlign))
- tp->stats.rx_frame_errors++;
- if (rx_status & (RxRunt | RxTooLong))
- tp->stats.rx_length_errors++;
- if (rx_status & RxCRCErr)
- tp->stats.rx_crc_errors++;
- /* Reset the receiver, based on RealTek recommendation. (Bug?) */
- tp->cur_rx = 0;
-
- /* disable receive */
- tmp8 = RTL_R8 (ChipCmd) & ChipCmdClear;
- RTL_W8_F (ChipCmd, tmp8 | CmdTxEnb);
-
- /* A.C.: Reset the multicast list. */
- rtl8139_set_rx_mode (dev);
-
- /* XXX potentially temporary hack to
- * restart hung receiver */
- while (--tmp_work > 0) {
- tmp8 = RTL_R8 (ChipCmd);
- if ((tmp8 & CmdRxEnb) && (tmp8 & CmdTxEnb))
- break;
- RTL_W8_F (ChipCmd, (tmp8 & ChipCmdClear) | CmdRxEnb | CmdTxEnb);
- }
+ (RxBadSymbol | RxRunt | RxTooLong | RxCRCErr | RxBadAlign)) {
+ rtl8139_rx_err (rx_status, dev, tp, ioaddr);
+ return;
+ }
X
- /* G.S.: Re-enable receiver */
- /* XXX temporary hack to work around receiver hang */
- rtl8139_set_rx_mode (dev);
+ /* Malloc up new buffer, compatible with net-2e. */
+ /* Omit the four octet CRC from the length. */
X
- if (tmp_work <= 0)
- printk (KERN_WARNING PFX "tx/rx enable wait too long\n");
- } else {
- /* Malloc up new buffer, compatible with net-2e. */
- /* Omit the four octet CRC from the length. */
- struct sk_buff *skb;
- int pkt_size = rx_size - 4;
-
- skb = dev_alloc_skb (pkt_size + 2);
- if (skb == NULL) {
- printk (KERN_WARNING
- "%s: Memory squeeze, dropping packet.\n",
- dev->name);
- /* We should check that some rx space is free.
- If not, free one and mark stats->rx_dropped++. */
- tp->stats.rx_dropped++;
- break;
- }
- skb->dev = dev;
- skb_reserve (skb, 2); /* 16 byte align the IP fields. */
+ /* TODO: consider allocating skb's outside of
+ * interrupt context, both to speed interrupt processing,
+ * and also to reduce the chances of having to
+ * drop packets here under memory pressure.
+ */
X
- if (ring_offset + rx_size + 4 > RX_BUF_LEN) {
- int semi_count =
- RX_BUF_LEN - ring_offset - 4;
- /* This could presumably use two calls to copy_and_sum()? */
- memcpy (skb_put (skb, semi_count),
- &rx_ring[ring_offset + 4],
- semi_count);
- memcpy (skb_put (skb, pkt_size - semi_count),
- rx_ring, pkt_size - semi_count);
-#ifdef RTL8139_DEBUG
- {
- int i;
- printk (KERN_DEBUG "%s: Frame wrap @%d",
- dev->name, semi_count);
- for (i = 0; i < 16; i++)
- printk (" %2.2x", rx_ring[i]);
- printk ("\n");
- memset (rx_ring, 0xcc, 16);
- }
-#endif /* RTL8139_DEBUG */
-
- } else {
- eth_copy_and_sum (skb,
- &rx_ring[ring_offset + 4],
- pkt_size, 0);
- skb_put (skb, pkt_size);
- }
- skb->protocol = eth_type_trans (skb, dev);
- netif_rx (skb);
- tp->stats.rx_bytes += pkt_size;
- tp->stats.rx_packets++;
+ skb = dev_alloc_skb (pkt_size + 2);
+ if (skb == NULL) {
+ printk (KERN_WARNING
+ "%s: Memory squeeze, dropping packet.\n",
+ dev->name);
+ tp->stats.rx_dropped++;
+ break;
X }
+ skb->dev = dev;
+ skb_reserve (skb, 2); /* 16 byte align the IP fields. */
+
+ eth_copy_and_sum (skb, &rx_ring[ring_offset + 4], pkt_size, 0);
+ skb_put (skb, pkt_size);
+
+ skb->protocol = eth_type_trans (skb, dev);
+ netif_rx (skb);
+ tp->stats.rx_bytes += pkt_size;
+ tp->stats.rx_packets++;
X
X cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
X RTL_W16_F (RxBufPtr, cur_rx - 16);
X }
+
X DPRINTK ("%s: Done rtl8139_rx(), current %4.4x BufAddr %4.4x,"
- " free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx,
- RTL_R16 (RxBufAddr),
- RTL_R16 (RxBufPtr),
- RTL_R8 (ChipCmd));
+ " free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx,
+ RTL_R16 (RxBufAddr),
+ RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
+
X tp->cur_rx = cur_rx;
X }
X
X
-static int rtl8139_weird_interrupt (struct net_device *dev,
- struct rtl8139_private *tp,
- void *ioaddr,
- int status, int link_changed)
-{
- DPRINTK ("%s: Abnormal interrupt, status %8.8x.\n",
- dev->name, status);
-
+static void rtl8139_weird_interrupt (struct net_device *dev,
+ struct rtl8139_private *tp,
+ void *ioaddr,
+ int status, int link_changed)
+{
+ printk (KERN_DEBUG "%s: Abnormal interrupt, status %8.8x.\n",
+ dev->name, status);
+
X assert (dev != NULL);
X assert (tp != NULL);
X assert (ioaddr != NULL);
-
+
X /* Update the error count. */
X tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
X RTL_W32 (RxMissed, 0);
@@ -1768,8 +1832,6 @@
X printk (KERN_ERR "%s: PCI Bus error %4.4x.\n",
X dev->name, pci_cmd_status);
X }
-
- return 0;
X }
X
X
@@ -1785,14 +1847,14 @@
X int status = 0, link_changed = 0; /* avoid bogus "uninit" warning */
X
X spin_lock (&tp->lock);
-
+
X do {
X status = RTL_R16 (IntrStatus);
X
X /* h/w no longer present (hotplug?) or major error, bail */
X if (status == 0xFFFF)
X break;
-
+
X /* Acknowledge all of the current interrupt sources ASAP, but
X an first get an additional status bit from CSCR. */
X if (status & RxUnderrun)
@@ -1854,7 +1916,7 @@
X }
X
X spin_unlock (&tp->lock);
-
+
X DPRINTK ("%s: exiting interrupt, intr_status=%#4.4x.\n",
X dev->name, RTL_R16 (IntrStatus));
X }
@@ -1875,7 +1937,7 @@
X dev->name, RTL_R16 (IntrStatus));
X
X del_timer_sync (&tp->timer);
-
+
X spin_lock_irqsave (&tp->lock, flags);
X
X /* Disable interrupts by clearing the interrupt mask. */
@@ -1889,7 +1951,7 @@
X RTL_W32 (RxMissed, 0);
X
X spin_unlock_irqrestore (&tp->lock, flags);
-
+
X /* snooze for a small bit */
X if (current->need_resched)
X schedule ();
@@ -2053,7 +2115,7 @@
X set_bit (ether_crc (ETH_ALEN, mclist->dmi_addr) >> 26,
X mc_filter);
X }
-
+
X /* if called from irq handler, lock already acquired */
X if (!in_irq ())
X spin_lock_irq (&tp->lock);
@@ -2074,13 +2136,13 @@
X
X static void rtl8139_suspend (struct pci_dev *pdev)
X {
- struct net_device *dev = PCI_GET_DRIVER_DATA (pdev);
+ struct net_device *dev = pdev->driver_data;
X struct rtl8139_private *tp = (struct rtl8139_private *) dev->priv;
X void *ioaddr = tp->mmio_addr;
X unsigned long flags;
X
X netif_device_detach (dev);
-
+
X spin_lock_irqsave (&tp->lock, flags);
X
X /* Disable interrupts, stop Tx and Rx. */
@@ -2097,7 +2159,7 @@
X
X static void rtl8139_resume (struct pci_dev *pdev)
X {
- struct net_device *dev = PCI_GET_DRIVER_DATA (pdev);
+ struct net_device *dev = pdev->driver_data;
X
X netif_device_attach (dev);
X rtl8139_hw_start (dev);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/8390.h linux/drivers/net/8390.h
--- v2.4.0-test8/linux/drivers/net/8390.h Fri Sep 8 12:53:27 2000
+++ linux/drivers/net/8390.h Mon Oct 2 12:05:22 2000
@@ -53,11 +53,11 @@
X #if defined(LOAD_8390_BY_KMOD) && defined(MODULE) && !defined(NS8390_CORE)
X
X /* Function pointers to be mapped onto the 8390 core support */
-static int (*S_ethdev_init)(struct net_device *dev) = NULL;
-static void (*S_NS8390_init)(struct net_device *dev, int startp) = NULL;
-static int (*S_ei_open)(struct net_device *dev) = NULL;
-static int (*S_ei_close)(struct net_device *dev) = NULL;
-static void (*S_ei_interrupt)(int irq, void *dev_id, struct pt_regs *regs) = NULL;
+static int (*S_ethdev_init)(struct net_device *dev);
+static void (*S_NS8390_init)(struct net_device *dev, int startp);
+static int (*S_ei_open)(struct net_device *dev);
+static int (*S_ei_close)(struct net_device *dev);
+static void (*S_ei_interrupt)(int irq, void *dev_id, struct pt_regs *regs);
X
X extern __inline__ void unload_8390_module(void)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/Config.in linux/drivers/net/Config.in
--- v2.4.0-test8/linux/drivers/net/Config.in Wed Aug 23 09:30:13 2000
+++ linux/drivers/net/Config.in Thu Sep 21 13:27:10 2000
@@ -151,17 +151,16 @@
X tristate ' Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL)' CONFIG_NE3210
X fi
X if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- tristate ' RealTek 8129 (not 8019/8029!) support (EXPERIMENTAL)' CONFIG_RTL8129
- fi
- tristate ' RealTek RTL-8139 PCI Fast Ethernet Adapter support' CONFIG_8139TOO
- tristate ' SiS 900/7016 PCI Fast Ethernet Adapter support' CONFIG_SIS900
- # tristate ' Sundance Alta support' CONFIG_ALTA
- tristate ' TI ThunderLAN support' CONFIG_TLAN
- tristate ' VIA Rhine support' CONFIG_VIA_RHINE
- if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
X tristate ' Racal-Interlan EISA ES3210 support (EXPERIMENTAL)' CONFIG_ES3210
- tristate ' SMC EtherPower II (EXPERIMENTAL)' CONFIG_EPIC100
+ dep_tristate ' RealTek 8129 (not 8019/8029/8139!) support (EXPERIMENTAL)' CONFIG_RTL8129 $CONFIG_PCI
X fi
+ dep_tristate ' RealTek RTL-8139 PCI Fast Ethernet Adapter support' CONFIG_8139TOO $CONFIG_PCI
+ dep_tristate ' SiS 900/7016 PCI Fast Ethernet Adapter support' CONFIG_SIS900 $CONFIG_PCI
+ dep_tristate ' SMC EtherPower II' CONFIG_EPIC100 $CONFIG_PCI
+ dep_tristate ' Sundance Alta support' CONFIG_SUNDANCE $CONFIG_PCI
+ tristate ' TI ThunderLAN support' CONFIG_TLAN
+ dep_tristate ' VIA Rhine support' CONFIG_VIA_RHINE $CONFIG_PCI
+ dep_tristate ' Winbond W89c840 Ethernet support' CONFIG_WINBOND_840 $CONFIG_PCI
X if [ "$CONFIG_OBSOLETE" = "y" ]; then
X bool ' Zenith Z-Note support (EXPERIMENTAL)' CONFIG_ZNET
X fi
@@ -185,21 +184,21 @@
X mainmenu_option next_comment
X comment 'Ethernet (1000 Mbit)'
X
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- # tristate 'Packet Engines Hamachi GNIC-II support (EXPERIMENTAL)' CONFIG_HAMACHI
- tristate 'Packet Engines Yellowfin Gigabit-NIC support (EXPERIMENTAL)' CONFIG_YELLOWFIN
-fi
-tristate 'Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support' CONFIG_ACENIC
+dep_tristate 'Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support' CONFIG_ACENIC $CONFIG_PCI
X if [ "$CONFIG_ACENIC" != "n" ]; then
X bool ' Omit support for old Tigon I based AceNICs' CONFIG_ACENIC_OMIT_TIGON_I
X fi
+dep_tristate 'Packet Engines Hamachi GNIC-II support' CONFIG_HAMACHI $CONFIG_PCI
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ dep_tristate 'Packet Engines Yellowfin Gigabit-NIC support (EXPERIMENTAL)' CONFIG_YELLOWFIN $CONFIG_PCI
+fi
X tristate 'SysKonnect SK-98xx support' CONFIG_SK98LIN
X
X endmenu
X
X bool 'FDDI driver support' CONFIG_FDDI
X if [ "$CONFIG_FDDI" = "y" ]; then
- tristate ' Digital DEFEA and DEFPA adapter support' CONFIG_DEFXX
+ dep_tristate ' Digital DEFEA and DEFPA adapter support' CONFIG_DEFXX $CONFIG_PCI
X tristate ' SysKonnect FDDI PCI support' CONFIG_SKFP
X fi
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/Makefile linux/drivers/net/Makefile
--- v2.4.0-test8/linux/drivers/net/Makefile Wed Aug 23 09:30:13 2000
+++ linux/drivers/net/Makefile Thu Sep 21 13:27:10 2000
@@ -170,6 +170,9 @@
X obj-$(CONFIG_AIRONET4500_PROC) += aironet4500_proc.o
X obj-$(CONFIG_AIRONET4500_CS) += aironet4500_proc.o
X
+obj-$(CONFIG_WINBOND_840) += winbond-840.o
+obj-$(CONFIG_SUNDANCE) += sundance.o
+obj-$(CONFIG_HAMACHI) += hamachi.o
X obj-$(CONFIG_NET) += Space.o setup.o net_init.o loopback.o
X obj-$(CONFIG_SEEQ8005) += seeq8005.o
X obj-$(CONFIG_ETHERTAP) += ethertap.o
@@ -304,7 +307,7 @@
X MX_OBJS := $(sort $(filter $(export-objs), $(obj-m)))
X
X ifneq ($(ARCH),s390)
-O_OBJS += auto_irq.o
+OX_OBJS += auto_irq.o
X endif
X
X include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/Space.c linux/drivers/net/Space.c
--- v2.4.0-test8/linux/drivers/net/Space.c Wed Aug 23 09:30:13 2000
+++ linux/drivers/net/Space.c Fri Sep 22 15:19:30 2000
@@ -440,7 +440,7 @@
X #endif
X
X
-/* Pad device name to IFNAMSIZ=16. F.e. __PAD6 is tring of 9 zeros. */
+/* Pad device name to IFNAMSIZ=16. F.e. __PAD6 is string of 9 zeros. */
X #define __PAD6 "\0\0\0\0\0\0\0\0\0"
X #define __PAD5 __PAD6 "\0"
X #define __PAD4 __PAD5 "\0"
@@ -677,14 +677,6 @@
X #undef NEXT_DEV
X #define NEXT_DEV (&escon0_dev)
X #endif
-
-#ifdef CONFIG_TUN
- extern int tun_init(struct net_device *dev);
- static struct net_device tun_dev = {
- "tun", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, tun_init };
-# undef NEXT_DEV
-# define NEXT_DEV (&tun_dev)
-#endif
X
X /*
X * The loopback device is global so it can be directly referenced
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/acenic.c linux/drivers/net/acenic.c
--- v2.4.0-test8/linux/drivers/net/acenic.c Fri Jul 28 12:47:19 2000
+++ linux/drivers/net/acenic.c Mon Oct 2 14:22:40 2000
@@ -29,7 +29,16 @@
X * infrastructure and Sparc support
X * Pierrick Pinasseau (CERN): For lending me an Ultra 5 to test the
X * driver under Linux/Sparc64
- * Matt Domsch <Matt_...@dell.com>: Detect 1000baseT cards
+ * Matt Domsch <Matt_...@dell.com>: Detect Alteon 1000baseT cards
+ * Chip Salzenberg <ch...@valinux.com>: Fix race condition between tx
+ * handler and close() cleanup.
+ * Ken Aaker <kda...@rchland.vnet.ibm.com>: Correct check for whether
+ * memory mapped IO is enabled to
+ * make the driver work on RS/6000.
+ * Takayoshi Kouchi <kou...@hpc.bs1.fc.nec.co.jp>: Identifying problem
+ * where the driver would disable
+ * bus master mode if it had to disable
+ * write and invalidate.
X */
X
X #include <linux/config.h>
@@ -83,8 +92,13 @@
X #define PCI_VENDOR_ID_NETGEAR 0x1385
X #define PCI_DEVICE_ID_NETGEAR_GA620 0x620a
X #endif
+#ifndef PCI_DEVICE_ID_NETGEAR_GA620T
+#define PCI_DEVICE_ID_NETGEAR_GA620T 0x630a
+#endif
+
X /*
- * They used the DEC vendor ID by mistake
+ * Farallon used the DEC vendor ID by mistake and they seem not
+ * to care - stinky!
X */
X #ifndef PCI_DEVICE_ID_FARALLON_PN9000SX
X #define PCI_DEVICE_ID_FARALLON_PN9000SX 0x1a
@@ -379,22 +393,22 @@
X #define DEF_TRACE 0
X #define DEF_STAT (2 * TICKS_PER_SEC)
X
-static int link[ACE_MAX_MOD_PARMS] = {0, };
-static int trace[ACE_MAX_MOD_PARMS] = {0, };
-static int tx_coal_tick[ACE_MAX_MOD_PARMS] = {0, };
-static int rx_coal_tick[ACE_MAX_MOD_PARMS] = {0, };
-static int max_tx_desc[ACE_MAX_MOD_PARMS] = {0, };
-static int max_rx_desc[ACE_MAX_MOD_PARMS] = {0, };
-static int tx_ratio[ACE_MAX_MOD_PARMS] = {0, };
+static int link[ACE_MAX_MOD_PARMS];
+static int trace[ACE_MAX_MOD_PARMS];
+static int tx_coal_tick[ACE_MAX_MOD_PARMS];
+static int rx_coal_tick[ACE_MAX_MOD_PARMS];
+static int max_tx_desc[ACE_MAX_MOD_PARMS];
+static int max_rx_desc[ACE_MAX_MOD_PARMS];
+static int tx_ratio[ACE_MAX_MOD_PARMS];
X static int dis_pci_mem_inval[ACE_MAX_MOD_PARMS] = {1, 1, 1, 1, 1, 1, 1, 1};
X
-static const char __initdata *version =
- "acenic.c: v0.44 05/11/2000 Jes Sorensen, linux-...@SunSITE.auc.dk\n"
+static char version[] __initdata =
+ "acenic.c: v0.47 09/18/2000 Jes Sorensen, linux-...@SunSITE.auc.dk\n"
X " http://home.cern.ch/~jes/gige/acenic.html\n";
X
-static struct net_device *root_dev = NULL;
+static struct net_device *root_dev;
X
-static int probed __initdata = 0;
+static int probed __initdata;
X
X
X #ifdef NEW_NETINIT
@@ -429,7 +443,8 @@
X !((pdev->vendor == PCI_VENDOR_ID_3COM) &&
X (pdev->device == PCI_DEVICE_ID_3COM_3C985)) &&
X !((pdev->vendor == PCI_VENDOR_ID_NETGEAR) &&
- (pdev->device == PCI_DEVICE_ID_NETGEAR_GA620)) &&
+ ((pdev->device == PCI_DEVICE_ID_NETGEAR_GA620) ||
+ (pdev->device == PCI_DEVICE_ID_NETGEAR_GA620T))) &&
X /*
X * Farallon used the DEC vendor ID on their cards by
X * mistake for a while
@@ -477,10 +492,17 @@
X printk(version);
X }
X
+ /*
+ * Enable master mode before we start playing with the
+ * pci_command word since pci_set_master() will modify
+ * it.
+ */
+ pci_set_master(pdev);
+
X pci_read_config_word(pdev, PCI_COMMAND, &ap->pci_command);
X
X /* OpenFirmware on Mac's does not set this - DOH.. */
- if (!ap->pci_command & PCI_COMMAND_MEMORY) {
+ if (!(ap->pci_command & PCI_COMMAND_MEMORY)) {
X printk(KERN_INFO "%s: Enabling PCI Memory Mapped "
X "access - was not enabled by BIOS/Firmware\n",
X dev->name);
@@ -498,8 +520,6 @@
X ap->pci_latency);
X }
X
- pci_set_master(pdev);
-
X /*
X * Remap the regs into kernel space - this is abuse of
X * dev->base_addr since it was means for I/O port
@@ -606,9 +626,9 @@
X MODULE_PARM(max_tx_desc, "1-" __MODULE_STRING(8) "i");
X MODULE_PARM(rx_coal_tick, "1-" __MODULE_STRING(8) "i");
X MODULE_PARM(max_rx_desc, "1-" __MODULE_STRING(8) "i");
-
X #endif
X
+
X void __exit ace_module_cleanup(void)
X {
X struct ace_private *ap;
@@ -713,6 +733,7 @@
X }
X
X
+#ifdef MODULE
X #if (LINUX_VERSION_CODE < 0x02032a)
X int init_module(void)
X {
@@ -728,6 +749,7 @@
X module_init(ace_module_init);
X module_exit(ace_module_cleanup);
X #endif
+#endif
X
X
X static void ace_free_descriptors(struct net_device *dev)
@@ -1994,18 +2016,34 @@
X if (txcsm != idx) {
X do {
X struct sk_buff *skb;
- dma_addr_t mapping;
X
X skb = ap->skb->tx_skbuff[idx].skb;
- mapping = ap->skb->tx_skbuff[idx].mapping;
+ /*
+ * Race condition between the code cleaning
+ * the tx queue in the interrupt handler and the
+ * interface close,
+ *
+ * This is a kludge that really should be fixed
+ * by preventing the driver from generating a tx
+ * interrupt when the packet has already been
+ * removed from the tx queue.
+ *
+ * Nailed by Don Dugger and Chip Salzenberg of
+ * VA Linux.
+ */
+ if (skb) {
+ dma_addr_t mapping;
X
- ap->stats.tx_packets++;
- ap->stats.tx_bytes += skb->len;
- pci_unmap_single(ap->pdev, mapping, skb->len,
- PCI_DMA_TODEVICE);
- dev_kfree_skb_irq(skb);
+ mapping = ap->skb->tx_skbuff[idx].mapping;
X
- ap->skb->tx_skbuff[idx].skb = NULL;
+ ap->stats.tx_packets++;
+ ap->stats.tx_bytes += skb->len;
+ pci_unmap_single(ap->pdev, mapping, skb->len,
+ PCI_DMA_TODEVICE);
+ dev_kfree_skb_irq(skb);
+
+ ap->skb->tx_skbuff[idx].skb = NULL;
+ }
X
X /*
X * Question here is whether one should not skip
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/acenic.h linux/drivers/net/acenic.h
--- v2.4.0-test8/linux/drivers/net/acenic.h Fri May 12 11:38:35 2000
+++ linux/drivers/net/acenic.h Mon Sep 18 15:16:48 2000
@@ -609,7 +609,7 @@
X struct timer_list timer;
X
X unsigned long std_refill_busy
- __attribute__ ((aligned (L1_CACHE_BYTES)));
+ __attribute__ ((aligned (SMP_CACHE_BYTES)));
X unsigned long mini_refill_busy, jumbo_refill_busy;
X atomic_t cur_rx_bufs,
X cur_mini_bufs,
@@ -642,7 +642,7 @@
X char name[48];
X #ifdef INDEX_DEBUG
X spinlock_t debug_lock
- __attribute__ ((aligned (L1_CACHE_BYTES)));;
+ __attribute__ ((aligned (SMP_CACHE_BYTES)));;
X u32 last_tx, last_std_rx, last_mini_rx;
X #endif
X struct net_device_stats stats;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/acenic_firmware.h linux/drivers/net/acenic_firmware.h
--- v2.4.0-test8/linux/drivers/net/acenic_firmware.h Thu Jul 6 19:27:48 2000
+++ linux/drivers/net/acenic_firmware.h Mon Sep 18 15:16:48 2000
@@ -17,6 +17,9 @@
X #define tigonFwSbssLen 0x38
X #define tigonFwBssAddr 0x00015dd0
X #define tigonFwBssLen 0x2080
+u32 tigonFwText[];
+u32 tigonFwData[];
+u32 tigonFwRodata[];
X #ifndef CONFIG_ACENIC_OMIT_TIGON_I
X /* Generated by genfw.c */
X u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
@@ -4592,10 +4595,6 @@
X 0x0, 0x0, 0x0, 0x2,
X 0x0, 0x0, 0x30001, 0x1,
X 0x30201, 0x0, 0x0, 0x0 };
-#else
-#define tigonFwText NULL
-#define tigonFwData NULL
-#define tigonFwRodata NULL
X #endif
X /* Generated by genfw.c */
X #define tigon2FwReleaseMajor 0xc
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/aironet4500_core.c linux/drivers/net/aironet4500_core.c
--- v2.4.0-test8/linux/drivers/net/aironet4500_core.c Tue Jul 11 11:12:23 2000
+++ linux/drivers/net/aironet4500_core.c Fri Sep 22 14:21:16 2000
@@ -2613,7 +2613,7 @@
X
X long long jiff;
X
- DEBUG(2, " awc_reset dev %x \n", (int)dev);
+ DEBUG(2, " awc_reset dev %p \n", dev);
X DEBUG(2, "%s: awc_reset \n", dev->name);
X
X awc_issue_soft_reset(dev);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/am79c961a.c linux/drivers/net/am79c961a.c
--- v2.4.0-test8/linux/drivers/net/am79c961a.c Tue Jul 11 11:12:23 2000
+++ linux/drivers/net/am79c961a.c Mon Sep 18 15:15:22 2000
@@ -1,9 +1,13 @@
X /*
- * linux/drivers/net/am79c961.c
+ * linux/drivers/net/am79c961.c
X *
- * Derived from various things including skeleton.c
+ * by Russell King <r...@arm.linux.org.uk> 1995-2000.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X *
- * Russell King 1995-2000.
+ * Derived from various things including skeleton.c
X *
X * This is a special driver for the am79c961A Lance chip used in the
X * Intel (formally Digital Equipment Corp) EBSA110 platform.
@@ -204,9 +208,12 @@
X u_int hdr_addr, first_free_addr;
X int i;
X
- save_flags_cli (flags);
+ /*
+ * Stop the chip.
+ */
+ spin_lock_irqsave(priv->chip_lock, flags);
X write_rreg (dev->base_addr, CSR0, CSR0_BABL|CSR0_CERR|CSR0_MISS|CSR0_MERR|CSR0_TINT|CSR0_RINT|CSR0_STOP);
- restore_flags (flags);
+ spin_unlock_irqrestore(priv->chip_lock, flags);
X
X write_ireg (dev->base_addr, 5, 0x00a0); /* Receive address LED */
X write_ireg (dev->base_addr, 6, 0x0081); /* Collision LED */
@@ -301,16 +308,15 @@
X static int
X am79c961_close(struct net_device *dev)
X {
+ struct dev_priv *priv = (struct dev_priv *)dev->priv;
X unsigned long flags;
X
X netif_stop_queue(dev);
X
- save_flags_cli (flags);
-
+ spin_lock_irqsave(priv->chip_lock, flags);
X write_rreg (dev->base_addr, CSR0, CSR0_STOP);
X write_rreg (dev->base_addr, CSR3, CSR3_MASKALL);
-
- restore_flags (flags);
+ spin_unlock_irqrestore(priv->chip_lock, flags);
X
X free_irq (dev->irq, dev);
X
@@ -368,6 +374,7 @@
X */
X static void am79c961_setmulticastlist (struct net_device *dev)
X {
+ struct dev_priv *priv = (struct dev_priv *)dev->priv;
X unsigned long flags;
X unsigned short multi_hash[4], mode;
X int i, stopped;
@@ -387,7 +394,7 @@
X am79c961_mc_hash(dmi, multi_hash);
X }
X
- save_flags_cli(flags);
+ spin_lock_irqsave(priv->chip_lock, flags);
X
X stopped = read_rreg(dev->base_addr, CSR0) & CSR0_STOP;
X
@@ -401,9 +408,9 @@
X * Spin waiting for chip to report suspend mode
X */
X while ((read_rreg(dev->base_addr, CTRL1) & CTRL1_SPND) == 0) {
- restore_flags(flags);
+ spin_unlock_irqrestore(priv->chip_lock, flags);
X nop();
- save_flags_cli(flags);
+ spin_lock_irqsave(priv->chip_lock, flags);
X }
X }
X
@@ -425,7 +432,7 @@
X write_rreg(dev->base_addr, CTRL1, 0);
X }
X
- restore_flags(flags);
+ spin_unlock_irqrestore(priv->chip_lock, flags);
X }
X
X static void am79c961_timeout(struct net_device *dev)
@@ -464,10 +471,10 @@
X am_writeword (dev, hdraddr + 2, TMD_OWN|TMD_STP|TMD_ENP);
X priv->txhead = head;
X
- save_flags_cli (flags);
+ spin_lock_irqsave(priv->chip_lock, flags);
X write_rreg (dev->base_addr, CSR0, CSR0_TDMD|CSR0_IENA);
X dev->trans_start = jiffies;
- restore_flags (flags);
+ spin_unlock_irqrestore(priv->chip_lock, flags);
X
X /*
X * If the next packet is owned by the ethernet device,
@@ -611,20 +618,22 @@
X priv->stats.rx_dropped ++;
X }
X
+/*
+ * Initialise the chip. Note that we always expect
+ * to be entered with interrupts enabled.
+ */
X static int
X am79c961_hw_init(struct net_device *dev)


X {
- unsigned long flags;
-

- am79c961_ramtest(dev, 0x66);
- am79c961_ramtest(dev, 0x99);
-
- save_flags_cli (flags);
+ struct dev_priv *priv = (struct dev_priv *)dev->priv;
X
+ spin_lock_irq(priv->chip_lock);
X write_rreg (dev->base_addr, CSR0, CSR0_STOP);
X write_rreg (dev->base_addr, CSR3, CSR3_MASKALL);
+ spin_unlock_irq(priv->chip_lock);
X
- restore_flags (flags);
+ am79c961_ramtest(dev, 0x66);
+ am79c961_ramtest(dev, 0x99);


X
X return 0;
X }

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/am79c961a.h linux/drivers/net/am79c961a.h
--- v2.4.0-test8/linux/drivers/net/am79c961a.h Tue Jul 11 11:12:23 2000
+++ linux/drivers/net/am79c961a.h Mon Sep 18 15:15:22 2000
@@ -1,5 +1,9 @@
X /*
X * linux/drivers/net/am79c961.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X */
X
X #ifndef _LINUX_am79c961a_H
@@ -118,6 +122,7 @@
X unsigned char rxtail;
X unsigned long rxhdr;
X unsigned long txhdr;
+ spinlock_t chip_lock;
X };
X
X extern int am79c961_probe (struct net_device *dev);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/appletalk/Makefile linux/drivers/net/appletalk/Makefile
--- v2.4.0-test8/linux/drivers/net/appletalk/Makefile Fri Mar 3 12:54:44 2000
+++ linux/drivers/net/appletalk/Makefile Fri Sep 22 14:21:15 2000
@@ -16,13 +16,13 @@
X obj- :=
X export-objs :=
X
-obj-$(CONFIG_LTPC) += ltpc.o
-obj-$(CONFIG_COPS) += cops.o
X obj-$(CONFIG_IPDDP) += ipddp.o
+obj-$(CONFIG_COPS) += cops.o
+obj-$(CONFIG_LTPC) += ltpc.o
X
-L_TARGET := appletalk.a
-L_OBJS := $(filter-out $(export-objs), $(obj-y))
-LX_OBJS := $(filter $(export-objs), $(obj-y))
+O_TARGET := appletalk.o


+O_OBJS := $(filter-out $(export-objs), $(obj-y))
+OX_OBJS := $(filter $(export-objs), $(obj-y))

X M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m)))
X MX_OBJS := $(sort $(filter $(export-objs), $(obj-m)))
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/appletalk/ipddp.c linux/drivers/net/appletalk/ipddp.c
--- v2.4.0-test8/linux/drivers/net/appletalk/ipddp.c Tue Jul 18 16:52:35 2000
+++ linux/drivers/net/appletalk/ipddp.c Fri Sep 22 14:21:16 2000
@@ -27,36 +27,15 @@
X "ipddp.c:v0.01 8/28/97 Bradford W. Johnson <john...@maroon.tc.umn.edu>\n";
X
X #include <linux/config.h>
-#ifdef MODULE
X #include <linux/module.h>
-#include <linux/version.h>
-#endif
-
X #include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/malloc.h>
-#include <linux/string.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <linux/errno.h>
+#include <linux/init.h>
X #include <linux/netdevice.h>
-#include <linux/inetdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/if_arp.h>
-#include <linux/atalk.h>
X #include <linux/ip.h>
+#include <linux/atalk.h>
+#include <linux/if_arp.h>
X #include <net/route.h>
-#include <linux/inet.h>
+#include <asm/uaccess.h>
X
X #include "ipddp.h" /* Our stuff */
X
@@ -85,23 +64,17 @@
X
X static int ipddp_open(struct net_device *dev)
X {
-#ifdef MODULE
X MOD_INC_USE_COUNT;
-#endif
-


X return 0;
X }
X

X static int ipddp_close(struct net_device *dev)
X {
-#ifdef MODULE
X MOD_DEC_USE_COUNT;
-#endif
-


X return 0;
X }
X

-int ipddp_init(struct net_device *dev)
+static int __init ipddp_init(struct net_device *dev)
X {
X static unsigned version_printed = 0;
X
@@ -151,7 +124,7 @@
X */
X static struct net_device_stats *ipddp_get_stats(struct net_device *dev)
X {
- return (struct net_device_stats *)dev->priv;
+ return dev->priv;
X }
X
X /*
@@ -242,7 +215,10 @@
X rt->next = NULL;
X rt->dev = atrtr_get_dev(&rt->at);
X if(rt->dev == NULL)
+ {
+ kfree(rt);
X return (-ENETUNREACH);
+ }
X
X test = ipddp_find_route(rt);
X if(test != NULL)
@@ -322,19 +298,11 @@
X }
X }
X
-#ifdef MODULE /* Module specific functions for ipddp.c */
-
-static struct net_device dev_ipddp=
-{
- "ipddp0\0 ",
- 0, 0, 0, 0,
- 0x0, 0,
- 0, 0, 0, NULL, ipddp_init
-};
+static struct net_device dev_ipddp = { init: ipddp_init };
X
X MODULE_PARM(ipddp_mode, "i");
X
-int init_module(void)
+static int __init ipddp_init_module(void)
X {
X int err;
X
@@ -348,11 +316,14 @@
X return 0;
X }
X
-void cleanup_module(void)
+static void __exit ipddp_cleanup_module(void)
X {
X unregister_netdev(&dev_ipddp);
X kfree(dev_ipddp.priv);
- dev_ipddp.priv = NULL;
+
+ memset(&dev_ipddp, 0, sizeof(dev_ipddp));
+ dev_ipddp.init = ipddp_init;
X }
X
-#endif /* MODULE */
+module_init(ipddp_init_module);
+module_exit(ipddp_cleanup_module);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/arcnet/arcnet.c linux/drivers/net/arcnet/arcnet.c
--- v2.4.0-test8/linux/drivers/net/arcnet/arcnet.c Thu Jun 29 11:11:22 2000
+++ linux/drivers/net/arcnet/arcnet.c Sun Sep 17 09:45:05 2000
@@ -155,9 +155,6 @@
X #ifdef CONFIG_ARCNET_COM90xx
X com90xx_probe(NULL);
X #endif
-#ifdef CONFIG_ARCNET_COM20020_PCI
- com20020pci_probe_all();
-#endif
X #endif
X }
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/arcnet/com20020-isa.c linux/drivers/net/arcnet/com20020-isa.c
--- v2.4.0-test8/linux/drivers/net/arcnet/com20020-isa.c Sat May 13 07:50:25 2000
+++ linux/drivers/net/arcnet/com20020-isa.c Sun Sep 17 09:45:05 2000
@@ -205,7 +205,7 @@
X case 6: /* Timeout */
X lp->timeout = ints[6];
X case 5: /* CKP value */
- lp->clock = ints[5];
+ lp->clockp = ints[5];
X case 4: /* Backplane flag */
X lp->backplane = ints[4];
X case 3: /* Node ID */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/arcnet/com20020-pci.c linux/drivers/net/arcnet/com20020-pci.c
--- v2.4.0-test8/linux/drivers/net/arcnet/com20020-pci.c Sat May 13 08:19:21 2000
+++ linux/drivers/net/arcnet/com20020-pci.c Sun Sep 17 09:45:05 2000
@@ -148,7 +148,7 @@
X remove: com20020pci_remove
X };
X
-int com20020pci_init(void)
+static int __init com20020pci_init(void)
X {
X BUGLVL(D_NORMAL) printk(VERSION);
X #ifndef MODULE
@@ -157,7 +157,7 @@
X return pci_module_init(&com20020pci_driver);
X }
X
-void com20020pci_cleanup(void)
+static void __exit com20020pci_cleanup(void)
X {
X pci_unregister_driver(&com20020pci_driver);
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/atp.c linux/drivers/net/atp.c
--- v2.4.0-test8/linux/drivers/net/atp.c Fri Aug 11 15:57:57 2000
+++ linux/drivers/net/atp.c Thu Sep 21 13:33:32 2000
@@ -1,27 +1,59 @@
X /* atp.c: Attached (pocket) ethernet adapter driver for linux. */
X /*
- This is a driver for a commonly OEMed pocket (parallel port)
- ethernet adapter.
+ This is a driver for commonly OEM pocket (parallel port)
+ ethernet adapters based on the Realtek RTL8002 and RTL8012 chips.
X
- Written 1993,1994,1995 by Donald Becker.
+ Written 1993-2000 by Donald Becker.
X
- Copyright 1993 United States Government as represented by the
- Director, National Security Agency.
+ This software may be used and distributed according to the terms of
+ the GNU General Public License (GPL), incorporated herein by reference.
+ Drivers based on or derived from this code fall under the GPL and must
+ retain the authorship, copyright and license notice. This file is not
+ a complete program and may only be used when the entire operating
+ system is licensed under the GPL.
+
+ Copyright 1993 United States Government as represented by the Director,
+ National Security Agency. Copyright 1994-2000 retained by the original
+ author, Donald Becker. The timer-based reset code was supplied in 1995
+ by Bill Carlson, w...@super.org.
+
+ The author may be reached as bec...@scyld.com, or C/O
+ Scyld Computing Corporation
+ 410 Severn Ave., Suite 210
+ Annapolis MD 21403
X
- This software may be used and distributed according to the terms
- of the GNU Public License, incorporated herein by reference.
+ Support information and updates available at
+ http://www.scyld.com/network/atp.html
X
- The author may be reached as bec...@CESDIS.gsfc.nasa.gov, or C/O
- Center of Excellence in Space Data and Information Sciences
- Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
X
- The timer-based reset code was written by Bill Carlson, w...@super.org.
-
X Modular support/softnet added by Alan Cox.
+
X */
X
-static const char *version =
- "atp.c:v1.01 1/18/95 Donald Becker (bec...@cesdis.gsfc.nasa.gov)\n";
+static const char versionA[] =
+"atp.c:v1.09 8/9/2000 Donald Becker <bec...@scyld.com>\n";
+static const char versionB[] =
+" http://www.scyld.com/network/atp.html\n";
+
+/* The user-configurable values.
+ These may be modified when a driver module is loaded.*/
+
+static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */
+#define net_debug debug
+
+/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
+static int max_interrupt_work = 15;
+
+#define NUM_UNITS 2
+/* The standard set of ISA module parameters. */
+static int io[NUM_UNITS] = {0, 0};
+static int irq[NUM_UNITS] = {0, 0};
+static int xcvr[NUM_UNITS] = {0, 0}; /* The data transfer mode. */
+
+/* Operational parameters that are set at compile time. */
+
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT (400*HZ/1000)
X
X /*
X This file is a device driver for the RealTek (aka AT-Lan-Tec) pocket
@@ -35,8 +67,12 @@
X description is written based on guesses and writing lots of special-purpose
X code to test my theorized operation.
X
+ In 1997 Realtek made available the documentation for the second generation
+ RTL8012 chip, which has lead to several driver improvements.
+ http://www.realtek.com.tw/cn/cn.html
+
X Theory of Operation
-
+
X The RTL8002 adapter seems to be built around a custom spin of the SEEQ
X controller core. It probably has a 16K or 64K internal packet buffer, of
X which the first 4K is devoted to transmit and the rest to receive.


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 061'
echo 'File patch-2.4.0-test9 is continued in part 062'
echo "062" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part058

#!/bin/sh -x
# this is part 058 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 058; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ *
+ * We need to make sure that no normal I/O request - particularly write
+ * requests - conflict with active sync requests.
+ * This is achieved by conceptually dividing the device space into a
+ * number of sections:
+ * DONE: 0 .. a-1 These blocks are in-sync
+ * ACTIVE: a.. b-1 These blocks may have active sync requests, but
+ * no normal IO requests
+ * READY: b .. c-1 These blocks have no normal IO requests - sync
+ * request may be happening
+ * PENDING: c .. d-1 These blocks may have IO requests, but no new
+ * ones will be added
+ * FUTURE: d .. end These blocks are not to be considered yet. IO may
+ * be happening, but not sync
+ *
+ * We keep a
+ * phase which flips (0 or 1) each time d moves and
+ * a count of:
+ * z = active io requests in FUTURE since d moved - marked with
+ * current phase
+ * y = active io requests in FUTURE before d moved, or PENDING -
+ * marked with previous phase
+ * x = active sync requests in READY
+ * w = active sync requests in ACTIVE
+ * v = active io requests in DONE
+ *
+ * Normally, a=b=c=d=0 and z= active io requests
+ * or a=b=c=d=END and v= active io requests
+ * Allowed changes to a,b,c,d:
+ * A: c==d && y==0 -> d+=window, y=z, z=0, phase=!phase
+ * B: y==0 -> c=d
+ * C: b=c, w+=x, x=0
+ * D: w==0 -> a=b
+ * E: a==b==c==d==end -> a=b=c=d=0, z=v, v=0
+ *
+ * At start of sync we apply A.
+ * When y reaches 0, we apply B then A then being sync requests
+ * When sync point reaches c-1, we wait for y==0, and W==0, and
+ * then apply apply B then A then D then C.
+ * Finally, we apply E
+ *
+ * The sync request simply issues a "read" against a working drive
+ * This is marked so that on completion the raid1d thread is woken to
+ * issue suitable write requests
+ */
+
+static int raid1_sync_request (mddev_t *mddev, unsigned long block_nr)


+{
+ raid1_conf_t *conf = mddev_to_conf(mddev);

+ struct mirror_info *mirror;


+ struct raid1_bh *r1_bh;
+ struct buffer_head *bh;

+ int bsize;
+
+ spin_lock_irq(&conf->segment_lock);
+ if (!block_nr) {
+ /* initialize ...*/
+ int buffs;
+ conf->start_active = 0;
+ conf->start_ready = 0;
+ conf->start_pending = 0;
+ conf->start_future = 0;


+ conf->phase = 0;

+ /* we want enough buffers to hold twice the window of 128*/
+ buffs = 128 *2 / (PAGE_SIZE>>9);
+ buffs = raid1_grow_buffers(conf, buffs);
+ if (buffs < 2)
+ goto nomem;
+
+ conf->window = buffs*(PAGE_SIZE>>9)/2;
+ conf->cnt_future += conf->cnt_done+conf->cnt_pending;
+ conf->cnt_done = conf->cnt_pending = 0;
+ if (conf->cnt_ready || conf->cnt_active)
+ MD_BUG();
+ }
+ while ((block_nr<<1) >= conf->start_pending) {
+ PRINTK("wait .. sect=%lu start_active=%d ready=%d pending=%d future=%d, cnt_done=%d active=%d ready=%d pending=%d future=%d\n",
+ block_nr<<1, conf->start_active, conf->start_ready, conf->start_pending, conf->start_future,
+ conf->cnt_done, conf->cnt_active, conf->cnt_ready, conf->cnt_pending, conf->cnt_future);
+ wait_event_lock_irq(conf->wait_done,
+ !conf->cnt_active,
+ conf->segment_lock);
+ wait_event_lock_irq(conf->wait_ready,
+ !conf->cnt_pending,
+ conf->segment_lock);
+ conf->start_active = conf->start_ready;


+ conf->start_ready = conf->start_pending;

+ conf->start_pending = conf->start_future;
+ conf->start_future = conf->start_future+conf->window;
+ // Note: falling off the end is not a problem


+ conf->phase = conf->phase ^1;

+ conf->cnt_active = conf->cnt_ready;
+ conf->cnt_ready = 0;


+ conf->cnt_pending = conf->cnt_future;
+ conf->cnt_future = 0;

+ wake_up(&conf->wait_done);
+ }
+ conf->cnt_ready++;


+ spin_unlock_irq(&conf->segment_lock);
+
+

+ /* If reconstructing, and >1 working disc,
+ * could dedicate one to rebuild and others to
+ * service read requests ..
+ */
+ mirror = conf->mirrors+conf->last_used;
+
+ r1_bh = raid1_alloc_buf (conf);
+ r1_bh->master_bh = NULL;


+ r1_bh->mddev = mddev;

+ r1_bh->cmd = SPECIAL;


+ bh = &r1_bh->bh_req;
+

+ bh->b_blocknr = block_nr;
+ bsize = 1024;
+ while (!(bh->b_blocknr & 1) && bsize < PAGE_SIZE
+ && (bh->b_blocknr+2)*(bsize>>10) < mddev->sb->size) {
+ bh->b_blocknr >>= 1;
+ bsize <<= 1;
+ }
+ bh->b_size = bsize;
+ bh->b_list = BUF_LOCKED;
+ bh->b_dev = mirror->dev;
+ bh->b_rdev = mirror->dev;
+ bh->b_state = (1<<BH_Req) | (1<<BH_Mapped);
+ if (!bh->b_page)
+ BUG();
+ if (!bh->b_data)
+ BUG();
+ if (bh->b_data != page_address(bh->b_page))
+ BUG();
+ bh->b_end_io = end_sync_read;
+ bh->b_private = r1_bh;
+ bh->b_rsector = block_nr<<1;
+ init_waitqueue_head(&bh->b_wait);
+
+ generic_make_request(READ, bh);
+ md_sync_acct(bh->b_rdev, bh->b_size/512);
+
+ return (bsize >> 10);
+
+nomem:
+ raid1_shrink_buffers(conf);
+ spin_unlock_irq(&conf->segment_lock);


+ return -ENOMEM;
+}
+

+static void end_sync_read(struct buffer_head *bh, int uptodate)

+{
+ struct raid1_bh * r1_bh = (struct raid1_bh *)(bh->b_private);
+

+ /* we have read a block, now it needs to be re-written,
+ * or re-read if the read failed.
+ * We don't do much here, just schedule handling by raid1d


+ */
+ if (!uptodate)
+ md_error (mddev_to_kdev(r1_bh->mddev), bh->b_dev);
+ else

+ set_bit(R1BH_Uptodate, &r1_bh->state);
+ raid1_reschedule_retry(r1_bh);
+}
+


+static void end_sync_write(struct buffer_head *bh, int uptodate)

+{
+ struct raid1_bh * r1_bh = (struct raid1_bh *)(bh->b_private);
+

+ if (!uptodate)
+ md_error (mddev_to_kdev(r1_bh->mddev), bh->b_dev);

+ if (atomic_dec_and_test(&r1_bh->remaining)) {


+ mddev_t *mddev = r1_bh->mddev;

+ unsigned long sect = bh->b_blocknr * (bh->b_size>>9);
+ int size = bh->b_size;
+ raid1_free_buf(r1_bh);
+ sync_request_done(sect, mddev_to_conf(mddev));
+ md_done_sync(mddev,size>>10, uptodate);
+ }
+}
+
+/*
+ * This will catch the scenario in which one of the mirrors was
+ * mounted as a normal device rather than as a part of a raid set.
+ *
+ * check_consistency is very personality-dependent, eg. RAID5 cannot
+ * do this check, it uses another method.
+ */
+static int __check_consistency (mddev_t *mddev, int row)


+{
+ raid1_conf_t *conf = mddev_to_conf(mddev);

+ int disks = MD_SB_DISKS;
+ kdev_t dev;
+ struct buffer_head *bh = NULL;
+ int i, rc = 0;
+ char *buffer = NULL;


+
+ for (i = 0; i < disks; i++) {

+ printk("(checking disk %d)\n",i);


+ if (!conf->mirrors[i].operational)
+ continue;

+ printk("(really checking disk %d)\n",i);
+ dev = conf->mirrors[i].dev;
+ set_blocksize(dev, 4096);
+ if ((bh = bread(dev, row / 4, 4096)) == NULL)
+ break;
+ if (!buffer) {
+ buffer = (char *) __get_free_page(GFP_KERNEL);
+ if (!buffer)
+ break;
+ memcpy(buffer, bh->b_data, 4096);
+ } else if (memcmp(buffer, bh->b_data, 4096)) {
+ rc = 1;
+ break;
+ }
+ bforget(bh);
+ fsync_dev(dev);
+ invalidate_buffers(dev);
+ bh = NULL;
+ }
+ if (buffer)
+ free_page((unsigned long) buffer);
+ if (bh) {


+ dev = bh->b_dev;

+ bforget(bh);


+ fsync_dev(dev);
+ invalidate_buffers(dev);
+ }

+ return rc;
+}
+

+static int check_consistency (mddev_t *mddev)
+{
+ if (__check_consistency(mddev, 0))
+/*
+ * we do not do this currently, as it's perfectly possible to
+ * have an inconsistent array when it's freshly created. Only
+ * newly written data has to be consistent.
+ */
+ return 0;
+


+ return 0;
+}
+

+#define INVALID_LEVEL KERN_WARNING \
+"raid1: md%d: raid level not set to mirroring (%d)\n"
+
+#define NO_SB KERN_ERR \
+"raid1: disabled mirror %s (couldn't access raid superblock)\n"
+
+#define ERRORS KERN_ERR \
+"raid1: disabled mirror %s (errors detected)\n"
+
+#define NOT_IN_SYNC KERN_ERR \
+"raid1: disabled mirror %s (not in sync)\n"
+
+#define INCONSISTENT KERN_ERR \
+"raid1: disabled mirror %s (inconsistent descriptor)\n"
+
+#define ALREADY_RUNNING KERN_ERR \
+"raid1: disabled mirror %s (mirror %d already operational)\n"
+
+#define OPERATIONAL KERN_INFO \
+"raid1: device %s operational as mirror %d\n"
+
+#define MEM_ERROR KERN_ERR \
+"raid1: couldn't allocate memory for md%d\n"
+
+#define SPARE KERN_INFO \
+"raid1: spare disk %s\n"
+
+#define NONE_OPERATIONAL KERN_ERR \
+"raid1: no operational mirrors for md%d\n"
+
+#define RUNNING_CKRAID KERN_ERR \
+"raid1: detected mirror differences -- running resync\n"
+
+#define ARRAY_IS_ACTIVE KERN_INFO \
+"raid1: raid set md%d active with %d out of %d mirrors\n"
+
+#define THREAD_ERROR KERN_ERR \
+"raid1: couldn't allocate thread for md%d\n"
+
+#define START_RESYNC KERN_WARNING \
+"raid1: raid set md%d not clean; reconstructing mirrors\n"
+
+static int raid1_run (mddev_t *mddev)
+{
+ raid1_conf_t *conf;
+ int i, j, disk_idx;
+ struct mirror_info *disk;


+ mdp_super_t *sb = mddev->sb;

+ mdp_disk_t *descriptor;
+ mdk_rdev_t *rdev;
+ struct md_list_head *tmp;
+ int start_recovery = 0;
+
+ MOD_INC_USE_COUNT;
+
+ if (sb->level != 1) {
+ printk(INVALID_LEVEL, mdidx(mddev), sb->level);
+ goto out;
+ }
+ /*
+ * copy the already verified devices into our private RAID1
+ * bookkeeping area. [whatever we allocate in raid1_run(),
+ * should be freed in raid1_stop()]
+ */
+
+ conf = kmalloc(sizeof(raid1_conf_t), GFP_KERNEL);


+ mddev->private = conf;

+ if (!conf) {
+ printk(MEM_ERROR, mdidx(mddev));
+ goto out;
+ }
+ memset(conf, 0, sizeof(*conf));


+
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->faulty) {

+ printk(ERRORS, partition_name(rdev->dev));
+ } else {


+ if (!rdev->sb) {
+ MD_BUG();

+ continue;
+ }
+ }
+ if (rdev->desc_nr == -1) {
+ MD_BUG();
+ continue;
+ }
+ descriptor = &sb->disks[rdev->desc_nr];
+ disk_idx = descriptor->raid_disk;
+ disk = conf->mirrors + disk_idx;
+
+ if (disk_faulty(descriptor)) {
+ disk->number = descriptor->number;
+ disk->raid_disk = disk_idx;
+ disk->dev = rdev->dev;
+ disk->sect_limit = MAX_WORK_PER_DISK;
+ disk->operational = 0;
+ disk->write_only = 0;
+ disk->spare = 0;
+ disk->used_slot = 1;
+ disk->head_position = 0;
+ continue;
+ }
+ if (disk_active(descriptor)) {
+ if (!disk_sync(descriptor)) {
+ printk(NOT_IN_SYNC,
+ partition_name(rdev->dev));
+ continue;
+ }
+ if ((descriptor->number > MD_SB_DISKS) ||
+ (disk_idx > sb->raid_disks)) {
+
+ printk(INCONSISTENT,
+ partition_name(rdev->dev));
+ continue;
+ }
+ if (disk->operational) {
+ printk(ALREADY_RUNNING,
+ partition_name(rdev->dev),
+ disk_idx);
+ continue;
+ }
+ printk(OPERATIONAL, partition_name(rdev->dev),
+ disk_idx);
+ disk->number = descriptor->number;
+ disk->raid_disk = disk_idx;
+ disk->dev = rdev->dev;
+ disk->sect_limit = MAX_WORK_PER_DISK;
+ disk->operational = 1;
+ disk->write_only = 0;
+ disk->spare = 0;
+ disk->used_slot = 1;
+ disk->head_position = 0;
+ conf->working_disks++;
+ } else {
+ /*
+ * Must be a spare disk ..
+ */
+ printk(SPARE, partition_name(rdev->dev));
+ disk->number = descriptor->number;
+ disk->raid_disk = disk_idx;
+ disk->dev = rdev->dev;
+ disk->sect_limit = MAX_WORK_PER_DISK;
+ disk->operational = 0;
+ disk->write_only = 0;
+ disk->spare = 1;
+ disk->used_slot = 1;
+ disk->head_position = 0;
+ }
+ }
+ conf->raid_disks = sb->raid_disks;
+ conf->nr_disks = sb->nr_disks;
+ conf->mddev = mddev;
+ conf->device_lock = MD_SPIN_LOCK_UNLOCKED;
+
+ conf->segment_lock = MD_SPIN_LOCK_UNLOCKED;
+ init_waitqueue_head(&conf->wait_buffer);
+ init_waitqueue_head(&conf->wait_done);
+ init_waitqueue_head(&conf->wait_ready);
+
+ if (!conf->working_disks) {
+ printk(NONE_OPERATIONAL, mdidx(mddev));


+ goto out_free_conf;
+ }
+
+

+ /* pre-allocate some buffer_head structures.
+ * As a minimum, 1 r1bh and raid_disks buffer_heads
+ * would probably get us by in tight memory situations,
+ * but a few more is probably a good idea.
+ * For now, try 16 r1bh and 16*raid_disks bufferheads
+ * This will allow at least 16 concurrent reads or writes
+ * even if kmalloc starts failing
+ */
+ if (raid1_grow_r1bh(conf, 16) < 16 ||
+ raid1_grow_bh(conf, 16*conf->raid_disks)< 16*conf->raid_disks) {
+ printk(MEM_ERROR, mdidx(mddev));


+ goto out_free_conf;
+ }
+

+ for (i = 0; i < MD_SB_DISKS; i++) {
+

+ descriptor = sb->disks+i;
+ disk_idx = descriptor->raid_disk;
+ disk = conf->mirrors + disk_idx;
+
+ if (disk_faulty(descriptor) && (disk_idx < conf->raid_disks) &&
+ !disk->used_slot) {
+
+ disk->number = descriptor->number;
+ disk->raid_disk = disk_idx;
+ disk->dev = MKDEV(0,0);
+
+ disk->operational = 0;
+ disk->write_only = 0;
+ disk->spare = 0;
+ disk->used_slot = 1;
+ disk->head_position = 0;
+ }
+ }
+
+ /*
+ * find the first working one and use it as a starting point
+ * to read balancing.
+ */
+ for (j = 0; !conf->mirrors[j].operational; j++)
+ /* nothing */;
+ conf->last_used = j;
+
+ /*
+ * initialize the 'working disks' list.
+ */
+ for (i = conf->raid_disks - 1; i >= 0; i--) {


+ if (conf->mirrors[i].operational) {

+ conf->mirrors[i].next = j;
+ j = i;
+ }
+ }
+
+ if (conf->working_disks != sb->raid_disks) {
+ printk(KERN_ALERT "raid1: md%d, not all disks are operational -- trying to recover array\n", mdidx(mddev));
+ start_recovery = 1;
+ }
+
+ if (!start_recovery && (sb->state & (1 << MD_SB_CLEAN))) {
+ /*
+ * we do sanity checks even if the device says
+ * it's clean ...
+ */
+ if (check_consistency(mddev)) {
+ printk(RUNNING_CKRAID);
+ sb->state &= ~(1 << MD_SB_CLEAN);
+ }
+ }
+
+ {
+ const char * name = "raid1d";
+
+ conf->thread = md_register_thread(raid1d, conf, name);
+ if (!conf->thread) {
+ printk(THREAD_ERROR, mdidx(mddev));


+ goto out_free_conf;
+ }
+ }
+

+ if (!start_recovery && !(sb->state & (1 << MD_SB_CLEAN))) {
+ const char * name = "raid1syncd";
+
+ conf->resync_thread = md_register_thread(raid1syncd, conf,name);
+ if (!conf->resync_thread) {
+ printk(THREAD_ERROR, mdidx(mddev));


+ goto out_free_conf;
+ }
+

+ printk(START_RESYNC, mdidx(mddev));
+ conf->resync_mirrors = 1;
+ md_wakeup_thread(conf->resync_thread);
+ }
+
+ /*
+ * Regenerate the "device is in sync with the raid set" bit for
+ * each device.
+ */
+ for (i = 0; i < MD_SB_DISKS; i++) {
+ mark_disk_nonsync(sb->disks+i);
+ for (j = 0; j < sb->raid_disks; j++) {
+ if (!conf->mirrors[j].operational)
+ continue;
+ if (sb->disks[i].number == conf->mirrors[j].number)
+ mark_disk_sync(sb->disks+i);
+ }
+ }
+ sb->active_disks = conf->working_disks;
+
+ if (start_recovery)
+ md_recover_arrays();
+
+
+ printk(ARRAY_IS_ACTIVE, mdidx(mddev), sb->active_disks, sb->raid_disks);
+ /*
+ * Ok, everything is just fine now
+ */
+ return 0;
+
+out_free_conf:
+ raid1_shrink_r1bh(conf);
+ raid1_shrink_bh(conf, conf->freebh_cnt);
+ raid1_shrink_buffers(conf);
+ kfree(conf);


+ mddev->private = NULL;
+out:
+ MOD_DEC_USE_COUNT;

+ return -EIO;
+}
+
+#undef INVALID_LEVEL
+#undef NO_SB
+#undef ERRORS
+#undef NOT_IN_SYNC
+#undef INCONSISTENT
+#undef ALREADY_RUNNING
+#undef OPERATIONAL
+#undef SPARE
+#undef NONE_OPERATIONAL
+#undef RUNNING_CKRAID
+#undef ARRAY_IS_ACTIVE
+
+static int raid1_stop_resync (mddev_t *mddev)


+{
+ raid1_conf_t *conf = mddev_to_conf(mddev);
+

+ if (conf->resync_thread) {
+ if (conf->resync_mirrors) {
+ conf->resync_mirrors = 2;
+ md_interrupt_thread(conf->resync_thread);
+
+ printk(KERN_INFO "raid1: mirror resync was not fully finished, restarting next time.\n");
+ return 1;
+ }
+ return 0;


+ }
+ return 0;
+}
+

+static int raid1_restart_resync (mddev_t *mddev)


+{
+ raid1_conf_t *conf = mddev_to_conf(mddev);
+

+ if (conf->resync_mirrors) {
+ if (!conf->resync_thread) {
+ MD_BUG();
+ return 0;
+ }
+ conf->resync_mirrors = 1;
+ md_wakeup_thread(conf->resync_thread);
+ return 1;
+ }


+ return 0;
+}
+

+static int raid1_stop (mddev_t *mddev)


+{
+ raid1_conf_t *conf = mddev_to_conf(mddev);
+

+ md_unregister_thread(conf->thread);
+ if (conf->resync_thread)
+ md_unregister_thread(conf->resync_thread);
+ raid1_shrink_r1bh(conf);
+ raid1_shrink_bh(conf, conf->freebh_cnt);
+ raid1_shrink_buffers(conf);
+ kfree(conf);


+ mddev->private = NULL;
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+

+static mdk_personality_t raid1_personality=
+{
+ name: "raid1",
+ make_request: raid1_make_request,
+ run: raid1_run,
+ stop: raid1_stop,
+ status: raid1_status,
+ error_handler: raid1_error,
+ diskop: raid1_diskop,
+ stop_resync: raid1_stop_resync,
+ restart_resync: raid1_restart_resync,
+ sync_request: raid1_sync_request
+};
+
+int raid1_init (void)
+{
+ return register_md_personality (RAID1, &raid1_personality);
+}


+
+#ifdef MODULE
+int init_module (void)
+{

+ return raid1_init();


+}
+
+void cleanup_module (void)
+{

+ unregister_md_personality (RAID1);
+}
+#endif
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/md/raid5.c linux/drivers/md/raid5.c
--- v2.4.0-test8/linux/drivers/md/raid5.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/md/raid5.c Mon Aug 14 08:26:34 2000
@@ -0,0 +1,2371 @@
+/*
+ * raid5.c : Multiple Devices driver for Linux
+ * Copyright (C) 1996, 1997 Ingo Molnar, Miguel de Icaza, Gadi Oxman
+ * Copyright (C) 1999, 2000 Ingo Molnar
+ *
+ * RAID-5 management functions.
+ *


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * You should have received a copy of the GNU General Public License
+ * (for example /usr/src/linux/COPYING); if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+

+
+#include <linux/config.h>
+#include <linux/module.h>

+#include <linux/locks.h>
+#include <linux/malloc.h>
+#include <linux/raid/raid5.h>
+#include <asm/bitops.h>
+#include <asm/atomic.h>
+
+static mdk_personality_t raid5_personality;
+
+/*
+ * Stripe cache
+ */
+
+#define NR_STRIPES 128
+#define HASH_PAGES 1
+#define HASH_PAGES_ORDER 0
+#define NR_HASH (HASH_PAGES * PAGE_SIZE / sizeof(struct stripe_head *))
+#define HASH_MASK (NR_HASH - 1)
+#define stripe_hash(conf, sect, size) ((conf)->stripe_hashtbl[((sect) / (size >> 9)) & HASH_MASK])


+
+/*
+ * The following can be used to debug the driver
+ */

+#define RAID5_DEBUG 0
+#define RAID5_PARANOIA 1
+#if RAID5_PARANOIA && CONFIG_SMP
+# define CHECK_DEVLOCK() if (!spin_is_locked(&conf->device_lock)) BUG()
+# define CHECK_SHLOCK(sh) if (!stripe_locked(sh)) BUG()
+#else
+# define CHECK_DEVLOCK()
+# define CHECK_SHLOCK(unused)
+#endif
+
+#if RAID5_DEBUG


+#define PRINTK(x...) printk(x)
+#define inline
+#define __inline__
+#else
+#define PRINTK(x...) do { } while (0)
+#endif
+

+static void print_raid5_conf (raid5_conf_t *conf);
+
+static inline int stripe_locked(struct stripe_head *sh)
+{
+ return test_bit(STRIPE_LOCKED, &sh->state);
+}
+
+static void __unlock_stripe(struct stripe_head *sh)
+{
+ if (!md_test_and_clear_bit(STRIPE_LOCKED, &sh->state))
+ BUG();
+ PRINTK("unlocking stripe %lu\n", sh->sector);
+ wake_up(&sh->wait);
+}
+
+static void finish_unlock_stripe(struct stripe_head *sh)
+{
+ raid5_conf_t *conf = sh->raid_conf;
+ sh->cmd = STRIPE_NONE;
+ sh->phase = PHASE_COMPLETE;
+ atomic_dec(&conf->nr_pending_stripes);
+ atomic_inc(&conf->nr_cached_stripes);
+ __unlock_stripe(sh);
+ atomic_dec(&sh->count);
+ wake_up(&conf->wait_for_stripe);
+}
+
+static void remove_hash(raid5_conf_t *conf, struct stripe_head *sh)
+{
+ PRINTK("remove_hash(), stripe %lu\n", sh->sector);
+
+ CHECK_DEVLOCK();
+ CHECK_SHLOCK(sh);
+ if (sh->hash_pprev) {
+ if (sh->hash_next)
+ sh->hash_next->hash_pprev = sh->hash_pprev;
+ *sh->hash_pprev = sh->hash_next;
+ sh->hash_pprev = NULL;
+ atomic_dec(&conf->nr_hashed_stripes);
+ }
+}
+
+static void lock_get_bh (struct buffer_head *bh)
+{
+ while (md_test_and_set_bit(BH_Lock, &bh->b_state))
+ __wait_on_buffer(bh);
+ atomic_inc(&bh->b_count);
+}
+
+static __inline__ void insert_hash(raid5_conf_t *conf, struct stripe_head *sh)
+{
+ struct stripe_head **shp = &stripe_hash(conf, sh->sector, sh->size);
+
+ PRINTK("insert_hash(), stripe %lu, nr_hashed_stripes %d\n",
+ sh->sector, atomic_read(&conf->nr_hashed_stripes));
+
+ CHECK_DEVLOCK();
+ CHECK_SHLOCK(sh);
+ if ((sh->hash_next = *shp) != NULL)
+ (*shp)->hash_pprev = &sh->hash_next;
+ *shp = sh;
+ sh->hash_pprev = shp;
+ atomic_inc(&conf->nr_hashed_stripes);
+}
+
+static struct buffer_head *get_free_buffer(struct stripe_head *sh, int b_size)
+{
+ struct buffer_head *bh;


+ unsigned long flags;
+

+ CHECK_SHLOCK(sh);
+ md_spin_lock_irqsave(&sh->stripe_lock, flags);
+ bh = sh->buffer_pool;
+ if (!bh)
+ goto out_unlock;
+ sh->buffer_pool = bh->b_next;
+ bh->b_size = b_size;
+ if (atomic_read(&bh->b_count))
+ BUG();
+out_unlock:
+ md_spin_unlock_irqrestore(&sh->stripe_lock, flags);


+
+ return bh;
+}
+

+static struct buffer_head *get_free_bh(struct stripe_head *sh)
+{
+ struct buffer_head *bh;


+ unsigned long flags;
+

+ CHECK_SHLOCK(sh);
+ md_spin_lock_irqsave(&sh->stripe_lock, flags);
+ bh = sh->bh_pool;
+ if (!bh)
+ goto out_unlock;
+ sh->bh_pool = bh->b_next;
+ if (atomic_read(&bh->b_count))
+ BUG();
+out_unlock:
+ md_spin_unlock_irqrestore(&sh->stripe_lock, flags);


+
+ return bh;
+}
+

+static void put_free_buffer(struct stripe_head *sh, struct buffer_head *bh)
+{


+ unsigned long flags;
+

+ if (atomic_read(&bh->b_count))
+ BUG();
+ CHECK_SHLOCK(sh);
+ md_spin_lock_irqsave(&sh->stripe_lock, flags);
+ bh->b_next = sh->buffer_pool;
+ sh->buffer_pool = bh;
+ md_spin_unlock_irqrestore(&sh->stripe_lock, flags);
+}
+
+static void put_free_bh(struct stripe_head *sh, struct buffer_head *bh)
+{


+ unsigned long flags;
+

+ if (atomic_read(&bh->b_count))
+ BUG();
+ CHECK_SHLOCK(sh);
+ md_spin_lock_irqsave(&sh->stripe_lock, flags);
+ bh->b_next = sh->bh_pool;
+ sh->bh_pool = bh;
+ md_spin_unlock_irqrestore(&sh->stripe_lock, flags);
+}
+
+static struct stripe_head *get_free_stripe(raid5_conf_t *conf)
+{
+ struct stripe_head *sh;
+
+ md_spin_lock_irq(&conf->device_lock);
+ sh = conf->free_sh_list;
+ if (!sh)
+ goto out;
+ conf->free_sh_list = sh->free_next;
+ atomic_dec(&conf->nr_free_sh);
+ if (!atomic_read(&conf->nr_free_sh) && conf->free_sh_list)
+ BUG();
+ if (sh->hash_pprev || md_atomic_read(&sh->nr_pending) ||
+ atomic_read(&sh->count))
+ BUG();
+out:
+ md_spin_unlock_irq(&conf->device_lock);
+ return sh;
+}
+
+static void __put_free_stripe (raid5_conf_t *conf, struct stripe_head *sh)
+{
+ if (atomic_read(&sh->count) != 0)
+ BUG();
+ CHECK_DEVLOCK();
+ CHECK_SHLOCK(sh);
+ clear_bit(STRIPE_LOCKED, &sh->state);
+ sh->free_next = conf->free_sh_list;
+ conf->free_sh_list = sh;
+ atomic_inc(&conf->nr_free_sh);
+}
+
+static void shrink_buffers(struct stripe_head *sh, int num)
+{
+ struct buffer_head *bh;
+
+ while (num--) {
+ bh = get_free_buffer(sh, -1);
+ if (!bh)
+ return;
+ free_page((unsigned long) bh->b_data);
+ kfree(bh);
+ }
+}
+
+static void shrink_bh(struct stripe_head *sh, int num)
+{
+ struct buffer_head *bh;
+
+ while (num--) {
+ bh = get_free_bh(sh);
+ if (!bh)
+ return;
+ kfree(bh);
+ }
+}
+
+static int grow_raid5_buffers(struct stripe_head *sh, int num, int b_size, int priority)
+{
+ struct buffer_head *bh;
+
+ while (num--) {
+ struct page *page;
+ bh = kmalloc(sizeof(struct buffer_head), priority);
+ if (!bh)
+ return 1;
+ memset(bh, 0, sizeof (struct buffer_head));
+ init_waitqueue_head(&bh->b_wait);
+ page = alloc_page(priority);
+ bh->b_data = page_address(page);
+ if (!bh->b_data) {
+ kfree(bh);
+ return 1;
+ }
+ bh->b_size = b_size;
+ atomic_set(&bh->b_count, 0);
+ bh->b_page = page;
+ put_free_buffer(sh, bh);


+ }
+ return 0;
+}
+

+static int grow_bh(struct stripe_head *sh, int num, int priority)
+{
+ struct buffer_head *bh;
+
+ while (num--) {
+ bh = kmalloc(sizeof(struct buffer_head), priority);
+ if (!bh)
+ return 1;
+ memset(bh, 0, sizeof (struct buffer_head));
+ init_waitqueue_head(&bh->b_wait);
+ put_free_bh(sh, bh);


+ }
+ return 0;
+}
+

+static void raid5_free_buffer(struct stripe_head *sh, struct buffer_head *bh)
+{
+ put_free_buffer(sh, bh);
+}
+
+static void raid5_free_bh(struct stripe_head *sh, struct buffer_head *bh)
+{
+ put_free_bh(sh, bh);
+}
+
+static void raid5_free_old_bh(struct stripe_head *sh, int i)
+{
+ CHECK_SHLOCK(sh);
+ if (!sh->bh_old[i])
+ BUG();
+ raid5_free_buffer(sh, sh->bh_old[i]);
+ sh->bh_old[i] = NULL;
+}
+
+static void raid5_update_old_bh(struct stripe_head *sh, int i)
+{
+ CHECK_SHLOCK(sh);
+ PRINTK("stripe %lu, idx %d, updating cache copy\n", sh->sector, i);
+ if (!sh->bh_copy[i])
+ BUG();
+ if (sh->bh_old[i])
+ raid5_free_old_bh(sh, i);
+ sh->bh_old[i] = sh->bh_copy[i];
+ sh->bh_copy[i] = NULL;
+}
+
+static void free_stripe(struct stripe_head *sh)
+{
+ raid5_conf_t *conf = sh->raid_conf;
+ int disks = conf->raid_disks, j;
+
+ if (atomic_read(&sh->count) != 0)
+ BUG();
+ CHECK_DEVLOCK();
+ CHECK_SHLOCK(sh);
+ PRINTK("free_stripe called, stripe %lu\n", sh->sector);
+ if (sh->phase != PHASE_COMPLETE || atomic_read(&sh->count)) {
+ PRINTK("raid5: free_stripe(), sector %lu, phase %d, count %d\n", sh->sector, sh->phase, atomic_read(&sh->count));
+ return;
+ }
+ for (j = 0; j < disks; j++) {
+ if (sh->bh_old[j])
+ raid5_free_old_bh(sh, j);
+ if (sh->bh_new[j] || sh->bh_copy[j])
+ BUG();
+ }
+ remove_hash(conf, sh);
+ __put_free_stripe(conf, sh);
+}
+
+static int shrink_stripe_cache(raid5_conf_t *conf, int nr)
+{
+ struct stripe_head *sh;
+ int i, count = 0;
+
+ PRINTK("shrink_stripe_cache called, %d/%d, clock %d\n", nr, atomic_read(&conf->nr_hashed_stripes), conf->clock);
+ md_spin_lock_irq(&conf->device_lock);
+ for (i = 0; i < NR_HASH; i++) {
+ sh = conf->stripe_hashtbl[(i + conf->clock) & HASH_MASK];
+ for (; sh; sh = sh->hash_next) {
+ if (sh->phase != PHASE_COMPLETE)
+ continue;
+ if (atomic_read(&sh->count))
+ continue;
+ /*
+ * Try to lock this stripe:
+ */
+ if (md_test_and_set_bit(STRIPE_LOCKED, &sh->state))
+ continue;
+ free_stripe(sh);
+ if (++count == nr) {
+ conf->clock = (i + conf->clock) & HASH_MASK;


+ goto out;
+ }
+ }
+ }

+out:
+ md_spin_unlock_irq(&conf->device_lock);
+ PRINTK("shrink completed, nr_hashed_stripes %d, nr_pending_strips %d\n",
+ atomic_read(&conf->nr_hashed_stripes),
+ atomic_read(&conf->nr_pending_stripes));
+ return count;
+}
+
+void __wait_lock_stripe(struct stripe_head *sh)
+{
+ MD_DECLARE_WAITQUEUE(wait, current);
+
+ PRINTK("wait_lock_stripe %lu\n", sh->sector);
+ if (!atomic_read(&sh->count))
+ BUG();
+ add_wait_queue(&sh->wait, &wait);
+repeat:
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ if (md_test_and_set_bit(STRIPE_LOCKED, &sh->state)) {
+ schedule();
+ goto repeat;
+ }
+ PRINTK("wait_lock_stripe %lu done\n", sh->sector);
+ remove_wait_queue(&sh->wait, &wait);


+ current->state = TASK_RUNNING;
+}

+
+static struct stripe_head *__find_stripe(raid5_conf_t *conf, unsigned long sector, int size)
+{
+ struct stripe_head *sh;
+
+ PRINTK("__find_stripe, sector %lu\n", sector);
+ for (sh = stripe_hash(conf, sector, size); sh; sh = sh->hash_next) {
+ if (sh->sector == sector && sh->raid_conf == conf) {
+ if (sh->size != size)
+ BUG();
+ return sh;
+ }
+ }
+ PRINTK("__stripe %lu not in cache\n", sector);


+ return NULL;
+}
+

+static inline struct stripe_head *alloc_stripe(raid5_conf_t *conf, unsigned long sector, int size)
+{
+ struct stripe_head *sh;
+ struct buffer_head *buffer_pool, *bh_pool;
+ MD_DECLARE_WAITQUEUE(wait, current);
+
+ PRINTK("alloc_stripe called\n");
+
+
+ while ((sh = get_free_stripe(conf)) == NULL) {
+ int cnt;
+ add_wait_queue(&conf->wait_for_stripe, &wait);
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ cnt = shrink_stripe_cache(conf, conf->max_nr_stripes / 8);
+ sh = get_free_stripe(conf);
+ if (!sh && cnt < (conf->max_nr_stripes/8)) {
+ md_wakeup_thread(conf->thread);
+ PRINTK("waiting for some stripes to complete - %d %d\n", cnt, conf->max_nr_stripes/8);
+ schedule();
+ }
+ remove_wait_queue(&conf->wait_for_stripe, &wait);


+ current->state = TASK_RUNNING;

+ if (sh)
+ break;
+ }
+
+ buffer_pool = sh->buffer_pool;
+ bh_pool = sh->bh_pool;
+ memset(sh, 0, sizeof(*sh));
+ sh->stripe_lock = MD_SPIN_LOCK_UNLOCKED;
+ md_init_waitqueue_head(&sh->wait);
+ sh->buffer_pool = buffer_pool;
+ sh->bh_pool = bh_pool;
+ sh->phase = PHASE_COMPLETE;
+ sh->cmd = STRIPE_NONE;
+ sh->raid_conf = conf;
+ sh->sector = sector;
+ sh->size = size;
+ atomic_inc(&conf->nr_cached_stripes);
+
+ return sh;
+}
+
+static struct stripe_head *get_lock_stripe(raid5_conf_t *conf, unsigned long sector, int size)
+{
+ struct stripe_head *sh, *new = NULL;
+
+ PRINTK("get_stripe, sector %lu\n", sector);
+
+ /*
+ * Do this in set_blocksize()!
+ */
+ if (conf->buffer_size != size) {
+ PRINTK("switching size, %d --> %d\n", conf->buffer_size, size);
+ shrink_stripe_cache(conf, conf->max_nr_stripes);
+ conf->buffer_size = size;
+ }
+
+repeat:
+ md_spin_lock_irq(&conf->device_lock);
+ sh = __find_stripe(conf, sector, size);
+ if (!sh) {
+ if (!new) {
+ md_spin_unlock_irq(&conf->device_lock);
+ new = alloc_stripe(conf, sector, size);
+ goto repeat;
+ }
+ sh = new;
+ new = NULL;
+ if (md_test_and_set_bit(STRIPE_LOCKED, &sh->state))
+ BUG();
+ insert_hash(conf, sh);
+ atomic_inc(&sh->count);


+ md_spin_unlock_irq(&conf->device_lock);
+ } else {

+ atomic_inc(&sh->count);
+ if (new) {
+ if (md_test_and_set_bit(STRIPE_LOCKED, &new->state))
+ BUG();
+ __put_free_stripe(conf, new);
+ }
+ md_spin_unlock_irq(&conf->device_lock);
+ PRINTK("get_stripe, waiting, sector %lu\n", sector);
+ if (md_test_and_set_bit(STRIPE_LOCKED, &sh->state))
+ __wait_lock_stripe(sh);
+ }
+ return sh;
+}
+
+static int grow_stripes(raid5_conf_t *conf, int num, int priority)
+{
+ struct stripe_head *sh;
+
+ while (num--) {
+ sh = kmalloc(sizeof(struct stripe_head), priority);
+ if (!sh)
+ return 1;
+ memset(sh, 0, sizeof(*sh));
+ sh->raid_conf = conf;
+ sh->stripe_lock = MD_SPIN_LOCK_UNLOCKED;
+ md_init_waitqueue_head(&sh->wait);
+
+ if (md_test_and_set_bit(STRIPE_LOCKED, &sh->state))
+ BUG();
+ if (grow_raid5_buffers(sh, 2 * conf->raid_disks, PAGE_SIZE, priority)) {
+ shrink_buffers(sh, 2 * conf->raid_disks);
+ kfree(sh);
+ return 1;
+ }
+ if (grow_bh(sh, conf->raid_disks, priority)) {
+ shrink_buffers(sh, 2 * conf->raid_disks);
+ shrink_bh(sh, conf->raid_disks);
+ kfree(sh);
+ return 1;
+ }
+ md_spin_lock_irq(&conf->device_lock);
+ __put_free_stripe(conf, sh);
+ atomic_inc(&conf->nr_stripes);
+ md_spin_unlock_irq(&conf->device_lock);
+ }


+ return 0;
+}
+

+static void shrink_stripes(raid5_conf_t *conf, int num)
+{
+ struct stripe_head *sh;
+
+ while (num--) {
+ sh = get_free_stripe(conf);
+ if (!sh)
+ break;
+ if (md_test_and_set_bit(STRIPE_LOCKED, &sh->state))
+ BUG();
+ shrink_buffers(sh, conf->raid_disks * 2);
+ shrink_bh(sh, conf->raid_disks);
+ kfree(sh);
+ atomic_dec(&conf->nr_stripes);
+ }
+}
+
+
+static struct buffer_head *raid5_alloc_buffer(struct stripe_head *sh, int b_size)
+{
+ struct buffer_head *bh;
+
+ bh = get_free_buffer(sh, b_size);
+ if (!bh)
+ BUG();


+ return bh;
+}
+

+static struct buffer_head *raid5_alloc_bh(struct stripe_head *sh)
+{
+ struct buffer_head *bh;
+
+ bh = get_free_bh(sh);
+ if (!bh)
+ BUG();


+ return bh;
+}
+

+static void raid5_end_buffer_io (struct stripe_head *sh, int i, int uptodate)
+{
+ struct buffer_head *bh = sh->bh_new[i];
+
+ PRINTK("raid5_end_buffer_io %lu, uptodate: %d.\n", bh->b_blocknr, uptodate);
+ sh->bh_new[i] = NULL;
+ raid5_free_bh(sh, sh->bh_req[i]);
+ sh->bh_req[i] = NULL;
+ PRINTK("calling %p->end_io: %p.\n", bh, bh->b_end_io);
+ bh->b_end_io(bh, uptodate);
+ if (!uptodate)
+ printk(KERN_ALERT "raid5: %s: unrecoverable I/O error for "
+ "block %lu\n",
+ partition_name(mddev_to_kdev(sh->raid_conf->mddev)),
+ bh->b_blocknr);
+}
+
+static inline void raid5_mark_buffer_uptodate (struct buffer_head *bh, int uptodate)
+{
+ if (uptodate)
+ set_bit(BH_Uptodate, &bh->b_state);
+ else
+ clear_bit(BH_Uptodate, &bh->b_state);
+}
+
+static void raid5_end_request (struct buffer_head * bh, int uptodate)
+{
+ struct stripe_head *sh = bh->b_private;
+ raid5_conf_t *conf = sh->raid_conf;
+ int disks = conf->raid_disks, i;


+ unsigned long flags;
+

+ PRINTK("end_request %lu, nr_pending %d, uptodate: %d, (caller: %p,%p,%p,%p).\n", sh->sector, atomic_read(&sh->nr_pending), uptodate, __builtin_return_address(0),__builtin_return_address(1),__builtin_return_address(2), __builtin_return_address(3));
+ md_spin_lock_irqsave(&sh->stripe_lock, flags);
+ raid5_mark_buffer_uptodate(bh, uptodate);
+ if (!uptodate)
+ md_error(mddev_to_kdev(conf->mddev), bh->b_dev);
+ if (conf->failed_disks) {


+ for (i = 0; i < disks; i++) {

+ if (conf->disks[i].operational)
+ continue;
+ if (bh != sh->bh_old[i] && bh != sh->bh_req[i] && bh != sh->bh_copy[i])
+ continue;
+ if (bh->b_dev != conf->disks[i].dev)
+ continue;
+ set_bit(STRIPE_ERROR, &sh->state);
+ }
+ }
+ md_spin_unlock_irqrestore(&sh->stripe_lock, flags);
+
+ if (atomic_dec_and_test(&sh->nr_pending)) {
+ atomic_inc(&conf->nr_handle);


+ md_wakeup_thread(conf->thread);
+ }
+}
+

+static void raid5_build_block (struct stripe_head *sh, struct buffer_head *bh, int i)
+{
+ raid5_conf_t *conf = sh->raid_conf;
+ char *b_data;
+ struct page *b_page;
+ unsigned long block = sh->sector / (sh->size >> 9);
+
+ b_data = bh->b_data;
+ b_page = bh->b_page;
+ memset (bh, 0, sizeof (struct buffer_head));
+ init_waitqueue_head(&bh->b_wait);
+ init_buffer(bh, raid5_end_request, sh);
+ bh->b_dev = conf->disks[i].dev;
+ bh->b_blocknr = block;
+
+ bh->b_data = b_data;
+ bh->b_page = b_page;
+
+ bh->b_rdev = conf->disks[i].dev;
+ bh->b_rsector = sh->sector;
+
+ bh->b_state = (1 << BH_Req) | (1 << BH_Mapped);
+ bh->b_size = sh->size;
+ bh->b_list = BUF_LOCKED;
+}
+
+static int raid5_error (mddev_t *mddev, kdev_t dev)
+{
+ raid5_conf_t *conf = (raid5_conf_t *) mddev->private;


+ mdp_super_t *sb = mddev->sb;

+ struct disk_info *disk;
+ int i;
+
+ PRINTK("raid5_error called\n");
+ conf->resync_parity = 0;
+ for (i = 0, disk = conf->disks; i < conf->raid_disks; i++, disk++) {
+ if (disk->dev == dev && disk->operational) {
+ disk->operational = 0;
+ mark_disk_faulty(sb->disks+disk->number);
+ mark_disk_nonsync(sb->disks+disk->number);
+ mark_disk_inactive(sb->disks+disk->number);


+ sb->active_disks--;
+ sb->working_disks--;
+ sb->failed_disks++;
+ mddev->sb_dirty = 1;

+ conf->working_disks--;
+ conf->failed_disks++;
+ md_wakeup_thread(conf->thread);
+ printk (KERN_ALERT
+ "raid5: Disk failure on %s, disabling device."
+ " Operation continuing on %d devices\n",
+ partition_name (dev), conf->working_disks);


+ return 0;
+ }
+ }
+ /*

+ * handle errors in spares (during reconstruction)
+ */
+ if (conf->spare) {
+ disk = conf->spare;
+ if (disk->dev == dev) {
+ printk (KERN_ALERT
+ "raid5: Disk failure on spare %s\n",
+ partition_name (dev));
+ if (!conf->spare->operational) {
+ MD_BUG();
+ return -EIO;
+ }
+ disk->operational = 0;
+ disk->write_only = 0;
+ conf->spare = NULL;
+ mark_disk_faulty(sb->disks+disk->number);
+ mark_disk_nonsync(sb->disks+disk->number);
+ mark_disk_inactive(sb->disks+disk->number);


+ sb->spare_disks--;
+ sb->working_disks--;
+ sb->failed_disks++;
+

+ return 0;
+ }
+ }

+ MD_BUG();
+ return -EIO;
+}
+
+/*
+ * Input: a 'big' sector number,
+ * Output: index of the data and parity disk, and the sector # in them.
+ */
+static unsigned long raid5_compute_sector(unsigned long r_sector, unsigned int raid_disks,
+ unsigned int data_disks, unsigned int * dd_idx,
+ unsigned int * pd_idx, raid5_conf_t *conf)
+{
+ unsigned long stripe;
+ unsigned long chunk_number;
+ unsigned int chunk_offset;
+ unsigned long new_sector;
+ int sectors_per_chunk = conf->chunk_size >> 9;
+
+ /* First compute the information on this sector */
+
+ /*
+ * Compute the chunk number and the sector offset inside the chunk
+ */
+ chunk_number = r_sector / sectors_per_chunk;
+ chunk_offset = r_sector % sectors_per_chunk;
+
+ /*
+ * Compute the stripe number
+ */
+ stripe = chunk_number / data_disks;
+
+ /*
+ * Compute the data disk and parity disk indexes inside the stripe
+ */
+ *dd_idx = chunk_number % data_disks;
+
+ /*
+ * Select the parity disk based on the user selected algorithm.
+ */
+ if (conf->level == 4)
+ *pd_idx = data_disks;
+ else switch (conf->algorithm) {
+ case ALGORITHM_LEFT_ASYMMETRIC:
+ *pd_idx = data_disks - stripe % raid_disks;
+ if (*dd_idx >= *pd_idx)
+ (*dd_idx)++;
+ break;
+ case ALGORITHM_RIGHT_ASYMMETRIC:
+ *pd_idx = stripe % raid_disks;
+ if (*dd_idx >= *pd_idx)
+ (*dd_idx)++;
+ break;
+ case ALGORITHM_LEFT_SYMMETRIC:
+ *pd_idx = data_disks - stripe % raid_disks;
+ *dd_idx = (*pd_idx + 1 + *dd_idx) % raid_disks;
+ break;
+ case ALGORITHM_RIGHT_SYMMETRIC:
+ *pd_idx = stripe % raid_disks;
+ *dd_idx = (*pd_idx + 1 + *dd_idx) % raid_disks;
+ break;
+ default:
+ printk ("raid5: unsupported algorithm %d\n", conf->algorithm);
+ }
+
+ /*
+ * Finally, compute the new sector number
+ */
+ new_sector = stripe * sectors_per_chunk + chunk_offset;
+ return new_sector;
+}
+
+static unsigned long compute_blocknr(struct stripe_head *sh, int i)
+{
+ raid5_conf_t *conf = sh->raid_conf;
+ int raid_disks = conf->raid_disks, data_disks = raid_disks - 1;
+ unsigned long new_sector = sh->sector, check;
+ int sectors_per_chunk = conf->chunk_size >> 9;
+ unsigned long stripe = new_sector / sectors_per_chunk;
+ int chunk_offset = new_sector % sectors_per_chunk;
+ int chunk_number, dummy1, dummy2, dd_idx = i;
+ unsigned long r_sector, blocknr;
+
+ switch (conf->algorithm) {
+ case ALGORITHM_LEFT_ASYMMETRIC:
+ case ALGORITHM_RIGHT_ASYMMETRIC:
+ if (i > sh->pd_idx)
+ i--;
+ break;
+ case ALGORITHM_LEFT_SYMMETRIC:
+ case ALGORITHM_RIGHT_SYMMETRIC:
+ if (i < sh->pd_idx)
+ i += raid_disks;
+ i -= (sh->pd_idx + 1);
+ break;
+ default:
+ printk ("raid5: unsupported algorithm %d\n", conf->algorithm);
+ }
+
+ chunk_number = stripe * data_disks + i;
+ r_sector = chunk_number * sectors_per_chunk + chunk_offset;
+ blocknr = r_sector / (sh->size >> 9);
+
+ check = raid5_compute_sector (r_sector, raid_disks, data_disks, &dummy1, &dummy2, conf);
+ if (check != sh->sector || dummy1 != dd_idx || dummy2 != sh->pd_idx) {
+ printk("compute_blocknr: map not correct\n");
+ return 0;
+ }
+ return blocknr;
+}
+
+static void compute_block(struct stripe_head *sh, int dd_idx)
+{
+ raid5_conf_t *conf = sh->raid_conf;
+ int i, count, disks = conf->raid_disks;
+ struct buffer_head *bh_ptr[MAX_XOR_BLOCKS];
+
+ PRINTK("compute_block, stripe %lu, idx %d\n", sh->sector, dd_idx);
+
+ if (sh->bh_old[dd_idx] == NULL)
+ sh->bh_old[dd_idx] = raid5_alloc_buffer(sh, sh->size);
+ raid5_build_block(sh, sh->bh_old[dd_idx], dd_idx);
+
+ memset(sh->bh_old[dd_idx]->b_data, 0, sh->size);
+ bh_ptr[0] = sh->bh_old[dd_idx];
+ count = 1;


+ for (i = 0; i < disks; i++) {

+ if (i == dd_idx)
+ continue;
+ if (sh->bh_old[i]) {
+ bh_ptr[count++] = sh->bh_old[i];
+ } else {
+ printk("compute_block() %d, stripe %lu, %d not present\n", dd_idx, sh->sector, i);
+ }
+ if (count == MAX_XOR_BLOCKS) {
+ xor_block(count, &bh_ptr[0]);
+ count = 1;
+ }
+ }
+ if (count != 1)
+ xor_block(count, &bh_ptr[0]);
+ raid5_mark_buffer_uptodate(sh->bh_old[dd_idx], 1);
+}
+
+static void compute_parity(struct stripe_head *sh, int method)
+{
+ raid5_conf_t *conf = sh->raid_conf;
+ int i, pd_idx = sh->pd_idx, disks = conf->raid_disks, count;
+ struct buffer_head *bh_ptr[MAX_XOR_BLOCKS];
+
+ PRINTK("compute_parity, stripe %lu, method %d\n", sh->sector, method);


+ for (i = 0; i < disks; i++) {

+ if (i == pd_idx || !sh->bh_new[i])
+ continue;
+ if (!sh->bh_copy[i])
+ sh->bh_copy[i] = raid5_alloc_buffer(sh, sh->size);
+ raid5_build_block(sh, sh->bh_copy[i], i);
+ atomic_set_buffer_dirty(sh->bh_copy[i]);
+ memcpy(sh->bh_copy[i]->b_data, sh->bh_new[i]->b_data, sh->size);
+ }
+ if (sh->bh_copy[pd_idx] == NULL) {
+ sh->bh_copy[pd_idx] = raid5_alloc_buffer(sh, sh->size);
+ atomic_set_buffer_dirty(sh->bh_copy[pd_idx]);
+ }
+ raid5_build_block(sh, sh->bh_copy[pd_idx], sh->pd_idx);
+
+ if (method == RECONSTRUCT_WRITE) {
+ memset(sh->bh_copy[pd_idx]->b_data, 0, sh->size);
+ bh_ptr[0] = sh->bh_copy[pd_idx];
+ count = 1;


+ for (i = 0; i < disks; i++) {

+ if (i == sh->pd_idx)
+ continue;
+ if (sh->bh_new[i]) {
+ bh_ptr[count++] = sh->bh_copy[i];
+ } else if (sh->bh_old[i]) {
+ bh_ptr[count++] = sh->bh_old[i];
+ }
+ if (count == MAX_XOR_BLOCKS) {
+ xor_block(count, &bh_ptr[0]);
+ count = 1;
+ }
+ }
+ if (count != 1) {
+ xor_block(count, &bh_ptr[0]);
+ }
+ } else if (method == READ_MODIFY_WRITE) {
+ memcpy(sh->bh_copy[pd_idx]->b_data, sh->bh_old[pd_idx]->b_data, sh->size);
+ bh_ptr[0] = sh->bh_copy[pd_idx];
+ count = 1;


+ for (i = 0; i < disks; i++) {

+ if (i == sh->pd_idx)
+ continue;
+ if (sh->bh_new[i] && sh->bh_old[i]) {
+ bh_ptr[count++] = sh->bh_copy[i];
+ bh_ptr[count++] = sh->bh_old[i];
+ }
+ if (count >= (MAX_XOR_BLOCKS - 1)) {
+ xor_block(count, &bh_ptr[0]);
+ count = 1;
+ }
+ }
+ if (count != 1) {
+ xor_block(count, &bh_ptr[0]);
+ }
+ }
+ raid5_mark_buffer_uptodate(sh->bh_copy[pd_idx], 1);
+}
+
+static void add_stripe_bh (struct stripe_head *sh, struct buffer_head *bh, int dd_idx, int rw)
+{
+ raid5_conf_t *conf = sh->raid_conf;
+ struct buffer_head *bh_req;
+
+ PRINTK("adding bh b#%lu to stripe s#%lu\n", bh->b_blocknr, sh->sector);
+ CHECK_SHLOCK(sh);
+ if (sh->bh_new[dd_idx])
+ BUG();
+
+ bh_req = raid5_alloc_bh(sh);
+ raid5_build_block(sh, bh_req, dd_idx);
+ bh_req->b_data = bh->b_data;
+ bh_req->b_page = bh->b_page;
+
+ md_spin_lock_irq(&conf->device_lock);
+ if (sh->phase == PHASE_COMPLETE && sh->cmd == STRIPE_NONE) {
+ PRINTK("stripe s#%lu => PHASE_BEGIN (%s)\n", sh->sector, rw == READ ? "read" : "write");
+ sh->phase = PHASE_BEGIN;
+ sh->cmd = (rw == READ) ? STRIPE_READ : STRIPE_WRITE;
+ atomic_inc(&conf->nr_pending_stripes);
+ atomic_inc(&conf->nr_handle);
+ PRINTK("# of pending stripes: %u, # of handle: %u\n", atomic_read(&conf->nr_pending_stripes), atomic_read(&conf->nr_handle));
+ }
+ sh->bh_new[dd_idx] = bh;
+ sh->bh_req[dd_idx] = bh_req;
+ sh->cmd_new[dd_idx] = rw;
+ sh->new[dd_idx] = 1;
+ md_spin_unlock_irq(&conf->device_lock);
+
+ PRINTK("added bh b#%lu to stripe s#%lu, disk %d.\n", bh->b_blocknr, sh->sector, dd_idx);
+}
+
+static void complete_stripe(struct stripe_head *sh)
+{
+ raid5_conf_t *conf = sh->raid_conf;
+ int disks = conf->raid_disks;
+ int i, new = 0;
+
+ PRINTK("complete_stripe %lu\n", sh->sector);


+ for (i = 0; i < disks; i++) {

+ if (sh->cmd == STRIPE_SYNC && sh->bh_copy[i])
+ raid5_update_old_bh(sh, i);
+ if (sh->cmd == STRIPE_WRITE && i == sh->pd_idx)
+ raid5_update_old_bh(sh, i);
+ if (sh->bh_new[i]) {
+ PRINTK("stripe %lu finishes new bh, sh->new == %d\n", sh->sector, sh->new[i]);
+ if (!sh->new[i]) {
+#if 0
+ if (sh->cmd == STRIPE_WRITE) {
+ if (memcmp(sh->bh_new[i]->b_data, sh->bh_copy[i]->b_data, sh->size)) {
+ printk("copy differs, %s, sector %lu ",
+ test_bit(BH_Dirty, &sh->bh_new[i]->b_state) ? "dirty" : "clean",
+ sh->sector);
+ } else if (test_bit(BH_Dirty, &sh->bh_new[i]->b_state))
+ printk("sector %lu dirty\n", sh->sector);
+ }
+#endif
+ if (sh->cmd == STRIPE_WRITE)
+ raid5_update_old_bh(sh, i);
+ raid5_end_buffer_io(sh, i, 1);
+ continue;
+ } else
+ new++;
+ }
+ if (new && sh->cmd == STRIPE_WRITE)
+ printk("raid5: bug, completed STRIPE_WRITE with new == %d\n", new);
+ }
+ if (sh->cmd == STRIPE_SYNC)
+ md_done_sync(conf->mddev, (sh->size>>10) - sh->sync_redone,1);
+ if (!new)
+ finish_unlock_stripe(sh);
+ else {
+ PRINTK("stripe %lu, new == %d\n", sh->sector, new);
+ sh->phase = PHASE_BEGIN;
+ }
+}
+
+
+static void handle_stripe_write (mddev_t *mddev , raid5_conf_t *conf,
+ struct stripe_head *sh, int nr_write, int * operational, int disks,
+ int parity, int parity_failed, int nr_cache, int nr_cache_other,
+ int nr_failed_other, int nr_cache_overwrite, int nr_failed_overwrite)
+{
+ int i;
+ unsigned int block;
+ struct buffer_head *bh;
+ int method1 = INT_MAX, method2 = INT_MAX;
+
+ /*
+ * Attempt to add entries :-)
+ */
+ if (nr_write != disks - 1) {


+ for (i = 0; i < disks; i++) {

+ if (i == sh->pd_idx)
+ continue;
+ if (sh->bh_new[i])
+ continue;
+ block = (int) compute_blocknr(sh, i);
+ bh = get_hash_table(mddev_to_kdev(mddev), block, sh->size);
+ if (!bh)
+ continue;
+ if (buffer_dirty(bh) && !md_test_and_set_bit(BH_Lock, &bh->b_state)) {
+ PRINTK("Whee.. sector %lu, index %d (%d) found in the buffer cache!\n", sh->sector, i, block);
+ add_stripe_bh(sh, bh, i, WRITE);
+ sh->new[i] = 0;
+ nr_write++;
+ if (sh->bh_old[i]) {
+ nr_cache_overwrite++;
+ nr_cache_other--;
+ } else
+ if (!operational[i]) {
+ nr_failed_overwrite++;
+ nr_failed_other--;
+ }
+ }
+ atomic_dec(&bh->b_count);
+ }
+ }
+ PRINTK("handle_stripe() -- begin writing, stripe %lu\n", sh->sector);
+ /*
+ * Writing, need to update parity buffer.
+ *
+ * Compute the number of I/O requests in the "reconstruct
+ * write" and "read modify write" methods.
+ */
+ if (!nr_failed_other)
+ method1 = (disks - 1) - (nr_write + nr_cache_other);
+ if (!nr_failed_overwrite && !parity_failed)
+ method2 = nr_write - nr_cache_overwrite + (1 - parity);
+
+ if (method1 == INT_MAX && method2 == INT_MAX)
+ BUG();
+ PRINTK("handle_stripe(), sector %lu, nr_write %d, method1 %d, method2 %d\n", sh->sector, nr_write, method1, method2);
+
+ if (!method1 || !method2) {
+ sh->phase = PHASE_WRITE;
+ compute_parity(sh, method1 <= method2 ? RECONSTRUCT_WRITE : READ_MODIFY_WRITE);


+
+ for (i = 0; i < disks; i++) {

+ if (!operational[i] && !conf->spare && !conf->resync_parity)
+ continue;
+ bh = sh->bh_copy[i];
+ if (i != sh->pd_idx && ((bh == NULL) ^ (sh->bh_new[i] == NULL)))
+ printk("raid5: bug: bh == %p, bh_new[%d] == %p\n", bh, i, sh->bh_new[i]);
+ if (i == sh->pd_idx && !bh)
+ printk("raid5: bug: bh == NULL, i == pd_idx == %d\n", i);
+ if (bh) {
+ PRINTK("making request for buffer %d\n", i);
+ lock_get_bh(bh);
+ if (!operational[i] && !conf->resync_parity) {
+ PRINTK("writing spare %d\n", i);
+ atomic_inc(&sh->nr_pending);
+ bh->b_dev = bh->b_rdev = conf->spare->dev;
+ generic_make_request(WRITE, bh);
+ } else {
+ atomic_inc(&sh->nr_pending);
+ bh->b_dev = bh->b_rdev = conf->disks[i].dev;
+ generic_make_request(WRITE, bh);
+ }
+ atomic_dec(&bh->b_count);
+ }
+ }
+ PRINTK("handle_stripe() %lu, writing back %d buffers\n", sh->sector, md_atomic_read(&sh->nr_pending));
+ return;
+ }
+
+ if (method1 < method2) {
+ sh->write_method = RECONSTRUCT_WRITE;


+ for (i = 0; i < disks; i++) {

+ if (i == sh->pd_idx)
+ continue;
+ if (sh->bh_new[i] || sh->bh_old[i])
+ continue;
+ sh->bh_old[i] = raid5_alloc_buffer(sh, sh->size);
+ raid5_build_block(sh, sh->bh_old[i], i);
+ }
+ } else {
+ sh->write_method = READ_MODIFY_WRITE;


+ for (i = 0; i < disks; i++) {

+ if (sh->bh_old[i])
+ continue;
+ if (!sh->bh_new[i] && i != sh->pd_idx)
+ continue;
+ sh->bh_old[i] = raid5_alloc_buffer(sh, sh->size);
+ raid5_build_block(sh, sh->bh_old[i], i);
+ }
+ }
+ sh->phase = PHASE_READ_OLD;


+ for (i = 0; i < disks; i++) {

+ if (!sh->bh_old[i])
+ continue;
+ if (test_bit(BH_Uptodate, &sh->bh_old[i]->b_state))
+ continue;
+ lock_get_bh(sh->bh_old[i]);
+ atomic_inc(&sh->nr_pending);
+ sh->bh_old[i]->b_dev = sh->bh_old[i]->b_rdev = conf->disks[i].dev;
+ generic_make_request(READ, sh->bh_old[i]);
+ atomic_dec(&sh->bh_old[i]->b_count);
+ }
+ PRINTK("handle_stripe() %lu, reading %d old buffers\n", sh->sector, md_atomic_read(&sh->nr_pending));
+}
+
+/*
+ * Reading
+ */
+static void handle_stripe_read (mddev_t *mddev , raid5_conf_t *conf,
+ struct stripe_head *sh, int nr_read, int * operational, int disks,
+ int parity, int parity_failed, int nr_cache, int nr_cache_other,
+ int nr_failed_other, int nr_cache_overwrite, int nr_failed_overwrite)
+{
+ int i;
+ int method1 = INT_MAX;
+
+ method1 = nr_read - nr_cache_overwrite;
+
+ PRINTK("handle_stripe(), sector %lu, nr_read %d, nr_cache %d, method1 %d\n", sh->sector, nr_read, nr_cache, method1);
+
+ if (!method1 || (method1 == 1 && nr_cache == disks - 1)) {
+ PRINTK("read %lu completed from cache\n", sh->sector);


+ for (i = 0; i < disks; i++) {

+ if (!sh->bh_new[i])
+ continue;
+ if (!sh->bh_old[i])
+ compute_block(sh, i);
+ memcpy(sh->bh_new[i]->b_data, sh->bh_old[i]->b_data, sh->size);
+ }
+ complete_stripe(sh);
+ return;
+ }
+ if (nr_failed_overwrite) {
+ sh->phase = PHASE_READ_OLD;


+ for (i = 0; i < disks; i++) {

+ if (sh->bh_old[i])
+ continue;
+ if (!operational[i])
+ continue;
+ sh->bh_old[i] = raid5_alloc_buffer(sh, sh->size);
+ raid5_build_block(sh, sh->bh_old[i], i);
+ lock_get_bh(sh->bh_old[i]);
+ atomic_inc(&sh->nr_pending);
+ sh->bh_old[i]->b_dev = sh->bh_old[i]->b_rdev = conf->disks[i].dev;
+ generic_make_request(READ, sh->bh_old[i]);
+ atomic_dec(&sh->bh_old[i]->b_count);
+ }
+ PRINTK("handle_stripe() %lu, phase READ_OLD, pending %d buffers\n", sh->sector, md_atomic_read(&sh->nr_pending));
+ return;
+ }
+ sh->phase = PHASE_READ;


+ for (i = 0; i < disks; i++) {

+ if (!sh->bh_new[i])
+ continue;
+ if (sh->bh_old[i]) {
+ memcpy(sh->bh_new[i]->b_data, sh->bh_old[i]->b_data, sh->size);
+ continue;
+ }
+#if RAID5_PARANOIA
+ if (sh->bh_req[i] == NULL || test_bit(BH_Lock, &sh->bh_req[i]->b_state)) {
+ int j;
+ printk("req %d is NULL! or locked \n", i);
+ for (j=0; j<disks; j++) {
+ printk("%d: new=%p old=%p req=%p new=%d cmd=%d\n",
+ j, sh->bh_new[j], sh->bh_old[j], sh->bh_req[j],
+ sh->new[j], sh->cmd_new[j]);
+ }
+
+ }
+#endif
+ lock_get_bh(sh->bh_req[i]);
+ atomic_inc(&sh->nr_pending);
+ sh->bh_req[i]->b_dev = sh->bh_req[i]->b_rdev = conf->disks[i].dev;
+ generic_make_request(READ, sh->bh_req[i]);
+ atomic_dec(&sh->bh_req[i]->b_count);
+ }
+ PRINTK("handle_stripe() %lu, phase READ, pending %d\n", sh->sector, md_atomic_read(&sh->nr_pending));
+}
+
+/*
+ * Syncing
+ */
+static void handle_stripe_sync (mddev_t *mddev , raid5_conf_t *conf,
+ struct stripe_head *sh, int * operational, int disks,
+ int parity, int parity_failed, int nr_cache, int nr_cache_other,
+ int nr_failed_other, int nr_cache_overwrite, int nr_failed_overwrite)
+{
+ struct buffer_head *bh;
+ int i, pd_idx;
+
+ /* firstly, we want to have data from all non-failed drives
+ * in bh_old
+ */
+ PRINTK("handle_stripe_sync: sec=%lu disks=%d nr_cache=%d\n", sh->sector, disks, nr_cache);
+ if ((nr_cache < disks-1) || ((nr_cache == disks-1) && !(parity_failed+nr_failed_other+nr_failed_overwrite))
+ ) {
+ sh->phase = PHASE_READ_OLD;


+ for (i = 0; i < disks; i++) {

+ if (sh->bh_old[i])
+ continue;
+ if (!conf->disks[i].operational)
+ continue;
+
+ bh = raid5_alloc_buffer(sh, sh->size);
+ sh->bh_old[i] = bh;
+ raid5_build_block(sh, bh, i);
+ lock_get_bh(bh);
+ atomic_inc(&sh->nr_pending);
+ bh->b_dev = bh->b_rdev = conf->disks[i].dev;
+ generic_make_request(READ, bh);
+ md_sync_acct(bh->b_rdev, bh->b_size/512);
+ atomic_dec(&sh->bh_old[i]->b_count);
+ }
+ PRINTK("handle_stripe_sync() %lu, phase READ_OLD, pending %d buffers\n", sh->sector, md_atomic_read(&sh->nr_pending));
+
+ return;
+ }
+ /* now, if there is a failed drive, rebuild and write to spare */
+ if (nr_cache == disks-1) {
+ sh->phase = PHASE_WRITE;
+ /* we can generate the missing block, which will be on the failed drive */
+ for (i=0; i<disks; i++) {
+ if (operational[i])
+ continue;
+ compute_block(sh, i);
+ if (conf->spare) {
+ bh = sh->bh_copy[i];
+ if (bh) {
+ memcpy(bh->b_data, sh->bh_old[i]->b_data, sh->size);
+ set_bit(BH_Uptodate, &bh->b_state);
+ } else {
+ bh = sh->bh_old[i];
+ sh->bh_old[i] = NULL;
+ sh->bh_copy[i] = bh;
+ }
+ atomic_inc(&sh->nr_pending);
+ lock_get_bh(bh);
+ bh->b_dev = bh->b_rdev = conf->spare->dev;
+ generic_make_request(WRITE, bh);
+ md_sync_acct(bh->b_rdev, bh->b_size/512);
+ atomic_dec(&bh->b_count);
+ PRINTK("handle_stripe_sync() %lu, phase WRITE, pending %d buffers\n", sh->sector, md_atomic_read(&sh->nr_pending));
+ }
+ break;
+ }
+ return;
+ }
+
+ /* nr_cache == disks:
+ * check parity and compute/write if needed
+ */
+
+ compute_parity(sh, RECONSTRUCT_WRITE);
+ pd_idx = sh->pd_idx;
+ if (!memcmp(sh->bh_copy[pd_idx]->b_data, sh->bh_old[pd_idx]->b_data, sh->size)) {
+ /* the parity is correct - Yay! */
+ complete_stripe(sh);
+ } else {
+ sh->phase = PHASE_WRITE;
+ bh = sh->bh_copy[pd_idx];
+ atomic_set_buffer_dirty(bh);
+ lock_get_bh(bh);
+ atomic_inc(&sh->nr_pending);
+ bh->b_dev = bh->b_rdev = conf->disks[pd_idx].dev;
+ generic_make_request(WRITE, bh);
+ md_sync_acct(bh->b_rdev, bh->b_size/512);
+ atomic_dec(&bh->b_count);
+ PRINTK("handle_stripe_sync() %lu phase WRITE, pending %d buffers\n",
+ sh->sector, md_atomic_read(&sh->nr_pending));
+ }
+}
+
+/*
+ * handle_stripe() is our main logic routine. Note that:
+ *
+ * 1. lock_stripe() should be used whenever we can't accept additonal
+ * buffers, either during short sleeping in handle_stripe() or
+ * during io operations.
+ *
+ * 2. We should be careful to set sh->nr_pending whenever we sleep,
+ * to prevent re-entry of handle_stripe() for the same sh.
+ *
+ * 3. conf->failed_disks and disk->operational can be changed
+ * from an interrupt. This complicates things a bit, but it allows
+ * us to stop issuing requests for a failed drive as soon as possible.
+ */
+static void handle_stripe(struct stripe_head *sh)
+{
+ raid5_conf_t *conf = sh->raid_conf;


+ mddev_t *mddev = conf->mddev;

+ int disks = conf->raid_disks;
+ int i, nr_read = 0, nr_write = 0, parity = 0;
+ int nr_cache = 0, nr_cache_other = 0, nr_cache_overwrite = 0;
+ int nr_failed_other = 0, nr_failed_overwrite = 0, parity_failed = 0;
+ int operational[MD_SB_DISKS], failed_disks = conf->failed_disks;
+
+ PRINTK("handle_stripe(), stripe %lu\n", sh->sector);
+ if (!stripe_locked(sh))
+ BUG();
+ if (md_atomic_read(&sh->nr_pending))
+ BUG();
+ if (sh->phase == PHASE_COMPLETE)
+ BUG();
+
+ atomic_dec(&conf->nr_handle);
+
+ if (md_test_and_clear_bit(STRIPE_ERROR, &sh->state)) {
+ printk("raid5: restarting stripe %lu\n", sh->sector);
+ sh->phase = PHASE_BEGIN;
+ }
+
+ if ((sh->cmd == STRIPE_WRITE && sh->phase == PHASE_WRITE) ||
+ (sh->cmd == STRIPE_READ && sh->phase == PHASE_READ) ||
+ (sh->cmd == STRIPE_SYNC && sh->phase == PHASE_WRITE)
+ ) {
+ /*
+ * Completed
+ */
+ complete_stripe(sh);
+ if (sh->phase == PHASE_COMPLETE)
+ return;
+ }
+
+ md_spin_lock_irq(&conf->device_lock);


+ for (i = 0; i < disks; i++) {

+ operational[i] = conf->disks[i].operational;
+ if (i == sh->pd_idx && conf->resync_parity)
+ operational[i] = 0;
+ }
+ failed_disks = conf->failed_disks;
+ md_spin_unlock_irq(&conf->device_lock);
+
+ /*
+ * Make this one more graceful?
+ */
+ if (failed_disks > 1) {


+ for (i = 0; i < disks; i++) {

+ if (sh->bh_new[i]) {
+ raid5_end_buffer_io(sh, i, 0);
+ continue;
+ }
+ }
+ if (sh->cmd == STRIPE_SYNC)
+ md_done_sync(conf->mddev, (sh->size>>10) - sh->sync_redone,1);
+ finish_unlock_stripe(sh);
+ return;
+ }
+
+ PRINTK("=== stripe index START ===\n");


+ for (i = 0; i < disks; i++) {

+ PRINTK("disk %d, ", i);
+ if (sh->bh_old[i]) {
+ nr_cache++;
+ PRINTK(" (old cached, %d)", nr_cache);
+ }
+ if (i == sh->pd_idx) {
+ PRINTK(" PARITY.");
+ if (sh->bh_old[i]) {
+ PRINTK(" CACHED.");
+ parity = 1;
+ } else {
+ PRINTK(" UNCACHED.");
+ if (!operational[i]) {
+ PRINTK(" FAILED.");
+ parity_failed = 1;
+ }
+ }
+ PRINTK("\n");
+ continue;
+ }
+ if (!sh->bh_new[i]) {
+ PRINTK(" (no new data block) ");
+ if (sh->bh_old[i]) {
+ PRINTK(" (but old block cached) ");
+ nr_cache_other++;
+ } else {
+ if (!operational[i]) {
+ PRINTK(" (because failed disk) ");
+ nr_failed_other++;
+ } else
+ PRINTK(" (no old block either) ");
+ }
+ PRINTK("\n");
+ continue;
+ }
+ sh->new[i] = 0;
+ if (sh->cmd_new[i] == READ) {
+ nr_read++;
+ PRINTK(" (new READ %d)", nr_read);
+ }
+ if (sh->cmd_new[i] == WRITE) {
+ nr_write++;
+ PRINTK(" (new WRITE %d)", nr_write);
+ }
+ if (sh->bh_old[i]) {
+ nr_cache_overwrite++;
+ PRINTK(" (overwriting old %d)", nr_cache_overwrite);
+ } else {
+ if (!operational[i]) {
+ nr_failed_overwrite++;
+ PRINTK(" (overwriting failed %d)", nr_failed_overwrite);
+ }
+ }
+ PRINTK("\n");
+ }
+ PRINTK("=== stripe index END ===\n");
+
+ if (nr_write && nr_read)
+ BUG();
+
+ if (nr_write)
+ handle_stripe_write(
+ mddev, conf, sh, nr_write, operational, disks,
+ parity, parity_failed, nr_cache, nr_cache_other,
+ nr_failed_other, nr_cache_overwrite,
+ nr_failed_overwrite
+ );
+ else if (nr_read)
+ handle_stripe_read(
+ mddev, conf, sh, nr_read, operational, disks,
+ parity, parity_failed, nr_cache, nr_cache_other,
+ nr_failed_other, nr_cache_overwrite,
+ nr_failed_overwrite
+ );
+ else if (sh->cmd == STRIPE_SYNC)
+ handle_stripe_sync(
+ mddev, conf, sh, operational, disks,
+ parity, parity_failed, nr_cache, nr_cache_other,
+ nr_failed_other, nr_cache_overwrite, nr_failed_overwrite
+ );
+}
+
+
+static int raid5_make_request (mddev_t *mddev, int rw, struct buffer_head * bh)
+{
+ raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
+ const unsigned int raid_disks = conf->raid_disks;
+ const unsigned int data_disks = raid_disks - 1;
+ unsigned int dd_idx, pd_idx;
+ unsigned long new_sector;
+
+ struct stripe_head *sh;
+


+ if (rw == READA)
+ rw = READ;
+

+ new_sector = raid5_compute_sector(bh->b_rsector,
+ raid_disks, data_disks, &dd_idx, &pd_idx, conf);
+
+ PRINTK("raid5_make_request, sector %lu\n", new_sector);
+ sh = get_lock_stripe(conf, new_sector, bh->b_size);


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 058'
echo 'File patch-2.4.0-test9 is continued in part 059'
echo "059" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part059

#!/bin/sh -x
# this is part 059 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 059; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+#if 0
+ if ((rw == READ && sh->cmd == STRIPE_WRITE) || (rw == WRITE && sh->cmd == STRIPE_READ)) {
+ PRINTK("raid5: lock contention, rw == %d, sh->cmd == %d\n", rw, sh->cmd);
+ lock_stripe(sh);
+ if (!md_atomic_read(&sh->nr_pending))
+ handle_stripe(sh);
+ goto repeat;
+ }
+#endif
+ sh->pd_idx = pd_idx;
+ if (sh->phase != PHASE_COMPLETE && sh->phase != PHASE_BEGIN)
+ PRINTK("stripe %lu catching the bus!\n", sh->sector);


+ if (sh->bh_new[dd_idx])
+ BUG();

+ add_stripe_bh(sh, bh, dd_idx, rw);
+
+ md_wakeup_thread(conf->thread);


+ return 0;
+}
+

+/*
+ * Determine correct block size for this device.
+ */
+unsigned int device_bsize (kdev_t dev)
+{
+ unsigned int i, correct_size;
+
+ correct_size = BLOCK_SIZE;
+ if (blksize_size[MAJOR(dev)]) {
+ i = blksize_size[MAJOR(dev)][MINOR(dev)];
+ if (i)
+ correct_size = i;
+ }
+
+ return correct_size;
+}
+
+static int raid5_sync_request (mddev_t *mddev, unsigned long block_nr)
+{


+ raid5_conf_t *conf = (raid5_conf_t *) mddev->private;

+ struct stripe_head *sh;


+ int sectors_per_chunk = conf->chunk_size >> 9;

+ unsigned long stripe = (block_nr<<2)/sectors_per_chunk;
+ int chunk_offset = (block_nr<<2) % sectors_per_chunk;
+ int dd_idx, pd_idx;
+ unsigned long first_sector;
+ int raid_disks = conf->raid_disks;
+ int data_disks = raid_disks-1;
+ int redone = 0;
+ int bufsize;
+
+ if (!conf->buffer_size)
+ conf->buffer_size = /* device_bsize(mddev_to_kdev(mddev))*/ PAGE_SIZE;
+ bufsize = conf->buffer_size;
+ /* Hmm... race on buffer_size ?? */
+ redone = block_nr% (bufsize>>10);
+ block_nr -= redone;
+ sh = get_lock_stripe(conf, block_nr<<1, bufsize);
+ first_sector = raid5_compute_sector(stripe*data_disks*sectors_per_chunk
+ + chunk_offset, raid_disks, data_disks, &dd_idx, &pd_idx, conf);
+ sh->pd_idx = pd_idx;
+ sh->cmd = STRIPE_SYNC;


+ sh->phase = PHASE_BEGIN;

+ sh->sync_redone = redone;


+ atomic_inc(&conf->nr_pending_stripes);
+ atomic_inc(&conf->nr_handle);

+ md_wakeup_thread(conf->thread);
+ return (bufsize>>10)-redone;
+}
+
+/*
+ * This is our raid5 kernel thread.
+ *
+ * We scan the hash table for stripes which can be handled now.
+ * During the scan, completed stripes are saved for us by the interrupt
+ * handler, so that they will not have to wait for our next wakeup.
+ */
+static void raid5d (void *data)


+{
+ struct stripe_head *sh;

+ raid5_conf_t *conf = data;


+ mddev_t *mddev = conf->mddev;

+ int i, handled;
+
+ PRINTK("+++ raid5d active\n");
+
+ handled = 0;
+ md_spin_lock_irq(&conf->device_lock);
+ clear_bit(THREAD_WAKEUP, &conf->thread->flags);
+repeat_pass:
+ if (mddev->sb_dirty) {
+ md_spin_unlock_irq(&conf->device_lock);


+ mddev->sb_dirty = 0;

+ md_update_sb(mddev);
+ md_spin_lock_irq(&conf->device_lock);
+ }
+ for (i = 0; i < NR_HASH; i++) {
+repeat:
+ sh = conf->stripe_hashtbl[i];


+ for (; sh; sh = sh->hash_next) {

+ if (sh->raid_conf != conf)
+ continue;
+ if (sh->phase == PHASE_COMPLETE)
+ continue;
+ if (md_atomic_read(&sh->nr_pending))
+ continue;
+ md_spin_unlock_irq(&conf->device_lock);


+ if (!atomic_read(&sh->count))
+ BUG();
+

+ handled++;
+ handle_stripe(sh);
+ md_spin_lock_irq(&conf->device_lock);


+ goto repeat;
+ }
+ }

+ if (conf) {
+ PRINTK("%d stripes handled, nr_handle %d\n", handled, md_atomic_read(&conf->nr_handle));
+ if (test_and_clear_bit(THREAD_WAKEUP, &conf->thread->flags) &&
+ md_atomic_read(&conf->nr_handle))
+ goto repeat_pass;


+ }
+ md_spin_unlock_irq(&conf->device_lock);
+

+ PRINTK("--- raid5d inactive\n");
+}
+
+/*
+ * Private kernel thread for parity reconstruction after an unclean
+ * shutdown. Reconstruction on spare drives in case of a failed drive
+ * is done by the generic mdsyncd.
+ */
+static void raid5syncd (void *data)
+{
+ raid5_conf_t *conf = data;


+ mddev_t *mddev = conf->mddev;
+

+ if (!conf->resync_parity)
+ return;
+ if (conf->resync_parity == 2)


+ return;
+ down(&mddev->recovery_sem);

+ if (md_do_sync(mddev,NULL)) {
+ up(&mddev->recovery_sem);
+ printk("raid5: resync aborted!\n");
+ return;
+ }


+ conf->resync_parity = 0;

+ up(&mddev->recovery_sem);
+ printk("raid5: resync finished.\n");
+}
+


+static int __check_consistency (mddev_t *mddev, int row)
+{

+ raid5_conf_t *conf = mddev->private;
+ kdev_t dev;
+ struct buffer_head *bh[MD_SB_DISKS], *tmp = NULL;
+ int i, ret = 0, nr = 0, count;


+ struct buffer_head *bh_ptr[MAX_XOR_BLOCKS];
+

+ if (conf->working_disks != conf->raid_disks)
+ goto out;
+ tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
+ tmp->b_size = 4096;
+ tmp->b_page = alloc_page(GFP_KERNEL);
+ tmp->b_data = page_address(tmp->b_page);
+ if (!tmp->b_data)
+ goto out;
+ md_clear_page(tmp->b_data);
+ memset(bh, 0, MD_SB_DISKS * sizeof(struct buffer_head *));
+ for (i = 0; i < conf->raid_disks; i++) {
+ dev = conf->disks[i].dev;
+ set_blocksize(dev, 4096);
+ bh[i] = bread(dev, row / 4, 4096);
+ if (!bh[i])
+ break;
+ nr++;
+ }
+ if (nr == conf->raid_disks) {
+ bh_ptr[0] = tmp;
+ count = 1;
+ for (i = 1; i < nr; i++) {
+ bh_ptr[count++] = bh[i];


+ if (count == MAX_XOR_BLOCKS) {
+ xor_block(count, &bh_ptr[0]);
+ count = 1;
+ }
+ }
+ if (count != 1) {
+ xor_block(count, &bh_ptr[0]);
+ }

+ if (memcmp(tmp->b_data, bh[0]->b_data, 4096))
+ ret = 1;
+ }
+ for (i = 0; i < conf->raid_disks; i++) {
+ dev = conf->disks[i].dev;
+ if (bh[i]) {
+ bforget(bh[i]);
+ bh[i] = NULL;
+ }


+ fsync_dev(dev);
+ invalidate_buffers(dev);
+ }

+ free_page((unsigned long) tmp->b_data);
+out:
+ if (tmp)
+ kfree(tmp);
+ return ret;


+}
+
+static int check_consistency (mddev_t *mddev)
+{
+ if (__check_consistency(mddev, 0))
+/*

+ * We are not checking this currently, as it's legitimate to have
+ * an inconsistent array, at creation time.


+ */
+ return 0;
+
+ return 0;
+}
+

+static int raid5_run (mddev_t *mddev)
+{
+ raid5_conf_t *conf;
+ int i, j, raid_disk, memory;


+ mdp_super_t *sb = mddev->sb;

+ mdp_disk_t *desc;
+ mdk_rdev_t *rdev;
+ struct disk_info *disk;


+ struct md_list_head *tmp;
+ int start_recovery = 0;
+
+ MOD_INC_USE_COUNT;
+

+ if (sb->level != 5 && sb->level != 4) {
+ printk("raid5: md%d: raid level not set to 4/5 (%d)\n", mdidx(mddev), sb->level);


+ MOD_DEC_USE_COUNT;
+ return -EIO;
+ }
+

+ mddev->private = kmalloc (sizeof (raid5_conf_t), GFP_KERNEL);
+ if ((conf = mddev->private) == NULL)
+ goto abort;
+ memset (conf, 0, sizeof (*conf));


+ conf->mddev = mddev;
+

+ if ((conf->stripe_hashtbl = (struct stripe_head **) md__get_free_pages(GFP_ATOMIC, HASH_PAGES_ORDER)) == NULL)
+ goto abort;
+ memset(conf->stripe_hashtbl, 0, HASH_PAGES * PAGE_SIZE);
+


+ conf->device_lock = MD_SPIN_LOCK_UNLOCKED;

+ md_init_waitqueue_head(&conf->wait_for_stripe);
+ PRINTK("raid5_run(md%d) called.\n", mdidx(mddev));
+
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ /*
+ * This is important -- we are using the descriptor on
+ * the disk only to get a pointer to the descriptor on
+ * the main superblock, which might be more recent.
+ */
+ desc = sb->disks + rdev->desc_nr;
+ raid_disk = desc->raid_disk;
+ disk = conf->disks + raid_disk;
+
+ if (disk_faulty(desc)) {
+ printk(KERN_ERR "raid5: disabled device %s (errors detected)\n", partition_name(rdev->dev));
+ if (!rdev->faulty) {


+ MD_BUG();
+ goto abort;

+ }
+ disk->number = desc->number;
+ disk->raid_disk = raid_disk;


+ disk->dev = rdev->dev;
+

+ disk->operational = 0;
+ disk->write_only = 0;
+ disk->spare = 0;
+ disk->used_slot = 1;

+ continue;
+ }
+ if (disk_active(desc)) {
+ if (!disk_sync(desc)) {
+ printk(KERN_ERR "raid5: disabled device %s (not in sync)\n", partition_name(rdev->dev));


+ MD_BUG();
+ goto abort;
+ }

+ if (raid_disk > sb->raid_disks) {
+ printk(KERN_ERR "raid5: disabled device %s (inconsistent descriptor)\n", partition_name(rdev->dev));


+ continue;
+ }
+ if (disk->operational) {

+ printk(KERN_ERR "raid5: disabled device %s (device %d already operational)\n", partition_name(rdev->dev), raid_disk);
+ continue;
+ }
+ printk(KERN_INFO "raid5: device %s operational as raid disk %d\n", partition_name(rdev->dev), raid_disk);
+
+ disk->number = desc->number;
+ disk->raid_disk = raid_disk;


+ disk->dev = rdev->dev;

+ disk->operational = 1;

+ disk->used_slot = 1;
+


+ conf->working_disks++;
+ } else {
+ /*
+ * Must be a spare disk ..
+ */

+ printk(KERN_INFO "raid5: spare disk %s\n", partition_name(rdev->dev));
+ disk->number = desc->number;
+ disk->raid_disk = raid_disk;


+ disk->dev = rdev->dev;
+

+ disk->operational = 0;
+ disk->write_only = 0;
+ disk->spare = 1;
+ disk->used_slot = 1;
+ }

+ }
+
+ for (i = 0; i < MD_SB_DISKS; i++) {

+ desc = sb->disks + i;

+ raid_disk = desc->raid_disk;
+ disk = conf->disks + raid_disk;
+
+ if (disk_faulty(desc) && (raid_disk < sb->raid_disks) &&
+ !conf->disks[raid_disk].used_slot) {
+
+ disk->number = desc->number;
+ disk->raid_disk = raid_disk;


+ disk->dev = MKDEV(0,0);
+
+ disk->operational = 0;
+ disk->write_only = 0;
+ disk->spare = 0;
+ disk->used_slot = 1;
+ }

+ }
+
+ conf->raid_disks = sb->raid_disks;

+ /*
+ * 0 for a fully functional array, 1 for a degraded array.
+ */
+ conf->failed_disks = conf->raid_disks - conf->working_disks;


+ conf->mddev = mddev;

+ conf->chunk_size = sb->chunk_size;
+ conf->level = sb->level;
+ conf->algorithm = sb->layout;
+ conf->max_nr_stripes = NR_STRIPES;
+
+#if 0
+ for (i = 0; i < conf->raid_disks; i++) {
+ if (!conf->disks[i].used_slot) {


+ MD_BUG();
+ goto abort;
+ }
+ }

+#endif
+ if (!conf->chunk_size || conf->chunk_size % 4) {
+ printk(KERN_ERR "raid5: invalid chunk size %d for md%d\n", conf->chunk_size, mdidx(mddev));
+ goto abort;
+ }
+ if (conf->algorithm > ALGORITHM_RIGHT_SYMMETRIC) {
+ printk(KERN_ERR "raid5: unsupported parity algorithm %d for md%d\n", conf->algorithm, mdidx(mddev));
+ goto abort;
+ }
+ if (conf->failed_disks > 1) {
+ printk(KERN_ERR "raid5: not enough operational devices for md%d (%d/%d failed)\n", mdidx(mddev), conf->failed_disks, conf->raid_disks);
+ goto abort;


+ }
+
+ if (conf->working_disks != sb->raid_disks) {

+ printk(KERN_ALERT "raid5: md%d, not all disks are operational -- trying to recover array\n", mdidx(mddev));


+ start_recovery = 1;
+ }
+

+ if (!start_recovery && (sb->state & (1 << MD_SB_CLEAN)) &&
+ check_consistency(mddev)) {
+ printk(KERN_ERR "raid5: detected raid-5 superblock xor inconsistency -- running resync\n");


+ sb->state &= ~(1 << MD_SB_CLEAN);
+ }
+
+ {

+ const char * name = "raid5d";
+
+ conf->thread = md_register_thread(raid5d, conf, name);
+ if (!conf->thread) {
+ printk(KERN_ERR "raid5: couldn't allocate thread for md%d\n", mdidx(mddev));


+ goto abort;
+ }
+ }
+

+ memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
+ conf->raid_disks * (sizeof(struct buffer_head) +
+ 2 * (sizeof(struct buffer_head) + PAGE_SIZE))) / 1024;
+ if (grow_stripes(conf, conf->max_nr_stripes, GFP_KERNEL)) {
+ printk(KERN_ERR "raid5: couldn't allocate %dkB for buffers\n", memory);
+ shrink_stripes(conf, conf->max_nr_stripes);
+ goto abort;
+ } else
+ printk(KERN_INFO "raid5: allocated %dkB for md%d\n", memory, mdidx(mddev));


+
+ /*
+ * Regenerate the "device is in sync with the raid set" bit for
+ * each device.
+ */
+ for (i = 0; i < MD_SB_DISKS ; i++) {
+ mark_disk_nonsync(sb->disks + i);
+ for (j = 0; j < sb->raid_disks; j++) {

+ if (!conf->disks[j].operational)
+ continue;
+ if (sb->disks[i].number == conf->disks[j].number)
+ mark_disk_sync(sb->disks + i);


+ }
+ }
+ sb->active_disks = conf->working_disks;
+

+ if (sb->active_disks == sb->raid_disks)

+ printk("raid5: raid level %d set md%d active with %d out of %d devices, algorithm %d\n", conf->level, mdidx(mddev), sb->active_disks, sb->raid_disks, conf->algorithm);
+ else
+ printk(KERN_ALERT "raid5: raid level %d set md%d active with %d out of %d devices, algorithm %d\n", conf->level, mdidx(mddev), sb->active_disks, sb->raid_disks, conf->algorithm);


+
+ if (!start_recovery && !(sb->state & (1 << MD_SB_CLEAN))) {

+ const char * name = "raid5syncd";
+
+ conf->resync_thread = md_register_thread(raid5syncd, conf,name);
+ if (!conf->resync_thread) {
+ printk(KERN_ERR "raid5: couldn't allocate thread for md%d\n", mdidx(mddev));


+ goto abort;
+ }
+

+ printk("raid5: raid set md%d not clean; reconstructing parity\n", mdidx(mddev));
+ conf->resync_parity = 1;


+ md_wakeup_thread(conf->resync_thread);
+ }
+

+ print_raid5_conf(conf);


+ if (start_recovery)
+ md_recover_arrays();

+ print_raid5_conf(conf);
+
+ /* Ok, everything is just fine now */
+ return (0);
+abort:
+ if (conf) {
+ print_raid5_conf(conf);
+ if (conf->stripe_hashtbl)
+ free_pages((unsigned long) conf->stripe_hashtbl,
+ HASH_PAGES_ORDER);
+ kfree(conf);
+ }


+ mddev->private = NULL;

+ printk(KERN_ALERT "raid5: failed to run raid set md%d\n", mdidx(mddev));


+ MOD_DEC_USE_COUNT;
+ return -EIO;
+}
+

+static int raid5_stop_resync (mddev_t *mddev)
+{
+ raid5_conf_t *conf = mddev_to_conf(mddev);
+ mdk_thread_t *thread = conf->resync_thread;
+
+ if (thread) {
+ if (conf->resync_parity) {
+ conf->resync_parity = 2;
+ md_interrupt_thread(thread);
+ printk(KERN_INFO "raid5: parity resync was not fully finished, restarting next time.\n");


+ return 1;
+ }
+ return 0;
+ }
+ return 0;
+}
+

+static int raid5_restart_resync (mddev_t *mddev)
+{
+ raid5_conf_t *conf = mddev_to_conf(mddev);
+
+ if (conf->resync_parity) {


+ if (!conf->resync_thread) {
+ MD_BUG();
+ return 0;
+ }

+ printk("raid5: waking up raid5resync.\n");
+ conf->resync_parity = 1;


+ md_wakeup_thread(conf->resync_thread);
+ return 1;

+ } else
+ printk("raid5: no restart-resync needed.\n");


+ return 0;
+}
+

+
+static int raid5_stop (mddev_t *mddev)


+{
+ raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
+

+ shrink_stripe_cache(conf, conf->max_nr_stripes);
+ shrink_stripes(conf, conf->max_nr_stripes);


+ md_unregister_thread(conf->thread);
+ if (conf->resync_thread)
+ md_unregister_thread(conf->resync_thread);

+ free_pages((unsigned long) conf->stripe_hashtbl, HASH_PAGES_ORDER);


+ kfree(conf);
+ mddev->private = NULL;
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+

+#if RAID5_DEBUG
+static void print_sh (struct stripe_head *sh)


+{
+ int i;
+

+ printk("sh %lu, phase %d, size %d, pd_idx %d, state %ld, cmd %d.\n", sh->sector, sh->phase, sh->size, sh->pd_idx, sh->state, sh->cmd);
+ printk("sh %lu, write_method %d, nr_pending %d, count %d.\n", sh->sector, sh->write_method, atomic_read(&sh->nr_pending), atomic_read(&sh->count));
+ printk("sh %lu, ", sh->sector);
+ for (i = 0; i < MD_SB_DISKS; i++) {


+ if (sh->bh_old[i])

+ printk("(old%d: %p) ", i, sh->bh_old[i]);


+ if (sh->bh_new[i])

+ printk("(new%d: %p) ", i, sh->bh_new[i]);
+ if (sh->bh_copy[i])
+ printk("(copy%d: %p) ", i, sh->bh_copy[i]);
+ if (sh->bh_req[i])
+ printk("(req%d: %p) ", i, sh->bh_req[i]);
+ }
+ printk("\n");
+ for (i = 0; i < MD_SB_DISKS; i++)
+ printk("%d(%d/%d) ", i, sh->cmd_new[i], sh->new[i]);


+ printk("\n");
+}
+

+static void printall (raid5_conf_t *conf)


+{
+ struct stripe_head *sh;

+ int i;
+
+ md_spin_lock_irq(&conf->device_lock);


+ for (i = 0; i < NR_HASH; i++) {

+ sh = conf->stripe_hashtbl[i];


+ for (; sh; sh = sh->hash_next) {

+ if (sh->raid_conf != conf)
+ continue;
+ print_sh(sh);
+ }


+ }
+ md_spin_unlock_irq(&conf->device_lock);
+

+ PRINTK("--- raid5d inactive\n");
+}
+#endif
+
+static int raid5_status (char *page, mddev_t *mddev)


+{
+ raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
+ mdp_super_t *sb = mddev->sb;

+ int sz = 0, i;
+

+ sz += sprintf (page+sz, " level %d, %dk chunk, algorithm %d", sb->level, sb->chunk_size >> 10, sb->layout);
+ sz += sprintf (page+sz, " [%d/%d] [", conf->raid_disks, conf->working_disks);


+ for (i = 0; i < conf->raid_disks; i++)

+ sz += sprintf (page+sz, "%s", conf->disks[i].operational ? "U" : "_");


+ sz += sprintf (page+sz, "]");

+#if RAID5_DEBUG
+#define D(x) \
+ sz += sprintf (page+sz, "<"#x":%d>", atomic_read(&conf->x))
+ D(nr_handle);
+ D(nr_stripes);
+ D(nr_hashed_stripes);
+ D(nr_locked_stripes);
+ D(nr_pending_stripes);
+ D(nr_cached_stripes);
+ D(nr_free_sh);
+ printall(conf);
+#endif
+ return sz;
+}


+
+static void print_raid5_conf (raid5_conf_t *conf)

+{
+ int i;
+ struct disk_info *tmp;
+
+ printk("RAID5 conf printout:\n");


+ if (!conf) {
+ printk("(conf==NULL)\n");

+ return;
+ }
+ printk(" --- rd:%d wd:%d fd:%d\n", conf->raid_disks,
+ conf->working_disks, conf->failed_disks);


+
+ for (i = 0; i < MD_SB_DISKS; i++) {

+ tmp = conf->disks + i;


+ printk(" disk %d, s:%d, o:%d, n:%d rd:%d us:%d dev:%s\n",
+ i, tmp->spare,tmp->operational,
+ tmp->number,tmp->raid_disk,tmp->used_slot,
+ partition_name(tmp->dev));

+ }
+}
+
+static int raid5_diskop(mddev_t *mddev, mdp_disk_t **d, int state)


+{
+ int err = 0;

+ int i, failed_disk=-1, spare_disk=-1, removed_disk=-1, added_disk=-1;

+ raid5_conf_t *conf = mddev->private;
+ struct disk_info *tmp, *sdisk, *fdisk, *rdisk, *adisk;


+ mdp_super_t *sb = mddev->sb;

+ mdp_disk_t *failed_desc, *spare_desc, *added_desc;
+

+ print_raid5_conf(conf);
+ md_spin_lock_irq(&conf->device_lock);
+ /*


+ * find the disk ...
+ */
+ switch (state) {
+
+ case DISKOP_SPARE_ACTIVE:

+
+ /*
+ * Find the failed disk within the RAID5 configuration ...
+ * (this can only be in the first conf->raid_disks part)
+ */


+ for (i = 0; i < conf->raid_disks; i++) {

+ tmp = conf->disks + i;


+ if ((!tmp->operational && !tmp->spare) ||
+ !tmp->used_slot) {
+ failed_disk = i;

+ break;
+ }
+ }


+ /*
+ * When we activate a spare disk we _must_ have a disk in
+ * the lower (active) part of the array to replace.
+ */
+ if ((failed_disk == -1) || (failed_disk >= conf->raid_disks)) {

+ MD_BUG();
+ err = 1;
+ goto abort;
+ }


+ /* fall through */
+
+ case DISKOP_SPARE_WRITE:
+ case DISKOP_SPARE_INACTIVE:

+
+ /*


+ * Find the spare disk ... (can only be in the 'high'
+ * area of the array)

+ */
+ for (i = conf->raid_disks; i < MD_SB_DISKS; i++) {
+ tmp = conf->disks + i;


+ if (tmp->spare && tmp->number == (*d)->number) {
+ spare_disk = i;

+ break;
+ }
+ }
+ if (spare_disk == -1) {
+ MD_BUG();


+ err = 1;
+ goto abort;

+ }
+ break;
+
+ case DISKOP_HOT_REMOVE_DISK:


+
+ for (i = 0; i < MD_SB_DISKS; i++) {

+ tmp = conf->disks + i;


+ if (tmp->used_slot && (tmp->number == (*d)->number)) {
+ if (tmp->operational) {

+ err = -EBUSY;


+ goto abort;
+ }
+ removed_disk = i;

+ break;
+ }
+ }
+ if (removed_disk == -1) {
+ MD_BUG();


+ err = 1;
+ goto abort;

+ }
+ break;
+
+ case DISKOP_HOT_ADD_DISK:
+
+ for (i = conf->raid_disks; i < MD_SB_DISKS; i++) {
+ tmp = conf->disks + i;


+ if (!tmp->used_slot) {
+ added_disk = i;

+ break;
+ }
+ }
+ if (added_disk == -1) {
+ MD_BUG();


+ err = 1;
+ goto abort;

+ }
+ break;
+ }
+

+ switch (state) {
+ /*
+ * Switch the spare disk to write-only mode:
+ */
+ case DISKOP_SPARE_WRITE:

+ if (conf->spare) {


+ MD_BUG();
+ err = 1;

+ goto abort;
+ }
+ sdisk = conf->disks + spare_disk;


+ sdisk->operational = 1;
+ sdisk->write_only = 1;

+ conf->spare = sdisk;


+ break;
+ /*
+ * Deactivate a spare disk:
+ */
+ case DISKOP_SPARE_INACTIVE:

+ sdisk = conf->disks + spare_disk;


+ sdisk->operational = 0;
+ sdisk->write_only = 0;

+ /*
+ * Was the spare being resynced?
+ */
+ if (conf->spare == sdisk)


+ conf->spare = NULL;

+ break;
+ /*
+ * Activate (mark read-write) the (now sync) spare disk,
+ * which means we switch it's 'raid position' (->raid_disk)

+ * with the failed disk. (only the first 'conf->raid_disks'


+ * slots are used for 'real' disks and we must preserve this
+ * property)
+ */
+ case DISKOP_SPARE_ACTIVE:

+ if (!conf->spare) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+ sdisk = conf->disks + spare_disk;
+ fdisk = conf->disks + failed_disk;


+
+ spare_desc = &sb->disks[sdisk->number];
+ failed_desc = &sb->disks[fdisk->number];
+
+ if (spare_desc != *d) {

+ MD_BUG();
+ err = 1;


+ goto abort;
+ }
+

+ if (spare_desc->raid_disk != sdisk->raid_disk) {

+ MD_BUG();
+ err = 1;


+ goto abort;
+ }
+

+ if (sdisk->raid_disk != spare_disk) {
+ MD_BUG();
+ err = 1;


+ goto abort;
+ }
+

+ if (failed_desc->raid_disk != fdisk->raid_disk) {

+ MD_BUG();
+ err = 1;


+ goto abort;
+ }
+

+ if (fdisk->raid_disk != failed_disk) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+
+ /*


+ * do the switch finally
+ */
+ xchg_values(*spare_desc, *failed_desc);
+ xchg_values(*fdisk, *sdisk);

+
+ /*


+ * (careful, 'failed' and 'spare' are switched from now on)

+ *


+ * we want to preserve linear numbering and we want to
+ * give the proper raid_disk number to the now activated
+ * disk. (this means we switch back these values)
+ */
+
+ xchg_values(spare_desc->raid_disk, failed_desc->raid_disk);
+ xchg_values(sdisk->raid_disk, fdisk->raid_disk);
+ xchg_values(spare_desc->number, failed_desc->number);
+ xchg_values(sdisk->number, fdisk->number);
+
+ *d = failed_desc;
+
+ if (sdisk->dev == MKDEV(0,0))
+ sdisk->used_slot = 0;

+
+ /*


+ * this really activates the spare.
+ */
+ fdisk->spare = 0;
+ fdisk->write_only = 0;

+
+ /*


+ * if we activate a spare, we definitely replace a
+ * non-operational disk slot in the 'low' area of
+ * the disk array.
+ */

+ conf->failed_disks--;
+ conf->working_disks++;


+ conf->spare = NULL;
+

+ break;
+
+ case DISKOP_HOT_REMOVE_DISK:
+ rdisk = conf->disks + removed_disk;


+
+ if (rdisk->spare && (removed_disk < conf->raid_disks)) {

+ MD_BUG();
+ err = 1;
+ goto abort;
+ }


+ rdisk->dev = MKDEV(0,0);
+ rdisk->used_slot = 0;

+
+ break;
+
+ case DISKOP_HOT_ADD_DISK:
+ adisk = conf->disks + added_disk;


+ added_desc = *d;
+
+ if (added_disk != added_desc->number) {

+ MD_BUG();
+ err = 1;


+ goto abort;
+ }
+

+ adisk->number = added_desc->number;
+ adisk->raid_disk = added_desc->raid_disk;
+ adisk->dev = MKDEV(added_desc->major,added_desc->minor);
+
+ adisk->operational = 0;
+ adisk->write_only = 0;
+ adisk->spare = 1;

+ adisk->used_slot = 1;
+
+
+ break;
+
+ default:
+ MD_BUG();

+ err = 1;
+ goto abort;
+ }
+abort:
+ md_spin_unlock_irq(&conf->device_lock);

+ print_raid5_conf(conf);


+ return err;
+}
+

+static mdk_personality_t raid5_personality=
+{
+ name: "raid5",
+ make_request: raid5_make_request,
+ run: raid5_run,
+ stop: raid5_stop,
+ status: raid5_status,
+ error_handler: raid5_error,
+ diskop: raid5_diskop,
+ stop_resync: raid5_stop_resync,
+ restart_resync: raid5_restart_resync,
+ sync_request: raid5_sync_request
+};
+
+int raid5_init (void)


+{
+ int err;
+

+ err = register_md_personality (RAID5, &raid5_personality);
+ if (err)
+ return err;
+
+ /*
+ * pick a XOR routine, runtime.
+ */
+ calibrate_xor_block();


+
+ return 0;
+}
+

+#ifdef MODULE
+int init_module (void)
+{

+ return raid5_init();


+}
+
+void cleanup_module (void)
+{

+ unregister_md_personality (RAID5);
+}
+#endif
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/md/xor.c linux/drivers/md/xor.c
--- v2.4.0-test8/linux/drivers/md/xor.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/md/xor.c Mon Aug 28 21:21:57 2000
@@ -0,0 +1,2728 @@
+/*
+ * xor.c : Multiple Devices driver for Linux
+ *
+ * Copyright (C) 1996, 1997, 1998, 1999 Ingo Molnar, Matti Aarnio, Jakub Jelinek
+ *
+ *
+ * optimized RAID-5 checksumming functions.


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * You should have received a copy of the GNU General Public License
+ * (for example /usr/src/linux/COPYING); if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */

+#include <linux/config.h>
+#define BH_TRACE 0
+#include <linux/module.h>
+#include <linux/raid/md.h>
+#ifdef __sparc_v9__
+#include <asm/head.h>
+#include <asm/asi.h>
+#include <asm/visasm.h>
+#endif
+
+/*
+ * we use the 'XOR function template' to register multiple xor
+ * functions runtime. The kernel measures their speed upon bootup
+ * and decides which one to use. (compile-time registration is
+ * not enough as certain CPU features like MMX can only be detected
+ * runtime)
+ *
+ * this architecture makes it pretty easy to add new routines
+ * that are faster on certain CPUs, without killing other CPU's
+ * 'native' routine. Although the current routines are belived
+ * to be the physically fastest ones on all CPUs tested, but
+ * feel free to prove me wrong and add yet another routine =B-)
+ * --mingo
+ */
+
+#define MAX_XOR_BLOCKS 5
+
+#define XOR_ARGS (unsigned int count, struct buffer_head **bh_ptr)
+
+typedef void (*xor_block_t) XOR_ARGS;
+xor_block_t xor_block = NULL;
+
+#ifndef __sparc_v9__
+
+struct xor_block_template;
+
+struct xor_block_template {
+ char * name;
+ xor_block_t xor_block;
+ int speed;
+ struct xor_block_template * next;
+};
+
+struct xor_block_template * xor_functions = NULL;
+
+#define XORBLOCK_TEMPLATE(x) \
+static void xor_block_##x XOR_ARGS; \
+static struct xor_block_template t_xor_block_##x = \
+ { #x, xor_block_##x, 0, NULL }; \
+static void xor_block_##x XOR_ARGS
+
+#ifdef __i386__
+
+#ifdef CONFIG_X86_XMM
+/*
+ * Cache avoiding checksumming functions utilizing KNI instructions
+ * Copyright (C) 1999 Zach Brown (with obvious credit due Ingo)
+ */
+
+XORBLOCK_TEMPLATE(pIII_kni)
+{
+ char xmm_save[16*4];
+ int cr0;
+ int lines = (bh_ptr[0]->b_size>>8);
+
+ __asm__ __volatile__ (
+ "movl %%cr0,%0 ;\n\t"
+ "clts ;\n\t"
+ "movups %%xmm0,(%1) ;\n\t"
+ "movups %%xmm1,0x10(%1) ;\n\t"
+ "movups %%xmm2,0x20(%1) ;\n\t"
+ "movups %%xmm3,0x30(%1) ;\n\t"
+ : "=r" (cr0)
+ : "r" (xmm_save)
+ : "memory" );
+
+#define OFFS(x) "8*("#x"*2)"
+#define PF0(x) \
+ " prefetcht0 "OFFS(x)"(%1) ;\n"
+#define LD(x,y) \
+ " movaps "OFFS(x)"(%1), %%xmm"#y" ;\n"
+#define ST(x,y) \
+ " movaps %%xmm"#y", "OFFS(x)"(%1) ;\n"
+#define PF1(x) \
+ " prefetchnta "OFFS(x)"(%2) ;\n"
+#define PF2(x) \
+ " prefetchnta "OFFS(x)"(%3) ;\n"
+#define PF3(x) \
+ " prefetchnta "OFFS(x)"(%4) ;\n"
+#define PF4(x) \
+ " prefetchnta "OFFS(x)"(%5) ;\n"
+#define PF5(x) \
+ " prefetchnta "OFFS(x)"(%6) ;\n"
+#define XO1(x,y) \
+ " xorps "OFFS(x)"(%2), %%xmm"#y" ;\n"
+#define XO2(x,y) \
+ " xorps "OFFS(x)"(%3), %%xmm"#y" ;\n"
+#define XO3(x,y) \
+ " xorps "OFFS(x)"(%4), %%xmm"#y" ;\n"
+#define XO4(x,y) \
+ " xorps "OFFS(x)"(%5), %%xmm"#y" ;\n"
+#define XO5(x,y) \
+ " xorps "OFFS(x)"(%6), %%xmm"#y" ;\n"
+
+ switch(count) {
+ case 2:
+ __asm__ __volatile__ (
+#undef BLOCK
+#define BLOCK(i) \
+ LD(i,0) \
+ LD(i+1,1) \
+ PF1(i) \
+ PF1(i+2) \
+ LD(i+2,2) \
+ LD(i+3,3) \
+ PF0(i+4) \
+ PF0(i+6) \
+ XO1(i,0) \
+ XO1(i+1,1) \
+ XO1(i+2,2) \
+ XO1(i+3,3) \
+ ST(i,0) \
+ ST(i+1,1) \
+ ST(i+2,2) \
+ ST(i+3,3) \
+
+
+ PF0(0)
+ PF0(2)
+
+ " .align 32,0x90 ;\n"
+ " 1: ;\n"
+
+ BLOCK(0)
+ BLOCK(4)
+ BLOCK(8)
+ BLOCK(12)
+
+ " addl $256, %1 ;\n"
+ " addl $256, %2 ;\n"
+ " decl %0 ;\n"
+ " jnz 1b ;\n"
+
+ :
+ : "r" (lines),
+ "r" (bh_ptr[0]->b_data),
+ "r" (bh_ptr[1]->b_data)
+ : "memory" );
+ break;
+ case 3:
+ __asm__ __volatile__ (
+#undef BLOCK
+#define BLOCK(i) \
+ PF1(i) \
+ PF1(i+2) \
+ LD(i,0) \
+ LD(i+1,1) \
+ LD(i+2,2) \
+ LD(i+3,3) \
+ PF2(i) \
+ PF2(i+2) \
+ PF0(i+4) \
+ PF0(i+6) \
+ XO1(i,0) \
+ XO1(i+1,1) \
+ XO1(i+2,2) \
+ XO1(i+3,3) \
+ XO2(i,0) \
+ XO2(i+1,1) \
+ XO2(i+2,2) \
+ XO2(i+3,3) \
+ ST(i,0) \
+ ST(i+1,1) \
+ ST(i+2,2) \
+ ST(i+3,3) \
+
+
+ PF0(0)
+ PF0(2)
+
+ " .align 32,0x90 ;\n"
+ " 1: ;\n"
+
+ BLOCK(0)
+ BLOCK(4)
+ BLOCK(8)
+ BLOCK(12)
+
+ " addl $256, %1 ;\n"
+ " addl $256, %2 ;\n"
+ " addl $256, %3 ;\n"
+ " decl %0 ;\n"
+ " jnz 1b ;\n"
+ :
+ : "r" (lines),
+ "r" (bh_ptr[0]->b_data),
+ "r" (bh_ptr[1]->b_data),
+ "r" (bh_ptr[2]->b_data)
+ : "memory" );


+ break;
+ case 4:

+ __asm__ __volatile__ (
+#undef BLOCK
+#define BLOCK(i) \
+ PF1(i) \
+ PF1(i+2) \
+ LD(i,0) \
+ LD(i+1,1) \
+ LD(i+2,2) \
+ LD(i+3,3) \
+ PF2(i) \
+ PF2(i+2) \
+ XO1(i,0) \
+ XO1(i+1,1) \
+ XO1(i+2,2) \
+ XO1(i+3,3) \
+ PF3(i) \
+ PF3(i+2) \
+ PF0(i+4) \
+ PF0(i+6) \
+ XO2(i,0) \
+ XO2(i+1,1) \
+ XO2(i+2,2) \
+ XO2(i+3,3) \
+ XO3(i,0) \
+ XO3(i+1,1) \
+ XO3(i+2,2) \
+ XO3(i+3,3) \
+ ST(i,0) \
+ ST(i+1,1) \
+ ST(i+2,2) \
+ ST(i+3,3) \
+
+
+ PF0(0)
+ PF0(2)
+
+ " .align 32,0x90 ;\n"
+ " 1: ;\n"
+
+ BLOCK(0)
+ BLOCK(4)
+ BLOCK(8)
+ BLOCK(12)
+
+ " addl $256, %1 ;\n"
+ " addl $256, %2 ;\n"
+ " addl $256, %3 ;\n"
+ " addl $256, %4 ;\n"
+ " decl %0 ;\n"
+ " jnz 1b ;\n"
+
+ :
+ : "r" (lines),
+ "r" (bh_ptr[0]->b_data),
+ "r" (bh_ptr[1]->b_data),
+ "r" (bh_ptr[2]->b_data),
+ "r" (bh_ptr[3]->b_data)
+ : "memory" );
+ break;
+ case 5:
+ __asm__ __volatile__ (
+#undef BLOCK
+#define BLOCK(i) \
+ PF1(i) \
+ PF1(i+2) \
+ LD(i,0) \
+ LD(i+1,1) \
+ LD(i+2,2) \
+ LD(i+3,3) \
+ PF2(i) \
+ PF2(i+2) \
+ XO1(i,0) \
+ XO1(i+1,1) \
+ XO1(i+2,2) \
+ XO1(i+3,3) \
+ PF3(i) \
+ PF3(i+2) \
+ XO2(i,0) \
+ XO2(i+1,1) \
+ XO2(i+2,2) \
+ XO2(i+3,3) \
+ PF4(i) \
+ PF4(i+2) \
+ PF0(i+4) \
+ PF0(i+6) \
+ XO3(i,0) \
+ XO3(i+1,1) \
+ XO3(i+2,2) \
+ XO3(i+3,3) \
+ XO4(i,0) \
+ XO4(i+1,1) \
+ XO4(i+2,2) \
+ XO4(i+3,3) \
+ ST(i,0) \
+ ST(i+1,1) \
+ ST(i+2,2) \
+ ST(i+3,3) \
+
+
+ PF0(0)
+ PF0(2)
+
+ " .align 32,0x90 ;\n"
+ " 1: ;\n"
+
+ BLOCK(0)
+ BLOCK(4)
+ BLOCK(8)
+ BLOCK(12)
+
+ " addl $256, %1 ;\n"
+ " addl $256, %2 ;\n"
+ " addl $256, %3 ;\n"
+ " addl $256, %4 ;\n"
+ " addl $256, %5 ;\n"
+ " decl %0 ;\n"
+ " jnz 1b ;\n"
+
+ :
+ : "r" (lines),
+ "r" (bh_ptr[0]->b_data),
+ "r" (bh_ptr[1]->b_data),
+ "r" (bh_ptr[2]->b_data),
+ "r" (bh_ptr[3]->b_data),
+ "r" (bh_ptr[4]->b_data)
+ : "memory");
+ break;
+ }
+
+ __asm__ __volatile__ (
+ "sfence ;\n\t"
+ "movups (%1),%%xmm0 ;\n\t"
+ "movups 0x10(%1),%%xmm1 ;\n\t"
+ "movups 0x20(%1),%%xmm2 ;\n\t"
+ "movups 0x30(%1),%%xmm3 ;\n\t"
+ "movl %0,%%cr0 ;\n\t"
+ :
+ : "r" (cr0), "r" (xmm_save)
+ : "memory" );
+}
+
+#undef OFFS
+#undef LD
+#undef ST
+#undef PF0
+#undef PF1
+#undef PF2
+#undef PF3
+#undef PF4
+#undef PF5
+#undef XO1
+#undef XO2
+#undef XO3
+#undef XO4
+#undef XO5
+#undef BLOCK
+
+#endif /* CONFIG_X86_XMM */
+
+/*
+ * high-speed RAID5 checksumming functions utilizing MMX instructions
+ * Copyright (C) 1998 Ingo Molnar
+ */
+XORBLOCK_TEMPLATE(pII_mmx)
+{
+ char fpu_save[108];
+ int lines = (bh_ptr[0]->b_size>>7);
+
+ if (!(current->flags & PF_USEDFPU))
+ __asm__ __volatile__ ( " clts;\n");
+
+ __asm__ __volatile__ ( " fsave %0; fwait\n"::"m"(fpu_save[0]) );
+
+#define LD(x,y) \
+ " movq 8*("#x")(%1), %%mm"#y" ;\n"
+#define ST(x,y) \
+ " movq %%mm"#y", 8*("#x")(%1) ;\n"
+#define XO1(x,y) \
+ " pxor 8*("#x")(%2), %%mm"#y" ;\n"
+#define XO2(x,y) \
+ " pxor 8*("#x")(%3), %%mm"#y" ;\n"
+#define XO3(x,y) \
+ " pxor 8*("#x")(%4), %%mm"#y" ;\n"
+#define XO4(x,y) \
+ " pxor 8*("#x")(%5), %%mm"#y" ;\n"
+
+ switch(count) {
+ case 2:
+ __asm__ __volatile__ (
+#undef BLOCK
+#define BLOCK(i) \
+ LD(i,0) \
+ LD(i+1,1) \
+ LD(i+2,2) \
+ LD(i+3,3) \
+ XO1(i,0) \
+ ST(i,0) \
+ XO1(i+1,1) \
+ ST(i+1,1) \
+ XO1(i+2,2) \
+ ST(i+2,2) \
+ XO1(i+3,3) \
+ ST(i+3,3)
+
+ " .align 32,0x90 ;\n"
+ " 1: ;\n"
+
+ BLOCK(0)
+ BLOCK(4)
+ BLOCK(8)
+ BLOCK(12)
+
+ " addl $128, %1 ;\n"
+ " addl $128, %2 ;\n"
+ " decl %0 ;\n"
+ " jnz 1b ;\n"
+ :
+ : "r" (lines),
+ "r" (bh_ptr[0]->b_data),
+ "r" (bh_ptr[1]->b_data)
+ : "memory");
+ break;
+ case 3:
+ __asm__ __volatile__ (
+#undef BLOCK
+#define BLOCK(i) \
+ LD(i,0) \
+ LD(i+1,1) \
+ LD(i+2,2) \
+ LD(i+3,3) \
+ XO1(i,0) \
+ XO1(i+1,1) \
+ XO1(i+2,2) \
+ XO1(i+3,3) \
+ XO2(i,0) \
+ ST(i,0) \
+ XO2(i+1,1) \
+ ST(i+1,1) \
+ XO2(i+2,2) \
+ ST(i+2,2) \
+ XO2(i+3,3) \
+ ST(i+3,3)
+
+ " .align 32,0x90 ;\n"
+ " 1: ;\n"
+
+ BLOCK(0)
+ BLOCK(4)
+ BLOCK(8)
+ BLOCK(12)
+
+ " addl $128, %1 ;\n"
+ " addl $128, %2 ;\n"
+ " addl $128, %3 ;\n"
+ " decl %0 ;\n"
+ " jnz 1b ;\n"
+ :
+ : "r" (lines),
+ "r" (bh_ptr[0]->b_data),
+ "r" (bh_ptr[1]->b_data),
+ "r" (bh_ptr[2]->b_data)
+ : "memory");


+ break;
+ case 4:

+ __asm__ __volatile__ (
+#undef BLOCK
+#define BLOCK(i) \
+ LD(i,0) \
+ LD(i+1,1) \
+ LD(i+2,2) \
+ LD(i+3,3) \
+ XO1(i,0) \
+ XO1(i+1,1) \
+ XO1(i+2,2) \
+ XO1(i+3,3) \
+ XO2(i,0) \
+ XO2(i+1,1) \
+ XO2(i+2,2) \
+ XO2(i+3,3) \
+ XO3(i,0) \
+ ST(i,0) \
+ XO3(i+1,1) \
+ ST(i+1,1) \
+ XO3(i+2,2) \
+ ST(i+2,2) \
+ XO3(i+3,3) \
+ ST(i+3,3)
+
+ " .align 32,0x90 ;\n"
+ " 1: ;\n"
+
+ BLOCK(0)
+ BLOCK(4)
+ BLOCK(8)
+ BLOCK(12)
+
+ " addl $128, %1 ;\n"
+ " addl $128, %2 ;\n"
+ " addl $128, %3 ;\n"
+ " addl $128, %4 ;\n"
+ " decl %0 ;\n"
+ " jnz 1b ;\n"
+ :
+ : "r" (lines),
+ "r" (bh_ptr[0]->b_data),
+ "r" (bh_ptr[1]->b_data),
+ "r" (bh_ptr[2]->b_data),
+ "r" (bh_ptr[3]->b_data)
+ : "memory");
+ break;
+ case 5:
+ __asm__ __volatile__ (
+#undef BLOCK
+#define BLOCK(i) \
+ LD(i,0) \
+ LD(i+1,1) \
+ LD(i+2,2) \
+ LD(i+3,3) \
+ XO1(i,0) \
+ XO1(i+1,1) \
+ XO1(i+2,2) \
+ XO1(i+3,3) \
+ XO2(i,0) \
+ XO2(i+1,1) \
+ XO2(i+2,2) \
+ XO2(i+3,3) \
+ XO3(i,0) \
+ XO3(i+1,1) \
+ XO3(i+2,2) \
+ XO3(i+3,3) \
+ XO4(i,0) \
+ ST(i,0) \
+ XO4(i+1,1) \
+ ST(i+1,1) \
+ XO4(i+2,2) \
+ ST(i+2,2) \
+ XO4(i+3,3) \
+ ST(i+3,3)
+
+ " .align 32,0x90 ;\n"
+ " 1: ;\n"
+
+ BLOCK(0)
+ BLOCK(4)
+ BLOCK(8)
+ BLOCK(12)
+
+ " addl $128, %1 ;\n"
+ " addl $128, %2 ;\n"
+ " addl $128, %3 ;\n"
+ " addl $128, %4 ;\n"
+ " addl $128, %5 ;\n"
+ " decl %0 ;\n"
+ " jnz 1b ;\n"
+ :
+ : "g" (lines),
+ "r" (bh_ptr[0]->b_data),
+ "r" (bh_ptr[1]->b_data),
+ "r" (bh_ptr[2]->b_data),
+ "r" (bh_ptr[3]->b_data),
+ "r" (bh_ptr[4]->b_data)
+ : "memory");
+ break;
+ }
+
+ __asm__ __volatile__ ( " frstor %0;\n"::"m"(fpu_save[0]) );
+
+ if (!(current->flags & PF_USEDFPU))
+ stts();
+}
+
+#undef LD
+#undef XO1
+#undef XO2
+#undef XO3
+#undef XO4
+#undef ST
+#undef BLOCK
+
+XORBLOCK_TEMPLATE(p5_mmx)
+{
+ char fpu_save[108];
+ int lines = (bh_ptr[0]->b_size>>6);
+
+ if (!(current->flags & PF_USEDFPU))
+ __asm__ __volatile__ ( " clts;\n");
+
+ __asm__ __volatile__ ( " fsave %0; fwait\n"::"m"(fpu_save[0]) );
+
+ switch(count) {
+ case 2:
+ __asm__ __volatile__ (
+
+ " .align 32,0x90 ;\n"
+ " 1: ;\n"
+ " movq (%1), %%mm0 ;\n"
+ " movq 8(%1), %%mm1 ;\n"
+ " pxor (%2), %%mm0 ;\n"
+ " movq 16(%1), %%mm2 ;\n"
+ " movq %%mm0, (%1) ;\n"
+ " pxor 8(%2), %%mm1 ;\n"
+ " movq 24(%1), %%mm3 ;\n"
+ " movq %%mm1, 8(%1) ;\n"
+ " pxor 16(%2), %%mm2 ;\n"
+ " movq 32(%1), %%mm4 ;\n"
+ " movq %%mm2, 16(%1) ;\n"
+ " pxor 24(%2), %%mm3 ;\n"
+ " movq 40(%1), %%mm5 ;\n"
+ " movq %%mm3, 24(%1) ;\n"
+ " pxor 32(%2), %%mm4 ;\n"
+ " movq 48(%1), %%mm6 ;\n"
+ " movq %%mm4, 32(%1) ;\n"
+ " pxor 40(%2), %%mm5 ;\n"
+ " movq 56(%1), %%mm7 ;\n"
+ " movq %%mm5, 40(%1) ;\n"
+ " pxor 48(%2), %%mm6 ;\n"
+ " pxor 56(%2), %%mm7 ;\n"
+ " movq %%mm6, 48(%1) ;\n"
+ " movq %%mm7, 56(%1) ;\n"
+
+ " addl $64, %1 ;\n"
+ " addl $64, %2 ;\n"
+ " decl %0 ;\n"
+ " jnz 1b ;\n"
+
+ :
+ : "r" (lines),
+ "r" (bh_ptr[0]->b_data),
+ "r" (bh_ptr[1]->b_data)
+ : "memory" );
+ break;
+ case 3:
+ __asm__ __volatile__ (
+
+ " .align 32,0x90 ;\n"
+ " 1: ;\n"
+ " movq (%1), %%mm0 ;\n"
+ " movq 8(%1), %%mm1 ;\n"
+ " pxor (%2), %%mm0 ;\n"
+ " movq 16(%1), %%mm2 ;\n"
+ " pxor 8(%2), %%mm1 ;\n"
+ " pxor (%3), %%mm0 ;\n"
+ " pxor 16(%2), %%mm2 ;\n"
+ " movq %%mm0, (%1) ;\n"
+ " pxor 8(%3), %%mm1 ;\n"
+ " pxor 16(%3), %%mm2 ;\n"
+ " movq 24(%1), %%mm3 ;\n"
+ " movq %%mm1, 8(%1) ;\n"
+ " movq 32(%1), %%mm4 ;\n"
+ " movq 40(%1), %%mm5 ;\n"
+ " pxor 24(%2), %%mm3 ;\n"
+ " movq %%mm2, 16(%1) ;\n"
+ " pxor 32(%2), %%mm4 ;\n"
+ " pxor 24(%3), %%mm3 ;\n"
+ " pxor 40(%2), %%mm5 ;\n"
+ " movq %%mm3, 24(%1) ;\n"
+ " pxor 32(%3), %%mm4 ;\n"
+ " pxor 40(%3), %%mm5 ;\n"
+ " movq 48(%1), %%mm6 ;\n"
+ " movq %%mm4, 32(%1) ;\n"
+ " movq 56(%1), %%mm7 ;\n"
+ " pxor 48(%2), %%mm6 ;\n"
+ " movq %%mm5, 40(%1) ;\n"
+ " pxor 56(%2), %%mm7 ;\n"
+ " pxor 48(%3), %%mm6 ;\n"
+ " pxor 56(%3), %%mm7 ;\n"
+ " movq %%mm6, 48(%1) ;\n"
+ " movq %%mm7, 56(%1) ;\n"
+
+ " addl $64, %1 ;\n"
+ " addl $64, %2 ;\n"
+ " addl $64, %3 ;\n"
+ " decl %0 ;\n"
+ " jnz 1b ;\n"
+
+ :
+ : "r" (lines),
+ "r" (bh_ptr[0]->b_data),
+ "r" (bh_ptr[1]->b_data),
+ "r" (bh_ptr[2]->b_data)
+ : "memory" );


+ break;
+ case 4:

+ __asm__ __volatile__ (
+
+ " .align 32,0x90 ;\n"
+ " 1: ;\n"
+ " movq (%1), %%mm0 ;\n"
+ " movq 8(%1), %%mm1 ;\n"
+ " pxor (%2), %%mm0 ;\n"
+ " movq 16(%1), %%mm2 ;\n"
+ " pxor 8(%2), %%mm1 ;\n"
+ " pxor (%3), %%mm0 ;\n"
+ " pxor 16(%2), %%mm2 ;\n"
+ " pxor 8(%3), %%mm1 ;\n"
+ " pxor (%4), %%mm0 ;\n"
+ " movq 24(%1), %%mm3 ;\n"
+ " pxor 16(%3), %%mm2 ;\n"
+ " pxor 8(%4), %%mm1 ;\n"
+ " movq %%mm0, (%1) ;\n"
+ " movq 32(%1), %%mm4 ;\n"
+ " pxor 24(%2), %%mm3 ;\n"


+ " pxor 16(%4), %%mm2 ;\n"

+ " movq %%mm1, 8(%1) ;\n"
+ " movq 40(%1), %%mm5 ;\n"
+ " pxor 32(%2), %%mm4 ;\n"
+ " pxor 24(%3), %%mm3 ;\n"
+ " movq %%mm2, 16(%1) ;\n"
+ " pxor 40(%2), %%mm5 ;\n"
+ " pxor 32(%3), %%mm4 ;\n"
+ " pxor 24(%4), %%mm3 ;\n"
+ " movq %%mm3, 24(%1) ;\n"
+ " movq 56(%1), %%mm7 ;\n"
+ " movq 48(%1), %%mm6 ;\n"
+ " pxor 40(%3), %%mm5 ;\n"
+ " pxor 32(%4), %%mm4 ;\n"
+ " pxor 48(%2), %%mm6 ;\n"
+ " movq %%mm4, 32(%1) ;\n"
+ " pxor 56(%2), %%mm7 ;\n"
+ " pxor 40(%4), %%mm5 ;\n"
+ " pxor 48(%3), %%mm6 ;\n"
+ " pxor 56(%3), %%mm7 ;\n"
+ " movq %%mm5, 40(%1) ;\n"
+ " pxor 48(%4), %%mm6 ;\n"
+ " pxor 56(%4), %%mm7 ;\n"
+ " movq %%mm6, 48(%1) ;\n"
+ " movq %%mm7, 56(%1) ;\n"
+
+ " addl $64, %1 ;\n"
+ " addl $64, %2 ;\n"
+ " addl $64, %3 ;\n"
+ " addl $64, %4 ;\n"
+ " decl %0 ;\n"
+ " jnz 1b ;\n"
+
+ :
+ : "r" (lines),
+ "r" (bh_ptr[0]->b_data),
+ "r" (bh_ptr[1]->b_data),
+ "r" (bh_ptr[2]->b_data),
+ "r" (bh_ptr[3]->b_data)
+ : "memory" );
+ break;
+ case 5:
+ __asm__ __volatile__ (
+
+ " .align 32,0x90 ;\n"
+ " 1: ;\n"
+ " movq (%1), %%mm0 ;\n"
+ " movq 8(%1), %%mm1 ;\n"
+ " pxor (%2), %%mm0 ;\n"
+ " pxor 8(%2), %%mm1 ;\n"
+ " movq 16(%1), %%mm2 ;\n"
+ " pxor (%3), %%mm0 ;\n"
+ " pxor 8(%3), %%mm1 ;\n"
+ " pxor 16(%2), %%mm2 ;\n"
+ " pxor (%4), %%mm0 ;\n"
+ " pxor 8(%4), %%mm1 ;\n"
+ " pxor 16(%3), %%mm2 ;\n"
+ " movq 24(%1), %%mm3 ;\n"
+ " pxor (%5), %%mm0 ;\n"
+ " pxor 8(%5), %%mm1 ;\n"
+ " movq %%mm0, (%1) ;\n"


+ " pxor 16(%4), %%mm2 ;\n"

+ " pxor 24(%2), %%mm3 ;\n"
+ " movq %%mm1, 8(%1) ;\n"


+ " pxor 16(%5), %%mm2 ;\n"

+ " pxor 24(%3), %%mm3 ;\n"
+ " movq 32(%1), %%mm4 ;\n"
+ " movq %%mm2, 16(%1) ;\n"


+ " pxor 24(%4), %%mm3 ;\n"

+ " pxor 32(%2), %%mm4 ;\n"
+ " movq 40(%1), %%mm5 ;\n"


+ " pxor 24(%5), %%mm3 ;\n"

+ " pxor 32(%3), %%mm4 ;\n"
+ " pxor 40(%2), %%mm5 ;\n"
+ " movq %%mm3, 24(%1) ;\n"
+ " pxor 32(%4), %%mm4 ;\n"
+ " pxor 40(%3), %%mm5 ;\n"
+ " movq 48(%1), %%mm6 ;\n"
+ " movq 56(%1), %%mm7 ;\n"
+ " pxor 32(%5), %%mm4 ;\n"
+ " pxor 40(%4), %%mm5 ;\n"
+ " pxor 48(%2), %%mm6 ;\n"
+ " pxor 56(%2), %%mm7 ;\n"
+ " movq %%mm4, 32(%1) ;\n"
+ " pxor 48(%3), %%mm6 ;\n"
+ " pxor 56(%3), %%mm7 ;\n"
+ " pxor 40(%5), %%mm5 ;\n"
+ " pxor 48(%4), %%mm6 ;\n"
+ " pxor 56(%4), %%mm7 ;\n"
+ " movq %%mm5, 40(%1) ;\n"
+ " pxor 48(%5), %%mm6 ;\n"
+ " pxor 56(%5), %%mm7 ;\n"
+ " movq %%mm6, 48(%1) ;\n"
+ " movq %%mm7, 56(%1) ;\n"
+
+ " addl $64, %1 ;\n"
+ " addl $64, %2 ;\n"
+ " addl $64, %3 ;\n"
+ " addl $64, %4 ;\n"
+ " addl $64, %5 ;\n"
+ " decl %0 ;\n"
+ " jnz 1b ;\n"
+
+ :
+ : "g" (lines),
+ "r" (bh_ptr[0]->b_data),
+ "r" (bh_ptr[1]->b_data),
+ "r" (bh_ptr[2]->b_data),
+ "r" (bh_ptr[3]->b_data),
+ "r" (bh_ptr[4]->b_data)
+ : "memory" );
+ break;
+ }
+
+ __asm__ __volatile__ ( " frstor %0;\n"::"m"(fpu_save[0]) );
+
+ if (!(current->flags & PF_USEDFPU))
+ stts();
+}
+#endif /* __i386__ */
+#endif /* !__sparc_v9__ */
+
+#ifdef __sparc_v9__
+/*
+ * High speed xor_block operation for RAID4/5 utilizing the
+ * UltraSparc Visual Instruction Set.
+ *
+ * Copyright (C) 1997, 1999 Jakub Jelinek (j...@ultra.linux.cz)
+ *
+ * Requirements:
+ * !(((long)dest | (long)sourceN) & (64 - 1)) &&
+ * !(len & 127) && len >= 256
+ *
+ * It is done in pure assembly, as otherwise gcc makes it
+ * a non-leaf function, which is not what we want.
+ * Also, we don't measure the speeds as on other architectures,
+ * as the measuring routine does not take into account cold caches
+ * and the fact that xor_block_VIS bypasses the caches.
+ * xor_block_32regs might be 5% faster for count 2 if caches are hot
+ * and things just right (for count 3 VIS is about as fast as 32regs for
+ * hot caches and for count 4 and 5 VIS is faster by good margin always),
+ * but I think it is better not to pollute the caches.
+ * Actually, if I'd just fight for speed for hot caches, I could
+ * write a hybrid VIS/integer routine, which would do always two
+ * 64B blocks in VIS and two in IEUs, but I really care more about
+ * caches.
+ */
+extern void *VISenter(void);
+extern void xor_block_VIS XOR_ARGS;
+
+void __xor_block_VIS(void)
+{
+__asm__ ("
+ .globl xor_block_VIS
+xor_block_VIS:
+ ldx [%%o1 + 0], %%o4
+ ldx [%%o1 + 8], %%o3
+ ldx [%%o4 + %1], %%g5
+ ldx [%%o4 + %0], %%o4
+ ldx [%%o3 + %0], %%o3
+ rd %%fprs, %%o5
+ andcc %%o5, %2, %%g0
+ be,pt %%icc, 297f
+ sethi %%hi(%5), %%g1
+ jmpl %%g1 + %%lo(%5), %%g7
+ add %%g7, 8, %%g7
+297: wr %%g0, %4, %%fprs
+ membar #LoadStore|#StoreLoad|#StoreStore
+ sub %%g5, 64, %%g5
+ ldda [%%o4] %3, %%f0
+ ldda [%%o3] %3, %%f16
+ cmp %%o0, 4
+ bgeu,pt %%xcc, 10f
+ cmp %%o0, 3
+ be,pn %%xcc, 13f
+ mov -64, %%g1
+ sub %%g5, 64, %%g5
+ rd %%asi, %%g1
+ wr %%g0, %3, %%asi
+
+2: ldda [%%o4 + 64] %%asi, %%f32
+ fxor %%f0, %%f16, %%f16
+ fxor %%f2, %%f18, %%f18
+ fxor %%f4, %%f20, %%f20
+ fxor %%f6, %%f22, %%f22
+ fxor %%f8, %%f24, %%f24
+ fxor %%f10, %%f26, %%f26
+ fxor %%f12, %%f28, %%f28
+ fxor %%f14, %%f30, %%f30
+ stda %%f16, [%%o4] %3
+ ldda [%%o3 + 64] %%asi, %%f48
+ ldda [%%o4 + 128] %%asi, %%f0
+ fxor %%f32, %%f48, %%f48
+ fxor %%f34, %%f50, %%f50
+ add %%o4, 128, %%o4
+ fxor %%f36, %%f52, %%f52
+ add %%o3, 128, %%o3
+ fxor %%f38, %%f54, %%f54
+ subcc %%g5, 128, %%g5
+ fxor %%f40, %%f56, %%f56
+ fxor %%f42, %%f58, %%f58
+ fxor %%f44, %%f60, %%f60
+ fxor %%f46, %%f62, %%f62
+ stda %%f48, [%%o4 - 64] %%asi
+ bne,pt %%xcc, 2b
+ ldda [%%o3] %3, %%f16
+
+ ldda [%%o4 + 64] %%asi, %%f32
+ fxor %%f0, %%f16, %%f16
+ fxor %%f2, %%f18, %%f18
+ fxor %%f4, %%f20, %%f20
+ fxor %%f6, %%f22, %%f22
+ fxor %%f8, %%f24, %%f24
+ fxor %%f10, %%f26, %%f26
+ fxor %%f12, %%f28, %%f28
+ fxor %%f14, %%f30, %%f30
+ stda %%f16, [%%o4] %3
+ ldda [%%o3 + 64] %%asi, %%f48
+ membar #Sync
+ fxor %%f32, %%f48, %%f48
+ fxor %%f34, %%f50, %%f50
+ fxor %%f36, %%f52, %%f52
+ fxor %%f38, %%f54, %%f54
+ fxor %%f40, %%f56, %%f56
+ fxor %%f42, %%f58, %%f58
+ fxor %%f44, %%f60, %%f60
+ fxor %%f46, %%f62, %%f62
+ stda %%f48, [%%o4 + 64] %%asi
+ membar #Sync|#StoreStore|#StoreLoad
+ wr %%g0, 0, %%fprs
+ retl
+ wr %%g1, %%g0, %%asi
+
+13: ldx [%%o1 + 16], %%o2
+ ldx [%%o2 + %0], %%o2
+
+3: ldda [%%o2] %3, %%f32
+ fxor %%f0, %%f16, %%f48
+ fxor %%f2, %%f18, %%f50
+ add %%o4, 64, %%o4
+ fxor %%f4, %%f20, %%f52
+ fxor %%f6, %%f22, %%f54
+ add %%o3, 64, %%o3
+ fxor %%f8, %%f24, %%f56
+ fxor %%f10, %%f26, %%f58
+ fxor %%f12, %%f28, %%f60
+ fxor %%f14, %%f30, %%f62
+ ldda [%%o4] %3, %%f0
+ fxor %%f48, %%f32, %%f48
+ fxor %%f50, %%f34, %%f50
+ fxor %%f52, %%f36, %%f52
+ fxor %%f54, %%f38, %%f54
+ add %%o2, 64, %%o2
+ fxor %%f56, %%f40, %%f56
+ fxor %%f58, %%f42, %%f58
+ subcc %%g5, 64, %%g5
+ fxor %%f60, %%f44, %%f60
+ fxor %%f62, %%f46, %%f62
+ stda %%f48, [%%o4 + %%g1] %3
+ bne,pt %%xcc, 3b
+ ldda [%%o3] %3, %%f16
+
+ ldda [%%o2] %3, %%f32
+ fxor %%f0, %%f16, %%f48
+ fxor %%f2, %%f18, %%f50
+ fxor %%f4, %%f20, %%f52
+ fxor %%f6, %%f22, %%f54
+ fxor %%f8, %%f24, %%f56
+ fxor %%f10, %%f26, %%f58
+ fxor %%f12, %%f28, %%f60
+ fxor %%f14, %%f30, %%f62
+ membar #Sync
+ fxor %%f48, %%f32, %%f48
+ fxor %%f50, %%f34, %%f50
+ fxor %%f52, %%f36, %%f52
+ fxor %%f54, %%f38, %%f54
+ fxor %%f56, %%f40, %%f56
+ fxor %%f58, %%f42, %%f58
+ fxor %%f60, %%f44, %%f60
+ fxor %%f62, %%f46, %%f62
+ stda %%f48, [%%o4] %3
+ membar #Sync|#StoreStore|#StoreLoad
+ retl
+ wr %%g0, 0, %%fprs
+
+10: cmp %%o0, 5
+ be,pt %%xcc, 15f
+ mov -64, %%g1
+
+14: ldx [%%o1 + 16], %%o2
+ ldx [%%o1 + 24], %%o0
+ ldx [%%o2 + %0], %%o2
+ ldx [%%o0 + %0], %%o0
+
+4: ldda [%%o2] %3, %%f32
+ fxor %%f0, %%f16, %%f16
+ fxor %%f2, %%f18, %%f18
+ add %%o4, 64, %%o4
+ fxor %%f4, %%f20, %%f20
+ fxor %%f6, %%f22, %%f22
+ add %%o3, 64, %%o3
+ fxor %%f8, %%f24, %%f24
+ fxor %%f10, %%f26, %%f26
+ fxor %%f12, %%f28, %%f28
+ fxor %%f14, %%f30, %%f30
+ ldda [%%o0] %3, %%f48
+ fxor %%f16, %%f32, %%f32
+ fxor %%f18, %%f34, %%f34
+ fxor %%f20, %%f36, %%f36
+ fxor %%f22, %%f38, %%f38


+ add %%o2, 64, %%o2

+ fxor %%f24, %%f40, %%f40
+ fxor %%f26, %%f42, %%f42
+ fxor %%f28, %%f44, %%f44
+ fxor %%f30, %%f46, %%f46


+ ldda [%%o4] %3, %%f0

+ fxor %%f32, %%f48, %%f48
+ fxor %%f34, %%f50, %%f50
+ fxor %%f36, %%f52, %%f52
+ add %%o0, 64, %%o0
+ fxor %%f38, %%f54, %%f54
+ fxor %%f40, %%f56, %%f56
+ fxor %%f42, %%f58, %%f58
+ subcc %%g5, 64, %%g5
+ fxor %%f44, %%f60, %%f60
+ fxor %%f46, %%f62, %%f62
+ stda %%f48, [%%o4 + %%g1] %3
+ bne,pt %%xcc, 4b
+ ldda [%%o3] %3, %%f16
+
+ ldda [%%o2] %3, %%f32
+ fxor %%f0, %%f16, %%f16
+ fxor %%f2, %%f18, %%f18
+ fxor %%f4, %%f20, %%f20
+ fxor %%f6, %%f22, %%f22
+ fxor %%f8, %%f24, %%f24
+ fxor %%f10, %%f26, %%f26
+ fxor %%f12, %%f28, %%f28
+ fxor %%f14, %%f30, %%f30
+ ldda [%%o0] %3, %%f48
+ fxor %%f16, %%f32, %%f32
+ fxor %%f18, %%f34, %%f34
+ fxor %%f20, %%f36, %%f36
+ fxor %%f22, %%f38, %%f38
+ fxor %%f24, %%f40, %%f40
+ fxor %%f26, %%f42, %%f42
+ fxor %%f28, %%f44, %%f44
+ fxor %%f30, %%f46, %%f46
+ membar #Sync
+ fxor %%f32, %%f48, %%f48
+ fxor %%f34, %%f50, %%f50
+ fxor %%f36, %%f52, %%f52
+ fxor %%f38, %%f54, %%f54
+ fxor %%f40, %%f56, %%f56
+ fxor %%f42, %%f58, %%f58
+ fxor %%f44, %%f60, %%f60
+ fxor %%f46, %%f62, %%f62
+ stda %%f48, [%%o4] %3
+ membar #Sync|#StoreStore|#StoreLoad
+ retl
+ wr %%g0, 0, %%fprs
+
+15: ldx [%%o1 + 16], %%o2
+ ldx [%%o1 + 24], %%o0
+ ldx [%%o1 + 32], %%o1
+ ldx [%%o2 + %0], %%o2
+ ldx [%%o0 + %0], %%o0
+ ldx [%%o1 + %0], %%o1
+
+5: ldda [%%o2] %3, %%f32
+ fxor %%f0, %%f16, %%f48
+ fxor %%f2, %%f18, %%f50
+ add %%o4, 64, %%o4
+ fxor %%f4, %%f20, %%f52
+ fxor %%f6, %%f22, %%f54
+ add %%o3, 64, %%o3
+ fxor %%f8, %%f24, %%f56
+ fxor %%f10, %%f26, %%f58
+ fxor %%f12, %%f28, %%f60
+ fxor %%f14, %%f30, %%f62
+ ldda [%%o0] %3, %%f16
+ fxor %%f48, %%f32, %%f48
+ fxor %%f50, %%f34, %%f50
+ fxor %%f52, %%f36, %%f52
+ fxor %%f54, %%f38, %%f54
+ add %%o2, 64, %%o2
+ fxor %%f56, %%f40, %%f56
+ fxor %%f58, %%f42, %%f58
+ fxor %%f60, %%f44, %%f60
+ fxor %%f62, %%f46, %%f62
+ ldda [%%o1] %3, %%f32
+ fxor %%f48, %%f16, %%f48
+ fxor %%f50, %%f18, %%f50
+ add %%o0, 64, %%o0
+ fxor %%f52, %%f20, %%f52
+ fxor %%f54, %%f22, %%f54
+ add %%o1, 64, %%o1
+ fxor %%f56, %%f24, %%f56
+ fxor %%f58, %%f26, %%f58
+ fxor %%f60, %%f28, %%f60
+ fxor %%f62, %%f30, %%f62
+ ldda [%%o4] %3, %%f0
+ fxor %%f48, %%f32, %%f48
+ fxor %%f50, %%f34, %%f50
+ fxor %%f52, %%f36, %%f52
+ fxor %%f54, %%f38, %%f54
+ fxor %%f56, %%f40, %%f56
+ fxor %%f58, %%f42, %%f58
+ subcc %%g5, 64, %%g5
+ fxor %%f60, %%f44, %%f60
+ fxor %%f62, %%f46, %%f62
+ stda %%f48, [%%o4 + %%g1] %3
+ bne,pt %%xcc, 5b
+ ldda [%%o3] %3, %%f16
+
+ ldda [%%o2] %3, %%f32
+ fxor %%f0, %%f16, %%f48
+ fxor %%f2, %%f18, %%f50
+ fxor %%f4, %%f20, %%f52
+ fxor %%f6, %%f22, %%f54
+ fxor %%f8, %%f24, %%f56
+ fxor %%f10, %%f26, %%f58
+ fxor %%f12, %%f28, %%f60
+ fxor %%f14, %%f30, %%f62
+ ldda [%%o0] %3, %%f16
+ fxor %%f48, %%f32, %%f48
+ fxor %%f50, %%f34, %%f50
+ fxor %%f52, %%f36, %%f52
+ fxor %%f54, %%f38, %%f54
+ fxor %%f56, %%f40, %%f56
+ fxor %%f58, %%f42, %%f58
+ fxor %%f60, %%f44, %%f60
+ fxor %%f62, %%f46, %%f62
+ ldda [%%o1] %3, %%f32
+ fxor %%f48, %%f16, %%f48
+ fxor %%f50, %%f18, %%f50
+ fxor %%f52, %%f20, %%f52
+ fxor %%f54, %%f22, %%f54
+ fxor %%f56, %%f24, %%f56
+ fxor %%f58, %%f26, %%f58
+ fxor %%f60, %%f28, %%f60
+ fxor %%f62, %%f30, %%f62
+ membar #Sync
+ fxor %%f48, %%f32, %%f48
+ fxor %%f50, %%f34, %%f50
+ fxor %%f52, %%f36, %%f52
+ fxor %%f54, %%f38, %%f54
+ fxor %%f56, %%f40, %%f56
+ fxor %%f58, %%f42, %%f58
+ fxor %%f60, %%f44, %%f60
+ fxor %%f62, %%f46, %%f62
+ stda %%f48, [%%o4] %3
+ membar #Sync|#StoreStore|#StoreLoad
+ retl
+ wr %%g0, 0, %%fprs
+ " : :
+ "i" (&((struct buffer_head *)0)->b_data),
+ "i" (&((struct buffer_head *)0)->b_size),
+ "i" (FPRS_FEF|FPRS_DU), "i" (ASI_BLK_P),
+ "i" (FPRS_FEF), "i" (VISenter));
+}
+#endif /* __sparc_v9__ */
+
+#if defined(__sparc__) && !defined(__sparc_v9__)
+/*
+ * High speed xor_block operation for RAID4/5 utilizing the
+ * ldd/std SPARC instructions.
+ *
+ * Copyright (C) 1999 Jakub Jelinek (j...@ultra.linux.cz)


+ *
+ */
+

+XORBLOCK_TEMPLATE(SPARC)
+{
+ int size = bh_ptr[0]->b_size;
+ int lines = size / (sizeof (long)) / 8, i;
+ long *destp = (long *) bh_ptr[0]->b_data;
+ long *source1 = (long *) bh_ptr[1]->b_data;
+ long *source2, *source3, *source4;
+
+ switch (count) {
+ case 2:
+ for (i = lines; i > 0; i--) {
+ __asm__ __volatile__("
+ ldd [%0 + 0x00], %%g2
+ ldd [%0 + 0x08], %%g4
+ ldd [%0 + 0x10], %%o0
+ ldd [%0 + 0x18], %%o2
+ ldd [%1 + 0x00], %%o4
+ ldd [%1 + 0x08], %%l0
+ ldd [%1 + 0x10], %%l2
+ ldd [%1 + 0x18], %%l4
+ xor %%g2, %%o4, %%g2
+ xor %%g3, %%o5, %%g3
+ xor %%g4, %%l0, %%g4
+ xor %%g5, %%l1, %%g5
+ xor %%o0, %%l2, %%o0
+ xor %%o1, %%l3, %%o1
+ xor %%o2, %%l4, %%o2
+ xor %%o3, %%l5, %%o3
+ std %%g2, [%0 + 0x00]
+ std %%g4, [%0 + 0x08]
+ std %%o0, [%0 + 0x10]
+ std %%o2, [%0 + 0x18]
+ " : : "r" (destp), "r" (source1) : "g2", "g3", "g4", "g5", "o0",
+ "o1", "o2", "o3", "o4", "o5", "l0", "l1", "l2", "l3", "l4", "l5");
+ destp += 8;
+ source1 += 8;
+ }
+ break;
+ case 3:
+ source2 = (long *) bh_ptr[2]->b_data;
+ for (i = lines; i > 0; i--) {
+ __asm__ __volatile__("
+ ldd [%0 + 0x00], %%g2
+ ldd [%0 + 0x08], %%g4
+ ldd [%0 + 0x10], %%o0
+ ldd [%0 + 0x18], %%o2
+ ldd [%1 + 0x00], %%o4
+ ldd [%1 + 0x08], %%l0
+ ldd [%1 + 0x10], %%l2
+ ldd [%1 + 0x18], %%l4
+ xor %%g2, %%o4, %%g2
+ xor %%g3, %%o5, %%g3
+ ldd [%2 + 0x00], %%o4
+ xor %%g4, %%l0, %%g4
+ xor %%g5, %%l1, %%g5
+ ldd [%2 + 0x08], %%l0
+ xor %%o0, %%l2, %%o0
+ xor %%o1, %%l3, %%o1
+ ldd [%2 + 0x10], %%l2
+ xor %%o2, %%l4, %%o2
+ xor %%o3, %%l5, %%o3
+ ldd [%2 + 0x18], %%l4
+ xor %%g2, %%o4, %%g2
+ xor %%g3, %%o5, %%g3
+ xor %%g4, %%l0, %%g4
+ xor %%g5, %%l1, %%g5
+ xor %%o0, %%l2, %%o0
+ xor %%o1, %%l3, %%o1
+ xor %%o2, %%l4, %%o2
+ xor %%o3, %%l5, %%o3
+ std %%g2, [%0 + 0x00]
+ std %%g4, [%0 + 0x08]
+ std %%o0, [%0 + 0x10]
+ std %%o2, [%0 + 0x18]
+ " : : "r" (destp), "r" (source1), "r" (source2)
+ : "g2", "g3", "g4", "g5", "o0", "o1", "o2", "o3", "o4", "o5",
+ "l0", "l1", "l2", "l3", "l4", "l5");
+ destp += 8;
+ source1 += 8;
+ source2 += 8;
+ }


+ break;
+ case 4:

+ source2 = (long *) bh_ptr[2]->b_data;
+ source3 = (long *) bh_ptr[3]->b_data;
+ for (i = lines; i > 0; i--) {
+ __asm__ __volatile__("
+ ldd [%0 + 0x00], %%g2
+ ldd [%0 + 0x08], %%g4
+ ldd [%0 + 0x10], %%o0
+ ldd [%0 + 0x18], %%o2
+ ldd [%1 + 0x00], %%o4
+ ldd [%1 + 0x08], %%l0
+ ldd [%1 + 0x10], %%l2
+ ldd [%1 + 0x18], %%l4
+ xor %%g2, %%o4, %%g2
+ xor %%g3, %%o5, %%g3
+ ldd [%2 + 0x00], %%o4
+ xor %%g4, %%l0, %%g4
+ xor %%g5, %%l1, %%g5
+ ldd [%2 + 0x08], %%l0
+ xor %%o0, %%l2, %%o0
+ xor %%o1, %%l3, %%o1
+ ldd [%2 + 0x10], %%l2
+ xor %%o2, %%l4, %%o2
+ xor %%o3, %%l5, %%o3
+ ldd [%2 + 0x18], %%l4
+ xor %%g2, %%o4, %%g2
+ xor %%g3, %%o5, %%g3
+ ldd [%3 + 0x00], %%o4
+ xor %%g4, %%l0, %%g4


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 059'
echo 'File patch-2.4.0-test9 is continued in part 060'
echo "060" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part063

#!/bin/sh -x
# this is part 063 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 063; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

X {
- struct net_device_stats *stats = (struct net_device_stats *) dev->priv;
- return stats;


-}
-
-#ifdef MODULE
-

-static int __init dummy_probe(struct net_device *dev)
-{
- dummy_init(dev);
- return 0;
+ return dev->priv;
X }
X
-static struct net_device dev_dummy = {
- "",


- 0, 0, 0, 0,
- 0x0, 0,

- 0, 0, 0, NULL, dummy_probe };
+static struct net_device dev_dummy = { init: dummy_init };
X
-int init_module(void)
+static int __init dummy_init_module(void)
X {
X /* Find a name for this unit */
X int err=dev_alloc_name(&dev_dummy,"dummy%d");
@@ -150,10 +120,14 @@


X return 0;
X }
X
-void cleanup_module(void)

+static void __exit dummy_cleanup_module(void)
X {
X unregister_netdev(&dev_dummy);
X kfree(dev_dummy.priv);
- dev_dummy.priv = NULL;
+
+ memset(&dev_dummy, 0, sizeof(dev_dummy));
+ dev_dummy.init = dummy_init;


X }
-#endif /* MODULE */
+

+module_init(dummy_init_module);
+module_exit(dummy_cleanup_module);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/eepro100.c linux/drivers/net/eepro100.c
--- v2.4.0-test8/linux/drivers/net/eepro100.c Fri Aug 11 19:14:46 2000
+++ linux/drivers/net/eepro100.c Wed Sep 20 21:57:26 2000
@@ -2273,6 +2273,8 @@
X PCI_ANY_ID, PCI_ANY_ID, },
X { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1030,
X PCI_ANY_ID, PCI_ANY_ID, },
+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82820FW_4,
+ PCI_ANY_ID, PCI_ANY_ID, },
X { 0,}
X };
X MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/eexpress.c linux/drivers/net/eexpress.c
--- v2.4.0-test8/linux/drivers/net/eexpress.c Mon Jun 19 13:30:58 2000
+++ linux/drivers/net/eexpress.c Sun Sep 17 09:41:29 2000
@@ -1084,6 +1084,7 @@
X return -ENOMEM;
X
X memset(dev->priv, 0, sizeof(struct net_local));
+ spin_lock_init(&lp->lock);
X
X printk("(IRQ %d, %s connector, %d-bit bus", dev->irq,
X eexp_ifmap[dev->if_port], buswidth?8:16);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/epic100.c linux/drivers/net/epic100.c
--- v2.4.0-test8/linux/drivers/net/epic100.c Fri Sep 8 12:34:55 2000
+++ linux/drivers/net/epic100.c Sun Sep 10 13:21:13 2000
@@ -33,9 +33,9 @@
X LK1.1.4 (jgarzik):
X * Merge becker test version 1.09 (5/29/2000)
X
- LK1.1.5 (jgarzik):
- * Fix locking
- * Limit 83c175 probe to ethernet-class PCI devices
+ LK1.1.5:
+ * Fix locking (jgarzik)
+ * Limit 83c175 probe to ethernet-class PCI devices (rgooch)
X
X */
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/eql.c linux/drivers/net/eql.c
--- v2.4.0-test8/linux/drivers/net/eql.c Mon Mar 13 09:50:16 2000
+++ linux/drivers/net/eql.c Fri Sep 22 14:21:16 2000
@@ -113,32 +113,18 @@
X */
X
X #include <linux/module.h>


-
X #include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/malloc.h>
-#include <linux/string.h>

-#include <asm/system.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <asm/dma.h>

-#include <asm/uaccess.h>
-#include <linux/errno.h>
X #include <linux/init.h>
-
+#include <linux/timer.h>
X #include <linux/netdevice.h>
+
X #include <linux/if.h>
X #include <linux/if_arp.h>
-#include <linux/timer.h>
-
X #include <linux/if_eql.h>
X
+#include <asm/uaccess.h>
+
+
X #ifndef EQL_DEBUG
X /* #undef EQL_DEBUG -* print nothing at all, not even a boot-banner */
X /* #define EQL_DEBUG 1 -* print only the boot-banner */
@@ -150,7 +136,7 @@
X #endif
X static unsigned int eql_debug = EQL_DEBUG;
X
-int eql_init(struct net_device *dev); /* */
+static int eql_init(struct net_device *dev); /* */
X static int eql_open(struct net_device *dev); /* */
X static int eql_close(struct net_device *dev); /* */
X static int eql_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); /* */
@@ -209,7 +195,7 @@
X ---------------------------------------------------------
X */
X
-int __init eql_init(struct net_device *dev)
+static int __init eql_init(struct net_device *dev)


X {
X static unsigned version_printed = 0;

X /* static unsigned num_masters = 0; */
@@ -273,6 +259,8 @@
X equalizer_t *eql = (equalizer_t *) dev->priv;
X slave_queue_t *new_queue;
X
+ MOD_INC_USE_COUNT;
+
X #ifdef EQL_DEBUG
X if (eql_debug >= 5)
X printk ("%s: open\n", dev->name);
@@ -294,10 +282,10 @@
X eql->timer_on = 1;
X add_timer (&eql->timer);
X
- MOD_INC_USE_COUNT;
X return 0;
X }
- return 1;


+ MOD_DEC_USE_COUNT;
+ return -ENOMEM;

X }
X
X
@@ -409,16 +397,14 @@
X struct net_device *master_dev;
X struct net_device *slave_dev;
X slaving_request_t srq;
- int err;
X
- err = copy_from_user(&srq, srqp, sizeof (slaving_request_t));
- if (err)
+ if (copy_from_user(&srq, srqp, sizeof (slaving_request_t)))
X {
X #ifdef EQL_DEBUG
X if (eql_debug >= 20)
X printk ("EQL enslave: error detected by copy_from_user\n");
X #endif
- return err;
+ return -EFAULT;
X }
X
X #ifdef EQL_DEBUG
@@ -470,11 +456,9 @@
X struct net_device *master_dev;
X struct net_device *slave_dev;
X slaving_request_t srq;
- int err;
X
- err = copy_from_user(&srq, srqp, sizeof (slaving_request_t));


- if (err)
- return err;

+ if (copy_from_user(&srq, srqp, sizeof (slaving_request_t)))
+ return -EFAULT;
X
X #ifdef EQL_DEBUG
X if (eql_debug >= 20)
@@ -500,11 +484,9 @@
X equalizer_t *eql;
X struct net_device *slave_dev;
X slave_config_t sc;
- int err;
X
- err = copy_from_user (&sc, scp, sizeof (slave_config_t));


- if (err)
- return err;

+ if (copy_from_user (&sc, scp, sizeof (slave_config_t)))
+ return -EFAULT;
X
X #ifdef EQL_DEBUG
X if (eql_debug >= 20)
@@ -519,10 +501,8 @@
X if (slave != 0)
X {
X sc.priority = slave->priority;
- err = verify_area(VERIFY_WRITE, (void *)scp, sizeof (slave_config_t));


- if (err)
- return err;

- copy_to_user (scp, &sc, sizeof (slave_config_t));
+ if (copy_to_user (scp, &sc, sizeof (slave_config_t)))
+ return -EFAULT;


X return 0;
X }
X }

@@ -536,11 +516,9 @@
X equalizer_t *eql;
X struct net_device *slave_dev;
X slave_config_t sc;
- int err;
X
- err = copy_from_user (&sc, scp, sizeof (slave_config_t));


- if (err)
- return err;

+ if (copy_from_user (&sc, scp, sizeof (slave_config_t)))
+ return -EFAULT;
X
X #ifdef EQL_DEBUG
X if (eql_debug >= 20)
@@ -578,13 +556,11 @@
X
X if ( eql_is_master (dev) )
X {
- int err;
X eql = (equalizer_t *) dev->priv;
X mc.max_slaves = eql->max_slaves;
X mc.min_slaves = eql->min_slaves;
- err = copy_to_user (mcp, &mc, sizeof (master_config_t));


- if (err)
- return err;

+ if (copy_to_user (mcp, &mc, sizeof (master_config_t)))
+ return -EFAULT;
X return 0;
X }
X return -EINVAL;
@@ -595,11 +571,9 @@
X {
X equalizer_t *eql;
X master_config_t mc;
- int err;
X
- err = copy_from_user (&mc, mcp, sizeof (master_config_t));


- if (err)
- return err;

+ if (copy_from_user (&mc, mcp, sizeof (master_config_t)))
+ return -EFAULT;
X #if EQL_DEBUG
X if (eql_debug >= 20)
X printk ("%s: set master config\n", dev->name);
@@ -646,11 +620,8 @@
X
X slave = (slave_t *) kmalloc (sizeof (slave_t), GFP_KERNEL);
X if (slave)
- {
X memset(slave, 0, sizeof (slave_t));
- return slave;
- }
- return 0;
+ return slave;
X }
X
X
@@ -702,31 +673,32 @@
X slave_t *tail_slave;
X
X queue = (slave_queue_t *) kmalloc (sizeof (slave_queue_t), GFP_KERNEL);
- if (queue == NULL)
- return 0;
- memset (queue, 0, sizeof (slave_queue_t));
+ if (!queue)
+ goto err_out;
+
X head_slave = eql_new_slave ();
+ if (!head_slave)
+ goto err_out_queue;
+
X tail_slave = eql_new_slave ();
+ if (!tail_slave)
+ goto err_out_hs;
X
- if ( head_slave != 0 &&
- tail_slave != 0 )
- {
- head_slave->next = tail_slave;
- tail_slave->next = 0;
- queue->head = head_slave;
- queue->num_slaves = 0;
- queue->master_dev = dev;
- }
- else
- {
- if (head_slave)
- kfree(head_slave);
- if (tail_slave)
- kfree(tail_slave);
- kfree (queue);
- return 0;
- }
+ memset (queue, 0, sizeof (slave_queue_t));
+
+ head_slave->next = tail_slave;
+ tail_slave->next = 0;
+ queue->head = head_slave;
+ queue->num_slaves = 0;
+ queue->master_dev = dev;
X return queue;
+
+err_out_hs:
+ kfree (head_slave);
+err_out_queue:
+ kfree (queue);
+err_out:
+ return NULL;
X }
X
X
@@ -1013,13 +985,13 @@


X }
X }
X
-#ifdef MODULE

X static struct net_device dev_eql =
X {
- "eql", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, eql_init
+ name: "eql",
+ init: eql_init,
X };
X
-int init_module(void)
+static int __init eql_init_module(void)
X {
X if (register_netdev(&dev_eql) != 0) {
X printk("eql: register_netdev() returned non-zero.\n");
@@ -1028,13 +1000,15 @@


X return 0;
X }
X
-void cleanup_module(void)

+static void __exit eql_cleanup_module(void)
X {
X kfree(((equalizer_t *)dev_eql.priv)->stats );
X kfree(dev_eql.priv);
X unregister_netdev(&dev_eql);


X }
-#endif /* MODULE */
+

+module_init(eql_init_module);
+module_exit(eql_cleanup_module);
X
X /*
X * Local Variables:
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/gmac.c linux/drivers/net/gmac.c
--- v2.4.0-test8/linux/drivers/net/gmac.c Wed Aug 9 13:49:29 2000
+++ linux/drivers/net/gmac.c Sun Sep 17 09:48:05 2000
@@ -9,10 +9,15 @@
X * Changes:
X * Arnaldo Carvalho de Melo <ac...@conectiva.com.br> - 08/06/2000
X * - check init_etherdev return in gmac_probe1
+ * BenH <bh...@calva.net> - 03/09/2000
+ * - Add support for new PHYs
+ * - Add some PowerBook sleep code
X *
X */
X
X #include <linux/module.h>
+
+#include <linux/config.h>
X #include <linux/kernel.h>
X #include <linux/sched.h>
X #include <linux/types.h>
@@ -29,13 +34,19 @@
X #include <asm/io.h>
X #include <asm/pgtable.h>
X #include <asm/feature.h>
+#include <asm/keylargo.h>
+#ifdef CONFIG_PMAC_PBOOK
+#include <linux/adb.h>
+#include <linux/pmu.h>
+#include <asm/irq.h>
+#endif
X
X #include "gmac.h"
X
X #define DEBUG_PHY
X
-/* Driver version 1.1, kernel 2.4.x */
-#define GMAC_VERSION "v1.1k4"
+/* Driver version 1.2, kernel 2.4.x */
+#define GMAC_VERSION "v1.2k4"
X
X static unsigned char dummy_buf[RX_BUF_ALLOC_SIZE + RX_OFFSET + GMAC_BUFFER_ALIGN];
X static struct net_device *gmacs = NULL;
@@ -48,9 +59,12 @@
X static void mii_interrupt(struct gmac *gm);
X static int mii_lookup_and_reset(struct gmac *gm);
X static void mii_setup_phy(struct gmac *gm);
+static int mii_do_reset_phy(struct gmac *gm, int phy_addr);
+static void mii_init_BCM5400(struct gmac *gm);
X
X static void gmac_set_power(struct gmac *gm, int power_up);
X static int gmac_powerup_and_reset(struct net_device *dev);
+static void gmac_set_gigabit_mode(struct gmac *gm, int gigabit);
X static void gmac_set_duplex_mode(struct gmac *gm, int full_duplex);
X static void gmac_mac_init(struct gmac *gm, unsigned char *mac_addr);
X static void gmac_init_rings(struct gmac *gm, int from_irq);
@@ -71,6 +85,13 @@
X extern int pci_device_loc(struct device_node *dev, unsigned char *bus_ptr,
X unsigned char *devfn_ptr);
X
+#ifdef CONFIG_PMAC_PBOOK
+int gmac_sleep_notify(struct pmu_sleep_notifier *self, int when);
+static struct pmu_sleep_notifier gmac_sleep_notifier = {
+ gmac_sleep_notify, SLEEP_LEVEL_NET,
+};
+#endif
+
X /*
X * Read via the mii interface from a PHY register
X */
@@ -161,6 +182,19 @@
X * a timer and control the autoneg. process more closely. Also, we may
X * want to stop rx and tx side when the link is down.
X */
+
+/* Link modes of the BCM5400 PHY */
+static int phy_BCM5400_link_table[8][3] = {
+ { 0, 0, 0 }, /* No link */
+ { 0, 0, 0 }, /* 10BT Half Duplex */
+ { 1, 0, 0 }, /* 10BT Full Duplex */
+ { 0, 1, 0 }, /* 100BT Half Duplex */
+ { 0, 1, 0 }, /* 100BT Half Duplex */
+ { 1, 1, 0 }, /* 100BT Full Duplex*/
+ { 1, 0, 1 }, /* 1000BT */
+ { 1, 0, 1 }, /* 1000BT */


+};
+
X static void

X mii_interrupt(struct gmac *gm)


X {
@@ -175,8 +209,9 @@

X /* We read the Auxilliary Status Summary register */
X phy_status = mii_read(gm, gm->phy_addr, MII_SR);
X if ((phy_status ^ gm->phy_status) & (MII_SR_ASSC | MII_SR_LKS)) {
- int full_duplex;
- int link_100;
+ int full_duplex = 0;
+ int link_100 = 0;
+ int gigabit = 0;
X #ifdef DEBUG_PHY
X printk("Link state change, phy_status: 0x%04x\n", phy_status);
X #endif
@@ -188,8 +223,9 @@
X else
X GM_BIC(GM_MAC_CTRL_CONFIG, GM_MAC_CTRL_CONF_SND_PAUSE_EN);
X
- /* Link ? For now we handle only the 5201 PHY */
+ /* Link ? Check for speed and duplex */
X if ((phy_status & MII_SR_LKS) && (phy_status & MII_SR_ASSC)) {
+ int restart = 0;
X if (gm->phy_type == PHY_B5201) {
X int aux_stat = mii_read(gm, gm->phy_addr, MII_BCM5201_AUXCTLSTATUS);
X #ifdef DEBUG_PHY
@@ -197,19 +233,41 @@
X #endif
X full_duplex = ((aux_stat & MII_BCM5201_AUXCTLSTATUS_DUPLEX) != 0);
X link_100 = ((aux_stat & MII_BCM5201_AUXCTLSTATUS_SPEED) != 0);
- } else {
- full_duplex = 1;
- link_100 = 1;
+ } else if (gm->phy_type == PHY_B5400) {
+ int aux_stat = mii_read(gm, gm->phy_addr, MII_BCM5400_AUXSTATUS);
+ int link = (aux_stat & MII_BCM5400_AUXSTATUS_LINKMODE_MASK) >>
+ MII_BCM5400_AUXSTATUS_LINKMODE_SHIFT;
+#ifdef DEBUG_PHY
+ printk(" Link up ! BCM5400 aux_stat: 0x%04x (link mode: %d)\n",
+ aux_stat, link);
+#endif
+ full_duplex = phy_BCM5400_link_table[link][0];
+ link_100 = phy_BCM5400_link_table[link][1];
+ gigabit = phy_BCM5400_link_table[link][2];
+ } else if (gm->phy_type == PHY_LXT971) {
+ int stat2 = mii_read(gm, gm->phy_addr, MII_LXT971_STATUS2);
+#ifdef DEBUG_PHY
+ printk(" Link up ! LXT971 stat2: 0x%04x\n", stat2);
+#endif
+ full_duplex = ((stat2 & MII_LXT971_STATUS2_FULLDUPLEX) != 0);
+ link_100 = ((stat2 & MII_LXT971_STATUS2_SPEED) != 0);
X }
X #ifdef DEBUG_PHY
X printk(" full_duplex: %d, speed: %s\n", full_duplex,
- link_100 ? "100" : "10");
+ gigabit ? "1000" : (link_100 ? "100" : "10"));
X #endif
+ if (gigabit != gm->gigabit) {
+ gm->gigabit = gigabit;
+ gmac_set_gigabit_mode(gm, gm->gigabit);
+ restart = 1;
+ }
X if (full_duplex != gm->full_duplex) {
X gm->full_duplex = full_duplex;
X gmac_set_duplex_mode(gm, gm->full_duplex);
- gmac_start_dma(gm);
+ restart = 1;
X }
+ if (restart)
+ gmac_start_dma(gm);
X } else if (!(phy_status & MII_SR_LKS)) {
X #ifdef DEBUG_PHY
X printk(" Link down !\n");
@@ -218,19 +276,73 @@
X }
X }
X
-/*
- * Lookup for a PHY on the mii interface and reset it
- */
+static int
+mii_do_reset_phy(struct gmac *gm, int phy_addr)
+{
+ int mii_control, timeout;
+
+ mii_control = mii_read(gm, phy_addr, MII_CR);
+ mii_write(gm, phy_addr, MII_CR, mii_control | MII_CR_RST);
+ mdelay(10);
+ for (timeout = 100; timeout > 0; --timeout) {
+ mii_control = mii_read(gm, phy_addr, MII_CR);
+ if (mii_control == -1) {
+ printk(KERN_ERR "%s PHY died after reset !\n",
+ gm->dev->name);
+ return 1;
+ }
+ if ((mii_control & MII_CR_RST) == 0)
+ break;
+ mdelay(10);
+ }
+ if (mii_control & MII_CR_RST) {
+ printk(KERN_ERR "%s PHY reset timeout !\n", gm->dev->name);
+ return 1;
+ }
+ mii_write(gm, phy_addr, MII_CR, mii_control & ~MII_CR_ISOL);


+ return 0;
+}
+

+static void
+mii_init_BCM5400(struct gmac *gm)
+{
+ int data;
+
+ data = mii_read(gm, gm->phy_addr, MII_BCM5400_AUXCONTROL);
+ data |= MII_BCM5400_AUXCONTROL_PWR10BASET;
+ mii_write(gm, gm->phy_addr, MII_BCM5400_AUXCONTROL, data);
+
+ data = mii_read(gm, gm->phy_addr, MII_BCM5400_GB_CONTROL);
+ data |= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP;
+ mii_write(gm, gm->phy_addr, MII_BCM5400_GB_CONTROL, data);
+
+ mdelay(10);
+ mii_do_reset_phy(gm, 0x1f);
+
+ data = mii_read(gm, 0x1f, MII_BCM5201_MULTIPHY);
+ data |= MII_BCM5201_MULTIPHY_SERIALMODE;
+ mii_write(gm, 0x1f, MII_BCM5201_MULTIPHY, data);
+
+ data = mii_read(gm, gm->phy_addr, MII_BCM5400_AUXCONTROL);
+ data &= ~MII_BCM5400_AUXCONTROL_PWR10BASET;
+ mii_write(gm, gm->phy_addr, MII_BCM5400_AUXCONTROL, data);


+}
+
X static int

X mii_lookup_and_reset(struct gmac *gm)
X {
- int i, timeout;
- int mii_status, mii_control;
+ int i, mii_status, mii_control;
X
- /* Find the PHY */
X gm->phy_addr = -1;
X gm->phy_type = PHY_UNKNOWN;
+
+ /* Hard reset the PHY */
+ feature_set_gmac_phy_reset(gm->of_node, KL_GPIO_ETH_PHY_RESET_ASSERT);
+ mdelay(10);
+ feature_set_gmac_phy_reset(gm->of_node, KL_GPIO_ETH_PHY_RESET_RELEASE);
+ mdelay(10);
X
+ /* Find the PHY */
X for(i=31; i>0; --i) {
X mii_control = mii_read(gm, i, MII_CR);
X mii_status = mii_read(gm, i, MII_SR);
@@ -243,25 +355,9 @@
X return 0;
X
X /* Reset it */
- mii_write(gm, gm->phy_addr, MII_CR, mii_control | MII_CR_RST);
- mdelay(10);
- for (timeout = 100; timeout > 0; --timeout) {
- mii_control = mii_read(gm, gm->phy_addr, MII_CR);
- if (mii_control == -1) {
- printk(KERN_ERR "%s PHY died after reset !\n",
- gm->dev->name);
- goto fail;
- }
- if ((mii_control & MII_CR_RST) == 0)
- break;
- mdelay(10);
- }
- if (mii_control & MII_CR_RST) {
- printk(KERN_ERR "%s PHY reset timeout !\n", gm->dev->name);
+ if (mii_do_reset_phy(gm, gm->phy_addr))
X goto fail;
- }
- mii_write(gm, gm->phy_addr, MII_CR, mii_control & ~MII_CR_ISOL);
-
+
X /* Read the PHY ID */
X gm->phy_id = (mii_read(gm, gm->phy_addr, MII_ID0) << 16) |
X mii_read(gm, gm->phy_addr, MII_ID1);
@@ -270,10 +366,15 @@
X #endif
X if ((gm->phy_id & MII_BCM5400_MASK) == MII_BCM5400_ID) {
X gm->phy_type = PHY_B5400;
- printk(KERN_ERR "%s Warning ! Unsupported BCM5400 PHY !\n",
+ printk(KERN_ERR "%s Found Broadcom BCM5400 PHY (Gigabit)\n",
X gm->dev->name);
+ mii_init_BCM5400(gm);
X } else if ((gm->phy_id & MII_BCM5201_MASK) == MII_BCM5201_ID) {
X gm->phy_type = PHY_B5201;
+ printk(KERN_INFO "%s Found Broadcom BCM5201 PHY\n", gm->dev->name);
+ } else if ((gm->phy_id & MII_LXT971_MASK) == MII_LXT971_ID) {
+ gm->phy_type = PHY_LXT971;
+ printk(KERN_INFO "%s Found LevelOne LX971 PHY\n", gm->dev->name);
X } else {
X printk(KERN_ERR "%s: Warning ! Unknown PHY ID 0x%08x !\n",
X gm->dev->name, gm->phy_id);
@@ -405,6 +506,22 @@
X }
X }
X
+/* Set the MAC gigabit mode. Side effect: stops Tx MAC */
+static void
+gmac_set_gigabit_mode(struct gmac *gm, int gigabit)
+{
+ /* Stop Tx MAC */
+ GM_BIC(GM_MAC_TX_CONFIG, GM_MAC_TX_CONF_ENABLE);
+ while(GM_IN(GM_MAC_TX_CONFIG) & GM_MAC_TX_CONF_ENABLE)
+ ;
+
+ if (gigabit) {
+ GM_BIS(GM_MAC_XIF_CONFIG, GM_MAC_XIF_CONF_GMII_MODE);
+ } else {
+ GM_BIC(GM_MAC_XIF_CONFIG, GM_MAC_XIF_CONF_GMII_MODE);


+ }
+}
+
X /*

X * Initialize a bunch of registers to put the chip into a known
X * and hopefully happy state
@@ -788,6 +905,65 @@


X return 0;
X }
X

+#ifdef CONFIG_PMAC_PBOOK
+int
+gmac_sleep_notify(struct pmu_sleep_notifier *self, int when)
+{
+ struct gmac *gm;
+ int i;
+
+ /* XXX should handle more than one */
+ if (gmacs == NULL)
+ return PBOOK_SLEEP_OK;
+
+ gm = (struct gmac *) gmacs->priv;
+ if (!gm->opened)
+ return PBOOK_SLEEP_OK;
+
+ switch (when) {
+ case PBOOK_SLEEP_REQUEST:
+ break;
+ case PBOOK_SLEEP_REJECT:
+ break;
+ case PBOOK_SLEEP_NOW:
+ disable_irq(gm->dev->irq);
+ netif_stop_queue(gm->dev);
+ gmac_stop_dma(gm);
+ mii_poll_stop(gm);
+ gmac_set_power(gm, 0);
+ for (i = 0; i < NRX; ++i) {
+ if (gm->rx_buff[i] != 0) {
+ dev_kfree_skb(gm->rx_buff[i]);
+ gm->rx_buff[i] = 0;
+ }
+ }
+ for (i = 0; i < NTX; ++i) {
+ if (gm->tx_buff[i] != 0) {
+ dev_kfree_skb(gm->tx_buff[i]);
+ gm->tx_buff[i] = 0;
+ }
+ }
+ break;
+ case PBOOK_WAKE:
+ /* see if this is enough */
+ gmac_powerup_and_reset(gm->dev);
+ gm->full_duplex = 0;
+ gm->phy_status = 0;
+ mii_lookup_and_reset(gm);
+ mii_setup_phy(gm);
+ gmac_init_rings(gm, 0);
+ gmac_mac_init(gm, gm->dev->dev_addr);
+ gmac_set_multicast(gm->dev);
+ mii_interrupt(gm);
+ gmac_start_dma(gm);
+ netif_start_queue(gm->dev);
+ enable_irq(gm->dev->irq);
+ break;
+ }
+ return PBOOK_SLEEP_OK;
+}
+#endif /* CONFIG_PMAC_PBOOK */
+
X /*
X * Handle a transmit timeout
X */
@@ -1196,7 +1372,8 @@
X ioremap(gmac->addrs[0].address, 0x10000);
X dev->irq = gmac->intrs[0].line;
X gm->dev = dev;
-
+ gm->of_node = gmac;
+
X if (pci_device_loc(gmac, &gm->pci_bus, &gm->pci_devfn)) {
X gm->pci_bus = gm->pci_devfn = 0xff;
X printk(KERN_ERR "Can't locate GMAC PCI entry\n");
@@ -1229,6 +1406,10 @@
X
X gm->next_gmac = gmacs;
X gmacs = dev;
+
+#ifdef CONFIG_PMAC_PBOOK
+ pmu_register_sleep_notifier(&gmac_sleep_notifier);
+#endif
X }
X
X MODULE_AUTHOR("Paul Mackerras/Ben Herrenschmidt");
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/gmac.h linux/drivers/net/gmac.h
--- v2.4.0-test8/linux/drivers/net/gmac.h Wed Jul 26 15:53:45 2000
+++ linux/drivers/net/gmac.h Sun Sep 17 09:48:05 2000
@@ -730,8 +730,9 @@
X */
X
X /* Supported PHYs (phy_type field ) */
-#define PHY_B5400 5400
-#define PHY_B5201 5201
+#define PHY_B5400 0x5400
+#define PHY_B5201 0x5201
+#define PHY_LXT971 0x0971
X #define PHY_UNKNOWN 0
X
X /* Identification (for multi-PHY) */
@@ -745,6 +746,11 @@
X #define MII_BCM5400_REV 0x01
X #define MII_BCM5400_ID ((MII_BCM5400_OUI << 10) | (MII_BCM5400_MODEL << 4))
X #define MII_BCM5400_MASK 0xfffffff0
+#define MII_LXT971_OUI 0x0004de
+#define MII_LXT971_MODEL 0x0e
+#define MII_LXT971_REV 0x00
+#define MII_LXT971_ID ((MII_LXT971_OUI << 10) | (MII_LXT971_MODEL << 4))
+#define MII_LXT971_MASK 0xfffffff0
X
X /* BCM5201 AUX STATUS register */
X #define MII_BCM5201_AUXCTLSTATUS 0x18
@@ -764,6 +770,26 @@
X #define MII_BCM5201_MULTIPHY_SERIALMODE 0x0002
X #define MII_BCM5201_MULTIPHY_SUPERISOLATE 0x0008
X
+/* MII BCM5400 1000-BASET Control register */
+#define MII_BCM5400_GB_CONTROL 0x09
+#define MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP 0x0200
+
+/* MII BCM5400 AUXCONTROL register */
+#define MII_BCM5400_AUXCONTROL 0x18
+#define MII_BCM5400_AUXCONTROL_PWR10BASET 0x0004
+
+/* MII BCM5400 AUXSTATUS register */
+#define MII_BCM5400_AUXSTATUS 0x19
+#define MII_BCM5400_AUXSTATUS_LINKMODE_MASK 0x0700
+#define MII_BCM5400_AUXSTATUS_LINKMODE_SHIFT 8
+
+/* MII LXT971 STATUS2 register */
+#define MII_LXT971_STATUS2 0x11
+#define MII_LXT971_STATUS2_SPEED 0x4000
+#define MII_LXT971_STATUS2_LINK 0x0400
+#define MII_LXT971_STATUS2_FULLDUPLEX 0x0200
+#define MII_LXT971_STATUS2_AUTONEG_COMPLETE 0x0080
+
X
X
X /*
@@ -845,6 +871,7 @@
X int phy_type;
X int phy_status; /* Cached PHY status */
X int full_duplex; /* Current set to full duplex */
+ int gigabit; /* Current set to 1000BT */
X struct net_device_stats stats;
X u8 pci_bus;
X u8 pci_devfn;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/hamachi.c linux/drivers/net/hamachi.c
--- v2.4.0-test8/linux/drivers/net/hamachi.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/hamachi.c Mon Oct 2 12:00:15 2000
@@ -0,0 +1,1904 @@
+/* hamachi.c: A Packet Engines GNIC-II Gigabit Ethernet driver for Linux. */
+/*
+ Written 1998-2000 by Donald Becker.
+ Updates 2000 by Keith Underwood.
+


+ This software may be used and distributed according to the terms of

+ the GNU Public License (GPL), incorporated herein by reference.


+ Drivers based on or derived from this code fall under the GPL and must
+ retain the authorship, copyright and license notice. This file is not
+ a complete program and may only be used when the entire operating
+ system is licensed under the GPL.
+

+ The author may be reached as bec...@scyld.com, or C/O
+ Scyld Computing Corporation
+ 410 Severn Ave., Suite 210
+ Annapolis MD 21403

+
+ This driver is for the Packet Engines GNIC-II PCI Gigabit Ethernet
+ adapter.


+
+ Support and updates available at

+ http://www.scyld.com/network/hamachi.html
+ or
+ http://www.parl.clemson.edu/~keithu/hamachi.html
+
+ For best viewing, set your tabs to 3.
+
+*/
+
+static const char *version =
+"hamachi.c:v1.01 5/16/2000 Written by Donald Becker\n"
+" Some modifications by Eric kasten <kas...@nscl.msu.edu>\n"
+" Further modifications by Keith Underwood <kei...@parl.clemson.edu>\n"
+" Support by many others\n"
+" http://www.scyld.com/network/hamachi.html\n"
+" or\n"
+" http://www.parl.clemson.edu/~keithu/drivers/hamachi.html\n";
+
+
+/* A few user-configurable values. */


+
+static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */

+#define final_version
+#define hamachi_debug debug


+/* Maximum events (Rx packets, etc.) to handle at each interrupt. */

+static int max_interrupt_work = 40;
+static int mtu = 0;
+/* Default values selected by testing on a dual processor PIII-450 */
+/* These six interrupt control parameters may be set directly when loading the
+ * module, or through the rx_params and tx_params variables
+ */
+static int max_rx_latency = 0x11;
+static int max_rx_gap = 0x05;
+static int min_rx_pkt = 0x18;
+static int max_tx_latency = 0x00;
+static int max_tx_gap = 0x00;
+static int min_tx_pkt = 0x30;
+
+/* Set the copy breakpoint for the copy-only-tiny-frames scheme.
+ -Setting to > 1518 causes all frames to be copied
+ -Setting to 0 disables copies
+*/
+static int rx_copybreak = 0;
+
+/* An override for the hardware detection of bus width.
+ Set to 1 to force 32 bit PCI bus detection. Set to 4 to force 64 bit.
+ Add 2 to disable parity detection.
+*/
+static int force32 = 0;
+
+
+/* Used to pass the media type, etc.
+ These exist for driver interoperability.
+ No media types are currently defined.
+ - The lower 4 bits are reserved for the media type.
+ - The next three bits may be set to one of the following:
+ 0x00000000 : Autodetect PCI bus
+ 0x00000010 : Force 32 bit PCI bus
+ 0x00000020 : Disable parity detection
+ 0x00000040 : Force 64 bit PCI bus
+ Default is autodetect
+ - The next bit can be used to force half-duplex. This is a bad
+ idea since no known implementations implement half-duplex, and,
+ in general, half-duplex for gigabit ethernet is a bad idea.
+ 0x00000080 : Force half-duplex
+ Default is full-duplex.
+ - In the original driver, the ninth bit could be used to force
+ full-duplex. Maintain that for compatibility
+ 0x00000200 : Force full-duplex
+*/
+#define MAX_UNITS 8 /* More are supported, limit only on options */
+static int options[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
+static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
+/* The Hamachi chipset supports 3 parameters each for Rx and Tx
+ * interruput management. Parameters will be loaded as specified into
+ * the TxIntControl and RxIntControl registers.
+ *
+ * The registers are arranged as follows:
+ * 23 - 16 15 - 8 7 - 0
+ * _________________________________
+ * | min_pkt | max_gap | max_latency |
+ * ---------------------------------
+ * min_pkt : The minimum number of packets processed between
+ * interrupts.
+ * max_gap : The maximum inter-packet gap in units of 8.192 us
+ * max_latency : The absolute time between interrupts in units of 8.192 us
+ *
+ */
+static int rx_params[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
+static int tx_params[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};


+
+/* Operational parameters that are set at compile time. */
+

+/* Keep the ring sizes a power of two for compile efficiency.
+ The compiler will convert <unsigned>'%'<2^N> into a bit mask.
+ Making the Tx ring too large decreases the effectiveness of channel
+ bonding and packet priority.
+ There are no ill effects from too-large receive rings, except for
+ excessive memory usage */
+/* Empirically it appears that the Tx ring needs to be a little bigger
+ for these Gbit adapters or you get into an overrun condition really
+ easily. Also, things appear to work a bit better in back-to-back
+ configurations if the Rx ring is 8 times the size of the Tx ring
+*/
+#define TX_RING_SIZE 64
+#define RX_RING_SIZE 512
+
+/*
+ * Enable mii_ioctl. Added interrupt coalescing parameter adjustment.
+ * 2/19/99 Pete Wyckoff <wyc...@ca.sandia.gov>
+ */
+#define HAVE_PRIVATE_IOCTL
+
+/* play with 64-bit addrlen; seems to be a teensy bit slower --pw */
+/* #define ADDRLEN 64 */
+
+/*
+ * RX_CHECKSUM turns on card-generated receive checksum generation for
+ * TCP and UDP packets. Otherwise the upper layers do the calculation.
+ * TX_CHECKSUM won't do anything too useful, even if it works. There's no
+ * easy mechanism by which to tell the TCP/UDP stack that it need not
+ * generate checksums for this device. But if somebody can find a way
+ * to get that to work, most of the card work is in here already.
+ * 3/10/1999 Pete Wyckoff <wyc...@ca.sandia.gov>
+ */
+#undef TX_CHECKSUM
+#define RX_CHECKSUM
+
+/* Operational parameters that usually are not changed. */


+/* Time in jiffies before concluding the transmitter is hung. */

+#define TX_TIMEOUT (5*HZ)
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/time.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/malloc.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/processor.h> /* Processor type for cache alignment. */
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/unaligned.h>
+#include <asm/cache.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+#include <linux/delay.h>
+
+/* IP_MF appears to be only defined in <netinet/ip.h>, however,
+ we need it for hardware checksumming support. FYI... some of
+ the definitions in <netinet/ip.h> conflict/duplicate those in
+ other linux headers causing many compiler warnings.
+*/
+#ifndef IP_MF
+ #define IP_MF 0x2000 /* IP more frags from <netinet/ip.h> */
+#endif
+
+/* Define IP_OFFSET to be IPOPT_OFFSET */
+#ifndef IP_OFFSET
+ #ifdef IPOPT_OFFSET
+ #define IP_OFFSET IPOPT_OFFSET
+ #else
+ #define IP_OFFSET 2
+ #endif
+#endif
+
+#define RUN_AT(x) (jiffies + (x))
+
+/* Condensed bus+endian portability operations. */
+#if ADDRLEN == 64
+#define virt_to_desc(addr) cpu_to_le64(virt_to_bus(addr))
+#else
+#define virt_to_desc(addr) cpu_to_le32(virt_to_bus(addr))
+#define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr))
+#endif
+
+
+/*
+ Theory of Operation
+
+I. Board Compatibility
+
+This device driver is designed for the Packet Engines "Hamachi"
+Gigabit Ethernet chip. The only PCA currently supported is the GNIC-II 64-bit
+66Mhz PCI card.
+
+II. Board-specific settings
+
+No jumpers exist on the board. The chip supports software correction of
+various motherboard wiring errors, however this driver does not support
+that feature.
+
+III. Driver operation
+
+IIIa. Ring buffers
+
+The Hamachi uses a typical descriptor based bus-master architecture.
+The descriptor list is similar to that used by the Digital Tulip.
+This driver uses two statically allocated fixed-size descriptor lists
+formed into rings by a branch from the final descriptor to the beginning of
+the list. The ring sizes are set at compile time by RX/TX_RING_SIZE.
+
+This driver uses a zero-copy receive and transmit scheme similar my other
+network drivers.
+The driver allocates full frame size skbuffs for the Rx ring buffers at
+open() time and passes the skb->data field to the Hamachi as receive data
+buffers. When an incoming frame is less than RX_COPYBREAK bytes long,
+a fresh skbuff is allocated and the frame is copied to the new skbuff.
+When the incoming frame is larger, the skbuff is passed directly up the
+protocol stack and replaced by a newly allocated skbuff.
+
+The RX_COPYBREAK value is chosen to trade-off the memory wasted by
+using a full-sized skbuff for small frames vs. the copying costs of larger
+frames. Gigabit cards are typically used on generously configured machines
+and the underfilled buffers have negligible impact compared to the benefit of
+a single allocation size, so the default value of zero results in never
+copying packets.
+
+IIIb/c. Transmit/Receive Structure
+
+The Rx and Tx descriptor structure are straight-forward, with no historical
+baggage that must be explained. Unlike the awkward DBDMA structure, there
+are no unused fields or option bits that had only one allowable setting.
+
+Two details should be noted about the descriptors: The chip supports both 32
+bit and 64 bit address structures, and the length field is overwritten on
+the receive descriptors. The descriptor length is set in the control word
+for each channel. The development driver uses 32 bit addresses only, however
+64 bit addresses may be enabled for 64 bit architectures e.g. the Alpha.
+
+IIId. Synchronization
+
+This driver is very similar to my other network drivers.
+The driver runs as two independent, single-threaded flows of control. One
+is the send-packet routine, which enforces single-threaded use by the
+dev->tbusy flag. The other thread is the interrupt handler, which is single
+threaded by the hardware and other software.
+
+The send packet thread has partial control over the Tx ring and 'dev->tbusy'
+flag. It sets the tbusy flag whenever it's queuing a Tx packet. If the next
+queue slot is empty, it clears the tbusy flag when finished otherwise it sets
+the 'hmp->tx_full' flag.
+
+The interrupt handler has exclusive control over the Rx ring and records stats
+from the Tx ring. After reaping the stats, it marks the Tx queue entry as
+empty by incrementing the dirty_tx mark. Iff the 'hmp->tx_full' flag is set, it
+clears both the tx_full and tbusy flags.
+
+IV. Notes
+
+Thanks to Kim Stearns of Packet Engines for providing a pair of GNIC-II boards.
+
+IVb. References
+
+Hamachi Engineering Design Specification, 5/15/97
+(Note: This version was marked "Confidential".)
+
+IVc. Errata
+
+None noted.
+
+V. Recent Changes
+
+01/15/1999 EPK Enlargement of the TX and RX ring sizes. This appears
+ to help avoid some stall conditions -- this needs further research.
+
+01/15/1999 EPK Creation of the hamachi_tx function. This function cleans
+ the Tx ring and is called from hamachi_start_xmit (this used to be
+ called from hamachi_interrupt but it tends to delay execution of the
+ interrupt handler and thus reduce bandwidth by reducing the latency
+ between hamachi_rx()'s). Notably, some modification has been made so
+ that the cleaning loop checks only to make sure that the DescOwn bit
+ isn't set in the status flag since the card is not required
+ to set the entire flag to zero after processing.
+
+01/15/1999 EPK In the hamachi_start_tx function, the Tx ring full flag is
+ checked before attempting to add a buffer to the ring. If the ring is full
+ an attempt is made to free any dirty buffers and thus find space for
+ the new buffer or the function returns non-zero which should case the
+ scheduler to reschedule the buffer later.
+
+01/15/1999 EPK Some adjustments were made to the chip intialization.
+ End-to-end flow control should now be fully active and the interrupt
+ algorithm vars have been changed. These could probably use further tuning.
+
+01/15/1999 EPK Added the max_{rx,tx}_latency options. These are used to
+ set the rx and tx latencies for the Hamachi interrupts. If you're having
+ problems with network stalls, try setting these to higher values.
+ Valid values are 0x00 through 0xff.
+
+01/15/1999 EPK In general, the overall bandwidth has increased and
+ latencies are better (sometimes by a factor of 2). Stalls are rare at
+ this point, however there still appears to be a bug somewhere between the
+ hardware and driver. TCP checksum errors under load also appear to be
+ eliminated at this point.
+
+01/18/1999 EPK Ensured that the DescEndRing bit was being set on both the
+ Rx and Tx rings. This appears to have been affecting whether a particular
+ peer-to-peer connection would hang under high load. I believe the Rx
+ rings was typically getting set correctly, but the Tx ring wasn't getting
+ the DescEndRing bit set during initialization. ??? Does this mean the
+ hamachi card is using the DescEndRing in processing even if a particular
+ slot isn't in use -- hypothetically, the card might be searching the
+ entire Tx ring for slots with the DescOwn bit set and then processing
+ them. If the DescEndRing bit isn't set, then it might just wander off
+ through memory until it hits a chunk of data with that bit set
+ and then looping back.
+
+02/09/1999 EPK Added Michel Mueller's TxDMA Interrupt and Tx-timeout
+ problem (TxCmd and RxCmd need only to be set when idle or stopped.
+
+02/09/1999 EPK Added code to check/reset dev->tbusy in hamachi_interrupt.
+ (Michel Mueller pointed out the ``permanently busy'' potential
+ problem here).
+
+02/22/1999 EPK Added Pete Wyckoff's ioctl to control the Tx/Rx latencies.
+
+02/23/1999 EPK Verified that the interrupt status field bits for Tx were
+ incorrectly defined and corrected (as per Michel Mueller).
+
+02/23/1999 EPK Corrected the Tx full check to check that at least 4 slots
+ were available before reseting the tbusy and tx_full flags
+ (as per Michel Mueller).
+
+03/11/1999 EPK Added Pete Wyckoff's hardware checksumming support.
+
+12/31/1999 KDU Cleaned up assorted things and added Don's code to force
+32 bit.
+
+02/20/2000 KDU Some of the control was just plain odd. Cleaned up the
+hamachi_start_xmit() and hamachi_interrupt() code. There is still some
+re-structuring I would like to do.
+
+03/01/2000 KDU Experimenting with a WIDE range of interrupt mitigation
+parameters on a dual P3-450 setup yielded the new default interrupt
+mitigation parameters. Tx should interrupt VERY infrequently due to
+Eric's scheme. Rx should be more often...
+
+03/13/2000 KDU Added a patch to make the Rx Checksum code interact
+nicely with non-linux machines.
+
+03/13/2000 KDU Experimented with some of the configuration values:
+
+ -It seems that enabling PCI performance commands for descriptors
+ (changing RxDMACtrl and TxDMACtrl lower nibble from 5 to D) has minimal
+ performance impact for any of my tests. (ttcp, netpipe, netperf) I will
+ leave them that way until I hear further feedback.
+
+ -Increasing the PCI_LATENCY_TIMER to 130
+ (2 + (burst size of 128 * (0 wait states + 1))) seems to slightly
+ degrade performance. Leaving default at 64 pending further information.
+
+03/14/2000 KDU Further tuning:
+
+ -adjusted boguscnt in hamachi_rx() to depend on interrupt
+ mitigation parameters chosen.
+
+ -Selected a set of interrupt parameters based on some extensive testing.
+ These may change with more testing.
+
+TO DO:
+
+-Consider borrowing from the acenic driver code to check PCI_COMMAND for
+PCI_COMMAND_INVALIDATE. Set maximum burst size to cache line size in
+that case.
+
+-fix the reset procedure. It doesn't quite work.
+*/
+
+/* A few values that may be tweaked. */
+/* Size of each temporary Rx buffer, calculated as:
+ * 1518 bytes (ethernet packet) + 2 bytes (to get 8 byte alignment for
+ * the card) + 8 bytes of status info + 8 bytes for the Rx Checksum +
+ * 2 more because we use skb_reserve.
+ */
+#define PKT_BUF_SZ 1538
+
+/* For now, this is going to be set to the maximum size of an ethernet
+ * packet. Eventually, we may want to make it a variable that is
+ * related to the MTU
+ */
+#define MAX_FRAME_SIZE 1518
+
+/* The rest of these values should never change. */
+
+static void hamachi_timer(unsigned long data);
+
+enum capability_flags {CanHaveMII=1, };
+static struct chip_info {
+ u16 vendor_id, device_id, device_id_mask, pad;
+ const char *name;
+ void (*media_timer)(unsigned long data);
+ int flags;
+} chip_tbl[] = {
+ {0x1318, 0x0911, 0xffff, 0, "Hamachi GNIC-II", hamachi_timer, 0},
+ {0,},
+};
+
+/* Offsets to the Hamachi registers. Various sizes. */
+enum hamachi_offsets {
+ TxDMACtrl=0x00, TxCmd=0x04, TxStatus=0x06, TxPtr=0x08, TxCurPtr=0x10,
+ RxDMACtrl=0x20, RxCmd=0x24, RxStatus=0x26, RxPtr=0x28, RxCurPtr=0x30,
+ PCIClkMeas=0x060, MiscStatus=0x066, ChipRev=0x68, ChipReset=0x06B,
+ LEDCtrl=0x06C, VirtualJumpers=0x06D, GPIO=0x6E,
+ TxChecksum=0x074, RxChecksum=0x076,
+ TxIntrCtrl=0x078, RxIntrCtrl=0x07C,
+ InterruptEnable=0x080, InterruptClear=0x084, IntrStatus=0x088,
+ EventStatus=0x08C,
+ MACCnfg=0x0A0, FrameGap0=0x0A2, FrameGap1=0x0A4,
+ /* See enum MII_offsets below. */
+ MACCnfg2=0x0B0, RxDepth=0x0B8, FlowCtrl=0x0BC, MaxFrameSize=0x0CE,
+ AddrMode=0x0D0, StationAddr=0x0D2,
+ /* Gigabit AutoNegotiation. */
+ ANCtrl=0x0E0, ANStatus=0x0E2, ANXchngCtrl=0x0E4, ANAdvertise=0x0E8,
+ ANLinkPartnerAbility=0x0EA,
+ EECmdStatus=0x0F0, EEData=0x0F1, EEAddr=0x0F2,
+ FIFOcfg=0x0F8,
+};
+
+/* Offsets to the MII-mode registers. */
+enum MII_offsets {
+ MII_Cmd=0xA6, MII_Addr=0xA8, MII_Wr_Data=0xAA, MII_Rd_Data=0xAC,
+ MII_Status=0xAE,
+};
+
+/* Bits in the interrupt status/mask registers. */
+enum intr_status_bits {
+ IntrRxDone=0x01, IntrRxPCIFault=0x02, IntrRxPCIErr=0x04,
+ IntrTxDone=0x100, IntrTxPCIFault=0x200, IntrTxPCIErr=0x400,
+ LinkChange=0x10000, NegotiationChange=0x20000, StatsMax=0x40000, };
+
+/* The Hamachi Rx and Tx buffer descriptors. */
+struct hamachi_desc {
+ u32 status_n_length;
+#if ADDRLEN == 64
+ u32 pad;
+ u64 addr;
+#else
+ u32 addr;
+#endif
+};
+
+/* Bits in hamachi_desc.status_n_length */
+enum desc_status_bits {
+ DescOwn=0x80000000, DescEndPacket=0x40000000, DescEndRing=0x20000000,
+ DescIntr=0x10000000,
+};
+
+#define PRIV_ALIGN 15 /* Required alignment mask */
+struct hamachi_private {
+ /* Descriptor rings first for alignment. Tx requires a second descriptor
+ for status. */
+ struct hamachi_desc rx_ring[RX_RING_SIZE];
+ struct hamachi_desc tx_ring[TX_RING_SIZE];
+ /* The addresses of receive-in-place skbuffs. */
+ struct sk_buff* rx_skbuff[RX_RING_SIZE];
+ /* The saved address of a sent-in-place packet/buffer, for skfree(). */
+ struct sk_buff* tx_skbuff[TX_RING_SIZE];
+ struct net_device_stats stats;
+ struct timer_list timer; /* Media selection timer. */
+ /* Frequently used and paired value: keep adjacent for cache effect. */
+ spinlock_t lock;
+ int chip_id;
+ struct hamachi_desc *rx_head_desc;
+ unsigned int cur_rx, dirty_rx; /* Producer/consumer ring indices */
+ unsigned int cur_tx, dirty_tx;
+ unsigned int rx_buf_sz; /* Based on MTU+slack. */
+ unsigned int tx_full:1; /* The Tx queue is full. */
+ unsigned int full_duplex:1; /* Full-duplex operation requested. */
+ unsigned int duplex_lock:1;
+ unsigned int medialock:1; /* Do not sense media. */
+ unsigned int default_port:4; /* Last dev->if_port value. */
+ /* MII transceiver section. */
+ int mii_cnt; /* MII device addresses. */
+ u16 advertising; /* NWay media advertisement */
+ unsigned char phys[2]; /* MII device addresses. */
+ u_int32_t rx_int_var, tx_int_var; /* interrupt control variables */
+ u_int32_t option; /* Hold on to a copy of the options */
+ u_int8_t pad[16]; /* Used for 32-byte alignment */
+};
+
+MODULE_AUTHOR("Donald Becker <bec...@scyld.com>, Eric Kasten <kas...@nscl.msu.edu>, Keith Underwood <kei...@parl.clemson.edu>");
+MODULE_DESCRIPTION("Packet Engines 'Hamachi' GNIC-II Gigabit Ethernet driver");
+MODULE_PARM(max_interrupt_work, "i");
+MODULE_PARM(mtu, "i");
+MODULE_PARM(debug, "i");
+MODULE_PARM(min_rx_pkt, "i");
+MODULE_PARM(max_rx_gap, "i");
+MODULE_PARM(max_rx_latency, "i");
+MODULE_PARM(min_tx_pkt, "i");
+MODULE_PARM(max_tx_gap, "i");
+MODULE_PARM(max_tx_latency, "i");
+MODULE_PARM(rx_copybreak, "i");
+MODULE_PARM(rx_params, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(tx_params, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(force32, "i");
+
+static int read_eeprom(long ioaddr, int location);
+static int mdio_read(long ioaddr, int phy_id, int location);
+static void mdio_write(long ioaddr, int phy_id, int location, int value);
+static int hamachi_open(struct net_device *dev);
+#ifdef HAVE_PRIVATE_IOCTL
+static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+#endif
+static void hamachi_timer(unsigned long data);
+static void hamachi_tx_timeout(struct net_device *dev);
+static void hamachi_init_ring(struct net_device *dev);
+static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static void hamachi_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+static inline int hamachi_rx(struct net_device *dev);
+static inline int hamachi_tx(struct net_device *dev);
+static void hamachi_error(struct net_device *dev, int intr_status);
+static int hamachi_close(struct net_device *dev);
+static struct net_device_stats *hamachi_get_stats(struct net_device *dev);
+static void set_rx_mode(struct net_device *dev);
+
+
+static int __init hamachi_init_one (struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ static int did_version = 0; /* Already printed version info. */
+ struct hamachi_private *hmp;
+ int option, i, rx_int_var, tx_int_var, boguscnt;
+ int chip_id = ent->driver_data;
+ int irq = pdev->irq;
+ long ioaddr;
+ static int card_idx = 0;
+ struct net_device *dev;
+
+ if (hamachi_debug > 0 && did_version++ == 0)
+ printk(version);
+
+ ioaddr = pci_resource_start(pdev, 0);
+#ifdef __alpha__ /* Really "64 bit addrs" */
+ ioaddr |= (pci_resource_start(pdev, 1) << 32);
+#endif
+
+ if (pci_enable_device(pdev))
+ return -EIO;
+ pci_set_master(pdev);
+
+ ioaddr = (long) ioremap(ioaddr, 0x400);
+ if (!ioaddr)
+ return -ENOMEM;
+
+ dev = init_etherdev(NULL, sizeof(struct hamachi_private));
+ if (!dev) {
+ iounmap((char *)ioaddr);


+ return -ENOMEM;
+ }
+

+#ifdef TX_CHECKSUM
+ printk("check that skbcopy in ip_queue_xmit isn't happening\n");
+ dev->hard_header_len += 8; /* for cksum tag */
+#endif
+
+ printk(KERN_INFO "%s: %s type %x at 0x%lx, ",
+ dev->name, chip_tbl[chip_id].name, readl(ioaddr + ChipRev),
+ ioaddr);
+
+ for (i = 0; i < 6; i++)
+ dev->dev_addr[i] = 1 ? read_eeprom(ioaddr, 4 + i)
+ : readb(ioaddr + StationAddr + i);
+ for (i = 0; i < 5; i++)
+ printk("%2.2x:", dev->dev_addr[i]);
+ printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq);
+
+#if ! defined(final_version)
+ if (hamachi_debug > 4)
+ for (i = 0; i < 0x10; i++)
+ printk("%2.2x%s",
+ read_eeprom(ioaddr, i), i % 16 != 15 ? " " : "\n");
+#endif
+
+#if 0 /* Moving this until after the force 32 check and reset. */
+ i = readb(ioaddr + PCIClkMeas);
+ printk(KERN_INFO "%s: %d-bit %d Mhz PCI bus (%d), Virtual Jumpers "
+ "%2.2x, LPA %4.4x.\n",
+ dev->name, readw(ioaddr + MiscStatus) & 1 ? 64 : 32,
+ i ? 2000/(i&0x7f) : 0, i&0x7f, (int)readb(ioaddr + VirtualJumpers),
+ readw(ioaddr + ANLinkPartnerAbility));
+#endif
+
+ hmp = dev->priv;
+ spin_lock_init(&hmp->lock);
+
+ /* Check for options being passed in */
+ option = card_idx < MAX_UNITS ? options[card_idx] : 0;
+ if (dev->mem_start)
+ option = dev->mem_start;
+
+ /* If the bus size is misidentified, do the following. */
+ force32 = force32 ? force32 :
+ ((option >= 0) ? ((option & 0x00000070) >> 4) : 0 );
+ if (force32)
+ writeb(force32, ioaddr + VirtualJumpers);
+
+ /* Hmmm, do we really need to reset the chip???. */
+ writeb(0x01, ioaddr + ChipReset);
+
+ /* After a reset, the clock speed measurement of the PCI bus will not
+ * be valid for a moment. Wait for a little while until it is. If
+ * it takes more than 10ms, forget it.
+ */
+ udelay(10);
+ i = readb(ioaddr + PCIClkMeas);
+ for (boguscnt = 0; (!(i & 0x080)) && boguscnt < 1000; boguscnt++){
+ udelay(10);
+ i = readb(ioaddr + PCIClkMeas);
+ }
+
+ printk(KERN_INFO "%s: %d-bit %d Mhz PCI bus (%d), Virtual Jumpers "
+ "%2.2x, LPA %4.4x.\n",
+ dev->name, readw(ioaddr + MiscStatus) & 1 ? 64 : 32,
+ i ? 2000/(i&0x7f) : 0, i&0x7f, (int)readb(ioaddr + VirtualJumpers),
+ readw(ioaddr + ANLinkPartnerAbility));
+
+ dev->base_addr = ioaddr;
+ dev->irq = irq;
+
+ hmp->chip_id = chip_id;
+
+ /* The lower four bits are the media type. */
+ if (option > 0) {
+ hmp->option = option;
+ if (option & 0x200)
+ hmp->full_duplex = 1;
+ else if (option & 0x080)
+ hmp->full_duplex = 0;
+ hmp->default_port = option & 15;
+ if (hmp->default_port)
+ hmp->medialock = 1;
+ }
+ if (card_idx < MAX_UNITS && full_duplex[card_idx] > 0)
+ hmp->full_duplex = 1;
+
+ /* lock the duplex mode if someone specified a value */
+ if (hmp->full_duplex || (option & 0x080))
+ hmp->duplex_lock = 1;
+
+ /* Set interrupt tuning parameters */
+ max_rx_latency = max_rx_latency & 0x00ff;
+ max_rx_gap = max_rx_gap & 0x00ff;
+ min_rx_pkt = min_rx_pkt & 0x00ff;
+ max_tx_latency = max_tx_latency & 0x00ff;
+ max_tx_gap = max_tx_gap & 0x00ff;
+ min_tx_pkt = min_tx_pkt & 0x00ff;
+
+ rx_int_var = card_idx < MAX_UNITS ? rx_params[card_idx] : -1;
+ tx_int_var = card_idx < MAX_UNITS ? tx_params[card_idx] : -1;
+ hmp->rx_int_var = rx_int_var >= 0 ? rx_int_var :
+ (min_rx_pkt << 16 | max_rx_gap << 8 | max_rx_latency);
+ hmp->tx_int_var = tx_int_var >= 0 ? tx_int_var :
+ (min_tx_pkt << 16 | max_tx_gap << 8 | max_tx_latency);
+
+
+ /* The Hamachi-specific entries in the device structure. */
+ dev->open = &hamachi_open;
+ dev->hard_start_xmit = &hamachi_start_xmit;
+ dev->stop = &hamachi_close;
+ dev->get_stats = &hamachi_get_stats;
+ dev->set_multicast_list = &set_rx_mode;
+#ifdef HAVE_PRIVATE_IOCTL
+ dev->do_ioctl = &mii_ioctl;
+#endif
+ dev->tx_timeout = &hamachi_tx_timeout;
+ dev->watchdog_timeo = TX_TIMEOUT;
+ if (mtu)
+ dev->mtu = mtu;
+
+ if (chip_tbl[hmp->chip_id].flags & CanHaveMII) {
+ int phy, phy_idx = 0;
+ for (phy = 0; phy < 32 && phy_idx < 4; phy++) {
+ int mii_status = mdio_read(ioaddr, phy, 1);
+ if (mii_status != 0xffff &&
+ mii_status != 0x0000) {
+ hmp->phys[phy_idx++] = phy;
+ hmp->advertising = mdio_read(ioaddr, phy, 4);
+ printk(KERN_INFO "%s: MII PHY found at address %d, status "
+ "0x%4.4x advertising %4.4x.\n",
+ dev->name, phy, mii_status, hmp->advertising);
+ }
+ }
+ hmp->mii_cnt = phy_idx;
+ }
+ /* Configure gigabit autonegotiation. */
+ writew(0x0400, ioaddr + ANXchngCtrl); /* Enable legacy links. */
+ writew(0x08e0, ioaddr + ANAdvertise); /* Set our advertise word. */
+ writew(0x1000, ioaddr + ANCtrl); /* Enable negotiation */
+
+ card_idx++;


+ return 0;
+}
+

+static int read_eeprom(long ioaddr, int location)
+{
+ int bogus_cnt = 1000;
+
+ /* We should check busy first - per docs -KDU */
+ while ((readb(ioaddr + EECmdStatus) & 0x40) && --bogus_cnt > 0);
+ writew(location, ioaddr + EEAddr);
+ writeb(0x02, ioaddr + EECmdStatus);
+ bogus_cnt = 1000;
+ while ((readb(ioaddr + EECmdStatus) & 0x40) && --bogus_cnt > 0);
+ if (hamachi_debug > 5)
+ printk(" EEPROM status is %2.2x after %d ticks.\n",
+ (int)readb(ioaddr + EECmdStatus), 1000- bogus_cnt);
+ return readb(ioaddr + EEData);
+}
+
+/* MII Managemen Data I/O accesses.
+ These routines assume the MDIO controller is idle, and do not exit until
+ the command is finished. */
+
+static int mdio_read(long ioaddr, int phy_id, int location)


+{
+ int i;
+

+ /* We should check busy first - per docs -KDU */
+ for (i = 10000; i >= 0; i--)
+ if ((readw(ioaddr + MII_Status) & 1) == 0)
+ break;
+ writew((phy_id<<8) + location, ioaddr + MII_Addr);
+ writew(0x0001, ioaddr + MII_Cmd);
+ for (i = 10000; i >= 0; i--)
+ if ((readw(ioaddr + MII_Status) & 1) == 0)
+ break;
+ return readw(ioaddr + MII_Rd_Data);
+}
+
+static void mdio_write(long ioaddr, int phy_id, int location, int value)


+{
+ int i;
+

+ /* We should check busy first - per docs -KDU */
+ for (i = 10000; i >= 0; i--)
+ if ((readw(ioaddr + MII_Status) & 1) == 0)
+ break;
+ writew((phy_id<<8) + location, ioaddr + MII_Addr);
+ writew(value, ioaddr + MII_Wr_Data);
+
+ /* Wait for the command to finish. */
+ for (i = 10000; i >= 0; i--)
+ if ((readw(ioaddr + MII_Status) & 1) == 0)
+ break;
+ return;
+}
+
+
+static int hamachi_open(struct net_device *dev)
+{
+ struct hamachi_private *hmp = (struct hamachi_private *)dev->priv;
+ long ioaddr = dev->base_addr;
+ int i;
+ u_int32_t rx_int_var, tx_int_var;
+ u_int16_t fifo_info;
+
+ MOD_INC_USE_COUNT;
+
+ if (request_irq(dev->irq, &hamachi_interrupt, SA_SHIRQ, dev->name, dev)) {
+ MOD_DEC_USE_COUNT;


+ return -EAGAIN;
+ }
+

+ if (hamachi_debug > 1)
+ printk(KERN_DEBUG "%s: hamachi_open() irq %d.\n",
+ dev->name, dev->irq);
+
+ hamachi_init_ring(dev);
+
+#if ADDRLEN == 64
+ writel(virt_to_bus(hmp->rx_ring), ioaddr + RxPtr);
+ writel(virt_to_bus(hmp->rx_ring) >> 32, ioaddr + RxPtr + 4);
+ writel(virt_to_bus(hmp->tx_ring), ioaddr + TxPtr);
+ writel(virt_to_bus(hmp->tx_ring) >> 32, ioaddr + TxPtr + 4);
+#else
+ writel(virt_to_bus(hmp->rx_ring), ioaddr + RxPtr);
+ writel(virt_to_bus(hmp->tx_ring), ioaddr + TxPtr);
+#endif
+
+ /* TODO: It would make sense to organize this as words since the card
+ * documentation does. -KDU
+ */
+ for (i = 0; i < 6; i++)
+ writeb(dev->dev_addr[i], ioaddr + StationAddr + i);
+
+ /* Initialize other registers: with so many this eventually this will
+ converted to an offset/value list. */
+
+ /* Configure the FIFO */
+ fifo_info = (readw(ioaddr + GPIO) & 0x00C0) >> 6;
+ switch (fifo_info){
+ case 0 :
+ /* No FIFO */
+ writew(0x0000, ioaddr + FIFOcfg);


+ break;
+ case 1 :

+ /* Configure the FIFO for 512K external, 16K used for Tx. */
+ writew(0x0028, ioaddr + FIFOcfg);


+ break;
+ case 2 :

+ /* Configure the FIFO for 1024 external, 32K used for Tx. */
+ writew(0x004C, ioaddr + FIFOcfg);


+ break;
+ case 3 :

+ /* Configure the FIFO for 2048 external, 32K used for Tx. */
+ writew(0x006C, ioaddr + FIFOcfg);
+ break;
+ default :
+ printk(KERN_WARNING "%s: Unsupported external memory config!\n",
+ dev->name);
+ /* Default to no FIFO */
+ writew(0x0000, ioaddr + FIFOcfg);
+ break;
+ }
+
+ if (dev->if_port == 0)
+ dev->if_port = hmp->default_port;
+
+
+ /* Setting the Rx mode will start the Rx process. */
+ /* If someone didn't choose a duplex, default to full-duplex */
+ if (hmp->duplex_lock != 1)
+ hmp->full_duplex = 1;
+
+ /* always 1, takes no more time to do it */
+ writew(0x0001, ioaddr + RxChecksum);
+#ifdef TX_CHECKSUM
+ writew(0x0001, ioaddr + TxChecksum);
+#else
+ writew(0x0000, ioaddr + TxChecksum);
+#endif
+ writew(0x8000, ioaddr + MACCnfg); /* Soft reset the MAC */
+ writew(0x215F, ioaddr + MACCnfg);
+ writew(0x000C, ioaddr + FrameGap0);
+ /* WHAT?!?!? Why isn't this documented somewhere? -KDU */
+ writew(0x1018, ioaddr + FrameGap1);
+ /* Why do we enable receives/transmits here? -KDU */
+ writew(0x0780, ioaddr + MACCnfg2); /* Upper 16 bits control LEDs. */
+ /* Enable automatic generation of flow control frames, period 0xffff. */
+ writel(0x0030FFFF, ioaddr + FlowCtrl);
+ writew(MAX_FRAME_SIZE, ioaddr + MaxFrameSize); /* dev->mtu+14 ??? */
+
+ /* Enable legacy links. */
+ writew(0x0400, ioaddr + ANXchngCtrl); /* Enable legacy links. */
+ /* Initial Link LED to blinking red. */
+ writeb(0x03, ioaddr + LEDCtrl);
+
+ /* Configure interrupt mitigation. This has a great effect on
+ performance, so systems tuning should start here!. */
+
+ rx_int_var = hmp->rx_int_var;
+ tx_int_var = hmp->tx_int_var;
+
+ if (hamachi_debug > 1) {
+ printk("max_tx_latency: %d, max_tx_gap: %d, min_tx_pkt: %d\n",
+ tx_int_var & 0x00ff, (tx_int_var & 0x00ff00) >> 8,
+ (tx_int_var & 0x00ff0000) >> 16);
+ printk("max_rx_latency: %d, max_rx_gap: %d, min_rx_pkt: %d\n",
+ rx_int_var & 0x00ff, (rx_int_var & 0x00ff00) >> 8,
+ (rx_int_var & 0x00ff0000) >> 16);
+ printk("rx_int_var: %x, tx_int_var: %x\n", rx_int_var, tx_int_var);
+ }
+
+ writel(tx_int_var, ioaddr + TxIntrCtrl);
+ writel(rx_int_var, ioaddr + RxIntrCtrl);
+
+ set_rx_mode(dev);
+
+ netif_start_queue(dev);
+
+ /* Enable interrupts by setting the interrupt mask. */
+ writel(0x80878787, ioaddr + InterruptEnable);
+ writew(0x0000, ioaddr + EventStatus); /* Clear non-interrupting events */
+
+ /* Configure and start the DMA channels. */
+ /* Burst sizes are in the low three bits: size = 4<<(val&7) */
+#if ADDRLEN == 64
+ writew(0x005D, ioaddr + RxDMACtrl); /* 128 dword bursts */
+ writew(0x005D, ioaddr + TxDMACtrl);
+#else
+ writew(0x001D, ioaddr + RxDMACtrl);
+ writew(0x001D, ioaddr + TxDMACtrl);
+#endif
+ writew(0x0001, dev->base_addr + RxCmd);
+
+ if (hamachi_debug > 2) {
+ printk(KERN_DEBUG "%s: Done hamachi_open(), status: Rx %x Tx %x.\n",
+ dev->name, readw(ioaddr + RxStatus), readw(ioaddr + TxStatus));
+ }
+ /* Set the timer to check for link beat. */
+ init_timer(&hmp->timer);
+ hmp->timer.expires = RUN_AT((24*HZ)/10); /* 2.4 sec. */
+ hmp->timer.data = (unsigned long)dev;
+ hmp->timer.function = &hamachi_timer; /* timer handler */
+ add_timer(&hmp->timer);


+
+ return 0;
+}
+

+static inline int hamachi_tx(struct net_device *dev)
+{
+ struct hamachi_private *hmp = (struct hamachi_private *)dev->priv;
+
+ /* Update the dirty pointer until we find an entry that is
+ still owned by the card */
+ for (; hmp->cur_tx - hmp->dirty_tx > 0; hmp->dirty_tx++) {
+ int entry = hmp->dirty_tx % TX_RING_SIZE;
+ if (hmp->tx_ring[entry].status_n_length & cpu_to_le32(DescOwn))
+ break;
+ /* Free the original skb. */
+ if (hmp->tx_skbuff[entry] != 0) {
+ dev_kfree_skb(hmp->tx_skbuff[entry]);
+ hmp->tx_skbuff[entry] = 0;
+ }
+ hmp->tx_ring[entry].status_n_length = 0;
+ if (entry >= TX_RING_SIZE-1)
+ hmp->tx_ring[TX_RING_SIZE-1].status_n_length |=
+ cpu_to_le32(DescEndRing);
+ hmp->stats.tx_packets++;
+ }


+
+ return 0;
+}
+

+static void hamachi_timer(unsigned long data)
+{
+ struct net_device *dev = (struct net_device *)data;


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 063'
echo 'File patch-2.4.0-test9 is continued in part 064'
echo "064" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part060

#!/bin/sh -x
# this is part 060 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 060; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ xor %%g5, %%l1, %%g5

+ ldd [%3 + 0x08], %%l0


+ xor %%o0, %%l2, %%o0
+ xor %%o1, %%l3, %%o1

+ ldd [%3 + 0x10], %%l2


+ xor %%o2, %%l4, %%o2
+ xor %%o3, %%l5, %%o3

+ ldd [%3 + 0x18], %%l4


+ xor %%g2, %%o4, %%g2
+ xor %%g3, %%o5, %%g3
+ xor %%g4, %%l0, %%g4
+ xor %%g5, %%l1, %%g5
+ xor %%o0, %%l2, %%o0
+ xor %%o1, %%l3, %%o1
+ xor %%o2, %%l4, %%o2
+ xor %%o3, %%l5, %%o3
+ std %%g2, [%0 + 0x00]
+ std %%g4, [%0 + 0x08]
+ std %%o0, [%0 + 0x10]
+ std %%o2, [%0 + 0x18]

+ " : : "r" (destp), "r" (source1), "r" (source2), "r" (source3)


+ : "g2", "g3", "g4", "g5", "o0", "o1", "o2", "o3", "o4", "o5",
+ "l0", "l1", "l2", "l3", "l4", "l5");
+ destp += 8;
+ source1 += 8;
+ source2 += 8;

+ source3 += 8;
+ }
+ break;
+ case 5:


+ source2 = (long *) bh_ptr[2]->b_data;
+ source3 = (long *) bh_ptr[3]->b_data;

+ source4 = (long *) bh_ptr[4]->b_data;

+ xor %%g5, %%l1, %%g5

+ ldd [%3 + 0x08], %%l0


+ xor %%o0, %%l2, %%o0
+ xor %%o1, %%l3, %%o1

+ ldd [%3 + 0x10], %%l2


+ xor %%o2, %%l4, %%o2
+ xor %%o3, %%l5, %%o3

+ ldd [%3 + 0x18], %%l4


+ xor %%g2, %%o4, %%g2
+ xor %%g3, %%o5, %%g3

+ ldd [%4 + 0x00], %%o4


+ xor %%g4, %%l0, %%g4
+ xor %%g5, %%l1, %%g5

+ ldd [%4 + 0x08], %%l0


+ xor %%o0, %%l2, %%o0
+ xor %%o1, %%l3, %%o1

+ ldd [%4 + 0x10], %%l2


+ xor %%o2, %%l4, %%o2
+ xor %%o3, %%l5, %%o3

+ ldd [%4 + 0x18], %%l4


+ xor %%g2, %%o4, %%g2
+ xor %%g3, %%o5, %%g3
+ xor %%g4, %%l0, %%g4
+ xor %%g5, %%l1, %%g5
+ xor %%o0, %%l2, %%o0
+ xor %%o1, %%l3, %%o1
+ xor %%o2, %%l4, %%o2
+ xor %%o3, %%l5, %%o3
+ std %%g2, [%0 + 0x00]
+ std %%g4, [%0 + 0x08]
+ std %%o0, [%0 + 0x10]
+ std %%o2, [%0 + 0x18]

+ " : : "r" (destp), "r" (source1), "r" (source2), "r" (source3), "r" (source4)


+ : "g2", "g3", "g4", "g5", "o0", "o1", "o2", "o3", "o4", "o5",
+ "l0", "l1", "l2", "l3", "l4", "l5");
+ destp += 8;
+ source1 += 8;
+ source2 += 8;

+ source3 += 8;
+ source4 += 8;
+ }
+ break;
+ }
+}
+#endif /* __sparc_v[78]__ */
+
+#ifdef __alpha__
+/*
+ * High speed xor_block operation for RAID4/5 pipelined for Alpha EV5.
+ * There is a second version using EV6 prefetch instructions.
+ *
+ * Copyright (C) 2000 Richard Henderson (r...@redhat.com)
+ */
+
+XORBLOCK_TEMPLATE(alpha)
+{
+ long lines = bh_ptr[0]->b_size / sizeof (long) / 8;
+ long *d = (long *) bh_ptr[0]->b_data;
+ long *s1 = (long *) bh_ptr[1]->b_data;
+ long *s2, *s3, *s4;
+
+ if (count == 2) goto two_blocks;
+
+ s2 = (long *) bh_ptr[2]->b_data;
+ if (count == 3) goto three_blocks;
+
+ s3 = (long *) bh_ptr[3]->b_data;
+ if (count == 4) goto four_blocks;
+
+ s4 = (long *) bh_ptr[4]->b_data;
+ goto five_blocks;
+
+two_blocks:
+asm volatile ("
+ .align 4
+2:
+ ldq $0,0(%0)
+ ldq $1,0(%1)
+ ldq $2,8(%0)
+ ldq $3,8(%1)
+
+ ldq $4,16(%0)
+ ldq $5,16(%1)
+ ldq $6,24(%0)
+ ldq $7,24(%1)
+
+ ldq $16,32(%0)
+ ldq $17,32(%1)
+ ldq $18,40(%0)
+ ldq $19,40(%1)
+
+ ldq $20,48(%0)
+ ldq $21,48(%1)
+ ldq $22,56(%0)
+ xor $0,$1,$0 # 7 cycles from $1 load
+
+ ldq $23,56(%1)
+ xor $2,$3,$2
+ stq $0,0(%0)
+ xor $4,$5,$4
+
+ stq $2,8(%0)
+ xor $6,$7,$6
+ stq $4,16(%0)
+ xor $16,$17,$16
+
+ stq $6,24(%0)
+ xor $18,$19,$18
+ stq $16,32(%0)
+ xor $20,$21,$20
+
+ stq $18,40(%0)
+ xor $22,$23,$22
+ stq $20,48(%0)
+ subq %2,1,%2
+
+ stq $22,56(%0)
+ addq %0,64,%0
+ addq %1,64,%1
+ bgt %2,2b"
+ : "=r"(d), "=r"(s1), "=r"(lines)
+ : "0"(d), "1"(s1), "2"(lines)
+ : "memory", "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
+ "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23");
+ return;
+
+three_blocks:
+asm volatile ("
+ .align 4
+3:
+ ldq $0,0(%0)
+ ldq $1,0(%1)
+ ldq $2,0(%2)
+ ldq $3,8(%0)
+
+ ldq $4,8(%1)
+ ldq $6,16(%0)
+ ldq $7,16(%1)
+ ldq $17,24(%0)
+
+ ldq $18,24(%1)
+ ldq $20,32(%0)
+ ldq $21,32(%1)
+ ldq $5,8(%2)
+
+ ldq $16,16(%2)
+ ldq $19,24(%2)
+ ldq $22,32(%2)
+ nop
+
+ xor $0,$1,$1 # 8 cycles from $0 load
+ xor $3,$4,$4 # 6 cycles from $4 load
+ xor $6,$7,$7 # 6 cycles from $7 load
+ xor $17,$18,$18 # 5 cycles from $18 load
+
+ xor $1,$2,$2 # 9 cycles from $2 load
+ xor $20,$21,$21 # 5 cycles from $21 load
+ stq $2,0(%0)
+ xor $4,$5,$5 # 6 cycles from $5 load
+
+ stq $5,8(%0)
+ xor $7,$16,$16 # 7 cycles from $16 load
+ stq $16,16(%0)
+ xor $18,$19,$19 # 7 cycles from $19 load
+
+ stq $19,24(%0)
+ xor $21,$22,$22 # 7 cycles from $22 load
+ stq $22,32(%0)
+ nop
+
+ ldq $0,40(%0)
+ ldq $1,40(%1)
+ ldq $3,48(%0)
+ ldq $4,48(%1)
+
+ ldq $6,56(%0)
+ ldq $7,56(%1)
+ ldq $2,40(%2)
+ ldq $5,48(%2)
+
+ ldq $16,56(%2)
+ xor $0,$1,$1 # 4 cycles from $1 load
+ xor $3,$4,$4 # 5 cycles from $4 load
+ xor $6,$7,$7 # 5 cycles from $7 load
+
+ xor $1,$2,$2 # 4 cycles from $2 load
+ xor $4,$5,$5 # 5 cycles from $5 load
+ stq $2,40(%0)
+ xor $7,$16,$16 # 4 cycles from $16 load
+
+ stq $5,48(%0)
+ subq %3,1,%3
+ stq $16,56(%0)
+ addq %2,64,%2
+
+ addq %1,64,%1
+ addq %0,64,%0
+ bgt %3,3b"
+ : "=r"(d), "=r"(s1), "=r"(s2), "=r"(lines)
+ : "0"(d), "1"(s1), "2"(s2), "3"(lines)
+ : "memory", "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
+ "$16", "$17", "$18", "$19", "$20", "$21", "$22");
+ return;
+
+four_blocks:
+asm volatile ("
+ .align 4
+4:
+ ldq $0,0(%0)
+ ldq $1,0(%1)
+ ldq $2,0(%2)
+ ldq $3,0(%3)
+
+ ldq $4,8(%0)
+ ldq $5,8(%1)
+ ldq $6,8(%2)
+ ldq $7,8(%3)
+
+ ldq $16,16(%0)
+ ldq $17,16(%1)
+ ldq $18,16(%2)
+ ldq $19,16(%3)
+
+ ldq $20,24(%0)
+ xor $0,$1,$1 # 6 cycles from $1 load
+ ldq $21,24(%1)
+ xor $2,$3,$3 # 6 cycles from $3 load
+
+ ldq $0,24(%2)
+ xor $1,$3,$3
+ ldq $1,24(%3)
+ xor $4,$5,$5 # 7 cycles from $5 load
+
+ stq $3,0(%0)
+ xor $6,$7,$7
+ xor $16,$17,$17 # 7 cycles from $17 load
+ xor $5,$7,$7
+
+ stq $7,8(%0)
+ xor $18,$19,$19 # 7 cycles from $19 load
+ ldq $2,32(%0)
+ xor $17,$19,$19
+
+ ldq $3,32(%1)
+ ldq $4,32(%2)
+ ldq $5,32(%3)
+ xor $20,$21,$21 # 8 cycles from $21 load
+
+ ldq $6,40(%0)
+ ldq $7,40(%1)
+ ldq $16,40(%2)
+ ldq $17,40(%3)
+
+ stq $19,16(%0)
+ xor $0,$1,$1 # 9 cycles from $1 load
+ xor $2,$3,$3 # 5 cycles from $3 load
+ xor $21,$1,$1
+
+ ldq $18,48(%0)
+ xor $4,$5,$5 # 5 cycles from $5 load
+ ldq $19,48(%1)
+ xor $3,$5,$5
+
+ ldq $20,48(%2)
+ ldq $21,48(%3)
+ ldq $0,56(%0)
+ ldq $1,56(%1)
+
+ ldq $2,56(%2)
+ xor $6,$7,$7 # 8 cycles from $6 load
+ ldq $3,56(%3)
+ xor $16,$17,$17 # 8 cycles from $17 load
+
+ xor $7,$17,$17
+ xor $18,$19,$19 # 5 cycles from $19 load
+ xor $20,$21,$21 # 5 cycles from $21 load
+ xor $19,$21,$21
+
+ stq $1,24(%0)
+ xor $0,$1,$1 # 5 cycles from $1 load
+ stq $5,32(%0)
+ xor $2,$3,$3 # 4 cycles from $3 load
+
+ stq $17,40(%0)
+ xor $1,$3,$3
+ stq $21,48(%0)
+ subq %4,1,%4
+
+ stq $3,56(%0)
+ addq %3,64,%3
+ addq %2,64,%2
+ addq %1,64,%1
+
+ addq %0,64,%0
+ bgt %4,4b"
+ : "=r"(d), "=r"(s1), "=r"(s2), "=r"(s3), "=r"(lines)
+ : "0"(d), "1"(s1), "2"(s2), "3"(s3), "4"(lines)
+ : "memory", "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
+ "$16", "$17", "$18", "$19", "$20", "$21");
+ return;
+
+five_blocks:
+asm volatile ("
+ ldq %0,0(%6)
+ ldq %1,8(%6)
+ ldq %2,16(%6)
+ ldq %3,24(%6)
+ ldq %4,32(%6)
+ ldq %0,%7(%0)
+ ldq %1,%7(%1)
+ ldq %2,%7(%2)
+ ldq %3,%7(%3)
+ ldq %4,%7(%4)
+ .align 4
+5:
+ ldq $0,0(%0)
+ ldq $1,0(%1)
+ ldq $2,0(%2)
+ ldq $3,0(%3)
+
+ ldq $4,0(%4)
+ ldq $5,8(%0)
+ ldq $6,8(%1)
+ ldq $7,8(%2)
+
+ ldq $16,8(%3)
+ ldq $17,8(%4)
+ ldq $18,16(%0)
+ ldq $19,16(%1)
+
+ ldq $20,16(%2)
+ xor $0,$1,$1 # 6 cycles from $1 load
+ ldq $21,16(%3)
+ xor $2,$3,$3 # 6 cycles from $3 load
+
+ ldq $0,16(%4)
+ xor $1,$3,$3
+ ldq $1,24(%0)
+ xor $3,$4,$4 # 7 cycles from $4 load
+
+ stq $4,0(%0)
+ xor $5,$6,$6 # 7 cycles from $6 load
+ xor $7,$16,$16 # 7 cycles from $16 load
+ xor $6,$17,$17 # 7 cycles from $17 load
+
+ ldq $2,24(%1)
+ xor $16,$17,$17
+ ldq $3,24(%2)
+ xor $18,$19,$19 # 8 cycles from $19 load
+
+ stq $17,8(%0)
+ xor $19,$20,$20 # 8 cycles from $20 load
+ ldq $4,24(%3)
+ xor $21,$0,$0 # 7 cycles from $0 load
+
+ ldq $5,24(%4)
+ xor $20,$0,$0
+ ldq $6,32(%0)
+ ldq $7,32(%1)
+
+ stq $0,16(%0)
+ xor $1,$2,$2 # 6 cycles from $2 load
+ ldq $16,32(%2)
+ xor $3,$4,$4 # 4 cycles from $4 load
+
+ ldq $17,32(%3)
+ xor $2,$4,$4
+ ldq $18,32(%4)
+ ldq $19,40(%0)
+
+ ldq $20,40(%1)
+ ldq $21,40(%2)
+ ldq $0,40(%3)
+ xor $4,$5,$5 # 7 cycles from $5 load
+
+ stq $5,24(%0)
+ xor $6,$7,$7 # 7 cycles from $7 load
+ ldq $1,40(%4)
+ ldq $2,48(%0)
+
+ ldq $3,48(%1)
+ xor $7,$16,$16 # 7 cycles from $16 load
+ ldq $4,48(%2)
+ xor $17,$18,$18 # 6 cycles from $18 load
+
+ ldq $5,48(%3)
+ xor $16,$18,$18
+ ldq $6,48(%4)
+ xor $19,$20,$20 # 7 cycles from $20 load
+
+ stq $18,32(%0)
+ xor $20,$21,$21 # 8 cycles from $21 load
+ ldq $7,56(%0)
+ xor $0,$1,$1 # 6 cycles from $1 load
+
+ ldq $16,56(%1)
+ ldq $17,56(%2)
+ ldq $18,56(%3)
+ ldq $19,56(%4)
+
+ xor $21,$1,$1
+ xor $2,$3,$3 # 9 cycles from $3 load
+ xor $3,$4,$4 # 9 cycles from $4 load
+ xor $5,$6,$6 # 8 cycles from $6 load
+
+ unop
+ xor $4,$6,$6
+ xor $7,$16,$16 # 7 cycles from $16 load
+ xor $17,$18,$18 # 6 cycles from $18 load
+
+ stq $6,48(%0)
+ xor $16,$18,$18
+ subq %5,1,%5
+ xor $18,$19,$19 # 8 cycles from $19 load
+
+ stq $19,56(%0)
+ addq %4,64,%4
+ addq %3,64,%3
+ addq %2,64,%2
+
+ addq %1,64,%1
+ addq %0,64,%0
+ bgt %5,5b"
+ : "=&r"(d), "=&r"(s1), "=&r"(s2), "=&r"(s3), "=r"(s4), "=r"(lines)
+ /* ARG! We've run out of asm arguments! We've got to reload
+ all those pointers we just loaded. */
+ : "r"(bh_ptr), "i" (&((struct buffer_head *)0)->b_data), "5"(lines)
+ : "memory", "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
+ "$16", "$17", "$18", "$19", "$20", "$21");
+ return;
+}
+
+#define prefetch(base, ofs) \
+ asm("ldq $31,%2(%0)" : "=r"(base) : "0"(base), "i"(ofs))
+
+XORBLOCK_TEMPLATE(alpha_prefetch)
+{
+ long lines = bh_ptr[0]->b_size / sizeof (long) / 8;
+ long *d = (long *) bh_ptr[0]->b_data;
+ long *s1 = (long *) bh_ptr[1]->b_data;
+ long *s2, *s3, *s4;
+ long p;
+
+ p = count == 2;
+ prefetch(d, 0);
+ prefetch(s1, 0);
+ prefetch(d, 64);
+ prefetch(s1, 64);
+ prefetch(d, 128);
+ prefetch(s1, 128);
+ prefetch(d, 192);
+ prefetch(s1, 192);
+ if (p) goto two_blocks;
+
+ s2 = (long *) bh_ptr[2]->b_data;
+ p = count == 3;
+ prefetch(s2, 0);
+ prefetch(s2, 64);
+ prefetch(s2, 128);
+ prefetch(s2, 192);
+ if (p) goto three_blocks;
+
+ s3 = (long *) bh_ptr[3]->b_data;
+ p = count == 4;
+ prefetch(s3, 0);
+ prefetch(s3, 64);
+ prefetch(s3, 128);
+ prefetch(s3, 192);
+ if (p) goto four_blocks;
+
+ s4 = (long *) bh_ptr[4]->b_data;
+ prefetch(s4, 0);
+ prefetch(s4, 64);
+ prefetch(s4, 128);
+ prefetch(s4, 192);
+ goto five_blocks;
+
+two_blocks:
+asm volatile ("
+ .align 4
+2:
+ ldq $0,0(%0)
+ ldq $1,0(%1)
+ ldq $2,8(%0)
+ ldq $3,8(%1)
+
+ ldq $4,16(%0)
+ ldq $5,16(%1)
+ ldq $6,24(%0)
+ ldq $7,24(%1)
+
+ ldq $16,32(%0)
+ ldq $17,32(%1)
+ ldq $18,40(%0)
+ ldq $19,40(%1)
+
+ ldq $20,48(%0)
+ ldq $21,48(%1)
+ ldq $22,56(%0)
+ ldq $23,56(%1)
+
+ ldq $31,256(%0)
+ xor $0,$1,$0 # 8 cycles from $1 load
+ ldq $31,256(%1)
+ xor $2,$3,$2
+
+ stq $0,0(%0)
+ xor $4,$5,$4
+ stq $2,8(%0)
+ xor $6,$7,$6
+
+ stq $4,16(%0)
+ xor $16,$17,$16
+ stq $6,24(%0)
+ xor $18,$19,$18
+
+ stq $16,32(%0)
+ xor $20,$21,$20
+ stq $18,40(%0)
+ xor $22,$23,$22
+
+ stq $20,48(%0)
+ subq %2,1,%2
+ stq $22,56(%0)
+ addq %0,64,%0
+
+ addq %1,64,%1
+ bgt %2,2b"
+ : "=r"(d), "=r"(s1), "=r"(lines)
+ : "0"(d), "1"(s1), "2"(lines)
+ : "memory", "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
+ "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23");
+ return;
+
+three_blocks:
+asm volatile ("
+ .align 4
+3:
+ ldq $0,0(%0)
+ ldq $1,0(%1)
+ ldq $2,0(%2)
+ ldq $3,8(%0)
+
+ ldq $4,8(%1)
+ ldq $6,16(%0)
+ ldq $7,16(%1)
+ ldq $17,24(%0)
+
+ ldq $18,24(%1)
+ ldq $20,32(%0)
+ ldq $21,32(%1)
+ ldq $5,8(%2)
+
+ ldq $16,16(%2)
+ ldq $19,24(%2)
+ ldq $22,32(%2)
+ nop
+
+ xor $0,$1,$1 # 8 cycles from $0 load
+ xor $3,$4,$4 # 7 cycles from $4 load
+ xor $6,$7,$7 # 6 cycles from $7 load
+ xor $17,$18,$18 # 5 cycles from $18 load
+
+ xor $1,$2,$2 # 9 cycles from $2 load
+ xor $20,$21,$21 # 5 cycles from $21 load
+ stq $2,0(%0)
+ xor $4,$5,$5 # 6 cycles from $5 load
+
+ stq $5,8(%0)
+ xor $7,$16,$16 # 7 cycles from $16 load
+ stq $16,16(%0)
+ xor $18,$19,$19 # 7 cycles from $19 load
+
+ stq $19,24(%0)
+ xor $21,$22,$22 # 7 cycles from $22 load
+ stq $22,32(%0)
+ nop
+
+ ldq $0,40(%0)
+ ldq $1,40(%1)
+ ldq $3,48(%0)
+ ldq $4,48(%1)
+
+ ldq $6,56(%0)
+ ldq $7,56(%1)
+ ldq $2,40(%2)
+ ldq $5,48(%2)
+
+ ldq $16,56(%2)
+ ldq $31,256(%0)
+ ldq $31,256(%1)
+ ldq $31,256(%2)
+
+ xor $0,$1,$1 # 6 cycles from $1 load
+ xor $3,$4,$4 # 5 cycles from $4 load
+ xor $6,$7,$7 # 5 cycles from $7 load
+ xor $1,$2,$2 # 4 cycles from $2 load
+
+ xor $4,$5,$5 # 5 cycles from $5 load
+ xor $7,$16,$16 # 4 cycles from $16 load
+ stq $2,40(%0)
+ subq %3,1,%3
+
+ stq $5,48(%0)
+ addq %2,64,%2
+ stq $16,56(%0)
+ addq %1,64,%1
+
+ addq %0,64,%0
+ bgt %3,3b"
+ : "=r"(d), "=r"(s1), "=r"(s2), "=r"(lines)
+ : "0"(d), "1"(s1), "2"(s2), "3"(lines)
+ : "memory", "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
+ "$16", "$17", "$18", "$19", "$20", "$21", "$22");
+ return;
+
+four_blocks:
+asm volatile ("
+ .align 4
+4:
+ ldq $0,0(%0)
+ ldq $1,0(%1)
+ ldq $2,0(%2)
+ ldq $3,0(%3)
+
+ ldq $4,8(%0)
+ ldq $5,8(%1)
+ ldq $6,8(%2)
+ ldq $7,8(%3)
+
+ ldq $16,16(%0)
+ ldq $17,16(%1)
+ ldq $18,16(%2)
+ ldq $19,16(%3)
+
+ ldq $20,24(%0)
+ xor $0,$1,$1 # 6 cycles from $1 load
+ ldq $21,24(%1)
+ xor $2,$3,$3 # 6 cycles from $3 load
+
+ ldq $0,24(%2)
+ xor $1,$3,$3
+ ldq $1,24(%3)
+ xor $4,$5,$5 # 7 cycles from $5 load
+
+ stq $3,0(%0)
+ xor $6,$7,$7
+ xor $16,$17,$17 # 7 cycles from $17 load
+ xor $5,$7,$7
+
+ stq $7,8(%0)
+ xor $18,$19,$19 # 7 cycles from $19 load
+ ldq $2,32(%0)
+ xor $17,$19,$19
+
+ ldq $3,32(%1)
+ ldq $4,32(%2)
+ ldq $5,32(%3)
+ xor $20,$21,$21 # 8 cycles from $21 load
+
+ ldq $6,40(%0)
+ ldq $7,40(%1)
+ ldq $16,40(%2)
+ ldq $17,40(%3)
+
+ stq $19,16(%0)
+ xor $0,$1,$1 # 9 cycles from $1 load
+ xor $2,$3,$3 # 5 cycles from $3 load
+ xor $21,$1,$1
+
+ ldq $18,48(%0)
+ xor $4,$5,$5 # 5 cycles from $5 load
+ ldq $19,48(%1)
+ xor $3,$5,$5
+
+ ldq $20,48(%2)
+ ldq $21,48(%3)
+ ldq $0,56(%0)
+ ldq $1,56(%1)
+
+ ldq $2,56(%2)
+ xor $6,$7,$7 # 8 cycles from $6 load
+ ldq $3,56(%3)
+ xor $16,$17,$17 # 8 cycles from $17 load
+
+ ldq $31,256(%0)
+ xor $7,$17,$17
+ ldq $31,256(%1)
+ xor $18,$19,$19 # 6 cycles from $19 load
+
+ ldq $31,256(%2)
+ xor $20,$21,$21 # 6 cycles from $21 load
+ ldq $31,256(%3)
+ xor $19,$21,$21
+
+ stq $1,24(%0)
+ xor $0,$1,$1 # 7 cycles from $1 load
+ stq $5,32(%0)
+ xor $2,$3,$3 # 6 cycles from $3 load
+
+ stq $17,40(%0)
+ xor $1,$3,$3
+ stq $21,48(%0)
+ subq %4,1,%4
+
+ stq $3,56(%0)
+ addq %3,64,%3
+ addq %2,64,%2
+ addq %1,64,%1
+
+ addq %0,64,%0
+ bgt %4,4b"
+ : "=r"(d), "=r"(s1), "=r"(s2), "=r"(s3), "=r"(lines)
+ : "0"(d), "1"(s1), "2"(s2), "3"(s3), "4"(lines)
+ : "memory", "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
+ "$16", "$17", "$18", "$19", "$20", "$21");
+ return;
+
+five_blocks:
+asm volatile ("
+ ldq %0,0(%6)
+ ldq %1,8(%6)
+ ldq %2,16(%6)
+ ldq %3,24(%6)
+ ldq %4,32(%6)
+ ldq %0,%7(%0)
+ ldq %1,%7(%1)
+ ldq %2,%7(%2)
+ ldq %3,%7(%3)
+ ldq %4,%7(%4)
+ .align 4
+5:
+ ldq $0,0(%0)
+ ldq $1,0(%1)
+ ldq $2,0(%2)
+ ldq $3,0(%3)
+
+ ldq $4,0(%4)
+ ldq $5,8(%0)
+ ldq $6,8(%1)
+ ldq $7,8(%2)
+
+ ldq $16,8(%3)
+ ldq $17,8(%4)
+ ldq $18,16(%0)
+ ldq $19,16(%1)
+
+ ldq $20,16(%2)
+ xor $0,$1,$1 # 6 cycles from $1 load
+ ldq $21,16(%3)
+ xor $2,$3,$3 # 6 cycles from $3 load
+
+ ldq $0,16(%4)
+ xor $1,$3,$3
+ ldq $1,24(%0)
+ xor $3,$4,$4 # 7 cycles from $4 load
+
+ stq $4,0(%0)
+ xor $5,$6,$6 # 7 cycles from $6 load
+ xor $7,$16,$16 # 7 cycles from $16 load
+ xor $6,$17,$17 # 7 cycles from $17 load
+
+ ldq $2,24(%1)
+ xor $16,$17,$17
+ ldq $3,24(%2)
+ xor $18,$19,$19 # 8 cycles from $19 load
+
+ stq $17,8(%0)
+ xor $19,$20,$20 # 8 cycles from $20 load
+ ldq $4,24(%3)
+ xor $21,$0,$0 # 7 cycles from $0 load
+
+ ldq $5,24(%4)
+ xor $20,$0,$0
+ ldq $6,32(%0)
+ ldq $7,32(%1)
+
+ stq $0,16(%0)
+ xor $1,$2,$2 # 6 cycles from $2 load
+ ldq $16,32(%2)
+ xor $3,$4,$4 # 4 cycles from $4 load
+
+ ldq $17,32(%3)
+ xor $2,$4,$4
+ ldq $18,32(%4)
+ ldq $19,40(%0)
+
+ ldq $20,40(%1)
+ ldq $21,40(%2)
+ ldq $0,40(%3)
+ xor $4,$5,$5 # 7 cycles from $5 load
+
+ stq $5,24(%0)
+ xor $6,$7,$7 # 7 cycles from $7 load
+ ldq $1,40(%4)
+ ldq $2,48(%0)
+
+ ldq $3,48(%1)
+ xor $7,$16,$16 # 7 cycles from $16 load
+ ldq $4,48(%2)
+ xor $17,$18,$18 # 6 cycles from $18 load
+
+ ldq $5,48(%3)
+ xor $16,$18,$18
+ ldq $6,48(%4)
+ xor $19,$20,$20 # 7 cycles from $20 load
+
+ stq $18,32(%0)
+ xor $20,$21,$21 # 8 cycles from $21 load
+ ldq $7,56(%0)
+ xor $0,$1,$1 # 6 cycles from $1 load
+
+ ldq $16,56(%1)
+ ldq $17,56(%2)
+ ldq $18,56(%3)
+ ldq $19,56(%4)
+
+ ldq $31,256(%0)
+ xor $21,$1,$1
+ ldq $31,256(%1)
+ xor $2,$3,$3 # 9 cycles from $3 load
+
+ ldq $31,256(%2)
+ xor $3,$4,$4 # 9 cycles from $4 load
+ ldq $31,256(%3)
+ xor $5,$6,$6 # 8 cycles from $6 load
+
+ ldq $31,256(%4)
+ xor $4,$6,$6
+ xor $7,$16,$16 # 7 cycles from $16 load
+ xor $17,$18,$18 # 6 cycles from $18 load
+
+ stq $6,48(%0)
+ xor $16,$18,$18
+ subq %5,1,%5
+ xor $18,$19,$19 # 8 cycles from $19 load
+
+ stq $19,56(%0)
+ addq %4,64,%4
+ addq %3,64,%3
+ addq %2,64,%2
+
+ addq %1,64,%1
+ addq %0,64,%0
+ bgt %5,5b"
+ : "=&r"(d), "=&r"(s1), "=&r"(s2), "=&r"(s3), "=r"(s4), "=r"(lines)
+ /* ARG! We've run out of asm arguments! We've got to reload
+ all those pointers we just loaded. */
+ : "r"(bh_ptr), "i" (&((struct buffer_head *)0)->b_data), "5"(lines)
+ : "memory", "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
+ "$16", "$17", "$18", "$19", "$20", "$21");
+ return;
+}
+
+#undef prefetch
+
+#endif /* __alpha__ */
+
+#ifndef __sparc_v9__
+
+/*
+ * this one works reasonably on any x86 CPU
+ * (send me an assembly version for inclusion if you can make it faster)
+ *
+ * this one is just as fast as written in pure assembly on x86.
+ * the reason for this separate version is that the
+ * fast open-coded xor routine "32reg" produces suboptimal code
+ * on x86, due to lack of registers.
+ */
+XORBLOCK_TEMPLATE(8regs)
+{
+ int len = bh_ptr[0]->b_size;


+ long *destp = (long *) bh_ptr[0]->b_data;

+ long *source1, *source2, *source3, *source4;
+ long lines = len / (sizeof (long)) / 8, i;
+


+ switch(count) {
+ case 2:

+ source1 = (long *) bh_ptr[1]->b_data;


+ for (i = lines; i > 0; i--) {

+ *(destp + 0) ^= *(source1 + 0);
+ *(destp + 1) ^= *(source1 + 1);
+ *(destp + 2) ^= *(source1 + 2);
+ *(destp + 3) ^= *(source1 + 3);
+ *(destp + 4) ^= *(source1 + 4);
+ *(destp + 5) ^= *(source1 + 5);
+ *(destp + 6) ^= *(source1 + 6);
+ *(destp + 7) ^= *(source1 + 7);
+ source1 += 8;
+ destp += 8;


+ }
+ break;
+ case 3:
+ source2 = (long *) bh_ptr[2]->b_data;

+ source1 = (long *) bh_ptr[1]->b_data;


+ for (i = lines; i > 0; i--) {

+ *(destp + 0) ^= *(source1 + 0);
+ *(destp + 0) ^= *(source2 + 0);
+ *(destp + 1) ^= *(source1 + 1);
+ *(destp + 1) ^= *(source2 + 1);
+ *(destp + 2) ^= *(source1 + 2);
+ *(destp + 2) ^= *(source2 + 2);
+ *(destp + 3) ^= *(source1 + 3);
+ *(destp + 3) ^= *(source2 + 3);
+ *(destp + 4) ^= *(source1 + 4);
+ *(destp + 4) ^= *(source2 + 4);
+ *(destp + 5) ^= *(source1 + 5);
+ *(destp + 5) ^= *(source2 + 5);
+ *(destp + 6) ^= *(source1 + 6);
+ *(destp + 6) ^= *(source2 + 6);
+ *(destp + 7) ^= *(source1 + 7);
+ *(destp + 7) ^= *(source2 + 7);


+ source1 += 8;
+ source2 += 8;

+ destp += 8;


+ }
+ break;
+ case 4:

+ source3 = (long *) bh_ptr[3]->b_data;

+ source2 = (long *) bh_ptr[2]->b_data;

+ source1 = (long *) bh_ptr[1]->b_data;


+ for (i = lines; i > 0; i--) {

+ *(destp + 0) ^= *(source1 + 0);
+ *(destp + 0) ^= *(source2 + 0);
+ *(destp + 0) ^= *(source3 + 0);
+ *(destp + 1) ^= *(source1 + 1);
+ *(destp + 1) ^= *(source2 + 1);
+ *(destp + 1) ^= *(source3 + 1);
+ *(destp + 2) ^= *(source1 + 2);
+ *(destp + 2) ^= *(source2 + 2);
+ *(destp + 2) ^= *(source3 + 2);
+ *(destp + 3) ^= *(source1 + 3);
+ *(destp + 3) ^= *(source2 + 3);
+ *(destp + 3) ^= *(source3 + 3);
+ *(destp + 4) ^= *(source1 + 4);
+ *(destp + 4) ^= *(source2 + 4);
+ *(destp + 4) ^= *(source3 + 4);
+ *(destp + 5) ^= *(source1 + 5);
+ *(destp + 5) ^= *(source2 + 5);
+ *(destp + 5) ^= *(source3 + 5);
+ *(destp + 6) ^= *(source1 + 6);
+ *(destp + 6) ^= *(source2 + 6);
+ *(destp + 6) ^= *(source3 + 6);
+ *(destp + 7) ^= *(source1 + 7);
+ *(destp + 7) ^= *(source2 + 7);
+ *(destp + 7) ^= *(source3 + 7);


+ source1 += 8;
+ source2 += 8;

+ source3 += 8;


+ destp += 8;
+ }

+ break;
+ case 5:

+ source4 = (long *) bh_ptr[4]->b_data;


+ source3 = (long *) bh_ptr[3]->b_data;

+ source2 = (long *) bh_ptr[2]->b_data;

+ source1 = (long *) bh_ptr[1]->b_data;


+ for (i = lines; i > 0; i--) {

+ *(destp + 0) ^= *(source1 + 0);
+ *(destp + 0) ^= *(source2 + 0);
+ *(destp + 0) ^= *(source3 + 0);
+ *(destp + 0) ^= *(source4 + 0);
+ *(destp + 1) ^= *(source1 + 1);
+ *(destp + 1) ^= *(source2 + 1);
+ *(destp + 1) ^= *(source3 + 1);
+ *(destp + 1) ^= *(source4 + 1);
+ *(destp + 2) ^= *(source1 + 2);
+ *(destp + 2) ^= *(source2 + 2);
+ *(destp + 2) ^= *(source3 + 2);
+ *(destp + 2) ^= *(source4 + 2);
+ *(destp + 3) ^= *(source1 + 3);
+ *(destp + 3) ^= *(source2 + 3);
+ *(destp + 3) ^= *(source3 + 3);
+ *(destp + 3) ^= *(source4 + 3);
+ *(destp + 4) ^= *(source1 + 4);
+ *(destp + 4) ^= *(source2 + 4);
+ *(destp + 4) ^= *(source3 + 4);
+ *(destp + 4) ^= *(source4 + 4);
+ *(destp + 5) ^= *(source1 + 5);
+ *(destp + 5) ^= *(source2 + 5);
+ *(destp + 5) ^= *(source3 + 5);
+ *(destp + 5) ^= *(source4 + 5);
+ *(destp + 6) ^= *(source1 + 6);
+ *(destp + 6) ^= *(source2 + 6);
+ *(destp + 6) ^= *(source3 + 6);
+ *(destp + 6) ^= *(source4 + 6);
+ *(destp + 7) ^= *(source1 + 7);
+ *(destp + 7) ^= *(source2 + 7);
+ *(destp + 7) ^= *(source3 + 7);
+ *(destp + 7) ^= *(source4 + 7);


+ source1 += 8;
+ source2 += 8;

+ source3 += 8;
+ source4 += 8;


+ destp += 8;
+ }

+ break;
+ }
+}
+

+/*
+ * platform independent RAID5 checksum calculation, this should
+ * be very fast on any platform that has a decent amount of
+ * registers. (32 or more)
+ */
+XORBLOCK_TEMPLATE(32regs)


+{
+ int size = bh_ptr[0]->b_size;
+ int lines = size / (sizeof (long)) / 8, i;
+ long *destp = (long *) bh_ptr[0]->b_data;

+ long *source1, *source2, *source3, *source4;
+
+ /* LOTS of registers available...
+ We do explicite loop-unrolling here for code which
+ favours RISC machines. In fact this is almoast direct
+ RISC assembly on Alpha and SPARC :-) */
+


+
+ switch(count) {
+ case 2:

+ source1 = (long *) bh_ptr[1]->b_data;


+ for (i = lines; i > 0; i--) {

+ register long d0, d1, d2, d3, d4, d5, d6, d7;
+ d0 = destp[0]; /* Pull the stuff into registers */
+ d1 = destp[1]; /* ... in bursts, if possible. */
+ d2 = destp[2];
+ d3 = destp[3];
+ d4 = destp[4];
+ d5 = destp[5];
+ d6 = destp[6];
+ d7 = destp[7];
+ d0 ^= source1[0];
+ d1 ^= source1[1];
+ d2 ^= source1[2];
+ d3 ^= source1[3];
+ d4 ^= source1[4];
+ d5 ^= source1[5];
+ d6 ^= source1[6];
+ d7 ^= source1[7];
+ destp[0] = d0; /* Store the result (in burts) */
+ destp[1] = d1;
+ destp[2] = d2;
+ destp[3] = d3;
+ destp[4] = d4; /* Store the result (in burts) */
+ destp[5] = d5;
+ destp[6] = d6;
+ destp[7] = d7;
+ source1 += 8;
+ destp += 8;


+ }
+ break;
+ case 3:
+ source2 = (long *) bh_ptr[2]->b_data;

+ source1 = (long *) bh_ptr[1]->b_data;


+ for (i = lines; i > 0; i--) {

+ register long d0, d1, d2, d3, d4, d5, d6, d7;
+ d0 = destp[0]; /* Pull the stuff into registers */
+ d1 = destp[1]; /* ... in bursts, if possible. */
+ d2 = destp[2];
+ d3 = destp[3];
+ d4 = destp[4];
+ d5 = destp[5];
+ d6 = destp[6];
+ d7 = destp[7];
+ d0 ^= source1[0];
+ d1 ^= source1[1];
+ d2 ^= source1[2];
+ d3 ^= source1[3];
+ d4 ^= source1[4];
+ d5 ^= source1[5];
+ d6 ^= source1[6];
+ d7 ^= source1[7];
+ d0 ^= source2[0];
+ d1 ^= source2[1];
+ d2 ^= source2[2];
+ d3 ^= source2[3];
+ d4 ^= source2[4];
+ d5 ^= source2[5];
+ d6 ^= source2[6];
+ d7 ^= source2[7];
+ destp[0] = d0; /* Store the result (in burts) */
+ destp[1] = d1;
+ destp[2] = d2;
+ destp[3] = d3;
+ destp[4] = d4; /* Store the result (in burts) */
+ destp[5] = d5;
+ destp[6] = d6;
+ destp[7] = d7;


+ source1 += 8;
+ source2 += 8;

+ destp += 8;


+ }
+ break;
+ case 4:

+ source3 = (long *) bh_ptr[3]->b_data;

+ source2 = (long *) bh_ptr[2]->b_data;

+ source1 = (long *) bh_ptr[1]->b_data;


+ for (i = lines; i > 0; i--) {

+ register long d0, d1, d2, d3, d4, d5, d6, d7;
+ d0 = destp[0]; /* Pull the stuff into registers */
+ d1 = destp[1]; /* ... in bursts, if possible. */
+ d2 = destp[2];
+ d3 = destp[3];
+ d4 = destp[4];
+ d5 = destp[5];
+ d6 = destp[6];
+ d7 = destp[7];
+ d0 ^= source1[0];
+ d1 ^= source1[1];
+ d2 ^= source1[2];
+ d3 ^= source1[3];
+ d4 ^= source1[4];
+ d5 ^= source1[5];
+ d6 ^= source1[6];
+ d7 ^= source1[7];
+ d0 ^= source2[0];
+ d1 ^= source2[1];
+ d2 ^= source2[2];
+ d3 ^= source2[3];
+ d4 ^= source2[4];
+ d5 ^= source2[5];
+ d6 ^= source2[6];
+ d7 ^= source2[7];
+ d0 ^= source3[0];
+ d1 ^= source3[1];
+ d2 ^= source3[2];
+ d3 ^= source3[3];
+ d4 ^= source3[4];
+ d5 ^= source3[5];
+ d6 ^= source3[6];
+ d7 ^= source3[7];
+ destp[0] = d0; /* Store the result (in burts) */
+ destp[1] = d1;
+ destp[2] = d2;
+ destp[3] = d3;
+ destp[4] = d4; /* Store the result (in burts) */
+ destp[5] = d5;
+ destp[6] = d6;
+ destp[7] = d7;


+ source1 += 8;
+ source2 += 8;

+ source3 += 8;


+ destp += 8;
+ }

+ break;
+ case 5:

+ source4 = (long *) bh_ptr[4]->b_data;


+ source3 = (long *) bh_ptr[3]->b_data;

+ source2 = (long *) bh_ptr[2]->b_data;

+ source1 = (long *) bh_ptr[1]->b_data;


+ for (i = lines; i > 0; i--) {

+ register long d0, d1, d2, d3, d4, d5, d6, d7;
+ d0 = destp[0]; /* Pull the stuff into registers */
+ d1 = destp[1]; /* ... in bursts, if possible. */
+ d2 = destp[2];
+ d3 = destp[3];
+ d4 = destp[4];
+ d5 = destp[5];
+ d6 = destp[6];
+ d7 = destp[7];
+ d0 ^= source1[0];
+ d1 ^= source1[1];
+ d2 ^= source1[2];
+ d3 ^= source1[3];
+ d4 ^= source1[4];
+ d5 ^= source1[5];
+ d6 ^= source1[6];
+ d7 ^= source1[7];
+ d0 ^= source2[0];
+ d1 ^= source2[1];
+ d2 ^= source2[2];
+ d3 ^= source2[3];
+ d4 ^= source2[4];
+ d5 ^= source2[5];
+ d6 ^= source2[6];
+ d7 ^= source2[7];
+ d0 ^= source3[0];
+ d1 ^= source3[1];
+ d2 ^= source3[2];
+ d3 ^= source3[3];
+ d4 ^= source3[4];
+ d5 ^= source3[5];
+ d6 ^= source3[6];
+ d7 ^= source3[7];
+ d0 ^= source4[0];
+ d1 ^= source4[1];
+ d2 ^= source4[2];
+ d3 ^= source4[3];
+ d4 ^= source4[4];
+ d5 ^= source4[5];
+ d6 ^= source4[6];
+ d7 ^= source4[7];
+ destp[0] = d0; /* Store the result (in burts) */
+ destp[1] = d1;
+ destp[2] = d2;
+ destp[3] = d3;
+ destp[4] = d4; /* Store the result (in burts) */
+ destp[5] = d5;
+ destp[6] = d6;
+ destp[7] = d7;


+ source1 += 8;
+ source2 += 8;

+ source3 += 8;
+ source4 += 8;


+ destp += 8;
+ }

+ break;
+ }
+}
+

+/*
+ * (the -6*32 shift factor colors the cache)
+ */
+#define SIZE (PAGE_SIZE-6*32)
+
+static void xor_speed ( struct xor_block_template * func,
+ struct buffer_head *b1, struct buffer_head *b2)
+{
+ int speed;
+ unsigned long now;
+ int i, count, max;
+ struct buffer_head *bh_ptr[6];
+
+ func->next = xor_functions;
+ xor_functions = func;
+ bh_ptr[0] = b1;
+ bh_ptr[1] = b2;
+
+ /*
+ * count the number of XORs done during a whole jiffy.
+ * calculate the speed of checksumming from this.
+ * (we use a 2-page allocation to have guaranteed
+ * color L1-cache layout)
+ */
+ max = 0;
+ for (i = 0; i < 5; i++) {
+ now = jiffies;
+ count = 0;
+ while (jiffies == now) {
+ mb();
+ func->xor_block(2,bh_ptr);
+ mb();
+ count++;
+ mb();
+ }
+ if (count > max)
+ max = count;
+ }
+
+ speed = max * (HZ*SIZE/1024);
+ func->speed = speed;
+
+ printk( " %-10s: %5d.%03d MB/sec\n", func->name,
+ speed / 1000, speed % 1000);
+}
+
+static inline void pick_fastest_function(void)
+{
+ struct xor_block_template *f, *fastest;
+
+ fastest = xor_functions;
+ for (f = fastest; f; f = f->next) {
+ if (f->speed > fastest->speed)
+ fastest = f;
+ }
+#ifdef CONFIG_X86_XMM
+ if (cpu_has_xmm) {
+ /* we force the use of the KNI xor block because it
+ can write around l2. we may also be able
+ to load into the l1 only depending on how
+ the cpu deals with a load to a line that is
+ being prefetched.
+ */
+ fastest = &t_xor_block_pIII_kni;
+ }
+#endif
+#ifdef __alpha__
+ if (implver() == IMPLVER_EV6) {
+ /* Force the use of alpha_prefetch if EV6, as it
+ is significantly faster in the cold cache case. */
+ fastest = &t_xor_block_alpha_prefetch;
+ }
+#endif
+ xor_block = fastest->xor_block;
+ printk( "using fastest function: %s (%d.%03d MB/sec)\n", fastest->name,
+ fastest->speed / 1000, fastest->speed % 1000);
+}
+
+static struct buffer_head b1, b2;
+
+void calibrate_xor_block(void)
+{
+ if (xor_block)
+ return;
+ memset(&b1,0,sizeof(b1));
+ b2 = b1;
+
+ b1.b_data = (char *) md__get_free_pages(GFP_KERNEL,2);
+ if (!b1.b_data) {
+ pick_fastest_function();
+ return;
+ }
+ b2.b_data = b1.b_data + 2*PAGE_SIZE + SIZE;
+
+ b1.b_size = SIZE;
+
+ printk(KERN_INFO "raid5: measuring checksumming speed\n");
+
+ sti(); /* should be safe */


+
+#if defined(__sparc__) && !defined(__sparc_v9__)

+ printk(KERN_INFO "raid5: trying high-speed SPARC checksum routine\n");
+ xor_speed(&t_xor_block_SPARC,&b1,&b2);
+#endif
+
+#ifdef CONFIG_X86_XMM
+ if (cpu_has_xmm) {
+ printk(KERN_INFO
+ "raid5: KNI detected, trying cache-avoiding KNI checksum routine\n");
+ xor_speed(&t_xor_block_pIII_kni,&b1,&b2);


+ }
+#endif /* CONFIG_X86_XMM */
+

+#ifdef __i386__
+ if (md_cpu_has_mmx()) {
+ printk(KERN_INFO
+ "raid5: MMX detected, trying high-speed MMX checksum routines\n");
+ xor_speed(&t_xor_block_pII_mmx,&b1,&b2);
+ xor_speed(&t_xor_block_p5_mmx,&b1,&b2);


+ }
+#endif /* __i386__ */
+

+#ifdef __alpha__
+ xor_speed(&t_xor_block_alpha,&b1,&b2);
+ xor_speed(&t_xor_block_alpha_prefetch,&b1,&b2);
+#endif
+
+ xor_speed(&t_xor_block_8regs,&b1,&b2);
+ xor_speed(&t_xor_block_32regs,&b1,&b2);
+
+ free_pages((unsigned long)b1.b_data,2);
+ pick_fastest_function();
+}
+
+#else /* __sparc_v9__ */
+
+void calibrate_xor_block(void)
+{
+ if (xor_block)
+ return;
+ printk(KERN_INFO "raid5: using high-speed VIS checksum routine\n");
+ xor_block = xor_block_VIS;
+}


+
+#endif /* __sparc_v9__ */
+

+MD_EXPORT_SYMBOL(xor_block);
+MD_EXPORT_SYMBOL(calibrate_xor_block);


+
+#ifdef MODULE
+int init_module(void)
+{

+ calibrate_xor_block();
+ return 0;
+}
+#endif
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/media/radio/Config.in linux/drivers/media/radio/Config.in
--- v2.4.0-test8/linux/drivers/media/radio/Config.in Wed Aug 23 14:59:55 2000
+++ linux/drivers/media/radio/Config.in Tue Sep 19 08:01:34 2000
@@ -21,6 +21,7 @@
X if [ "$CONFIG_RADIO_GEMTEK" = "y" ]; then
X hex ' GemTek i/o port (0x20c, 0x30c, 0x24c or 0x34c)' CONFIG_RADIO_GEMTEK_PORT 34c
X fi
+dep_tristate ' Maestro on board radio' CONFIG_RADIO_MAESTRO $CONFIG_VIDEO_DEV
X dep_tristate ' Miro PCM20 Radio' CONFIG_RADIO_MIROPCM20 $CONFIG_VIDEO_DEV
X dep_tristate ' SF16FMI Radio' CONFIG_RADIO_SF16FMI $CONFIG_VIDEO_DEV
X if [ "$CONFIG_RADIO_SF16FMI" = "y" ]; then
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/media/radio/Makefile linux/drivers/media/radio/Makefile
--- v2.4.0-test8/linux/drivers/media/radio/Makefile Tue Aug 22 11:29:02 2000
+++ linux/drivers/media/radio/Makefile Tue Sep 19 08:01:34 2000
@@ -45,6 +45,7 @@
X obj-$(CONFIG_RADIO_MIROPCM20) += radio-miropcm20.o
X obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o
X obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
+obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o


X
X # Extract lists of the multi-part drivers.
X # The 'int-*' lists are the intermediate files used to build the multi's.

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/media/radio/radio-maestro.c linux/drivers/media/radio/radio-maestro.c
--- v2.4.0-test8/linux/drivers/media/radio/radio-maestro.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/media/radio/radio-maestro.c Tue Sep 19 08:01:34 2000
@@ -0,0 +1,384 @@
+/* Maestro PCI sound card radio driver for Linux support
+ * (c) 2000 A. Tlalka, at...@pg.gda.pl
+ * Notes on the hardware
+ *
+ * + Frequency control is done digitally
+ * + No volume control - only mute/unmute - you have to use Aux line volume
+ * control on Maestro card to set the volume
+ * + Radio status (tuned/not_tuned and stereo/mono) is valid some time after
+ * frequency setting (>100ms) and only when the radio is unmuted.
+ * version 0.02
+ * + io port is automatically detected - only the first radio is used
+ * version 0.03
+ * + thread access locking additions
+ * version 0.04
+ * + code improvements
+ * + VIDEO_TUNER_LOW is permanent


+ */
+
+#include <linux/module.h>

+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/semaphore.h>
+#include <linux/pci.h>
+#include <linux/videodev.h>
+
+#define DRIVER_VERSION "0.04"
+
+#define PCI_VENDOR_ESS 0x125D
+#define PCI_DEVICE_ID_ESS_ESS1968 0x1968 /* Maestro 2 */
+#define PCI_DEVICE_ID_ESS_ESS1978 0x1978 /* Maestro 2E */
+
+#define GPIO_DATA 0x60 /* port offset from ESS_IO_BASE */
+
+#define IO_MASK 4 /* mask register offset from GPIO_DATA
+ bits 1=unmask write to given bit */
+#define IO_DIR 8 /* direction register offset from GPIO_DATA
+ bits 0/1=read/write direction */
+
+#define GPIO6 0x0040 /* mask bits for GPIO lines */
+#define GPIO7 0x0080
+#define GPIO8 0x0100
+#define GPIO9 0x0200
+
+#define STR_DATA GPIO6 /* radio TEA5757 pins and GPIO bits */
+#define STR_CLK GPIO7
+#define STR_WREN GPIO8
+#define STR_MOST GPIO9
+
+#define FREQ_LO 50*16000
+#define FREQ_HI 150*16000
+
+#define FREQ_IF 171200 /* 10.7*16000 */
+#define FREQ_STEP 200 /* 12.5*16 */
+
+#define FREQ2BITS(x) ((((unsigned int)(x)+FREQ_IF+(FREQ_STEP<<1))\
+ /(FREQ_STEP<<2))<<2) /* (x==fmhz*16*1000) -> bits */
+
+#define BITS2FREQ(x) ((x) * FREQ_STEP - FREQ_IF)
+
+
+
+static int radio_open(struct video_device *, int);
+static int radio_ioctl(struct video_device *, unsigned int, void *);
+static void radio_close(struct video_device *);
+
+static struct video_device maestro_radio=
+{
+ "Maestro radio",
+ VID_TYPE_TUNER,
+ VID_HARDWARE_SF16MI,
+ radio_open,
+ radio_close,
+ NULL,
+ NULL,
+ NULL,
+ radio_ioctl,
+ NULL,
+ NULL
+};
+
+static struct radio_device
+{
+ __u16 io, /* base of Maestro card radio io (GPIO_DATA)*/
+ muted, /* VIDEO_AUDIO_MUTE */
+ stereo, /* VIDEO_TUNER_STEREO_ON */
+ tuned; /* signal strength (0 or 0xffff) */
+ struct semaphore lock;
+} radio_unit = {0, 0, 0, 0, };
+
+static int users = 0;
+
+static void sleep_125ms(void)
+{
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(HZ >> 3);
+}
+
+static void udelay2(void)
+{
+ udelay(2);
+}
+
+static void udelay4(void)
+{
+ udelay(4);
+}
+
+static void udelay16(void)
+{
+ udelay(16);
+}
+
+static __u32 radio_bits_get(struct radio_device *dev)
+{
+ register __u16 io=dev->io, l, rdata;
+ register __u32 data=0;
+ __u16 omask;
+ omask = inw(io + IO_MASK);
+ outw(~(STR_CLK | STR_WREN), io + IO_MASK);
+ outw(0, io);
+ udelay16();
+ for (l=24;l--;) {
+ outw(STR_CLK, io); /* HI state */
+ udelay2();
+ if(!l)
+ dev->tuned = inw(io) & STR_MOST ? 0 : 0xffff;
+ outw(0, io); /* LO state */
+ udelay2();
+ data <<= 1; /* shift data */
+ rdata = inw(io);
+ if(!l)
+ dev->stereo = rdata & STR_MOST ?
+ 0 : VIDEO_TUNER_STEREO_ON;
+ else
+ if(rdata & STR_DATA)
+ data++;
+ udelay2();
+ }
+ if(dev->muted)
+ outw(STR_WREN, io);
+ udelay4();
+ outw(omask, io + IO_MASK);
+ return data & 0x3ffe;
+}
+
+static void radio_bits_set(struct radio_device *dev, __u32 data)
+{
+ register __u16 io=dev->io, l, bits;
+ __u16 omask, odir;
+ omask = inw(io + IO_MASK);
+ odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
+ outw(odir | STR_DATA, io + IO_DIR);
+ outw(~(STR_DATA | STR_CLK | STR_WREN), io + IO_MASK);
+ udelay16();
+ for (l=25;l;l--) {
+ bits = ((data >> 18) & STR_DATA) | STR_WREN ;
+ data <<= 1; /* shift data */
+ outw(bits, io); /* start strobe */
+ udelay2();
+ outw(bits | STR_CLK, io); /* HI level */
+ udelay2();
+ outw(bits, io); /* LO level */
+ udelay4();
+ }
+ if(!dev->muted)
+ outw(0, io);
+ udelay4();
+ outw(omask, io + IO_MASK);
+ outw(odir, io + IO_DIR);
+ sleep_125ms();
+}
+
+inline static int radio_function(struct video_device *dev,
+ unsigned int cmd, void *arg)
+{
+ struct radio_device *card=dev->priv;
+ switch(cmd) {
+ case VIDIOCGCAP: {
+ struct video_capability v;
+ strcpy(v.name, "Maestro radio");
+ v.type=VID_TYPE_TUNER;
+ v.channels=v.audios=1;
+ v.maxwidth=v.maxheight=v.minwidth=v.minheight=0;
+ if(copy_to_user(arg,&v,sizeof(v)))
+ return -EFAULT;
+ return 0;
+ }
+ case VIDIOCGTUNER: {
+ struct video_tuner v;
+ if(copy_from_user(&v, arg,sizeof(v))!=0)
+ return -EFAULT;
+ if(v.tuner)
+ return -EINVAL;
+ (void)radio_bits_get(card);
+ v.flags = VIDEO_TUNER_LOW | card->stereo;
+ v.signal = card->tuned;
+ strcpy(v.name, "FM");
+ v.rangelow = FREQ_LO;
+ v.rangehigh = FREQ_HI;
+ v.mode = VIDEO_MODE_AUTO;
+ if(copy_to_user(arg,&v, sizeof(v)))
+ return -EFAULT;
+ return 0;
+ }
+ case VIDIOCSTUNER: {
+ struct video_tuner v;
+ if(copy_from_user(&v, arg, sizeof(v)))
+ return -EFAULT;
+ if(v.tuner!=0)
+ return -EINVAL;
+ return 0;
+ }
+ case VIDIOCGFREQ: {
+ unsigned long tmp=BITS2FREQ(radio_bits_get(card));
+ if(copy_to_user(arg, &tmp, sizeof(tmp)))
+ return -EFAULT;
+ return 0;
+ }
+ case VIDIOCSFREQ: {
+ unsigned long tmp;
+ if(copy_from_user(&tmp, arg, sizeof(tmp)))
+ return -EFAULT;
+ if ( tmp<FREQ_LO || tmp>FREQ_HI )
+ return -EINVAL;
+ radio_bits_set(card, FREQ2BITS(tmp));
+ return 0;
+ }
+ case VIDIOCGAUDIO: {
+ struct video_audio v;
+ strcpy(v.name, "Radio");
+ v.audio=v.volume=v.bass=v.treble=v.balance=v.step=0;
+ v.flags=VIDEO_AUDIO_MUTABLE | card->muted;
+ v.mode=VIDEO_SOUND_STEREO;
+ if(copy_to_user(arg,&v, sizeof(v)))
+ return -EFAULT;
+ return 0;
+ }
+ case VIDIOCSAUDIO: {
+ struct video_audio v;
+ if(copy_from_user(&v, arg, sizeof(v)))
+ return -EFAULT;
+ if(v.audio)
+ return -EINVAL;
+ {
+ register __u16 io=card->io;
+ register __u16 omask = inw(io + IO_MASK);
+ outw(~STR_WREN, io + IO_MASK);
+ outw((card->muted = v.flags & VIDEO_AUDIO_MUTE)
+ ? STR_WREN : 0, io);
+ udelay4();
+ outw(omask, io + IO_MASK);
+ sleep_125ms();


+ return 0;
+ }
+ }

+ case VIDIOCGUNIT: {
+ struct video_unit v;
+ v.video=VIDEO_NO_UNIT;
+ v.vbi=VIDEO_NO_UNIT;
+ v.radio=dev->minor;
+ v.audio=0;
+ v.teletext=VIDEO_NO_UNIT;
+ if(copy_to_user(arg, &v, sizeof(v)))
+ return -EFAULT;
+ return 0;
+ }
+ default: return -ENOIOCTLCMD;
+ }
+}
+
+static int radio_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
+{
+ struct radio_device *card=dev->priv;
+ int ret;
+ down(&card->lock);
+ ret = radio_function(dev, cmd, arg);
+ up(&card->lock);


+ return ret;
+}
+

+static int radio_open(struct video_device *dev, int flags)
+{
+ if(users)
+ return -EBUSY;
+ users++;
+ MOD_INC_USE_COUNT;


+ return 0;
+}
+

+static void radio_close(struct video_device *dev)
+{
+ users--;
+ MOD_DEC_USE_COUNT;
+}
+
+
+inline static __u16 radio_install(struct pci_dev *pcidev);
+
+#ifdef MODULE
+MODULE_AUTHOR("Adam Tlalka, at...@pg.gda.pl");
+MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio.");
+
+EXPORT_NO_SYMBOLS;
+
+void cleanup_module(void)
+{
+ video_unregister_device(&maestro_radio);
+}
+
+int init_module(void)
+#else
+int __init maestro_radio_init(struct video_init *v)
+#endif
+{
+ register __u16 found=0;
+ struct pci_dev *pcidev = NULL;
+ if(!pci_present())
+ return -ENODEV;
+ while(!found && (pcidev = pci_find_device(PCI_VENDOR_ESS,
+ PCI_DEVICE_ID_ESS_ESS1968,
+ pcidev)))
+ found |= radio_install(pcidev);
+ while(!found && (pcidev = pci_find_device(PCI_VENDOR_ESS,
+ PCI_DEVICE_ID_ESS_ESS1978,
+ pcidev)))
+ found |= radio_install(pcidev);
+ if(!found) {
+ printk(KERN_INFO "radio-maestro: no devices found.\n");
+ return -ENODEV;


+ }
+ return 0;
+}
+

+inline static __u16 radio_power_on(struct radio_device *dev)
+{
+ register __u16 io=dev->io;
+ register __u32 ofreq;
+ __u16 omask, odir;
+ omask = inw(io + IO_MASK);
+ odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
+ outw(odir & ~STR_WREN, io + IO_DIR);
+ dev->muted = inw(io) & STR_WREN ? 0 : VIDEO_AUDIO_MUTE;
+ outw(odir, io + IO_DIR);
+ outw(~(STR_WREN | STR_CLK), io + IO_MASK);
+ outw(dev->muted ? 0 : STR_WREN, io);
+ udelay16();
+ outw(omask, io + IO_MASK);
+ ofreq = radio_bits_get(dev);
+ if((ofreq<FREQ2BITS(FREQ_LO)) || (ofreq>FREQ2BITS(FREQ_HI)))
+ ofreq = FREQ2BITS(FREQ_LO);
+ radio_bits_set(dev, ofreq);
+ return (ofreq == radio_bits_get(dev));
+}
+
+inline static __u16 radio_install(struct pci_dev *pcidev)
+{
+ if(((pcidev->class >> 8) & 0xffff) != PCI_CLASS_MULTIMEDIA_AUDIO)
+ return 0;
+
+ radio_unit.io = pcidev->resource[0].start + GPIO_DATA;
+ maestro_radio.priv = &radio_unit;
+ init_MUTEX(&radio_unit.lock);
+
+ if(radio_power_on(&radio_unit)) {
+ if(video_register_device(&maestro_radio, VFL_TYPE_RADIO)==-1) {
+ printk("radio-maestro: can't register device!");
+ return 0;
+ }
+ printk(KERN_INFO "radio-maestro: version "
+ DRIVER_VERSION
+ " time "
+ __TIME__ " "
+ __DATE__
+ "\n");
+ printk(KERN_INFO "radio-maestro: radio chip initialized\n");
+ return 1;
+ } else


+ return 0;
+}
+

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/media/video/bttv-driver.c linux/drivers/media/video/bttv-driver.c
--- v2.4.0-test8/linux/drivers/media/video/bttv-driver.c Mon Aug 7 21:01:35 2000
+++ linux/drivers/media/video/bttv-driver.c Sun Sep 17 09:45:06 2000
@@ -3027,11 +3027,11 @@
X * Scan for a Bt848 card, request the irq and map the io memory
X */
X
-static void __devinit bttv_remove(struct pci_dev *pci_dev)
+static void __devexit bttv_remove(struct pci_dev *pci_dev)
X {
X u8 command;
X int j;
- struct bttv *btv = PCI_GET_DRIVER_DATA(pci_dev);
+ struct bttv *btv = pci_get_drvdata(pci_dev);
X
X /* unregister i2c_bus */
X if (0 == btv->i2c_ok)
@@ -3093,6 +3093,8 @@
X btv->shutdown=1;
X wake_up(&btv->gpioq);
X
+ pci_set_drvdata(pci_dev, NULL);
+
X return;
X }
X
@@ -3198,7 +3200,7 @@
X }
X }
X
- PCI_SET_DRIVER_DATA(dev,btv);
+ pci_set_drvdata(dev,btv);
X
X if(init_bt848(btv) < 0) {
X bttv_remove(dev);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/media/video/bttv.h linux/drivers/media/video/bttv.h
--- v2.4.0-test8/linux/drivers/media/video/bttv.h Sun Aug 6 12:45:28 2000
+++ linux/drivers/media/video/bttv.h Sun Sep 17 09:45:06 2000
@@ -23,11 +23,6 @@
X
X #define BTTV_VERSION_CODE KERNEL_VERSION(0,7,38)


X
-#ifndef PCI_GET_DRIVER_DATA
-# define PCI_GET_DRIVER_DATA(pdev) ((pdev)->driver_data)

-# define PCI_SET_DRIVER_DATA(pdev,data) (((pdev)->driver_data) = (data))


-#endif /* PCI_GET_DRIVER_DATA */
-

X #include <linux/types.h>
X #include <linux/wait.h>
X #include <linux/videodev.h>
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/media/video/buz.c linux/drivers/media/video/buz.c
--- v2.4.0-test8/linux/drivers/media/video/buz.c Mon Aug 7 21:01:35 2000
+++ linux/drivers/media/video/buz.c Tue Sep 19 08:01:34 2000
@@ -202,6 +202,7 @@
X mem_map_reserve(virt_to_page(mem + off));
X DEBUG(printk(BUZ_INFO ": V4L frame %d mem 0x%x (bus: 0x%x=%d)\n", i, mem, virt_to_bus(mem), virt_to_bus(mem)));
X } else {
+ v4l_fbuffer_free(zr);
X return -ENOBUFS;
X }
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/media/video/cpia_usb.c linux/drivers/media/video/cpia_usb.c
--- v2.4.0-test8/linux/drivers/media/video/cpia_usb.c Tue Sep 5 13:42:52 2000
+++ linux/drivers/media/video/cpia_usb.c Mon Sep 18 17:31:25 2000
@@ -187,7 +187,7 @@
X if (ret < 0) {
X printk(KERN_ERR "cpia_usb_open: usb_set_interface error (ret = %d)\n", ret);
X retval = -EBUSY;
- goto error_all;
+ goto error_1;
X }
X
X ucpia->buffers[0]->status = FRAME_EMPTY;
@@ -204,7 +204,7 @@
X if (!urb) {
X printk(KERN_ERR "cpia_init_isoc: usb_alloc_urb 0\n");
X retval = -ENOMEM;
- goto error_all;
+ goto error_1;
X }
X
X ucpia->sbuf[0].urb = urb;
@@ -223,9 +223,9 @@
X
X urb = usb_alloc_urb(FRAMES_PER_DESC);
X if (!urb) {
- printk(KERN_ERR "cpia_init_isoc: usb_alloc_urb 0\n");
+ printk(KERN_ERR "cpia_init_isoc: usb_alloc_urb 1\n");
X retval = -ENOMEM;
- goto error_all;
+ goto error_urb0;
X }
X
X ucpia->sbuf[1].urb = urb;
@@ -246,20 +246,30 @@
X ucpia->sbuf[0].urb->next = ucpia->sbuf[1].urb;
X
X err = usb_submit_urb(ucpia->sbuf[0].urb);
- if (err)
+ if (err) {
X printk(KERN_ERR "cpia_init_isoc: usb_submit_urb 0 ret %d\n",
X err);
+ goto error_urb1;
+ }
X err = usb_submit_urb(ucpia->sbuf[1].urb);
- if (err)
+ if (err) {
X printk(KERN_ERR "cpia_init_isoc: usb_submit_urb 1 ret %d\n",
X err);
+ goto error_urb1;
+ }
X
X ucpia->streaming = 1;
X ucpia->open = 1;


X
X return 0;
X

-error_all:
+error_urb1: /* free urb 1 */
+ usb_free_urb(ucpia->sbuf[1].urb);
+
+error_urb0: /* free urb 0 */
+ usb_free_urb(ucpia->sbuf[0].urb);
+
+error_1:
X kfree (ucpia->sbuf[1].data);
X error_0:
X kfree (ucpia->sbuf[0].data);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/mtd/cfi_cmdset_0002.c linux/drivers/mtd/cfi_cmdset_0002.c
--- v2.4.0-test8/linux/drivers/mtd/cfi_cmdset_0002.c Thu Jul 13 10:19:55 2000
+++ linux/drivers/mtd/cfi_cmdset_0002.c Thu Sep 21 13:24:44 2000
@@ -437,7 +437,7 @@
X adr = instr->addr - (chipnum << cfi->chipshift) * (cfi->interleave);
X len = instr->len;
X
-printk("erase : 0x%x 0x%x 0x%x\n", adr, len, chipnum, mtd->size);
+printk("erase : 0x%lx 0x%lx 0x%x 0x%x\n", adr, len, chipnum, mtd->size);
X
X while(len) {
X //printk("erase : 0x%x 0x%x 0x%x 0x%x\n", chipnum, adr, len, cfi->chipshift);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/mtd/mapped.c linux/drivers/mtd/mapped.c
--- v2.4.0-test8/linux/drivers/mtd/mapped.c Tue Jul 4 10:10:05 2000
+++ linux/drivers/mtd/mapped.c Sun Sep 24 12:12:33 2000
@@ -21,7 +21,6 @@
X #include <linux/delay.h>
X #include <linux/sched.h>
X #include <asm/io.h>
-#include <asm/delay.h>
X
X struct JEDECTable mtd_JEDEC_table[] =
X {{0x01AD,"AMD Am29F016",2*1024*1024,64*1024,MTD_CAP_NORFLASH},
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/3c505.c linux/drivers/net/3c505.c
--- v2.4.0-test8/linux/drivers/net/3c505.c Tue May 2 12:40:58 2000
+++ linux/drivers/net/3c505.c Mon Oct 2 14:22:40 2000
@@ -130,15 +130,15 @@
X #define INVALID_PCB_MSG(len) \
X printk(invalid_pcb_msg, (len),filename,__FUNCTION__,__LINE__)
X
-static const char *search_msg = "%s: Looking for 3c505 adapter at address %#x...";
+static char search_msg[] __initdata = "%s: Looking for 3c505 adapter at address %#x...";
X
-static const char *stilllooking_msg = "still looking...";
+static char stilllooking_msg[] __initdata = "still looking...";
X
-static const char *found_msg = "found.\n";
+static char found_msg[] __initdata = "found.\n";
X
-static const char *notfound_msg = "not found (reason = %d)\n";
+static char notfound_msg[] __initdata = "not found (reason = %d)\n";
X
-static const char *couldnot_msg = "%s: 3c505 not found\n";
+static char couldnot_msg[] __initdata = "%s: 3c505 not found\n";
X
X /*********************************************************
X *
@@ -180,7 +180,7 @@
X * Last element MUST BE 0!
X *****************************************************************/
X
-static const int addr_list[] __initdata = {0x300, 0x280, 0x310, 0};
+static int addr_list[] __initdata = {0x300, 0x280, 0x310, 0};
X
X /* Dma Memory related stuff */
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/3c507.c linux/drivers/net/3c507.c
--- v2.4.0-test8/linux/drivers/net/3c507.c Mon Jun 19 13:30:56 2000
+++ linux/drivers/net/3c507.c Sun Sep 17 09:41:28 2000
@@ -332,6 +332,7 @@
X {
X static unsigned char init_ID_done = 0, version_printed = 0;
X int i, irq, irqval;
+ struct net_local *lp;
X
X if (init_ID_done == 0) {
X ushort lrs_state = 0xff;
@@ -355,7 +356,7 @@
X
X /* Allocate a new 'dev' if needed. */
X if (dev == NULL)
- dev = init_etherdev(0, sizeof(struct net_local));
+ dev = init_etherdev(0, 0);
X
X if (net_debug && version_printed++ == 0)
X printk(version);
@@ -417,10 +418,11 @@
X printk(version);
X
X /* Initialize the device structure. */
- dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+ lp = dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
X if (dev->priv == NULL)
X return -ENOMEM;


X memset(dev->priv, 0, sizeof(struct net_local));
+ spin_lock_init(&lp->lock);
X

X dev->open = el16_open;
X dev->stop = el16_close;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/3c509.c linux/drivers/net/3c509.c
--- v2.4.0-test8/linux/drivers/net/3c509.c Tue Jul 11 11:12:23 2000
+++ linux/drivers/net/3c509.c Sun Sep 17 09:41:28 2000
@@ -193,6 +193,7 @@
X
X int el3_probe(struct net_device *dev)
X {
+ struct el3_private *lp;
X short lrs_state = 0xff, i;
X int ioaddr, irq, if_port;
X u16 phys_addr[3];
@@ -200,7 +201,7 @@
X int mca_slot = -1;
X #ifdef __ISAPNP__
X static int pnp_cards = 0;
-#endif
+#endif /* __ISAPNP__ */
X
X /* First check all slots of the EISA bus. The next slot address to
X probe is kept in 'eisa_addr' to support multiple probe() calls. */
@@ -292,7 +293,7 @@
X /* if we get here, we didn't find an MCA adapter */
X return -ENODEV;
X }
-#endif
+#endif /* CONFIG_MCA */
X
X #ifdef __ISAPNP__
X if (nopnp == 1)


@@ -330,7 +331,7 @@
X }

X }
X no_pnp:
-#endif
+#endif /* __ISAPNP__ */
X
X /* Select an open I/O location at 0x1*0 to do contention select. */
X for ( ; id_port < 0x200; id_port += 0x10) {
@@ -396,7 +397,7 @@
X }
X }
X }
-#endif
+#endif /* __ISAPNP__ */
X
X {
X unsigned int iobase = id_read_eeprom(8);
@@ -466,9 +467,10 @@
X return -ENOMEM;
X memset(dev->priv, 0, sizeof(struct el3_private));
X
- ((struct el3_private *)dev->priv)->mca_slot = mca_slot;
- ((struct el3_private *)dev->priv)->next_dev = el3_root_dev;
- ((struct el3_private *)dev->priv)->lock = (spinlock_t) SPIN_LOCK_UNLOCKED;
+ lp = dev->priv;
+ lp->mca_slot = mca_slot;
+ lp->next_dev = el3_root_dev;
+ spin_lock_init(&lp->lock);
X el3_root_dev = dev;
X
X if (el3_debug > 0)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/3c527.c linux/drivers/net/3c527.c
--- v2.4.0-test8/linux/drivers/net/3c527.c Tue Jul 18 16:09:27 2000
+++ linux/drivers/net/3c527.c Tue Sep 19 08:01:34 2000
@@ -146,7 +146,7 @@
X char *name;
X };
X
-const struct mca_adapters_t mc32_adapters[] = {
+static struct mca_adapters_t mc32_adapters[] __initdata = {
X { 0x0041, "3COM EtherLink MC/32" },
X { 0x8EF5, "IBM High Performance Lan Adapter" },
X { 0x0000, NULL }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/3c59x.c linux/drivers/net/3c59x.c
--- v2.4.0-test8/linux/drivers/net/3c59x.c Sun Aug 13 19:27:39 2000
+++ linux/drivers/net/3c59x.c Fri Sep 15 16:28:25 2000
@@ -98,6 +98,18 @@
X - Added INVERT_LED_PWR, used it.
X - Backed out the extra_reset stuff
X
+ LK1.1.9 2 Sep 2000 andrewm
+ - Backed out the tx_reset_resume flags. It was a no-op.
+ - In vortex_error, don't reset the Tx on txReclaim errors
+ - In vortex_error, don't reset the Tx on maxCollisions errors.
+ Hence backed out all the DownListPtr logic here.
+ - In vortex_error, give Tornado cards a partial TxReset on
+ maxCollisions (David Hinds). Defined MAX_COLLISION_RESET for this.
+ - Redid some driver flags and device names based on pcmcia_cs-3.1.20.
+ - Fixed a bug where, if vp->tx_full is set when the interface
+ is downed, it remains set when the interface is upped. Bad
+ things happen.
+
X - See http://www.uow.edu.au/~andrewm/linux/#3c59x-2.3 for more details.
X - Also see Documentation/networking/vortex.txt
X */
@@ -183,7 +195,7 @@
X #include <linux/delay.h>
X
X static char version[] __devinitdata =
-"3c59x.c:LK1.1.8 13 Aug 2000 Donald Becker and others. http://www.scyld.com/network/vortex.html " "$Revision: 1.102.2.25 $\n";
+"3c59x.c:LK1.1.9 2 Sep 2000 Donald Becker and others. http://www.scyld.com/network/vortex.html " "$Revision: 1.102.2.38 $\n";
X
X MODULE_AUTHOR("Donald Becker <bec...@scyld.com>");
X MODULE_DESCRIPTION("3Com 3c59x/3c90x/3c575 series Vortex/Boomerang/Cyclone driver");
@@ -303,7 +315,7 @@
X enum { IS_VORTEX=1, IS_BOOMERANG=2, IS_CYCLONE=4, IS_TORNADO=8,
X EEPROM_8BIT=0x10, /* AKPM: Uses 0x230 as the base bitmaps for EEPROM reads */
X HAS_PWR_CTRL=0x20, HAS_MII=0x40, HAS_NWAY=0x80, HAS_CB_FNS=0x100,
- INVERT_MII_PWR=0x200, INVERT_LED_PWR=0x400 };
+ INVERT_MII_PWR=0x200, INVERT_LED_PWR=0x400, MAX_COLLISION_RESET=0x800 };
X
X
X enum vortex_chips {
@@ -415,14 +427,14 @@
X
X {"3CCFE575BT Cyclone CardBus",
X PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_LED_PWR, 128, },
- {"3CCFE575CT Cyclone CardBus",
- PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR, 128, },
+ {"3CCFE575CT Tornado CardBus",
+ PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|MAX_COLLISION_RESET, 128, },
X {"3CCFE656 Cyclone CardBus",
X PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|INVERT_LED_PWR, 128, },
X {"3CCFEM656B Cyclone+Winmodem CardBus",
X PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|INVERT_LED_PWR, 128, },
- {"3CCFE656C Tornado+Winmodem CardBus", /* From pcmcia-cs-3.1.5 */
- PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR, 128, },
+ {"3CXFEM656C Tornado+Winmodem CardBus", /* From pcmcia-cs-3.1.5 */
+ PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|MAX_COLLISION_RESET, 128, },
X
X {"3c450 HomePNA Tornado", /* AKPM: from Don's 0.99Q */
X PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY, 128, },
@@ -652,7 +664,6 @@
X open:1,
X must_free_region:1; /* Flag: if zero, Cardbus owns the I/O region */
X int drv_flags;
- int tx_reset_resume; /* Flag to retart timer after vortex_error handling */
X u16 status_enable;
X u16 intr_enable;
X u16 available_media; /* From Wn3_Options. */
@@ -1369,6 +1380,7 @@
X
X vortex_up(dev);
X vp->open = 1;
+ vp->tx_full = 0;
X return 0;
X
X out_free_irq:
@@ -1570,7 +1582,7 @@
X {
X struct vortex_private *vp = (struct vortex_private *)dev->priv;
X long ioaddr = dev->base_addr;
- int do_tx_reset = 0;
+ int do_tx_reset = 0, reset_mask = 0;
X unsigned char tx_status = 0;
X
X if (vortex_debug > 2) {
@@ -1589,10 +1601,14 @@
X if (tx_status & 0x14) vp->stats.tx_fifo_errors++;
X if (tx_status & 0x38) vp->stats.tx_aborted_errors++;
X outb(0, ioaddr + TxStatus);
- if (tx_status & 0x3a) /* TxReset after 16 collisions, despite what the manual says */
- do_tx_reset = 1; /* Also reset on reclaim errors */
- else /* Merely re-enable the transmitter. */
+ if (tx_status & 0x30) { /* txJabber or txUnderrun */
+ do_tx_reset = 1;
+ } else if ((tx_status & 0x08) && (vp->drv_flags & MAX_COLLISION_RESET)) { /* maxCollisions */
+ do_tx_reset = 1;
+ reset_mask = 0x0108; /* Reset interface logic, but not download logic */
+ } else { /* Merely re-enable the transmitter. */
X outw(TxEnable, ioaddr + EL3_CMD);
+ }
X }
X
X if (status & RxEarly) { /* Rx early is unused. */
@@ -1644,40 +1660,11 @@
X }
X }
X
- /*
- * Black magic. If we're resetting the transmitter, remember the current downlist
- * pointer and restore it afterwards. We can't usr cur_tx because that could
- * lag the actual hardware index.
- */
X if (do_tx_reset) {
- if (vp->full_bus_master_tx) {
- unsigned long old_down_list_ptr;
-
- wait_for_completion(dev, DownStall);
- old_down_list_ptr = inl(ioaddr + DownListPtr);


- wait_for_completion(dev, TxReset);
- outw(TxEnable, ioaddr + EL3_CMD);

-
- /* Restart DMA if necessary */
- outl(old_down_list_ptr, ioaddr + DownListPtr);


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 060'
echo 'File patch-2.4.0-test9 is continued in part 061'
echo "061" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part062

#!/bin/sh -x
# this is part 062 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 062; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

@@ -60,6 +96,10 @@
X timing and control bits. The data is then read from status port or written
X to the data port.
X
+ Correction: the controller has two banks of 16 registers. The second
+ bank contains only the multicast filter table (now used) and the EEPROM
+ access registers.
+
X Since the bulk data transfer of the actual packets through the slow
X parallel port dominates the driver's running time, four distinct data
X (non-register) transfer modes are provided by the adapter, two in each
@@ -105,18 +145,40 @@
X #include <linux/etherdevice.h>
X #include <linux/skbuff.h>
X #include <linux/spinlock.h>
+#include <linux/delay.h>
X
X #include "atp.h"
X
-/* use 0 for production, 1 for verification, >2 for debug */
-#ifndef NET_DEBUG
-#define NET_DEBUG 1
-#endif
-static unsigned int net_debug = NET_DEBUG;
+MODULE_AUTHOR("Donald Becker <bec...@scyld.com>");
+MODULE_DESCRIPTION("RealTek RTL8002/8012 parallel port Ethernet driver");
+MODULE_PARM(max_interrupt_work, "i");
+MODULE_PARM(debug, "i");
+MODULE_PARM(io, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(xcvr, "1-" __MODULE_STRING(MAX_UNITS) "i");


+
+#define RUN_AT(x) (jiffies + (x))

X
X /* The number of low I/O ports used by the ethercard. */
X #define ETHERCARD_TOTAL_SIZE 3
X
+/* Sequence to switch an 8012 from printer mux to ethernet mode. */
+static char mux_8012[] = { 0xff, 0xf7, 0xff, 0xfb, 0xf3, 0xfb, 0xff, 0xf7,};
+
+struct net_local {
+ spinlock_t lock;
+ struct net_device *next_module;


+ struct net_device_stats stats;
+ struct timer_list timer; /* Media selection timer. */

+ long last_rx_time; /* Last Rx, in jiffies, to handle Rx hang. */
+ int saved_tx_size;
+ unsigned int tx_unit_busy:1;
+ unsigned char re_tx, /* Number of packet retransmissions. */
+ addr_mode, /* Current Rx filter e.g. promiscuous, etc. */
+ pac_cnt_in_tx_buf,
+ chip_type;
+};
+
X /* This code, written by w...@super.org, resets the adapter every
X TIMED_CHECKER ticks. This recovers from an unknown error which
X hangs the device. */
@@ -124,40 +186,41 @@
X #ifdef TIMED_CHECKER
X #include <linux/timer.h>
X static void atp_timed_checker(unsigned long ignored);
-static struct net_device *atp_timed_dev;
-static struct timer_list atp_timer = { function: atp_timed_checker };
X #endif
X
X /* Index to functions, as function prototypes. */
X
-static int atp_probe1(struct net_device *dev, short ioaddr);
+static int atp_probe1(struct net_device *dev, long ioaddr);
X static void get_node_ID(struct net_device *dev);
-static unsigned short eeprom_op(short ioaddr, unsigned int cmd);
+static unsigned short eeprom_op(long ioaddr, unsigned int cmd);
X static int net_open(struct net_device *dev);
X static void hardware_init(struct net_device *dev);
-static void tx_timeout(struct net_device *dev);
-static void write_packet(short ioaddr, int length, unsigned char *packet, int mode);
-static void trigger_send(short ioaddr, int length);
-static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
-static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static void write_packet(long ioaddr, int length, unsigned char *packet, int mode);
+static void trigger_send(long ioaddr, int length);
+static int atp_send_packet(struct sk_buff *skb, struct net_device *dev);
+static void atp_interrupt(int irq, void *dev_id, struct pt_regs *regs);
X static void net_rx(struct net_device *dev);
-static void read_block(short ioaddr, int length, unsigned char *buffer, int data_mode);
+static void read_block(long ioaddr, int length, unsigned char *buffer, int data_mode);
X static int net_close(struct net_device *dev);
X static struct net_device_stats *net_get_stats(struct net_device *dev);
-static void set_multicast_list(struct net_device *dev);
+static void set_rx_mode_8002(struct net_device *dev);
+static void set_rx_mode_8012(struct net_device *dev);
+static void tx_timeout(struct net_device *dev);
+
+
+/* A list of all installed ATP devices, for removing the driver module. */
+static struct net_device *root_atp_dev = NULL;
X
-
X /* Check for a network adapter of this type, and return '0' iff one exists.
X If dev->base_addr == 0, probe all likely locations.
X If dev->base_addr == 1, always return failure.
X If dev->base_addr == 2, allocate space for the device and return success
X (detachable devices only).
X */
-
X static int __init atp_init(struct net_device *dev)
X {
X int *port, ports[] = {0x378, 0x278, 0x3bc, 0};
- int base_addr = dev->base_addr;
+ int base_addr = dev ? dev->base_addr : io[0];
X
X if (base_addr > 0x1ff) /* Check a single specified location. */
X return atp_probe1(dev, base_addr);
@@ -165,7 +228,7 @@
X return -ENXIO;
X
X for (port = ports; *port; port++) {
- int ioaddr = *port;
+ long ioaddr = *port;
X outb(0x57, ioaddr + PAR_DATA);
X if (inb(ioaddr + PAR_DATA) != 0x57)
X continue;
@@ -176,36 +239,68 @@
X return -ENODEV;
X }
X
-static int __init atp_probe1(struct net_device *dev, short ioaddr)
+static int __init atp_probe1(struct net_device *dev, long ioaddr)
X {
- int saved_ctrl_reg, status;
+ struct net_local *lp;
+ int saved_ctrl_reg, status, i;
X
X outb(0xff, ioaddr + PAR_DATA);
X /* Save the original value of the Control register, in case we guessed
X wrong. */
X saved_ctrl_reg = inb(ioaddr + PAR_CONTROL);
+ if (net_debug > 3)
+ printk("atp: Control register was %#2.2x.\n", saved_ctrl_reg);
X /* IRQEN=0, SLCTB=high INITB=high, AUTOFDB=high, STBB=high. */
X outb(0x04, ioaddr + PAR_CONTROL);
+#ifndef final_version
+ if (net_debug > 3) {
+ /* Turn off the printer multiplexer on the 8012. */
+ for (i = 0; i < 8; i++)
+ outb(mux_8012[i], ioaddr + PAR_DATA);
+ write_reg(ioaddr, MODSEL, 0x00);
+ printk("atp: Registers are ");
+ for (i = 0; i < 32; i++)
+ printk(" %2.2x", read_nibble(ioaddr, i));
+ printk(".\n");
+ }
+#endif
+ /* Turn off the printer multiplexer on the 8012. */
+ for (i = 0; i < 8; i++)
+ outb(mux_8012[i], ioaddr + PAR_DATA);
X write_reg_high(ioaddr, CMR1, CMR1h_RESET);
- udelay(100);
+ /* udelay() here? */
X status = read_nibble(ioaddr, CMR1);
X
+ if (net_debug > 3) {
+ printk(KERN_DEBUG "atp: Status nibble was %#2.2x..", status);
+ for (i = 0; i < 32; i++)
+ printk(" %2.2x", read_nibble(ioaddr, i));


+ printk("\n");
+ }
+

X if ((status & 0x78) != 0x08) {
X /* The pocket adapter probe failed, restore the control register. */
X outb(saved_ctrl_reg, ioaddr + PAR_CONTROL);
- return 1;
+ return -ENODEV;
X }
X status = read_nibble(ioaddr, CMR2_h);
X if ((status & 0x78) != 0x10) {
X outb(saved_ctrl_reg, ioaddr + PAR_CONTROL);
- return 1;
+ return -ENODEV;
X }
+
+ dev = init_etherdev(dev, sizeof(struct net_local));
+ if (!dev)
+ return -ENOMEM;
+
X /* Find the IRQ used by triggering an interrupt. */
X write_reg_byte(ioaddr, CMR2, 0x01); /* No accept mode, IRQ out. */
X write_reg_high(ioaddr, CMR1, CMR1h_RxENABLE | CMR1h_TxENABLE); /* Enable Tx and Rx. */
X
X /* Omit autoIRQ routine for now. Use "table lookup" instead. Uhgggh. */
- if (ioaddr == 0x378)
+ if (irq[0])
+ dev->irq = irq[0];
+ else if (ioaddr == 0x378)
X dev->irq = 7;
X else
X dev->irq = 5;
@@ -217,69 +312,73 @@
X /* Read the station address PROM. */
X get_node_ID(dev);
X
- printk("%s: Pocket adapter found at %#3lx, IRQ %d, SAPROM "
+#ifndef MODULE
+ if (net_debug)
+ printk(KERN_INFO "%s" KERN_INFO "%s", versionA, versionB);
+#endif
+
+ printk(KERN_NOTICE "%s: Pocket adapter found at %#3lx, IRQ %d, SAPROM "
X "%02X:%02X:%02X:%02X:%02X:%02X.\n", dev->name, dev->base_addr,
X dev->irq, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
X dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
X
- /* Leave the hardware in a reset state. */
- write_reg_high(ioaddr, CMR1, CMR1h_RESET);
-
- if (net_debug)
- printk(version);
+ /* Reset the ethernet hardware and activate the printer pass-through. */
+ write_reg_high(ioaddr, CMR1, CMR1h_RESET | CMR1h_MUX);


X
X /* Initialize the device structure. */

X ether_setup(dev);


- dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);

+ if (dev->priv == NULL)
+ dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);


X if (dev->priv == NULL)
X return -ENOMEM;
X memset(dev->priv, 0, sizeof(struct net_local));

- {
- struct net_local *lp = (struct net_local *)dev->priv;
- lp->addr_mode = CMR2h_Normal;
- spin_lock_init(&lp->lock);
- }
+
+ lp = (struct net_local *)dev->priv;
+ lp->chip_type = RTL8002;
+ lp->addr_mode = CMR2h_Normal;
+ spin_lock_init(&lp->lock);
+
+ lp->next_module = root_atp_dev;
+ root_atp_dev = dev;
X
X /* For the ATP adapter the "if_port" is really the data transfer mode. */
- dev->if_port = (dev->mem_start & 0xf) ? dev->mem_start & 0x7 : 4;
+ if (xcvr[0])
+ dev->if_port = xcvr[0];
+ else
+ dev->if_port = (dev->mem_start & 0xf) ? (dev->mem_start & 0x7) : 4;
X if (dev->mem_end & 0xf)
X net_debug = dev->mem_end & 7;
X
X dev->open = net_open;
X dev->stop = net_close;
- dev->hard_start_xmit = net_send_packet;
+ dev->hard_start_xmit = atp_send_packet;
X dev->get_stats = net_get_stats;
- dev->set_multicast_list = set_multicast_list;
+ dev->set_multicast_list =
+ lp->chip_type == RTL8002 ? &set_rx_mode_8002 : &set_rx_mode_8012;
X dev->tx_timeout = tx_timeout;
- dev->watchdog_timeo = HZ/20;
+ dev->watchdog_timeo = TX_TIMEOUT;
X
-#ifdef TIMED_CHECKER
- del_timer(&atp_timer);
- atp_timer.expires = jiffies + TIMED_CHECKER;
- atp_timed_dev = dev;
- add_timer(&atp_timer);
-#endif


X return 0;
X }
X

X /* Read the station address PROM, usually a word-wide EEPROM. */
X static void __init get_node_ID(struct net_device *dev)
X {
- short ioaddr = dev->base_addr;
+ long ioaddr = dev->base_addr;
X int sa_offset = 0;


X int i;
-
+

X write_reg(ioaddr, CMR2, CMR2_EEPROM); /* Point to the EEPROM control registers. */
-
+
X /* Some adapters have the station address at offset 15 instead of offset
X zero. Check for it, and fix it if needed. */
X if (eeprom_op(ioaddr, EE_READ(0)) == 0xffff)
X sa_offset = 15;
-
+
X for (i = 0; i < 3; i++)
- ((unsigned short *)dev->dev_addr)[i] =
- ntohs(eeprom_op(ioaddr, EE_READ(sa_offset + i)));
-
+ ((u16 *)dev->dev_addr)[i] =
+ be16_to_cpu(eeprom_op(ioaddr, EE_READ(sa_offset + i)));
+
X write_reg(ioaddr, CMR2, CMR2_NULL);
X }
X
@@ -295,26 +394,24 @@
X * DO : _________X_______X
X */
X
-static unsigned short __init eeprom_op(short ioaddr, unsigned int cmd)
+static unsigned short __init eeprom_op(long ioaddr, unsigned int cmd)
X {
X unsigned eedata_out = 0;
X int num_bits = EE_CMD_SIZE;
-
+
X while (--num_bits >= 0) {
X char outval = test_bit(num_bits, &cmd) ? EE_DATA_WRITE : 0;
X write_reg_high(ioaddr, PROM_CMD, outval | EE_CLK_LOW);
- udelay(5);
X write_reg_high(ioaddr, PROM_CMD, outval | EE_CLK_HIGH);
X eedata_out <<= 1;
X if (read_nibble(ioaddr, PROM_DATA) & EE_DATA_READ)
X eedata_out++;
- udelay(5);
X }
X write_reg_high(ioaddr, PROM_CMD, EE_CLK_LOW & ~EE_CS);
X return eedata_out;
X }
X
-
+
X /* Open/initialize the board. This is called (in the current kernel)
X sometime after booting when the 'ifconfig' program is run.
X
@@ -327,17 +424,25 @@
X */
X static int net_open(struct net_device *dev)
X {
+ struct net_local *lp = (struct net_local *)dev->priv;
+
+ MOD_INC_USE_COUNT;
X
X /* The interrupt line is turned off (tri-stated) when the device isn't in
X use. That's especially important for "attached" interfaces where the
X port or interrupt may be shared. */
-
- if (request_irq(dev->irq, &net_interrupt, 0, "ATP", dev)) {
+ if (request_irq(dev->irq, &atp_interrupt, 0, "ATP Ethernet", dev)) {
+ MOD_DEC_USE_COUNT;
X return -EAGAIN;
X }
+
X hardware_init(dev);
X
- MOD_INC_USE_COUNT;
+ init_timer(&lp->timer);
+ lp->timer.expires = RUN_AT(TIMED_CHECKER);
+ lp->timer.data = (unsigned long)dev;
+ lp->timer.function = &atp_timed_checker; /* timer handler */
+ add_timer(&lp->timer);
X
X netif_start_queue(dev);
X return 0;
@@ -348,54 +453,57 @@
X static void hardware_init(struct net_device *dev)
X {
X struct net_local *lp = (struct net_local *)dev->priv;
- int ioaddr = dev->base_addr;
- int i;
+ long ioaddr = dev->base_addr;
+ int i;
X
+ /* Turn off the printer multiplexer on the 8012. */
+ for (i = 0; i < 8; i++)
+ outb(mux_8012[i], ioaddr + PAR_DATA);
X write_reg_high(ioaddr, CMR1, CMR1h_RESET);
-
- for (i = 0; i < 6; i++)
+
+ for (i = 0; i < 6; i++)
X write_reg_byte(ioaddr, PAR0 + i, dev->dev_addr[i]);
X
X write_reg_high(ioaddr, CMR2, lp->addr_mode);
X
X if (net_debug > 2) {
- printk("%s: Reset: current Rx mode %d.\n", dev->name,
+ printk(KERN_DEBUG "%s: Reset: current Rx mode %d.\n", dev->name,
X (read_nibble(ioaddr, CMR2_h) >> 3) & 0x0f);
X }
X
- write_reg(ioaddr, CMR2, CMR2_IRQOUT);
- write_reg_high(ioaddr, CMR1, CMR1h_RxENABLE | CMR1h_TxENABLE);
+ write_reg(ioaddr, CMR2, CMR2_IRQOUT);
+ write_reg_high(ioaddr, CMR1, CMR1h_RxENABLE | CMR1h_TxENABLE);
X
X /* Enable the interrupt line from the serial port. */
X outb(Ctrl_SelData + Ctrl_IRQEN, ioaddr + PAR_CONTROL);
X
X /* Unmask the interesting interrupts. */
- write_reg(ioaddr, IMR, ISR_RxOK | ISR_TxErr | ISR_TxOK);
- write_reg_high(ioaddr, IMR, ISRh_RxErr);
+ write_reg(ioaddr, IMR, ISR_RxOK | ISR_TxErr | ISR_TxOK);
+ write_reg_high(ioaddr, IMR, ISRh_RxErr);
X
X lp->tx_unit_busy = 0;
- lp->pac_cnt_in_tx_buf = 0;
+ lp->pac_cnt_in_tx_buf = 0;
X lp->saved_tx_size = 0;
X }
X
-static void trigger_send(short ioaddr, int length)
+static void trigger_send(long ioaddr, int length)
X {
X write_reg_byte(ioaddr, TxCNT0, length & 0xff);
X write_reg(ioaddr, TxCNT1, length >> 8);
X write_reg(ioaddr, CMR1, CMR1_Xmit);
X }
X
-static void write_packet(short ioaddr, int length, unsigned char *packet, int data_mode)
+static void write_packet(long ioaddr, int length, unsigned char *packet, int data_mode)
X {
- length = (length + 1) & ~1; /* Round up to word length. */
- outb(EOC+MAR, ioaddr + PAR_DATA);
- if ((data_mode & 1) == 0) {
+ length = (length + 1) & ~1; /* Round up to word length. */
+ outb(EOC+MAR, ioaddr + PAR_DATA);
+ if ((data_mode & 1) == 0) {
X /* Write the packet out, starting with the write addr. */
X outb(WrAddr+MAR, ioaddr + PAR_DATA);
X do {
X write_byte_mode0(ioaddr, *packet++);
X } while (--length > 0) ;
- } else {
+ } else {
X /* Write the packet out in slow mode. */
X unsigned char outbyte = *packet++;
X
@@ -409,77 +517,85 @@
X outb(Ctrl_HNibWrite + Ctrl_IRQEN, ioaddr + PAR_CONTROL);
X while (--length > 0)
X write_byte_mode1(ioaddr, *packet++);
- }
- /* Terminate the Tx frame. End of write: ECB. */
- outb(0xff, ioaddr + PAR_DATA);
- outb(Ctrl_HNibWrite | Ctrl_SelData | Ctrl_IRQEN, ioaddr + PAR_CONTROL);
+ }
+ /* Terminate the Tx frame. End of write: ECB. */
+ outb(0xff, ioaddr + PAR_DATA);
+ outb(Ctrl_HNibWrite | Ctrl_SelData | Ctrl_IRQEN, ioaddr + PAR_CONTROL);
X }
X
X static void tx_timeout(struct net_device *dev)
X {
- struct net_local *lp = (struct net_local *)dev->priv;
- int ioaddr = dev->base_addr;
- /* If we get here, some higher level has decided we are broken. */
- printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
+ struct net_local *np = (struct net_local *)dev->priv;
+ long ioaddr = dev->base_addr;
+
+ printk(KERN_WARNING "%s: Transmit timed out, %s?\n", dev->name,
X inb(ioaddr + PAR_CONTROL) & 0x10 ? "network cable problem"
X : "IRQ conflict");
- lp->stats.tx_errors++;
+ np->stats.tx_errors++;
X /* Try to restart the adapter. */
X hardware_init(dev);


X dev->trans_start = jiffies;

X netif_wake_queue(dev);
+ np->stats.tx_errors++;
+ return;
X }
X
-static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
+static int atp_send_packet(struct sk_buff *skb, struct net_device *dev)
X {
X struct net_local *lp = (struct net_local *)dev->priv;
- int ioaddr = dev->base_addr;
- short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
- unsigned char *buf = skb->data;


- unsigned long flags;
-

+ long ioaddr = dev->base_addr;
+ int length;
+ long flags;
+
+ length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
+
X netif_stop_queue(dev);
-
+
X /* Disable interrupts by writing 0x00 to the Interrupt Mask Register.
X This sequence must not be interrupted by an incoming packet. */
-
+
X spin_lock_irqsave(&lp->lock, flags);
X write_reg(ioaddr, IMR, 0);
X write_reg_high(ioaddr, IMR, 0);
X spin_unlock_irqrestore(&lp->lock, flags);
-
- write_packet(ioaddr, length, buf, dev->if_port);
+
+ write_packet(ioaddr, length, skb->data, dev->if_port);
X
X lp->pac_cnt_in_tx_buf++;
X if (lp->tx_unit_busy == 0) {
X trigger_send(ioaddr, length);
X lp->saved_tx_size = 0; /* Redundant */
X lp->re_tx = 0;
- lp->tx_unit_busy = 1;
+ lp->tx_unit_busy = 1;
X } else
X lp->saved_tx_size = length;
-


- dev->trans_start = jiffies;

X /* Re-enable the LPT interrupts. */
X write_reg(ioaddr, IMR, ISR_RxOK | ISR_TxErr | ISR_TxOK);
X write_reg_high(ioaddr, IMR, ISRh_RxErr);
+
+ dev->trans_start = jiffies;
X dev_kfree_skb (skb);


X return 0;
X }
-

+
+
X /* The typical workload of the driver:
X Handle the network interface interrupts. */
-static void
-net_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static void atp_interrupt(int irq, void *dev_instance, struct pt_regs * regs)
X {
- struct net_device *dev = dev_id;
+ struct net_device *dev = (struct net_device *)dev_instance;
X struct net_local *lp;
- int ioaddr, status, boguscount = 20;
+ long ioaddr;
X static int num_tx_since_rx = 0;
+ int boguscount = max_interrupt_work;
X
+ if (dev == NULL) {
+ printk(KERN_ERR "ATP_interrupt(): irq %d for unknown device.\n", irq);
+ return;
+ }
X ioaddr = dev->base_addr;
X lp = (struct net_local *)dev->priv;
-
+
X spin_lock(&lp->lock);
X
X /* Disable additional spurious interrupts. */
@@ -489,14 +605,10 @@
X write_reg(ioaddr, CMR2, CMR2_NULL);
X write_reg(ioaddr, IMR, 0);
X
- if (net_debug > 5)
- printk("%s: In interrupt ", dev->name);
-
- while (--boguscount > 0)
- {
- status = read_nibble(ioaddr, ISR);
- if (net_debug > 5)
- printk("loop status %02x..", status);
+ if (net_debug > 5) printk(KERN_DEBUG "%s: In interrupt ", dev->name);
+ while (--boguscount > 0) {
+ int status = read_nibble(ioaddr, ISR);
+ if (net_debug > 5) printk("loop status %02x..", status);
X
X if (status & (ISR_RxOK<<3)) {
X write_reg(ioaddr, ISR, ISR_RxOK); /* Clear the Rx interrupt. */
@@ -534,8 +646,7 @@
X break;
X }
X /* Attempt to retransmit. */
- if (net_debug > 6)
- printk("attempting to ReTx");
+ if (net_debug > 6) printk("attempting to ReTx");
X write_reg(ioaddr, CMR1, CMR1_ReXmit + CMR1_Xmit);
X } else {
X /* Finish up the transmit. */
@@ -551,10 +662,10 @@
X }
X num_tx_since_rx++;
X } else if (num_tx_since_rx > 8
- && jiffies - dev->last_rx > 100) {
+ && jiffies > dev->last_rx + HZ) {
X if (net_debug > 2)
- printk("%s: Missed packet? No Rx after %d Tx and %ld jiffies"
- " status %02x CMR1 %02x.\n", dev->name,
+ printk(KERN_DEBUG "%s: Missed packet? No Rx after %d Tx and "
+ "%ld jiffies status %02x CMR1 %02x.\n", dev->name,
X num_tx_since_rx, jiffies - dev->last_rx, status,
X (read_nibble(ioaddr, CMR1) >> 3) & 15);
X lp->stats.rx_missed_errors++;
@@ -563,7 +674,7 @@
X break;
X } else


X break;
- }
+ }
X

X /* This following code fixes a rare (and very difficult to track down)
X problem where the adapter forgets its ethernet address. */
@@ -571,40 +682,62 @@
X int i;
X for (i = 0; i < 6; i++)
X write_reg_byte(ioaddr, PAR0 + i, dev->dev_addr[i]);
-#ifdef TIMED_CHECKER
- mod_timer(&atp_timer, jiffies+TIMED_CHECKER);
+#if 0 && defined(TIMED_CHECKER)
+ mod_timer(&lp->timer, RUN_AT(TIMED_CHECKER));
X #endif
X }
X
X /* Tell the adapter that it can go back to using the output line as IRQ. */
- write_reg(ioaddr, CMR2, CMR2_IRQOUT);
+ write_reg(ioaddr, CMR2, CMR2_IRQOUT);
X /* Enable the physical interrupt line, which is sure to be low until.. */
X outb(Ctrl_SelData + Ctrl_IRQEN, ioaddr + PAR_CONTROL);
X /* .. we enable the interrupt sources. */
X write_reg(ioaddr, IMR, ISR_RxOK | ISR_TxErr | ISR_TxOK);
X write_reg_high(ioaddr, IMR, ISRh_RxErr); /* Hmmm, really needed? */
X
- if (net_debug > 5)
- printk("exiting interrupt.\n");
-
X spin_unlock(&lp->lock);
+
+ if (net_debug > 5) printk("exiting interrupt.\n");
X return;
X }
X
X #ifdef TIMED_CHECKER
X /* This following code fixes a rare (and very difficult to track down)
X problem where the adapter forgets its ethernet address. */
-static void atp_timed_checker(unsigned long ignored)
+static void atp_timed_checker(unsigned long data)
X {
+ struct net_device *dev = (struct net_device *)data;
+ long ioaddr = dev->base_addr;
+ struct net_local *lp = (struct net_local *)dev->priv;
+ int tickssofar = jiffies - lp->last_rx_time;
X int i;
- struct net_local *lp = (struct net_local *)atp_timed_dev->priv;
- int ioaddr = atp_timed_dev->base_addr;
X
X spin_lock(&lp->lock);
- for (i = 0; i < 6; i++)
- write_reg_byte(ioaddr, PAR0 + i, atp_timed_dev->dev_addr[i]);
+ if (tickssofar > 2*HZ) {
+#if 1
+ for (i = 0; i < 6; i++)
+ write_reg_byte(ioaddr, PAR0 + i, dev->dev_addr[i]);
+ lp->last_rx_time = jiffies;
+#else
+ for (i = 0; i < 6; i++)
+ if (read_cmd_byte(ioaddr, PAR0 + i) != atp_timed_dev->dev_addr[i])
+ {
+ struct net_local *lp = (struct net_local *)atp_timed_dev->priv;
+ write_reg_byte(ioaddr, PAR0 + i, atp_timed_dev->dev_addr[i]);
+ if (i == 2)
+ lp->stats.tx_errors++;
+ else if (i == 3)
+ lp->stats.tx_dropped++;
+ else if (i == 4)
+ lp->stats.collisions++;
+ else
+ lp->stats.rx_errors++;
+ }
+#endif
+ }
X spin_unlock(&lp->lock);
- mod_timer(&atp_timer, jiffies+TIMED_CHECKER);
+ lp->timer.expires = RUN_AT(TIMED_CHECKER);
+ add_timer(&lp->timer);
X }
X #endif
X
@@ -612,61 +745,57 @@
X static void net_rx(struct net_device *dev)
X {
X struct net_local *lp = (struct net_local *)dev->priv;
- int ioaddr = dev->base_addr;
-#ifdef notdef
- ushort header[4];
-#else
+ long ioaddr = dev->base_addr;
X struct rx_header rx_head;
-#endif
X
X /* Process the received packet. */
X outb(EOC+MAR, ioaddr + PAR_DATA);
X read_block(ioaddr, 8, (unsigned char*)&rx_head, dev->if_port);
X if (net_debug > 5)
- printk(" rx_count %04x %04x %04x %04x..", rx_head.pad,
+ printk(KERN_DEBUG " rx_count %04x %04x %04x %04x..", rx_head.pad,
X rx_head.rx_count, rx_head.rx_status, rx_head.cur_addr);
X if ((rx_head.rx_status & 0x77) != 0x01) {
X lp->stats.rx_errors++;
- /* Ackkk! I don't have any documentation on what the error bits mean!
- The best I can do is slap the device around a bit. */
- if (net_debug > 3) printk("%s: Unknown ATP Rx error %04x.\n",
- dev->name, rx_head.rx_status);
- hardware_init(dev);
+ if (rx_head.rx_status & 0x0004) lp->stats.rx_frame_errors++;
+ else if (rx_head.rx_status & 0x0002) lp->stats.rx_crc_errors++;
+ if (net_debug > 3)
+ printk(KERN_DEBUG "%s: Unknown ATP Rx error %04x.\n",
+ dev->name, rx_head.rx_status);
+ if (rx_head.rx_status & 0x0020) {
+ lp->stats.rx_fifo_errors++;
+ write_reg_high(ioaddr, CMR1, CMR1h_TxENABLE);
+ write_reg_high(ioaddr, CMR1, CMR1h_RxENABLE | CMR1h_TxENABLE);
+ } else if (rx_head.rx_status & 0x0050)
+ hardware_init(dev);
X return;
X } else {
- /* Malloc up new buffer. */
- int pkt_len = (rx_head.rx_count & 0x7ff) - 4; /* The "-4" is omits the FCS (CRC). */
+ /* Malloc up new buffer. The "-4" omits the FCS (CRC). */
+ int pkt_len = (rx_head.rx_count & 0x7ff) - 4;


X struct sk_buff *skb;
-

- skb = dev_alloc_skb(pkt_len);
+
+ skb = dev_alloc_skb(pkt_len + 2);
X if (skb == NULL) {
- printk("%s: Memory squeeze, dropping packet.\n", dev->name);
+ printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n",
+ dev->name);
X lp->stats.rx_dropped++;
X goto done;
X }
X skb->dev = dev;
-
- read_block(ioaddr, pkt_len, skb_put(skb,pkt_len), dev->if_port);
X
- if (net_debug > 6) {
- unsigned char *data = skb->data;
- printk(" data %02x%02x%02x %02x%02x%02x %02x%02x%02x"
- "%02x%02x%02x %02x%02x..",
- data[0], data[1], data[2], data[3], data[4], data[5],
- data[6], data[7], data[8], data[9], data[10], data[11],
- data[12], data[13]);
- }
-
- skb->protocol=eth_type_trans(skb,dev);
+ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
+ read_block(ioaddr, pkt_len, skb_put(skb,pkt_len), dev->if_port);
+ skb->protocol = eth_type_trans(skb, dev);
X netif_rx(skb);
X lp->stats.rx_packets++;
+ lp->stats.rx_bytes += pkt_len;
X }
X done:
X write_reg(ioaddr, CMR1, CMR1_NextPkt);
+ lp->last_rx_time = jiffies;
X return;
X }
X
-static void read_block(short ioaddr, int length, unsigned char *p, int data_mode)
+static void read_block(long ioaddr, int length, unsigned char *p, int data_mode)
X {
X
X if (data_mode <= 3) { /* Mode 0 or 1 */
@@ -682,18 +811,21 @@
X else
X do *p++ = read_byte_mode6(ioaddr); while (--length > 0);
X
- outb(EOC+HNib+MAR, ioaddr + PAR_DATA);
+ outb(EOC+HNib+MAR, ioaddr + PAR_DATA);
X outb(Ctrl_SelData, ioaddr + PAR_CONTROL);
X }
X
X /* The inverse routine to net_open(). */
-static int net_close(struct net_device *dev)
+static int
+net_close(struct net_device *dev)
X {
X struct net_local *lp = (struct net_local *)dev->priv;
- int ioaddr = dev->base_addr;
+ long ioaddr = dev->base_addr;
X
X netif_stop_queue(dev);
X
+ del_timer_sync(&lp->timer);
+
X /* Flush the Tx and disable Rx here. */
X lp->addr_mode = CMR2h_OFF;
X write_reg_high(ioaddr, CMR2, CMR2h_OFF);
@@ -702,8 +834,8 @@
X outb(0x00, ioaddr + PAR_CONTROL);
X free_irq(dev->irq, dev);
X
- /* Leave the hardware in a reset state. */
- write_reg_high(ioaddr, CMR1, CMR1h_RESET);
+ /* Reset the ethernet hardware and activate the printer pass-through. */
+ write_reg_high(ioaddr, CMR1, CMR1h_RESET | CMR1h_MUX);
X
X MOD_DEC_USE_COUNT;
X

@@ -712,7 +844,8 @@
X

X /* Get the current statistics. This may be called with the card open or
X closed. */
-static struct net_device_stats *net_get_stats(struct net_device *dev)
+static struct net_device_stats *
+net_get_stats(struct net_device *dev)
X {
X struct net_local *lp = (struct net_local *)dev->priv;
X return &lp->stats;
@@ -721,46 +854,101 @@
X /*
X * Set or clear the multicast filter for this adapter.
X */
-
-static void set_multicast_list(struct net_device *dev)
+
+/* The little-endian AUTODIN32 ethernet CRC calculation.
+ This is common code and should be moved to net/core/crc.c */
+static unsigned const ethernet_polynomial_le = 0xedb88320U;
+static inline unsigned ether_crc_le(int length, unsigned char *data)
+{
+ unsigned int crc = 0xffffffff; /* Initial value. */
+ while(--length >= 0) {
+ unsigned char current_octet = *data++;
+ int bit;
+ for (bit = 8; --bit >= 0; current_octet >>= 1) {
+ if ((crc ^ current_octet) & 1) {
+ crc >>= 1;
+ crc ^= ethernet_polynomial_le;
+ } else
+ crc >>= 1;
+ }
+ }
+ return crc;
+}
+
+static void set_rx_mode_8002(struct net_device *dev)
X {
X struct net_local *lp = (struct net_local *)dev->priv;
- short ioaddr = dev->base_addr;
- int num_addrs=dev->mc_count;
-
- if(dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
- num_addrs=1;
- /*
- * We must make the kernel realise we had to move
- * into promisc mode or we start all out war on
- * the cable. - AC
- */
- if(num_addrs)
- dev->flags|=IFF_PROMISC;
- lp->addr_mode = num_addrs ? CMR2h_PROMISC : CMR2h_Normal;
+ long ioaddr = dev->base_addr;
+
+ if ( dev->mc_count > 0 || (dev->flags & (IFF_ALLMULTI|IFF_PROMISC))) {
+ /* We must make the kernel realise we had to move
+ * into promisc mode or we start all out war on
+ * the cable. - AC
+ */
+ dev->flags|=IFF_PROMISC;
+ lp->addr_mode = CMR2h_PROMISC;
+ } else
+ lp->addr_mode = CMR2h_Normal;
X write_reg_high(ioaddr, CMR2, lp->addr_mode);
X }
X
-/* module stuff */
-static int io;
-static struct net_device atp_dev = { init: atp_init };
-MODULE_AUTHOR("Donald Becker <bec...@scyld.com>");
-MODULE_DESCRIPTION("Realtek 8002/8012 Pocket Lan Adapter");
-MODULE_PARM(io, "I/O port of the pocket adapter");
+static void set_rx_mode_8012(struct net_device *dev)
+{
+ struct net_local *lp = (struct net_local *)dev->priv;
+ long ioaddr = dev->base_addr;
+ unsigned char new_mode, mc_filter[8]; /* Multicast hash filter */
+ int i;
X
-static int __init atp_init_module(void) {
- atp_dev.base_addr = io;
+ if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
+ new_mode = CMR2h_PROMISC;
+ } else if ((dev->mc_count > 1000) || (dev->flags & IFF_ALLMULTI)) {
+ /* Too many to filter perfectly -- accept all multicasts. */
+ memset(mc_filter, 0xff, sizeof(mc_filter));
+ new_mode = CMR2h_Normal;
+ } else {
+ struct dev_mc_list *mclist;
X
- if (register_netdev(&atp_dev) != 0)
- return -EIO;
+ memset(mc_filter, 0, sizeof(mc_filter));
+ for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
+ i++, mclist = mclist->next)
+ set_bit(ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x3f,
+ mc_filter);
+ new_mode = CMR2h_Normal;
+ }
+ lp->addr_mode = new_mode;
+ write_reg(ioaddr, CMR2, CMR2_IRQOUT | 0x04); /* Switch to page 1. */
+ for (i = 0; i < 8; i++)
+ write_reg_byte(ioaddr, i, mc_filter[i]);
+ if (net_debug > 2 || 1) {
+ lp->addr_mode = 1;
+ printk(KERN_DEBUG "%s: Mode %d, setting multicast filter to",
+ dev->name, lp->addr_mode);
+ for (i = 0; i < 8; i++)
+ printk(" %2.2x", mc_filter[i]);


+ printk(".\n");
+ }

X
- return 0;
+ write_reg_high(ioaddr, CMR2, lp->addr_mode);
+ write_reg(ioaddr, CMR2, CMR2_IRQOUT); /* Switch back to page 0 */
+}
+
+static int __init atp_init_module(void) {
+ if (debug) /* Emit version even if no cards detected. */
+ printk(KERN_INFO "%s" KERN_INFO "%s", versionA, versionB);
+ return atp_init(NULL);
X }
X
X static void __exit atp_cleanup_module(void) {
- unregister_netdev(&atp_dev);
+ struct net_device *next_dev;
+
+ while (root_atp_dev) {
+ next_dev = ((struct net_local *)root_atp_dev->priv)->next_module;
+ unregister_netdev(root_atp_dev);
+ /* No need to release_region(), since we never snarf it. */
+ kfree(root_atp_dev);
+ root_atp_dev = next_dev;
+ }
X }
X
X module_init(atp_init_module);
X module_exit(atp_cleanup_module);
-
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/atp.h linux/drivers/net/atp.h
--- v2.4.0-test8/linux/drivers/net/atp.h Sun Feb 13 18:20:21 2000
+++ linux/drivers/net/atp.h Thu Sep 21 13:33:32 2000
@@ -1,30 +1,23 @@
+/* Linux header file for the ATP pocket ethernet adapter. */
+/* v1.09 8/9/2000 bec...@scyld.com. */
+
X #include <linux/if_ether.h>
X #include <linux/types.h>
-#include <asm/io.h>
-
-struct net_local
-{
- struct net_device_stats stats;
- ushort saved_tx_size;
- unsigned char
- re_tx, /* Number of packet retransmissions. */
- tx_unit_busy,
- addr_mode, /* Current Rx filter e.g. promiscuous, etc. */
- pac_cnt_in_tx_buf;
- spinlock_t lock; /* Safety lock */
-};
X
+/* The header prepended to received packets. */
X struct rx_header {
- ushort pad; /* The first read is always corrupted. */
- ushort rx_count;
- ushort rx_status; /* Unknown bit assignments :-<. */
- ushort cur_addr; /* Apparently the current buffer address(?) */
+ ushort pad; /* Pad. */
+ ushort rx_count;
+ ushort rx_status; /* Unknown bit assignments :-<. */
+ ushort cur_addr; /* Apparently the current buffer address(?) */
X };
X
X #define PAR_DATA 0
X #define PAR_STATUS 1
X #define PAR_CONTROL 2
X
+enum chip_type { RTL8002, RTL8012 };
+
X #define Ctrl_LNibRead 0x08 /* LP_PSELECP */
X #define Ctrl_HNibRead 0
X #define Ctrl_LNibWrite 0x08 /* LP_PSELECP */
@@ -40,18 +33,19 @@
X
X enum page0_regs
X {
- /* The first six registers hold the ethernet physical station address. */
- PAR0 = 0, PAR1 = 1, PAR2 = 2, PAR3 = 3, PAR4 = 4, PAR5 = 5,
- TxCNT0 = 6, TxCNT1 = 7, /* The transmit byte count. */
- TxSTAT = 8, RxSTAT = 9, /* Tx and Rx status. */
- ISR = 10, IMR = 11, /* Interrupt status and mask. */
- CMR1 = 12, /* Command register 1. */
- CMR2 = 13, /* Command register 2. */
- MAR = 14, /* Memory address register. */
- CMR2_h = 0x1d,
-};
+ /* The first six registers hold the ethernet physical station address. */
+ PAR0 = 0, PAR1 = 1, PAR2 = 2, PAR3 = 3, PAR4 = 4, PAR5 = 5,
+ TxCNT0 = 6, TxCNT1 = 7, /* The transmit byte count. */
+ TxSTAT = 8, RxSTAT = 9, /* Tx and Rx status. */
+ ISR = 10, IMR = 11, /* Interrupt status and mask. */
+ CMR1 = 12, /* Command register 1. */
+ CMR2 = 13, /* Command register 2. */
+ MODSEL = 14, /* Mode select register. */
+ MAR = 14, /* Memory address register (?). */
+ CMR2_h = 0x1d, };
X
-enum eepage_regs { PROM_CMD = 6, PROM_DATA = 7 }; /* Note that PROM_CMD is in the "high" bits. */
+enum eepage_regs
+{ PROM_CMD = 6, PROM_DATA = 7 }; /* Note that PROM_CMD is in the "high" bits. */
X
X
X #define ISR_TxOK 0x01
@@ -59,6 +53,7 @@
X #define ISR_TxErr 0x02
X #define ISRh_RxErr 0x11 /* ISR, high nibble */
X
+#define CMR1h_MUX 0x08 /* Select printer multiplexor on 8012. */
X #define CMR1h_RESET 0x04 /* Reset. */
X #define CMR1h_RxENABLE 0x02 /* Rx unit enable. */
X #define CMR1h_TxENABLE 0x01 /* Tx unit enable. */
@@ -81,139 +76,135 @@
X
X /* An inline function used below: it differs from inb() by explicitly return an unsigned
X char, saving a truncation. */
-
-extern inline unsigned char inbyte(unsigned short port)
+static inline unsigned char inbyte(unsigned short port)
X {
- unsigned char _v;
- __asm__ __volatile__ ("inb %w1,%b0" :"=a" (_v):"d" (port));
- return _v;
+ unsigned char _v;
+ __asm__ __volatile__ ("inb %w1,%b0" :"=a" (_v):"d" (port));
+ return _v;
X }
X
X /* Read register OFFSET.
X This command should always be terminated with read_end(). */
-
-extern inline unsigned char read_nibble(short port, unsigned char offset)
+static inline unsigned char read_nibble(short port, unsigned char offset)
X {
- unsigned char retval;
- outb(EOC+offset, port + PAR_DATA);
- outb(RdAddr+offset, port + PAR_DATA);
- inbyte(port + PAR_STATUS); /* Settling time delay */
- retval = inbyte(port + PAR_STATUS);
- outb(EOC+offset, port + PAR_DATA);
+ unsigned char retval;
+ outb(EOC+offset, port + PAR_DATA);
+ outb(RdAddr+offset, port + PAR_DATA);
+ inbyte(port + PAR_STATUS); /* Settling time delay */
+ retval = inbyte(port + PAR_STATUS);
+ outb(EOC+offset, port + PAR_DATA);
X
- return retval;
+ return retval;
X }
X
X /* Functions for bulk data read. The interrupt line is always disabled. */
X /* Get a byte using read mode 0, reading data from the control lines. */
-
-extern inline unsigned char read_byte_mode0(short ioaddr)
+static inline unsigned char read_byte_mode0(short ioaddr)
X {
- unsigned char low_nib;
+ unsigned char low_nib;
X
- outb(Ctrl_LNibRead, ioaddr + PAR_CONTROL);
- inbyte(ioaddr + PAR_STATUS);
- low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f;
- outb(Ctrl_HNibRead, ioaddr + PAR_CONTROL);
- inbyte(ioaddr + PAR_STATUS); /* Settling time delay -- needed! */
- inbyte(ioaddr + PAR_STATUS); /* Settling time delay -- needed! */
- return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0);
+ outb(Ctrl_LNibRead, ioaddr + PAR_CONTROL);
+ inbyte(ioaddr + PAR_STATUS);
+ low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f;
+ outb(Ctrl_HNibRead, ioaddr + PAR_CONTROL);
+ inbyte(ioaddr + PAR_STATUS); /* Settling time delay -- needed! */
+ inbyte(ioaddr + PAR_STATUS); /* Settling time delay -- needed! */
+ return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0);
X }
X
X /* The same as read_byte_mode0(), but does multiple inb()s for stability. */
-
-extern inline unsigned char read_byte_mode2(short ioaddr)
+static inline unsigned char read_byte_mode2(short ioaddr)
X {
- unsigned char low_nib;
+ unsigned char low_nib;
X
- outb(Ctrl_LNibRead, ioaddr + PAR_CONTROL);
- inbyte(ioaddr + PAR_STATUS);
- low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f;
- outb(Ctrl_HNibRead, ioaddr + PAR_CONTROL);
- inbyte(ioaddr + PAR_STATUS); /* Settling time delay -- needed! */
- return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0);
+ outb(Ctrl_LNibRead, ioaddr + PAR_CONTROL);
+ inbyte(ioaddr + PAR_STATUS);
+ low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f;
+ outb(Ctrl_HNibRead, ioaddr + PAR_CONTROL);
+ inbyte(ioaddr + PAR_STATUS); /* Settling time delay -- needed! */
+ return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0);
X }
X
X /* Read a byte through the data register. */
-
-extern inline unsigned char read_byte_mode4(short ioaddr)
+static inline unsigned char read_byte_mode4(short ioaddr)
X {
- unsigned char low_nib;
+ unsigned char low_nib;
X
- outb(RdAddr | MAR, ioaddr + PAR_DATA);
- low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f;
- outb(RdAddr | HNib | MAR, ioaddr + PAR_DATA);
- return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0);
+ outb(RdAddr | MAR, ioaddr + PAR_DATA);
+ low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f;
+ outb(RdAddr | HNib | MAR, ioaddr + PAR_DATA);
+ return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0);
X }
X
X /* Read a byte through the data register, double reading to allow settling. */
-
-extern inline unsigned char read_byte_mode6(short ioaddr)
+static inline unsigned char read_byte_mode6(short ioaddr)
X {
- unsigned char low_nib;
+ unsigned char low_nib;
X
- outb(RdAddr | MAR, ioaddr + PAR_DATA);
- inbyte(ioaddr + PAR_STATUS);
- low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f;
- outb(RdAddr | HNib | MAR, ioaddr + PAR_DATA);
- inbyte(ioaddr + PAR_STATUS);
- return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0);
+ outb(RdAddr | MAR, ioaddr + PAR_DATA);
+ inbyte(ioaddr + PAR_STATUS);
+ low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f;
+ outb(RdAddr | HNib | MAR, ioaddr + PAR_DATA);
+ inbyte(ioaddr + PAR_STATUS);
+ return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0);
X }
X
-extern inline void write_reg(short port, unsigned char reg, unsigned char value)
+static inline void
+write_reg(short port, unsigned char reg, unsigned char value)
X {
- unsigned char outval;
- outb(EOC | reg, port + PAR_DATA);
- outval = WrAddr | reg;
- outb(outval, port + PAR_DATA);
- outb(outval, port + PAR_DATA); /* Double write for PS/2. */
+ unsigned char outval;
+ outb(EOC | reg, port + PAR_DATA);
+ outval = WrAddr | reg;
+ outb(outval, port + PAR_DATA);
+ outb(outval, port + PAR_DATA); /* Double write for PS/2. */
X
- outval &= 0xf0;
- outval |= value;
- outb(outval, port + PAR_DATA);
- outval &= 0x1f;
- outb(outval, port + PAR_DATA);
- outb(outval, port + PAR_DATA);
+ outval &= 0xf0;
+ outval |= value;
+ outb(outval, port + PAR_DATA);
+ outval &= 0x1f;
+ outb(outval, port + PAR_DATA);
+ outb(outval, port + PAR_DATA);
X
- outb(EOC | outval, port + PAR_DATA);
+ outb(EOC | outval, port + PAR_DATA);
X }
X
-extern inline void write_reg_high(short port, unsigned char reg, unsigned char value)
+static inline void
+write_reg_high(short port, unsigned char reg, unsigned char value)
X {
- unsigned char outval = EOC | HNib | reg;
+ unsigned char outval = EOC | HNib | reg;
X
- outb(outval, port + PAR_DATA);
- outval &= WrAddr | HNib | 0x0f;
- outb(outval, port + PAR_DATA);
- outb(outval, port + PAR_DATA); /* Double write for PS/2. */
+ outb(outval, port + PAR_DATA);
+ outval &= WrAddr | HNib | 0x0f;
+ outb(outval, port + PAR_DATA);
+ outb(outval, port + PAR_DATA); /* Double write for PS/2. */
X
- outval = WrAddr | HNib | value;
- outb(outval, port + PAR_DATA);
- outval &= HNib | 0x0f; /* HNib | value */
- outb(outval, port + PAR_DATA);
- outb(outval, port + PAR_DATA);
+ outval = WrAddr | HNib | value;
+ outb(outval, port + PAR_DATA);
+ outval &= HNib | 0x0f; /* HNib | value */
+ outb(outval, port + PAR_DATA);
+ outb(outval, port + PAR_DATA);
X
- outb(EOC | HNib | outval, port + PAR_DATA);
+ outb(EOC | HNib | outval, port + PAR_DATA);
X }
X
X /* Write a byte out using nibble mode. The low nibble is written first. */
-
-extern inline void write_reg_byte(short port, unsigned char reg, unsigned char value)
+static inline void
+write_reg_byte(short port, unsigned char reg, unsigned char value)
X {
- unsigned char outval;
- outb(EOC | reg, port + PAR_DATA); /* Reset the address register. */
- outval = WrAddr | reg;
- outb(outval, port + PAR_DATA);
- outb(outval, port + PAR_DATA); /* Double write for PS/2. */
-
- outb((outval & 0xf0) | (value & 0x0f), port + PAR_DATA);
- outb(value & 0x0f, port + PAR_DATA);
- value >>= 4;
- outb(value, port + PAR_DATA);
- outb(0x10 | value, port + PAR_DATA);
- outb(0x10 | value, port + PAR_DATA);
+ unsigned char outval;
+ outb(EOC | reg, port + PAR_DATA); /* Reset the address register. */
+ outval = WrAddr | reg;
+ outb(outval, port + PAR_DATA);
+ outb(outval, port + PAR_DATA); /* Double write for PS/2. */
+
+ outb((outval & 0xf0) | (value & 0x0f), port + PAR_DATA);
+ outb(value & 0x0f, port + PAR_DATA);
+ value >>= 4;
+ outb(value, port + PAR_DATA);
+ outb(0x10 | value, port + PAR_DATA);
+ outb(0x10 | value, port + PAR_DATA);
X
- outb(EOC | value, port + PAR_DATA); /* Reset the address register. */
+ outb(EOC | value, port + PAR_DATA); /* Reset the address register. */
X }
X
X /*
@@ -223,32 +214,30 @@
X * It should only be needed when there is skew between the individual data
X * lines.
X */
-
-extern inline void write_byte_mode0(short ioaddr, unsigned char value)
+static inline void write_byte_mode0(short ioaddr, unsigned char value)
X {
- outb(value & 0x0f, ioaddr + PAR_DATA);
- outb((value>>4) | 0x10, ioaddr + PAR_DATA);
+ outb(value & 0x0f, ioaddr + PAR_DATA);
+ outb((value>>4) | 0x10, ioaddr + PAR_DATA);
X }
X
-extern inline void write_byte_mode1(short ioaddr, unsigned char value)
+static inline void write_byte_mode1(short ioaddr, unsigned char value)
X {
- outb(value & 0x0f, ioaddr + PAR_DATA);
- outb(Ctrl_IRQEN | Ctrl_LNibWrite, ioaddr + PAR_CONTROL);
- outb((value>>4) | 0x10, ioaddr + PAR_DATA);
- outb(Ctrl_IRQEN | Ctrl_HNibWrite, ioaddr + PAR_CONTROL);
+ outb(value & 0x0f, ioaddr + PAR_DATA);
+ outb(Ctrl_IRQEN | Ctrl_LNibWrite, ioaddr + PAR_CONTROL);
+ outb((value>>4) | 0x10, ioaddr + PAR_DATA);
+ outb(Ctrl_IRQEN | Ctrl_HNibWrite, ioaddr + PAR_CONTROL);
X }
X
X /* Write 16bit VALUE to the packet buffer: the same as above just doubled. */
-
-extern inline void write_word_mode0(short ioaddr, unsigned short value)
+static inline void write_word_mode0(short ioaddr, unsigned short value)
X {
- outb(value & 0x0f, ioaddr + PAR_DATA);
- value >>= 4;
- outb((value & 0x0f) | 0x10, ioaddr + PAR_DATA);
- value >>= 4;
- outb(value & 0x0f, ioaddr + PAR_DATA);
- value >>= 4;
- outb((value & 0x0f) | 0x10, ioaddr + PAR_DATA);
+ outb(value & 0x0f, ioaddr + PAR_DATA);
+ value >>= 4;
+ outb((value & 0x0f) | 0x10, ioaddr + PAR_DATA);
+ value >>= 4;
+ outb(value & 0x0f, ioaddr + PAR_DATA);
+ value >>= 4;
+ outb((value & 0x0f) | 0x10, ioaddr + PAR_DATA);
X }
X
X /* EEPROM_Ctrl bits. */
@@ -258,6 +247,10 @@
X #define EE_CLK_LOW 0x16
X #define EE_DATA_WRITE 0x01 /* EEPROM chip data in. */
X #define EE_DATA_READ 0x08 /* EEPROM chip data out. */
+
+/* Delay between EEPROM clock transitions. */
+#define eeprom_delay(ticks) \
+do { int _i = 40; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0)
X
X /* The EEPROM commands include the alway-set leading bit. */
X #define EE_WRITE_CMD(offset) (((5 << 6) + (offset)) << 17)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/auto_irq.c linux/drivers/net/auto_irq.c
--- v2.4.0-test8/linux/drivers/net/auto_irq.c Tue Feb 10 12:56:44 1998
+++ linux/drivers/net/auto_irq.c Sun Sep 17 09:45:05 2000
@@ -32,6 +32,7 @@
X "auto_irq.c:v1.11 Donald Becker (bec...@cesdis.gsfc.nasa.gov)";
X #endif
X
+#include <linux/module.h>
X #include <linux/sched.h>
X #include <linux/delay.h>
X #include <asm/bitops.h>
@@ -53,6 +54,10 @@
X BUSY_LOOP_UNTIL(delay)
X return probe_irq_off(irqs);
X }
+
+EXPORT_SYMBOL(autoirq_setup);
+EXPORT_SYMBOL(autoirq_report);
+
X
X /*
X * Local variables:
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/bonding.c linux/drivers/net/bonding.c
--- v2.4.0-test8/linux/drivers/net/bonding.c Wed Jul 5 22:15:27 2000
+++ linux/drivers/net/bonding.c Fri Sep 22 14:21:16 2000
@@ -31,29 +31,10 @@


X *
X */
X

-#include <linux/kernel.h>
X #include <linux/module.h>


-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/malloc.h>
-#include <linux/string.h>

-#include <linux/init.h>


-#include <asm/system.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <asm/dma.h>

-#include <asm/uaccess.h>
-#include <linux/errno.h>
-
+#include <linux/kernel.h>
X #include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
+#include <linux/init.h>
X #include <linux/if_bonding.h>
X
X typedef struct slave
@@ -228,13 +209,13 @@
X return NOTIFY_DONE;
X }
X
-struct notifier_block bond_netdev_notifier={
+static struct notifier_block bond_netdev_notifier={
X bond_event,
X NULL,
X 0
X };
X
-int __init bond_init(struct net_device *dev)
+static int __init bond_init(struct net_device *dev)
X {
X bonding_t *bond;
X
@@ -308,15 +289,13 @@
X return &bond->stats;


X }
X
-#ifdef MODULE
-

X static struct net_device dev_bond = {
X "",
X 0, 0, 0, 0,
X 0x0, 0,
X 0, 0, 0, NULL, bond_init };
X
-int init_module(void)
+static int __init bonding_init(void)


X {
X /* Find a name for this unit */

X int err=dev_alloc_name(&dev_bond,"bond%d");
@@ -330,7 +309,7 @@


X return 0;
X }
X
-void cleanup_module(void)

+static void __exit bonding_exit(void)
X {
X unregister_netdevice_notifier(&bond_netdev_notifier);
X
@@ -338,7 +317,9 @@
X
X kfree(dev_bond.priv);


X }
-#endif /* MODULE */
+

+module_init(bonding_init);
+module_exit(bonding_exit);
X
X /*
X * Local variables:
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/cs89x0.c linux/drivers/net/cs89x0.c
--- v2.4.0-test8/linux/drivers/net/cs89x0.c Wed Jul 5 11:54:11 2000
+++ linux/drivers/net/cs89x0.c Tue Sep 19 08:31:53 2000
@@ -61,6 +61,11 @@
X : MOD_INC/DEC race fix (see
X : http://www.uwsg.indiana.edu/hypermail/linux/kernel/0003.3/1532.html)
X
+ Andrew Morton : and...@uow.edu.au / Kernel 2.4.0-test7-pre2
+ : Enhanced EEPROM support to cover more devices,
+ : abstracted IRQ mapping to support CONFIG_ARCH_CLPS7500 arch
+ : (Jason Gunthorpe <j...@ualberta.ca>)
+
X */
X
X static char *version =
@@ -71,6 +76,7 @@
X
X /* Always include 'config.h' first in case the user wants to turn on
X or override something. */
+#include <linux/config.h>
X #ifdef MODULE
X #include <linux/module.h>
X #include <linux/version.h>
@@ -128,10 +134,26 @@
X
X #include "cs89x0.h"
X
-/* First, a few definitions that the brave might change. */
-/* A zero-terminated list of I/O addresses to be probed. */
+/* First, a few definitions that the brave might change.
+ A zero-terminated list of I/O addresses to be probed. Some special flags..
+ Addr & 1 = Read back the address port, look for signature and reset
+ the page window before probing
+ Addr & 3 = Reset the page window and probe
+ The CLPS eval board has the Cirrus chip at 0x80090300, in ARM IO space,
+ but it is possible that a Cirrus board could be plugged into the ISA
+ slots. */
+/* The cs8900 has 4 IRQ pins, software selectable. cs8900_irq_map maps
+ them to system IRQ numbers. This mapping is card specific and is set to
+ the configuration of the Cirrus Eval board for this chip. */
+#ifdef CONFIG_ARCH_CLPS7500
+static unsigned int netcard_portlist[] __initdata =
+ { 0x80090303, 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
+static unsigned int cs8900_irq_map[] = {12,0,0,0};
+#else
X static unsigned int netcard_portlist[] __initdata =
X { 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
+static unsigned int cs8900_irq_map[] = {10,11,12,5};
+#endif
X
X #if DEBUGGING
X static unsigned int net_debug = DEBUGGING;
@@ -343,7 +365,7 @@
X dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
X if (dev->priv == 0)
X {
- retval = ENOMEM;
+ retval = -ENOMEM;
X goto out;
X }
X lp = (struct net_local *)dev->priv;
@@ -362,18 +384,20 @@
X
X /* if they give us an odd I/O address, then do ONE write to
X the address port, to get it back to address zero, where we
- expect to find the EISA signature word. */
+ expect to find the EISA signature word. An IO with a base of 0x3
+ will skip the test for the ADD_PORT. */
X if (ioaddr & 1) {
- ioaddr &= ~1;
- if ((inw(ioaddr + ADD_PORT) & ADD_MASK) != ADD_SIG)
- return -ENODEV;
+ if ((ioaddr & 2) != 2)
+ if ((inw((ioaddr & ~3)+ ADD_PORT) & ADD_MASK) != ADD_SIG)
+ return -ENODEV;
+ ioaddr &= ~3;
X outw(PP_ChipID, ioaddr + ADD_PORT);
X }
X
- if (inw(ioaddr + DATA_PORT) != CHIP_EISA_ID_SIG)
- {
- retval = ENODEV;
- goto out1;
+ if (inw(ioaddr + DATA_PORT) != CHIP_EISA_ID_SIG)
+ {
+ retval = -ENODEV;
+ goto out1;
X }
X
X /* Fill in the 'dev' fields. */
@@ -403,15 +427,77 @@
X dev->base_addr);
X
X reset_chip(dev);
-
- /* First check to see if an EEPROM is attached*/
+
+ /* Here we read the current configuration of the chip. If there
+ is no Extended EEPROM then the idea is to not disturb the chip
+ configuration, it should have been correctly setup by automatic
+ EEPROM read on reset. So, if the chip says it read the EEPROM
+ the driver will always do *something* instead of complain that
+ adapter_cnf is 0. */
+ if ((readreg(dev, PP_SelfST) & (EEPROM_OK | EEPROM_PRESENT)) ==
+ (EEPROM_OK|EEPROM_PRESENT)) {
+ /* Load the MAC. */
+ for (i=0; i < ETH_ALEN/2; i++) {
+ unsigned int Addr;
+ Addr = readreg(dev, PP_IA+i*2);
+ dev->dev_addr[i*2] = Addr & 0xFF;
+ dev->dev_addr[i*2+1] = Addr >> 8;
+ }
+
+ /* Load the Adapter Configuration.
+ Note: Barring any more specific information from some
+ other source (ie EEPROM+Schematics), we would not know
+ how to operate a 10Base2 interface on the AUI port.
+ However, since we do read the status of HCB1 and use
+ settings that always result in calls to control_dc_dc(dev,0)
+ a BNC interface should work if the enable pin
+ (dc/dc converter) is on HCB1. It will be called AUI
+ however. */
+
+ lp->adapter_cnf = 0;
+ i = readreg(dev, PP_LineCTL);
+ /* Preserve the setting of the HCB1 pin. */
+ if ((i & (HCB1 | HCB1_ENBL)) == (HCB1 | HCB1_ENBL))
+ lp->adapter_cnf |= A_CNF_DC_DC_POLARITY;
+ /* Save the sqelch bit */
+ if ((i & LOW_RX_SQUELCH) == LOW_RX_SQUELCH)
+ lp->adapter_cnf |= A_CNF_EXTND_10B_2 | A_CNF_LOW_RX_SQUELCH;
+ /* Check if the card is in 10Base-t only mode */
+ if ((i & (AUI_ONLY | AUTO_AUI_10BASET)) == 0)
+ lp->adapter_cnf |= A_CNF_10B_T | A_CNF_MEDIA_10B_T;
+ /* Check if the card is in AUI only mode */
+ if ((i & (AUI_ONLY | AUTO_AUI_10BASET)) == AUI_ONLY)
+ lp->adapter_cnf |= A_CNF_AUI | A_CNF_MEDIA_AUI;
+ /* Check if the card is in Auto mode. */
+ if ((i & (AUI_ONLY | AUTO_AUI_10BASET)) == AUTO_AUI_10BASET)
+ lp->adapter_cnf |= A_CNF_AUI | A_CNF_10B_T |
+ A_CNF_MEDIA_AUI | A_CNF_MEDIA_10B_T | A_CNF_MEDIA_AUTO;
+
+ /* IRQ. Other chips already probe, see below. */
+ if (lp->chip_type == CS8900)
+ lp->isa_config = readreg(dev, PP_CS8900_ISAINT) & INT_NO_MASK;
+
+ printk( "[Cirrus EEPROM] ");
+ }


+
+ printk("\n");
+

+ /* First check to see if an EEPROM is attached. */
X if ((readreg(dev, PP_SelfST) & EEPROM_PRESENT) == 0)
- printk(KERN_WARNING "\ncs89x0: No EEPROM, relying on command line....\n");
+ printk(KERN_WARNING "cs89x0: No EEPROM, relying on command line....\n");
X else if (get_eeprom_data(dev, START_EEPROM_DATA,CHKSUM_LEN,eeprom_buff) < 0) {
X printk(KERN_WARNING "\ncs89x0: EEPROM read failed, relying on command line.\n");
X } else if (get_eeprom_cksum(START_EEPROM_DATA,CHKSUM_LEN,eeprom_buff) < 0) {
- printk(KERN_WARNING "\ncs89x0: EEPROM checksum bad, relying on command line\n");
+ /* Check if the chip was able to read its own configuration starting
+ at 0 in the EEPROM*/
+ if ((readreg(dev, PP_SelfST) & (EEPROM_OK | EEPROM_PRESENT)) !=
+ (EEPROM_OK|EEPROM_PRESENT))
+ printk(KERN_WARNING "cs89x0: Extended EEPROM checksum bad and no Cirrus EEPROM, relying on command line\n");
+
X } else {
+ /* This reads an extended EEPROM that is not documented
+ in the CS8900 datasheet. */
+
X /* get transmission control word but keep the autonegotiation bits */
X if (!lp->auto_neg_cnf) lp->auto_neg_cnf = eeprom_buff[AUTO_NEG_CNF_OFFSET/2];
X /* Store adapter configuration */
@@ -464,17 +550,12 @@
X } else {
X i = lp->isa_config & INT_NO_MASK;
X if (lp->chip_type == CS8900) {
- /* the table that follows is dependent upon how you wired up your cs8900
- * in your system. The table is the same as the cs8900 engineering demo
- * board. irq_map also depends on the contents of the table. Also see
- * write_irq, which is the reverse mapping of the table below. */
- switch(i) {
- case 0: i = 10; break;
- case 1: i = 11; break;
- case 2: i = 12; break;
- case 3: i = 5; break;
- default: printk("\ncs89x0: bug: isa_config is %d\n", i);
- }
+ /* Translate the IRQ using the IRQ mapping table. */
+ if (i > sizeof(cs8900_irq_map)/sizeof(cs8900_irq_map[0]))
+ printk("\ncs89x0: bug: isa_config is %d\n", i);
+ else
+ i = cs8900_irq_map[i];
+
X lp->irq_map = CS8900_IRQ_MAP; /* fixed IRQ map for CS8900 */
X } else {
X int irq_map_buff[IRQ_MAP_LEN/2];
@@ -490,7 +571,7 @@
X dev->irq = i;
X }
X
- printk(", IRQ %d", dev->irq);
+ printk(" IRQ %d", dev->irq);
X
X #if ALLOW_DMA
X if (lp->use_dma)
@@ -741,7 +822,9 @@
X struct net_local *lp = (struct net_local *)dev->priv;
X unsigned int selfcontrol;
X int timenow = jiffies;
- /* control the DC to DC convertor in the SelfControl register. */
+ /* control the DC to DC convertor in the SelfControl register.
+ Note: This is hooked up to a general purpose pin, might not
+ always be a DC to DC convertor. */
X
X selfcontrol = HCB1_ENBL; /* Enable the HCB1 bit as an output */
X if (((lp->adapter_cnf & A_CNF_DC_DC_POLARITY) != 0) ^ on_not_off)
@@ -753,7 +836,6 @@
X /* Wait for the DC/DC converter to power up - 500ms */
X while (jiffies - timenow < HZ)
X ;
-
X }
X
X #define DETECTED_NONE 0
@@ -916,13 +998,13 @@
X int i;
X
X if (chip_type == CS8900) {
- switch(irq) {
- case 10: i = 0; break;
- case 11: i = 1; break;
- case 12: i = 2; break;
- case 5: i = 3; break;
- default: i = 3; break;
- }
+ /* Search the mapping table for the corrisponding IRQ pin. */
+ for (i = 0; i != sizeof(cs8900_irq_map)/sizeof(cs8900_irq_map[0]); i++)
+ if (cs8900_irq_map[i] == irq)
+ break;
+ /* Not found */
+ if (i == sizeof(cs8900_irq_map)/sizeof(cs8900_irq_map[0]))
+ i = 3;
X writereg(dev, PP_CS8900_ISAINT, i);
X } else {
X writereg(dev, PP_CS8920_ISAINT, irq);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/declance.c linux/drivers/net/declance.c
--- v2.4.0-test8/linux/drivers/net/declance.c Sat May 13 08:29:40 2000
+++ linux/drivers/net/declance.c Sun Sep 17 09:41:29 2000
@@ -1030,6 +1030,7 @@
X /* Make certain the data structures used by the LANCE are aligned. */
X dev->priv = (void *) (((unsigned long) dev->priv + 7) & ~7);
X lp = (struct lance_private *) dev->priv;
+ spin_lock_init(&lp->lock);
X
X switch (type) {
X #ifdef CONFIG_TC
@@ -1193,9 +1194,9 @@
X lp->multicast_timer.function = &lance_set_multicast_retry;
X
X #ifdef MODULE
- dev->ifindex = dev_new_index();
- lp->next_module = root_lance_dev;
- root_lance_dev = lp;
+ dev->ifindex = dev_new_index();
+ lp->next_module = root_lance_dev;
+ root_lance_dev = lp;
X #endif
X return 0;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/dummy.c linux/drivers/net/dummy.c
--- v2.4.0-test8/linux/drivers/net/dummy.c Thu Jun 22 07:23:26 2000
+++ linux/drivers/net/dummy.c Fri Sep 22 14:21:16 2000
@@ -31,27 +31,10 @@
X /* To have statistics (just packets sent) define this */
X
X #include <linux/config.h>
-#include <linux/kernel.h>
X #include <linux/module.h>


-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/malloc.h>
-#include <linux/string.h>

-#include <linux/init.h>


-#include <asm/system.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <linux/errno.h>

-
+#include <linux/kernel.h>
X #include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
+#include <linux/init.h>
X
X static int dummy_xmit(struct sk_buff *skb, struct net_device *dev);
X static struct net_device_stats *dummy_get_stats(struct net_device *dev);
@@ -80,7 +63,7 @@
X }
X #endif
X
-int __init dummy_init(struct net_device *dev)
+static int __init dummy_init(struct net_device *dev)


X {
X /* Initialize the device structure. */

X dev->hard_start_xmit = dummy_xmit;
@@ -121,25 +104,12 @@
X
X static struct net_device_stats *dummy_get_stats(struct net_device *dev)


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 062'
echo 'File patch-2.4.0-test9 is continued in part 063'
echo "063" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part064

#!/bin/sh -x
# this is part 064 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 064; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ struct hamachi_private *hmp = (struct hamachi_private *)dev->priv;
+ long ioaddr = dev->base_addr;

+ int next_tick = 10*HZ;


+
+ if (hamachi_debug > 2) {

+ printk(KERN_INFO "%s: Hamachi Autonegotiation status %4.4x, LPA "
+ "%4.4x.\n", dev->name, readw(ioaddr + ANStatus),
+ readw(ioaddr + ANLinkPartnerAbility));
+ printk(KERN_INFO "%s: Autonegotiation regs %4.4x %4.4x %4.4x "
+ "%4.4x %4.4x %4.4x.\n", dev->name,
+ readw(ioaddr + 0x0e0),
+ readw(ioaddr + 0x0e2),
+ readw(ioaddr + 0x0e4),
+ readw(ioaddr + 0x0e6),
+ readw(ioaddr + 0x0e8),
+ readw(ioaddr + 0x0eA));
+ }
+ /* We could do something here... nah. */
+ hmp->timer.expires = RUN_AT(next_tick);


+ add_timer(&hmp->timer);
+}
+

+static void hamachi_tx_timeout(struct net_device *dev)

+{
+ int i;


+ struct hamachi_private *hmp = (struct hamachi_private *)dev->priv;
+ long ioaddr = dev->base_addr;
+

+ printk(KERN_WARNING "%s: Hamachi transmit timed out, status %8.8x,"
+ " resetting...\n", dev->name, (int)readw(ioaddr + TxStatus));
+
+#ifndef __alpha__
+ {
+ int i;
+ printk(KERN_DEBUG " Rx ring %8.8x: ", (int)hmp->rx_ring);
+ for (i = 0; i < RX_RING_SIZE; i++)
+ printk(" %8.8x", (unsigned int)hmp->rx_ring[i].status_n_length);
+ printk("\n"KERN_DEBUG" Tx ring %8.8x: ", (int)hmp->tx_ring);
+ for (i = 0; i < TX_RING_SIZE; i++)
+ printk(" %4.4x", hmp->tx_ring[i].status_n_length);


+ printk("\n");
+ }

+#endif
+
+ /* Reinit the hardware and make sure the Rx and Tx processes
+ are up and running.
+ */
+ dev->if_port = 0;
+ /* The right way to do Reset. -KDU
+ * -Clear OWN bit in all Rx/Tx descriptors
+ * -Wait 50 uS for channels to go idle
+ * -Turn off MAC receiver
+ * -Issue Reset
+ */
+
+ for (i = 0; i < RX_RING_SIZE; i++)
+ hmp->rx_ring[i].status_n_length &= ~DescOwn;
+
+ /* Presume that all packets in the Tx queue are gone if we have to
+ * re-init the hardware.
+ */
+ for (i = 0; i < TX_RING_SIZE; i++){
+ if (i >= TX_RING_SIZE - 1)
+ hmp->tx_ring[i].status_n_length = DescEndRing |
+ (hmp->tx_ring[i].status_n_length & 0x0000FFFF);
+ else
+ hmp->tx_ring[i].status_n_length &= 0x0000ffff;
+ if (hmp->tx_skbuff[i]){
+ dev_kfree_skb(hmp->tx_skbuff[i]);
+ hmp->tx_skbuff[i] = 0;
+ }
+ }
+
+ udelay(60); /* Sleep 60 us just for safety sake */
+ writew(0x0002, dev->base_addr + RxCmd); /* STOP Rx */
+
+ writeb(0x01, ioaddr + ChipReset); /* Reinit the hardware */
+
+ hmp->tx_full = 0;
+ hmp->cur_rx = hmp->cur_tx = 0;
+ hmp->dirty_rx = hmp->dirty_tx = 0;
+ hmp->rx_head_desc = &hmp->rx_ring[0];
+ /* Rx packets are also presumed lost; however, we need to make sure a
+ * ring of buffers is in tact. -KDU
+ */
+ for (i = 0; i < RX_RING_SIZE; i++){
+ if (hmp->rx_skbuff[i]){
+ dev_kfree_skb(hmp->rx_skbuff[i]);
+ hmp->rx_skbuff[i] = 0;
+ }
+ }
+ /* Fill in the Rx buffers. Handle allocation failure gracefully. */
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ struct sk_buff *skb = dev_alloc_skb(hmp->rx_buf_sz);
+ hmp->rx_skbuff[i] = skb;
+ if (skb == NULL)
+ break;
+ skb->dev = dev; /* Mark as being used by this device. */
+ skb_reserve(skb, 2); /* 16 byte align the IP header. */
+ hmp->rx_ring[i].addr = virt_to_desc(skb->tail);
+ hmp->rx_ring[i].status_n_length =
+ cpu_to_le32(DescOwn | DescEndPacket | DescIntr | (hmp->rx_buf_sz - 2));
+ }
+ hmp->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
+ /* Mark the last entry as wrapping the ring. */
+ hmp->rx_ring[RX_RING_SIZE-1].status_n_length |= cpu_to_le32(DescEndRing);
+
+
+ /* Trigger an immediate transmit demand. */


+ dev->trans_start = jiffies;

+ hmp->stats.tx_errors++;
+
+ /* Restart the chip's Tx/Rx processes . */
+ writew(0x0002, dev->base_addr + TxCmd); /* STOP Tx */
+ writew(0x0001, dev->base_addr + TxCmd); /* START Tx */
+ writew(0x0001, dev->base_addr + RxCmd); /* START Rx */
+}
+
+
+/* Initialize the Rx and Tx rings, along with various 'dev' bits. */


+static void hamachi_init_ring(struct net_device *dev)

+{
+ struct hamachi_private *hmp = (struct hamachi_private *)dev->priv;

+ int i;
+
+ hmp->tx_full = 0;
+ hmp->cur_rx = hmp->cur_tx = 0;
+ hmp->dirty_rx = hmp->dirty_tx = 0;
+
+#if 0
+ /* This is wrong. I'm not sure what the original plan was, but this
+ * is wrong. An MTU of 1 gets you a buffer of 1536, while an MTU
+ * of 1501 gets a buffer of 1533? -KDU
+ */
+ hmp->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32);
+#endif
+ /* My attempt at a reasonable correction */
+ /* +26 gets the maximum ethernet encapsulation, +7 & ~7 because the
+ * card needs room to do 8 byte alignment, +2 so we can reserve
+ * the first 2 bytes, and +16 gets room for the status word from the
+ * card. -KDU
+ */
+ hmp->rx_buf_sz = (dev->mtu <= 1492 ? PKT_BUF_SZ :
+ (((dev->mtu+26+7) & ~7) + 2 + 16));
+
+ hmp->rx_head_desc = &hmp->rx_ring[0];
+
+ /* Initialize all Rx descriptors. */
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ hmp->rx_ring[i].status_n_length = 0;
+ hmp->rx_skbuff[i] = 0;
+ }
+ /* Fill in the Rx buffers. Handle allocation failure gracefully. */
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ struct sk_buff *skb = dev_alloc_skb(hmp->rx_buf_sz);
+ hmp->rx_skbuff[i] = skb;
+ if (skb == NULL)
+ break;
+ skb->dev = dev; /* Mark as being used by this device. */
+ skb_reserve(skb, 2); /* 16 byte align the IP header. */
+ hmp->rx_ring[i].addr = virt_to_desc(skb->tail);
+ /* -2 because it doesn't REALLY have that first 2 bytes -KDU */
+ hmp->rx_ring[i].status_n_length =
+ cpu_to_le32(DescOwn | DescEndPacket | DescIntr | (hmp->rx_buf_sz -2));
+ }
+ hmp->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
+ /* Mark the last entry as wrapping the ring. */
+ hmp->rx_ring[RX_RING_SIZE-1].status_n_length |= cpu_to_le32(DescEndRing);
+
+
+ /* Mark the last entry as wrapping the ring. */
+ hmp->rx_ring[RX_RING_SIZE-1].status_n_length |= DescEndRing;
+
+ for (i = 0; i < TX_RING_SIZE; i++) {
+ hmp->tx_skbuff[i] = 0;
+ hmp->tx_ring[i].status_n_length = 0;
+ }
+ /* Mark the last entry as wrapping the ring. */
+ hmp->tx_ring[TX_RING_SIZE-1].status_n_length |= cpu_to_le32(DescEndRing);
+


+ return;
+}
+
+

+#ifdef TX_CHECKSUM
+#define csum_add(it, val) \
+do { \
+ it += (u16) (val); \
+ if (it & 0xffff0000) { \
+ it &= 0xffff; \
+ ++it; \
+ } \
+} while (0)
+ /* printk("add %04x --> %04x\n", val, it); \ */
+
+/* uh->len already network format, do not swap */
+#define pseudo_csum_udp(sum,ih,uh) do { \
+ sum = 0; \
+ csum_add(sum, (ih)->saddr >> 16); \
+ csum_add(sum, (ih)->saddr & 0xffff); \
+ csum_add(sum, (ih)->daddr >> 16); \
+ csum_add(sum, (ih)->daddr & 0xffff); \
+ csum_add(sum, __constant_htons(IPPROTO_UDP)); \
+ csum_add(sum, (uh)->len); \
+} while (0)
+
+/* swap len */
+#define pseudo_csum_tcp(sum,ih,len) do { \
+ sum = 0; \
+ csum_add(sum, (ih)->saddr >> 16); \
+ csum_add(sum, (ih)->saddr & 0xffff); \
+ csum_add(sum, (ih)->daddr >> 16); \
+ csum_add(sum, (ih)->daddr & 0xffff); \
+ csum_add(sum, __constant_htons(IPPROTO_TCP)); \
+ csum_add(sum, htons(len)); \
+} while (0)
+#endif
+


+static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev)

+{
+ struct hamachi_private *hmp = (struct hamachi_private *)dev->priv;

+ unsigned entry;
+ u16 status;
+
+ /* Ok, now make sure that the queue has space before trying to
+ add another skbuff. if we return non-zero the scheduler
+ should interpret this as a queue full and requeue the buffer
+ for later.
+ */
+ if (hmp->tx_full) {
+ /* We should NEVER reach this point -KDU */
+ printk(KERN_WARNING "%s: Hamachi transmit queue full at slot %d.\n",dev->name, hmp->cur_tx);
+
+ /* Wake the potentially-idle transmit channel. */
+ /* If we don't need to read status, DON'T -KDU */
+ status=readw(dev->base_addr + TxStatus);
+ if( !(status & 0x0001) || (status & 0x0002))
+ writew(0x0001, dev->base_addr + TxCmd);


+ return 1;
+ }
+

+ /* Caution: the write order is important here, set the field
+ with the "ownership" bits last. */
+
+ /* Calculate the next Tx descriptor entry. */
+ entry = hmp->cur_tx % TX_RING_SIZE;
+
+ hmp->tx_skbuff[entry] = skb;
+
+#ifdef TX_CHECKSUM
+ {
+ /* tack on checksum tag */
+ u32 tagval = 0;
+ struct ethhdr *eh = (struct ethhdr *)skb->data;
+ if (eh->h_proto == __constant_htons(ETH_P_IP)) {
+ struct iphdr *ih = (struct iphdr *)((char *)eh + ETH_HLEN);
+ if (ih->protocol == IPPROTO_UDP) {
+ struct udphdr *uh
+ = (struct udphdr *)((char *)ih + ih->ihl*4);
+ u32 offset = ((unsigned char *)uh + 6) - skb->data;
+ u32 pseudo;
+ pseudo_csum_udp(pseudo, ih, uh);
+ pseudo = htons(pseudo);
+ printk("udp cksum was %04x, sending pseudo %04x\n",
+ uh->check, pseudo);
+ uh->check = 0; /* zero out uh->check before card calc */
+ /*
+ * start at 14 (skip ethhdr), store at offset (uh->check),
+ * use pseudo value given.
+ */
+ tagval = (14 << 24) | (offset << 16) | pseudo;
+ } else if (ih->protocol == IPPROTO_TCP) {
+ printk("tcp, no auto cksum\n");
+ }
+ }
+ *(u32 *)skb_push(skb, 8) = tagval;
+ }
+#endif
+
+ hmp->tx_ring[entry].addr = virt_to_desc(skb->data);
+
+ /* Hmmmm, could probably put a DescIntr on these, but the way
+ the driver is currently coded makes Tx interrupts unnecessary
+ since the clearing of the Tx ring is handled by the start_xmit
+ routine. This organization helps mitigate the interrupts a
+ bit and probably renders the max_tx_latency param useless.
+
+ Update: Putting a DescIntr bit on all of the descriptors and
+ mitigating interrupt frequency with the tx_min_pkt parameter. -KDU
+ */
+ if (entry >= TX_RING_SIZE-1) /* Wrap ring */


+ hmp->tx_ring[entry].status_n_length =

+ cpu_to_le32(DescOwn|DescEndPacket|DescEndRing|DescIntr | skb->len);
+ else


+ hmp->tx_ring[entry].status_n_length =

+ cpu_to_le32(DescOwn|DescEndPacket|DescIntr | skb->len);
+ hmp->cur_tx++;
+
+ /* Non-x86 Todo: explicitly flush cache lines here. */
+
+ /* Wake the potentially-idle transmit channel. */
+ /* If we don't need to read status, DON'T -KDU */
+ status=readw(dev->base_addr + TxStatus);
+ if( !(status & 0x0001) || (status & 0x0002))
+ writew(0x0001, dev->base_addr + TxCmd);
+
+ /* Immediately before returning, let's clear as many entries as we can. */
+ hamachi_tx(dev);
+
+ /* We should kick the bottom half here, since we are not accepting
+ * interrupts with every packet. i.e. realize that Gigabit ethernet
+ * can transmit faster than ordinary machines can load packets;
+ * hence, any packet that got put off because we were in the transmit
+ * routine should IMMEDIATELY get a chance to be re-queued. -KDU
+ */
+ if ((hmp->cur_tx - hmp->dirty_tx) < (TX_RING_SIZE - 4))
+ netif_wake_queue(dev); /* Typical path */
+ else {
+ hmp->tx_full = 1;
+ netif_stop_queue(dev);


+ }
+ dev->trans_start = jiffies;

+
+ if (hamachi_debug > 4) {
+ printk(KERN_DEBUG "%s: Hamachi transmit frame #%d queued in slot %d.\n",
+ dev->name, hmp->cur_tx, entry);


+ }
+ return 0;
+}
+

+/* The interrupt handler does all of the Rx thread work and cleans up
+ after the Tx thread. */
+static void hamachi_interrupt(int irq, void *dev_instance, struct pt_regs *rgs)
+{
+ struct net_device *dev = (struct net_device *)dev_instance;
+ struct hamachi_private *hmp;
+ long ioaddr, boguscnt = max_interrupt_work;
+
+#ifndef final_version /* Can never occur. */


+ if (dev == NULL) {

+ printk (KERN_ERR "hamachi_interrupt(): irq %d for unknown device.\n", irq);
+ return;
+ }
+#endif
+
+ ioaddr = dev->base_addr;
+ hmp = (struct hamachi_private *)dev->priv;
+ spin_lock(&hmp->lock);
+
+ do {
+ u32 intr_status = readl(ioaddr + InterruptClear);
+
+ if (hamachi_debug > 4)
+ printk(KERN_DEBUG "%s: Hamachi interrupt, status %4.4x.\n",
+ dev->name, intr_status);
+
+ if (intr_status == 0)
+ break;
+
+ if (intr_status & IntrRxDone)
+ hamachi_rx(dev);
+
+ if (intr_status & IntrTxDone){
+ /* This code should RARELY need to execute. After all, this is
+ * a gigabit link, it should consume packets as fast as we put
+ * them in AND we clear the Tx ring in hamachi_start_xmit().
+ */
+ if (hmp->tx_full){


+ for (; hmp->cur_tx - hmp->dirty_tx > 0; hmp->dirty_tx++){
+ int entry = hmp->dirty_tx % TX_RING_SIZE;
+ if (hmp->tx_ring[entry].status_n_length & cpu_to_le32(DescOwn))
+ break;
+ /* Free the original skb. */

+ if (hmp->tx_skbuff[entry]){
+ dev_kfree_skb_irq(hmp->tx_skbuff[entry]);


+ hmp->tx_skbuff[entry] = 0;
+ }
+ hmp->tx_ring[entry].status_n_length = 0;
+ if (entry >= TX_RING_SIZE-1)
+ hmp->tx_ring[TX_RING_SIZE-1].status_n_length |=
+ cpu_to_le32(DescEndRing);
+ hmp->stats.tx_packets++;
+ }

+ if (hmp->cur_tx - hmp->dirty_tx < TX_RING_SIZE - 4){
+ /* The ring is no longer full */
+ hmp->tx_full = 0;
+ netif_wake_queue(dev);
+ }
+ } else {
+ netif_wake_queue(dev);
+ }
+ }
+
+
+ /* Abnormal error summary/uncommon events handlers. */
+ if (intr_status &
+ (IntrTxPCIFault | IntrTxPCIErr | IntrRxPCIFault | IntrRxPCIErr |
+ LinkChange | NegotiationChange | StatsMax))
+ hamachi_error(dev, intr_status);
+
+ if (--boguscnt < 0) {
+ printk(KERN_WARNING "%s: Too much work at interrupt, status=0x%4.4x.\n",
+ dev->name, intr_status);
+ break;
+ }
+ } while (1);
+
+ if (hamachi_debug > 3)
+ printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
+ dev->name, readl(ioaddr + IntrStatus));
+
+#ifndef final_version
+ /* Code that should never be run! Perhaps remove after testing.. */
+ {
+ static int stopit = 10;
+ if (dev->start == 0 && --stopit < 0) {
+ printk(KERN_ERR "%s: Emergency stop, looping startup interrupt.\n",
+ dev->name);
+ free_irq(irq, dev);
+ }
+ }
+#endif
+
+ spin_unlock(&hmp->lock);
+}
+
+#ifdef TX_CHECKSUM
+/*
+ * Copied from eth_type_trans(), with reduced header, since we don't
+ * get it on RX, only on TX.
+ */
+static unsigned short hamachi_eth_type_trans(struct sk_buff *skb,
+ struct net_device *dev)
+{
+ struct ethhdr *eth;
+ unsigned char *rawp;
+
+ skb->mac.raw=skb->data;
+ skb_pull(skb,dev->hard_header_len-8); /* artificially enlarged on tx */
+ eth= skb->mac.ethernet;
+
+ if(*eth->h_dest&1)
+ {
+ if(memcmp(eth->h_dest,dev->broadcast, ETH_ALEN)==0)
+ skb->pkt_type=PACKET_BROADCAST;
+ else
+ skb->pkt_type=PACKET_MULTICAST;
+ }
+
+ /*
+ * This ALLMULTI check should be redundant by 1.4
+ * so don't forget to remove it.
+ *
+ * Seems, you forgot to remove it. All silly devices
+ * seems to set IFF_PROMISC.
+ */
+
+ else if(dev->flags&(IFF_PROMISC/*|IFF_ALLMULTI*/))
+ {
+ if(memcmp(eth->h_dest,dev->dev_addr, ETH_ALEN))
+ skb->pkt_type=PACKET_OTHERHOST;
+ }
+
+ if (ntohs(eth->h_proto) >= 1536)
+ return eth->h_proto;
+
+ rawp = skb->data;
+
+ /*
+ * This is a magic hack to spot IPX packets. Older Novell breaks
+ * the protocol design and runs IPX over 802.3 without an 802.2 LLC
+ * layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
+ * won't work for fault tolerant netware but does for the rest.
+ */
+ if (*(unsigned short *)rawp == 0xFFFF)
+ return htons(ETH_P_802_3);
+
+ /*
+ * Real 802.2 LLC
+ */
+ return htons(ETH_P_802_2);
+}
+#endif /* TX_CHECKSUM */
+
+/* This routine is logically part of the interrupt handler, but seperated
+ for clarity and better register allocation. */
+static int hamachi_rx(struct net_device *dev)


+{
+ struct hamachi_private *hmp = (struct hamachi_private *)dev->priv;

+ int entry = hmp->cur_rx % RX_RING_SIZE;
+ int boguscnt = (hmp->dirty_rx + RX_RING_SIZE) - hmp->cur_rx;
+
+ if (hamachi_debug > 4) {
+ printk(KERN_DEBUG " In hamachi_rx(), entry %d status %4.4x.\n",
+ entry, hmp->rx_ring[entry].status_n_length);
+ }
+
+ /* If EOP is set on the next entry, it's a new packet. Send it up. */
+ while ( ! (hmp->rx_head_desc->status_n_length & cpu_to_le32(DescOwn))) {
+ struct hamachi_desc *desc = hmp->rx_head_desc;
+ u32 desc_status = le32_to_cpu(desc->status_n_length);
+ u16 data_size = desc_status; /* Implicit truncate */
+ u8 *buf_addr = le32desc_to_virt(desc->addr);
+ s32 frame_status =
+ le32_to_cpu(get_unaligned((s32*)&(buf_addr[data_size - 12])));
+
+ if (hamachi_debug > 4)
+ printk(KERN_DEBUG " hamachi_rx() status was %8.8x.\n",
+ frame_status);
+ if (--boguscnt < 0)
+ break;
+ if ( ! (desc_status & DescEndPacket)) {
+ printk(KERN_WARNING "%s: Oversized Ethernet frame spanned "
+ "multiple buffers, entry %#x length %d status %4.4x!\n",
+ dev->name, hmp->cur_rx, data_size, desc_status);
+ printk(KERN_WARNING "%s: Oversized Ethernet frame %p vs %p.\n",
+ dev->name, desc, &hmp->rx_ring[hmp->cur_rx % RX_RING_SIZE]);
+ printk(KERN_WARNING "%s: Oversized Ethernet frame -- next status %x/%x last status %x.\n",
+ dev->name,
+ hmp->rx_ring[(hmp->cur_rx+1) % RX_RING_SIZE].status_n_length & 0xffff0000,
+ hmp->rx_ring[(hmp->cur_rx+1) % RX_RING_SIZE].status_n_length & 0x0000ffff,
+ hmp->rx_ring[(hmp->cur_rx-1) % RX_RING_SIZE].status_n_length);
+ hmp->stats.rx_length_errors++;
+ } /* else Omit for prototype errata??? */
+ if (frame_status & 0x00380000) {
+ /* There was an error. */
+ if (hamachi_debug > 2)
+ printk(KERN_DEBUG " hamachi_rx() Rx error was %8.8x.\n",
+ frame_status);
+ hmp->stats.rx_errors++;
+ if (frame_status & 0x00600000) hmp->stats.rx_length_errors++;
+ if (frame_status & 0x00080000) hmp->stats.rx_frame_errors++;
+ if (frame_status & 0x00100000) hmp->stats.rx_crc_errors++;
+ if (frame_status < 0) hmp->stats.rx_dropped++;
+ } else {
+ struct sk_buff *skb;
+ /* Omit CRC */
+ u16 pkt_len = (frame_status & 0x07ff) - 4;
+#ifdef RX_CHECKSUM
+ u32 pfck = *(u32 *) &buf_addr[data_size - 8];
+#endif
+
+
+#ifndef final_version
+ if (hamachi_debug > 4)
+ printk(KERN_DEBUG " hamachi_rx() normal Rx pkt length %d"
+ " of %d, bogus_cnt %d.\n",
+ pkt_len, data_size, boguscnt);
+ if (hamachi_debug > 5)
+ printk(KERN_DEBUG"%s: rx status %8.8x %8.8x %8.8x %8.8x %8.8x.\n",
+ dev->name,
+ *(s32*)&(buf_addr[data_size - 20]),
+ *(s32*)&(buf_addr[data_size - 16]),
+ *(s32*)&(buf_addr[data_size - 12]),
+ *(s32*)&(buf_addr[data_size - 8]),
+ *(s32*)&(buf_addr[data_size - 4]));
+#endif
+ /* Check if the packet is long enough to accept without copying
+ to a minimally-sized skbuff. */
+ if (pkt_len < rx_copybreak
+ && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+#ifdef RX_CHECKSUM
+ printk(KERN_ERR "%s: rx_copybreak non-zero "
+ "not good with RX_CHECKSUM\n", dev->name);
+#endif


+ skb->dev = dev;

+ skb_reserve(skb, 2); /* 16 byte align the IP header */
+ /* Call copy + cksum if available. */
+#if 1 || USE_IP_COPYSUM
+ eth_copy_and_sum(skb, bus_to_virt(desc->addr), pkt_len, 0);
+ skb_put(skb, pkt_len);
+#else
+ memcpy(skb_put(skb, pkt_len), bus_to_virt(desc->addr),pkt_len);
+#endif
+ } else {
+ char *temp = skb_put(skb = hmp->rx_skbuff[entry], pkt_len);
+ hmp->rx_skbuff[entry] = NULL;
+#ifndef final_version /* Remove after testing. */
+ if (bus_to_virt(desc->addr) != temp)
+ printk(KERN_ERR "%s: Internal fault: The skbuff addresses "
+ "do not match in hamachi_rx: %p vs. %p / %p.\n",
+ dev->name, bus_to_virt(desc->addr),
+ skb->head, temp);
+#else
+ (void) temp;
+#endif
+ }
+#ifdef TX_CHECKSUM
+ /* account for extra TX hard_header bytes */
+ skb->protocol = hamachi_eth_type_trans(skb, dev);
+#else


+ skb->protocol = eth_type_trans(skb, dev);

+#endif
+
+
+#ifdef RX_CHECKSUM
+ /* TCP or UDP on ipv4, DIX encoding */
+ if (pfck>>24 == 0x91 || pfck>>24 == 0x51) {
+ struct iphdr *ih = (struct iphdr *) skb->data;
+ /* Check that IP packet is at least 46 bytes, otherwise,
+ * there may be pad bytes included in the hardware checksum.
+ * This wouldn't happen if everyone padded with 0.
+ */
+ if (ntohs(ih->tot_len) >= 46){
+ /* don't worry about frags */
+ if (!(ih->frag_off & __constant_htons(IP_MF|IP_OFFSET))) {
+ u32 inv = *(u32 *) &buf_addr[data_size - 16];
+ u32 *p = (u32 *) &buf_addr[data_size - 20];
+ register u32 crc, p_r, p_r1;
+
+ if (inv & 4) {
+ inv &= ~4;
+ --p;
+ }
+ p_r = *p;
+ p_r1 = *(p-1);
+ switch (inv) {
+ case 0:
+ crc = (p_r & 0xffff) + (p_r >> 16);


+ break;
+ case 1:

+ crc = (p_r >> 16) + (p_r & 0xffff)
+ + (p_r1 >> 16 & 0xff00);

+ break;
+ case 2:

+ crc = p_r + (p_r1 >> 16);

+ break;
+ case 3:

+ crc = p_r + (p_r1 & 0xff00) + (p_r1 >> 16);
+ break;
+ default: /*NOTREACHED*/ crc = 0;
+ }
+ if (crc & 0xffff0000) {
+ crc &= 0xffff;
+ ++crc;
+ }
+ /* tcp/udp will add in pseudo */
+ skb->csum = ntohs(pfck & 0xffff);
+ if (skb->csum > crc)
+ skb->csum -= crc;
+ else
+ skb->csum += (~crc & 0xffff);
+ /*
+ * could do the pseudo myself and return
+ * CHECKSUM_UNNECESSARY
+ */
+ skb->ip_summed = CHECKSUM_HW;
+ }
+ }
+ }
+#endif /* RX_CHECKSUM */
+
+ netif_rx(skb);
+ dev->last_rx = jiffies;
+ hmp->stats.rx_packets++;
+ }
+ entry = (++hmp->cur_rx) % RX_RING_SIZE;
+ hmp->rx_head_desc = &hmp->rx_ring[entry];
+ }
+
+ /* Refill the Rx ring buffers. */
+ for (; hmp->cur_rx - hmp->dirty_rx > 0; hmp->dirty_rx++) {
+ struct sk_buff *skb;
+ entry = hmp->dirty_rx % RX_RING_SIZE;
+ if (hmp->rx_skbuff[entry] == NULL) {
+ skb = dev_alloc_skb(hmp->rx_buf_sz);
+ hmp->rx_skbuff[entry] = skb;


+ if (skb == NULL)

+ break; /* Better luck next round. */
+ skb->dev = dev; /* Mark as being used by this device. */


+ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */

+ hmp->rx_ring[entry].addr = virt_to_desc(skb->tail);
+ }
+ hmp->rx_ring[entry].status_n_length = cpu_to_le32(hmp->rx_buf_sz);
+ if (entry >= RX_RING_SIZE-1)
+ hmp->rx_ring[entry].status_n_length |=
+ cpu_to_le32(DescOwn | DescEndPacket | DescEndRing | DescIntr);
+ else
+ hmp->rx_ring[entry].status_n_length |=
+ cpu_to_le32(DescOwn | DescEndPacket | DescIntr);
+ }
+
+ /* Restart Rx engine if stopped. */
+ /* If we don't need to check status, don't. -KDU */
+ if (readw(dev->base_addr + RxStatus) & 0x0002)


+ writew(0x0001, dev->base_addr + RxCmd);
+

+ return 0;
+}
+

+/* This is more properly named "uncommon interrupt events", as it covers more
+ than just errors. */


+static void hamachi_error(struct net_device *dev, int intr_status)

+{


+ long ioaddr = dev->base_addr;

+ struct hamachi_private *hmp = (struct hamachi_private *)dev->priv;
+

+ if (intr_status & (LinkChange|NegotiationChange)) {
+ if (hamachi_debug > 1)
+ printk(KERN_INFO "%s: Link changed: AutoNegotiation Ctrl"
+ " %4.4x, Status %4.4x %4.4x Intr status %4.4x.\n",
+ dev->name, readw(ioaddr + 0x0E0), readw(ioaddr + 0x0E2),
+ readw(ioaddr + ANLinkPartnerAbility),
+ readl(ioaddr + IntrStatus));
+ if (readw(ioaddr + ANStatus) & 0x20)
+ writeb(0x01, ioaddr + LEDCtrl);
+ else


+ writeb(0x03, ioaddr + LEDCtrl);
+ }

+ if (intr_status & StatsMax) {
+ hamachi_get_stats(dev);
+ /* Read the overflow bits to clear. */
+ readl(ioaddr + 0x370);
+ readl(ioaddr + 0x3F0);
+ }
+ if ((intr_status & ~(LinkChange|StatsMax|NegotiationChange|IntrRxDone|IntrTxDone))
+ && hamachi_debug)
+ printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n",
+ dev->name, intr_status);
+ /* Hmmmmm, it's not clear how to recover from PCI faults. */
+ if (intr_status & (IntrTxPCIErr | IntrTxPCIFault))
+ hmp->stats.tx_fifo_errors++;
+ if (intr_status & (IntrRxPCIErr | IntrRxPCIFault))
+ hmp->stats.rx_fifo_errors++;
+}
+


+static int hamachi_close(struct net_device *dev)

+{


+ long ioaddr = dev->base_addr;
+ struct hamachi_private *hmp = (struct hamachi_private *)dev->priv;

+ int i;
+
+ netif_stop_queue(dev);


+
+ if (hamachi_debug > 1) {

+ printk(KERN_DEBUG "%s: Shutting down ethercard, status was Tx %4.4x Rx %4.4x Int %2.2x.\n",
+ dev->name, readw(ioaddr + TxStatus),
+ readw(ioaddr + RxStatus), readl(ioaddr + IntrStatus));
+ printk(KERN_DEBUG "%s: Queue pointers were Tx %d / %d, Rx %d / %d.\n",
+ dev->name, hmp->cur_tx, hmp->dirty_tx, hmp->cur_rx, hmp->dirty_rx);
+ }
+
+ /* Disable interrupts by clearing the interrupt mask. */
+ writel(0x0000, ioaddr + InterruptEnable);
+
+ /* Stop the chip's Tx and Rx processes. */
+ writel(2, ioaddr + RxCmd);
+ writew(2, ioaddr + TxCmd);
+
+#ifdef __i386__
+ if (hamachi_debug > 2) {
+ printk("\n"KERN_DEBUG" Tx ring at %8.8x:\n",
+ (int)virt_to_bus(hmp->tx_ring));
+ for (i = 0; i < TX_RING_SIZE; i++)
+ printk(" %c #%d desc. %8.8x %8.8x.\n",
+ readl(ioaddr + TxCurPtr) == (long)&hmp->tx_ring[i] ? '>' : ' ',
+ i, hmp->tx_ring[i].status_n_length, hmp->tx_ring[i].addr);
+ printk("\n"KERN_DEBUG " Rx ring %8.8x:\n",
+ (int)virt_to_bus(hmp->rx_ring));
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ printk(KERN_DEBUG " %c #%d desc. %4.4x %8.8x\n",
+ readl(ioaddr + RxCurPtr) == (long)&hmp->rx_ring[i] ? '>' : ' ',
+ i, hmp->rx_ring[i].status_n_length, hmp->rx_ring[i].addr);
+ if (hamachi_debug > 6) {
+ if (*(u8*)bus_to_virt(hmp->rx_ring[i].addr) != 0x69) {
+ int j;
+ for (j = 0; j < 0x50; j++)
+ printk(" %4.4x",((u16*)le32desc_to_virt(hmp->rx_ring[i].addr))[j]);


+ printk("\n");
+ }
+ }

+ }
+ }
+#endif /* __i386__ debugging only */
+
+ free_irq(dev->irq, dev);
+
+ del_timer_sync(&hmp->timer);
+
+ /* Free all the skbuffs in the Rx queue. */
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ hmp->rx_ring[i].status_n_length = 0;
+ hmp->rx_ring[i].addr = 0xBADF00D0; /* An invalid address. */
+ if (hmp->rx_skbuff[i]) {
+ dev_kfree_skb(hmp->rx_skbuff[i]);
+ }
+ hmp->rx_skbuff[i] = 0;
+ }
+ for (i = 0; i < TX_RING_SIZE; i++) {
+ if (hmp->tx_skbuff[i])
+ dev_kfree_skb(hmp->tx_skbuff[i]);
+ hmp->tx_skbuff[i] = 0;
+ }
+
+ writeb(0x00, ioaddr + LEDCtrl);
+
+ MOD_DEC_USE_COUNT;


+
+ return 0;
+}
+

+static struct net_device_stats *hamachi_get_stats(struct net_device *dev)

+{


+ long ioaddr = dev->base_addr;

+ struct hamachi_private *hmp = (struct hamachi_private *)dev->priv;
+

+ /* We should lock this segment of code for SMP eventually, although
+ the vulnerability window is very small and statistics are
+ non-critical. */
+ /* Ok, what goes here? This appears to be stuck at 21 packets
+ according to ifconfig. It does get incremented in hamachi_tx(),
+ so I think I'll comment it out here and see if better things
+ happen.
+ */
+ /* hmp->stats.tx_packets = readl(ioaddr + 0x000); */
+
+ hmp->stats.rx_bytes = readl(ioaddr + 0x330); /* Total Uni+Brd+Multi */
+ hmp->stats.tx_bytes = readl(ioaddr + 0x3B0); /* Total Uni+Brd+Multi */
+ hmp->stats.multicast = readl(ioaddr + 0x320); /* Multicast Rx */
+
+ hmp->stats.rx_length_errors = readl(ioaddr + 0x368); /* Over+Undersized */
+ hmp->stats.rx_over_errors = readl(ioaddr + 0x35C); /* Jabber */
+ hmp->stats.rx_crc_errors = readl(ioaddr + 0x360); /* Jabber */
+ hmp->stats.rx_frame_errors = readl(ioaddr + 0x364); /* Symbol Errs */
+ hmp->stats.rx_missed_errors = readl(ioaddr + 0x36C); /* Dropped */
+
+ return &hmp->stats;
+}
+


+static void set_rx_mode(struct net_device *dev)
+{

+ long ioaddr = dev->base_addr;
+

+ if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */

+ /* Unconditionally log net taps. */
+ printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
+ writew(0x000F, ioaddr + AddrMode);
+ } else if ((dev->mc_count > 63) || (dev->flags & IFF_ALLMULTI)) {
+ /* Too many to match, or accept all multicasts. */
+ writew(0x000B, ioaddr + AddrMode);
+ } else if (dev->mc_count > 0) { /* Must use the CAM filter. */
+ struct dev_mc_list *mclist;
+ int i;


+ for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
+ i++, mclist = mclist->next) {

+ writel(*(u32*)(mclist->dmi_addr), ioaddr + 0x100 + i*8);
+ writel(0x20000 | (*(u16*)&mclist->dmi_addr[4]),
+ ioaddr + 0x104 + i*8);
+ }
+ /* Clear remaining entries. */
+ for (; i < 64; i++)
+ writel(0, ioaddr + 0x104 + i*8);
+ writew(0x0003, ioaddr + AddrMode);
+ } else { /* Normal, unicast/broadcast-only mode. */
+ writew(0x0001, ioaddr + AddrMode);
+ }
+}
+


+#ifdef HAVE_PRIVATE_IOCTL
+static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)

+{


+ long ioaddr = dev->base_addr;

+ u16 *data = (u16 *)&rq->ifr_data;
+
+ switch(cmd) {
+ case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */
+ data[0] = ((struct hamachi_private *)dev->priv)->phys[0] & 0x1f;
+ /* Fall Through */
+ case SIOCDEVPRIVATE+1: /* Read the specified MII register. */
+ data[3] = mdio_read(ioaddr, data[0] & 0x1f, data[1] & 0x1f);
+ return 0;
+ case SIOCDEVPRIVATE+2: /* Write the specified MII register */
+ /* TODO: Check the sequencing of this. Might need to stop and
+ * restart Rx and Tx engines. -KDU
+ */
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+ mdio_write(ioaddr, data[0] & 0x1f, data[1] & 0x1f, data[2]);
+ return 0;
+ case SIOCDEVPRIVATE+3: { /* set rx,tx intr params */
+ u32 *d = (u32 *)&rq->ifr_data;
+ /* Should add this check here or an ordinary user can do nasty
+ * things. -KDU
+ *
+ * TODO: Shut down the Rx and Tx engines while doing this.
+ */
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+ writel(d[0], dev->base_addr + TxIntrCtrl);
+ writel(d[1], dev->base_addr + RxIntrCtrl);
+ printk(KERN_NOTICE "%s: tx %08x, rx %08x intr\n", dev->name,
+ (u32) readl(dev->base_addr + TxIntrCtrl),
+ (u32) readl(dev->base_addr + RxIntrCtrl));
+ return 0;
+ }
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+#endif /* HAVE_PRIVATE_IOCTL */
+
+
+static void __exit hamachi_remove_one (struct pci_dev *pdev)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+
+ /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
+ if (dev) {
+ unregister_netdev(dev);
+ iounmap((char *)dev->base_addr);
+ kfree(dev);
+ pci_set_drvdata(pdev, NULL);
+ }
+}
+
+static struct pci_device_id hamachi_pci_tbl[] __initdata = {
+ { 0x1318, 0x0911, PCI_ANY_ID, PCI_ANY_ID, },
+ { 0, }
+};
+MODULE_DEVICE_TABLE(pci, hamachi_pci_tbl);
+
+static struct pci_driver hamachi_driver = {
+ name: "hamachi",
+ id_table: hamachi_pci_tbl,
+ probe: hamachi_init_one,
+ remove: hamachi_remove_one,
+};
+
+static int __init hamachi_init (void)
+{
+ if (pci_register_driver(&hamachi_driver) > 0)
+ return 0;
+ pci_unregister_driver(&hamachi_driver);


+ return -ENODEV;
+}
+

+static void __exit hamachi_exit (void)
+{
+ pci_unregister_driver(&hamachi_driver);
+}
+
+
+module_init(hamachi_init);
+module_exit(hamachi_exit);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/hamradio/pi2.c linux/drivers/net/hamradio/pi2.c
--- v2.4.0-test8/linux/drivers/net/hamradio/pi2.c Mon Jun 19 13:30:58 2000
+++ linux/drivers/net/hamradio/pi2.c Fri Sep 8 17:56:49 2000
@@ -1182,7 +1182,7 @@
X }
X
X
-int __init pi_init(void)
+int __init pi2_init(void)
X {
X int *port;
X int ioaddr = 0;
@@ -1658,7 +1658,7 @@
X
X int init_module(void)
X {
- return pi_init();
+ return pi2_init();
X }
X
X void cleanup_module(void)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/hamradio/pt.c linux/drivers/net/hamradio/pt.c
--- v2.4.0-test8/linux/drivers/net/hamradio/pt.c Mon Jun 19 13:30:58 2000
+++ linux/drivers/net/hamradio/pt.c Fri Sep 8 17:56:49 2000
@@ -474,7 +474,7 @@
X } /* chipset_init() */
X
X
-int __init pt_init(void)
+int __init ptwin_init(void)
X {
X int *port;
X int ioaddr = 0;
@@ -531,7 +531,7 @@
X pt0b.irq = pt0a.irq; /* IRQ is shared */
X
X return 0;
-} /* pt_init() */
+} /* ptwin_init() */
X
X /*
X * Probe for PT card. Also initialises the timers
@@ -1758,7 +1758,7 @@
X
X int init_module(void)
X {
- return pt_init();
+ return ptwin_init();
X }
X
X void cleanup_module(void)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/ioc3-eth.c linux/drivers/net/ioc3-eth.c
--- v2.4.0-test8/linux/drivers/net/ioc3-eth.c Thu Jul 27 18:36:54 2000
+++ linux/drivers/net/ioc3-eth.c Mon Sep 25 14:55:04 2000
@@ -64,7 +64,7 @@
X #include <asm/sn/sn0/hubni.h>
X #include <asm/sn/sn0/hubio.h>
X #include <asm/sn/klconfig.h>
-#include <asm/ioc3.h>
+#include <asm/sn/ioc3.h>
X #include <asm/sn/sn0/ip27.h>
X #include <asm/pci/bridge.h>
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/irda/toshoboe.c linux/drivers/net/irda/toshoboe.c
--- v2.4.0-test8/linux/drivers/net/irda/toshoboe.c Tue Mar 21 11:17:28 2000
+++ linux/drivers/net/irda/toshoboe.c Sun Sep 17 09:45:07 2000
@@ -900,7 +900,6 @@
X static void
X toshoboe_wakeup (struct toshoboe_cb *self)
X {
- struct net_device *dev = self->netdev;


X unsigned long flags;
X

X if (!self->stopped)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/lne390.c linux/drivers/net/lne390.c
--- v2.4.0-test8/linux/drivers/net/lne390.c Mon Jun 19 13:30:58 2000
+++ linux/drivers/net/lne390.c Sun Sep 17 09:49:42 2000
@@ -26,10 +26,13 @@
X You can try <http://www.mylex.com> if you want more info, as I've
X never even seen one of these cards. :)
X
+ Arnaldo Carvalho de Melo <ac...@conectiva.com.br> - 2000/09/01
+ - get rid of check_region
+ - no need to check if dev == NULL in lne390_probe1
X */
X
X static const char *version =
- "lne390.c: Driver revision v0.99, 12/05/98\n";
+ "lne390.c: Driver revision v0.99.1, 01/09/2000\n";
X
X #include <linux/module.h>
X #include <linux/kernel.h>
@@ -103,9 +106,16 @@
X int __init lne390_probe(struct net_device *dev)
X {
X unsigned short ioaddr = dev->base_addr;
+ int ret;
X
- if (ioaddr > 0x1ff) /* Check a single specified location. */
- return lne390_probe1(dev, ioaddr);
+ if (ioaddr > 0x1ff) { /* Check a single specified location. */
+ if (!request_region(ioaddr, LNE390_IO_EXTENT, "lne390"))
+ return -EBUSY;
+ ret = lne390_probe1(dev, ioaddr);
+ if (ret)
+ release_region(ioaddr, LNE390_IO_EXTENT);
+ return ret;
+ }
X else if (ioaddr > 0) /* Don't probe at all. */
X return -ENXIO;
X
@@ -118,10 +128,11 @@
X
X /* EISA spec allows for up to 16 slots, but 8 is typical. */
X for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
- if (check_region(ioaddr , LNE390_IO_EXTENT))
+ if (!request_region(ioaddr, LNE390_IO_EXTENT, "lne390"))
X continue;
X if (lne390_probe1(dev, ioaddr) == 0)
X return 0;
+ release_region(ioaddr, LNE390_IO_EXTENT);
X }
X
X return -ENODEV;
@@ -129,7 +140,7 @@
X
X int __init lne390_probe1(struct net_device *dev, int ioaddr)
X {
- int i, revision;
+ int i, revision, ret;
X unsigned long eisa_id;
X
X if (inb_p(ioaddr + LNE390_ID_PORT) == 0xff) return -ENODEV;
@@ -161,13 +172,6 @@
X return -ENODEV;
X }
X #endif
-
- /* We should have a "dev" from Space.c or the static module table. */
- if (dev == NULL) {
- printk("lne390.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
- }
-
X /* Allocate dev->priv and fill in 8390 specific dev fields. */
X if (ethdev_init(dev)) {
X printk ("lne390.c: unable to allocate memory for dev->priv!\n");
@@ -225,20 +229,16 @@
X printk(KERN_CRIT "lne390.c: Use EISA SCU to set card memory below 1MB,\n");
X printk(KERN_CRIT "lne390.c: or to an address above 0x%lx.\n", virt_to_bus(high_memory));
X printk(KERN_CRIT "lne390.c: Driver NOT installed.\n");
- free_irq(dev->irq, dev);
- kfree(dev->priv);
- dev->priv = NULL;
- return -EINVAL;
+ ret = -EINVAL;
+ goto cleanup;
X }
X dev->mem_start = (unsigned long)ioremap(dev->mem_start, LNE390_STOP_PG*0x100);
X if (dev->mem_start == 0) {
X printk(KERN_ERR "lne390.c: Unable to remap card memory above 1MB !!\n");
X printk(KERN_ERR "lne390.c: Try using EISA SCU to set memory below 1MB.\n");
X printk(KERN_ERR "lne390.c: Driver NOT installed.\n");
- free_irq(dev->irq, dev);
- kfree(dev->priv);
- dev->priv = NULL;
- return -EAGAIN;
+ ret = -EAGAIN;
+ goto cleanup;
X }
X ei_status.reg0 = 1; /* Use as remap flag */
X printk("lne390.c: remapped %dkB card memory to virtual address %#lx\n",


@@ -251,7 +251,6 @@
X

X /* The 8390 offset is zero for the LNE390 */
X dev->base_addr = ioaddr;
- request_region(dev->base_addr, LNE390_IO_EXTENT, "lne390");
X
X ei_status.name = "LNE390";
X ei_status.tx_start_page = LNE390_START_PG;
@@ -271,6 +270,11 @@
X dev->stop = &lne390_close;
X NS8390_init(dev, 0);
X return 0;
+cleanup:
+ free_irq(dev->irq, dev);
+ kfree(dev->priv);
+ dev->priv = NULL;
+ return ret;
X }
X
X /*
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/ne2.c linux/drivers/net/ne2.c
--- v2.4.0-test8/linux/drivers/net/ne2.c Mon Jun 19 13:30:58 2000
+++ linux/drivers/net/ne2.c Tue Sep 19 08:01:34 2000
@@ -110,16 +110,16 @@
X #define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */
X
X /* From the .ADF file: */
-static unsigned int addresses[7]=
+static unsigned int addresses[7] __initdata =
X {0x1000, 0x2020, 0x8020, 0xa0a0, 0xb0b0, 0xc0c0, 0xc3d0};
-static int irqs[4] = {3, 4, 5, 9};
+static int irqs[4] __initdata = {3, 4, 5, 9};
X
X struct ne2_adapters_t {
X unsigned int id;


X char *name;
X };
X

-const struct ne2_adapters_t ne2_adapters[] = {
+static struct ne2_adapters_t ne2_adapters[] __initdata = {
X { 0x6354, "Arco Ethernet Adapter AE/2" },
X { 0x70DE, "Compex ENET-16 MC/P" },
X { 0x7154, "Novell Ethernet Adapter NE/2" },
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/ne2k-pci.c linux/drivers/net/ne2k-pci.c
--- v2.4.0-test8/linux/drivers/net/ne2k-pci.c Mon Jun 19 13:30:58 2000
+++ linux/drivers/net/ne2k-pci.c Mon Sep 18 14:57:01 2000
@@ -286,7 +286,7 @@
X /* Set up the rest of the parameters. */


X dev->irq = irq;

X dev->base_addr = ioaddr;
- pdev->driver_data = dev;
+ pci_set_drvdata(pdev, dev);
X
X /* Allocate dev->priv and fill in 8390 specific dev fields. */
X if (ethdev_init(dev)) {
@@ -535,16 +535,17 @@
X
X static void __devexit ne2k_pci_remove_one (struct pci_dev *pdev)
X {
- struct net_device *dev = pdev->driver_data;
+ struct net_device *dev = pci_get_drvdata(pdev);
X
X if (!dev) {
X printk (KERN_ERR "bug! ne2k_pci_remove_one called w/o net_device\n");
X return;
X }
X
- unregister_netdev (dev);
- release_region (dev->base_addr, NE_IO_EXTENT);
- kfree (dev);
+ unregister_netdev(dev);
+ release_region(dev->base_addr, NE_IO_EXTENT);
+ kfree(dev);
+ pci_set_drvdata(pdev, NULL);
X }
X
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/net_init.c linux/drivers/net/net_init.c
--- v2.4.0-test8/linux/drivers/net/net_init.c Fri Jul 14 14:46:30 2000
+++ linux/drivers/net/net_init.c Tue Sep 19 08:31:43 2000
@@ -96,7 +96,8 @@
X * setup.
X */
X
-static struct net_device *init_netdev(struct net_device *dev, int sizeof_priv, char *mask, void (*setup)(struct net_device *))
+static struct net_device *init_netdev(struct net_device *dev, int sizeof_priv,
+ char *mask, void (*setup)(struct net_device *))
X {
X int new_device = 0;
X
@@ -117,16 +118,14 @@
X
X if (dev->name[0] == '\0' || dev->name[0] == ' ') {
X strcpy(dev->name, mask);
- if (!netdev_boot_setup_check(dev)) {
- if (dev_alloc_name(dev, mask)<0) {
- if (new_device)
- kfree(dev);
- return NULL;
- }
+ if (dev_alloc_name(dev, mask)<0) {
+ if (new_device)
+ kfree(dev);
+ return NULL;
X }
- } else {
- netdev_boot_setup_check(dev);
X }
+
+ netdev_boot_setup_check(dev);
X
X /*
X * Configure via the caller provided setup function then
@@ -198,7 +197,7 @@
X return(0);
X }
X
-#endif
+#endif /* CONFIG_FDDI */
X
X #ifdef CONFIG_HIPPI
X
@@ -256,7 +255,7 @@


X return 0;
X }
X

-#endif
+#endif /* CONFIG_HIPPI */
X
X void ether_setup(struct net_device *dev)
X {
@@ -314,7 +313,7 @@
X return;
X }
X
-#endif
+#endif /* CONFIG_FDDI */
X
X #ifdef CONFIG_HIPPI
X void hippi_setup(struct net_device *dev)
@@ -350,7 +349,7 @@
X
X dev_init_buffers(dev);
X }
-#endif
+#endif /* CONFIG_HIPPI */
X
X #if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
X
@@ -389,7 +388,7 @@
X dev_init_buffers(dev);
X }
X
-#endif
+#endif /* CONFIG_ATALK || CONFIG_ATALK_MODULE */
X
X int ether_config(struct net_device *dev, struct ifmap *map)
X {
@@ -506,7 +505,7 @@
X unregister_netdevice(dev);
X rtnl_unlock();
X }
-#endif
+#endif /* CONFIG_TR */
X
X
X #ifdef CONFIG_NET_FC
@@ -555,10 +554,3 @@
X
X #endif /* CONFIG_NET_FC */
X
-/*
- * Local variables:
- * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c net_init.c"
- * version-control: t
- * kept-new-versions: 5
- * End:
- */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/pcmcia/xircom_tulip_cb.c linux/drivers/net/pcmcia/xircom_tulip_cb.c
--- v2.4.0-test8/linux/drivers/net/pcmcia/xircom_tulip_cb.c Mon Aug 21 07:54:43 2000
+++ linux/drivers/net/pcmcia/xircom_tulip_cb.c Sun Sep 17 09:41:29 2000
@@ -3034,10 +3034,7 @@
X if (entry == TX_RING_SIZE-1)
X tx_flags |= DESC_RING_WRAP; /* Wrap ring. */
X tp->tx_ring[entry].length = tx_flags;
- if(tp->chip_id == X3201_3)
- tp->tx_ring[entry].buffer1 = (virt_to_bus(tp->setup_frame) + 4);
- else
- tp->tx_ring[entry].buffer1 = virt_to_bus(tp->setup_frame);
+ tp->tx_ring[entry].buffer1 = virt_to_bus(tp->setup_frame);
X tp->tx_ring[entry].status = DescOwned;
X if (tp->cur_tx - tp->dirty_tx >= TX_RING_SIZE - 2) {
X tp->tx_full = 1;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/pppox.c linux/drivers/net/pppox.c
--- v2.4.0-test8/linux/drivers/net/pppox.c Fri May 12 11:32:08 2000
+++ linux/drivers/net/pppox.c Fri Sep 22 14:21:16 2000
@@ -17,7 +17,6 @@


X *
X */
X

-#include <linux/config.h>
X #include <linux/string.h>
X #include <linux/module.h>
X
@@ -141,22 +140,22 @@
X pppox_create
X };
X
+extern int pppoe_init (void);
+
X #ifdef MODULE
X int init_module(void)
X #else
-void __init pppox_proto_init(struct net_proto *pro)
+int __init pppox_proto_init(struct net_proto *pro)
X #endif
X {
X int err = 0;
X
X err = sock_register(&pppox_proto_family);
X
- if (err == 0)
+ if (err == 0) {
X printk(KERN_INFO "Registered PPPoX v0.5\n");
-
-#ifdef CONFIG_PPPOE
- pppoe_init();
-#endif
+ pppoe_init();
+ }
X
X return err;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/rrunner.c linux/drivers/net/rrunner.c
--- v2.4.0-test8/linux/drivers/net/rrunner.c Mon Jun 19 13:42:38 2000
+++ linux/drivers/net/rrunner.c Mon Oct 2 14:22:40 2000
@@ -102,7 +102,7 @@
X * stack will need to know about I/O vectors or something similar.
X */
X
-static const char __initdata *version = "rrunner.c: v0.22 03/01/2000 Jes Sorensen (Jes.So...@cern.ch)\n";
+static char version[] __initdata = "rrunner.c: v0.22 03/01/2000 Jes Sorensen (Jes.So...@cern.ch)\n";
X
X static struct net_device *root_dev = NULL;
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/rtl8129.c linux/drivers/net/rtl8129.c
--- v2.4.0-test8/linux/drivers/net/rtl8129.c Tue Jul 11 11:12:24 2000
+++ linux/drivers/net/rtl8129.c Sun Sep 17 09:41:29 2000
@@ -406,6 +406,8 @@
X printk(KERN_INFO "%s", version);
X
X dev = init_etherdev(NULL, 0);


+ if (dev == NULL)

+ goto out;
X
X printk(KERN_INFO "%s: %s at %#lx, IRQ %d, ",
X dev->name, pci_tbl[chip_idx].name, ioaddr, irq);
@@ -427,13 +429,17 @@
X printk("%2.2x.\n", dev->dev_addr[i]);
X
X /* We do a request_region() to register /proc/ioports info. */
- request_region(ioaddr, pci_tbl[chip_idx].io_size, dev->name);
+ if (!request_region(ioaddr, pci_tbl[chip_idx].io_size, dev->name))
+ goto out_free_dev;
X
X dev->base_addr = ioaddr;


X dev->irq = irq;
X

X /* Some data structures must be quadword aligned. */
X tp = kmalloc(sizeof(*tp), GFP_KERNEL | GFP_DMA);
+ if (tp == NULL)
+ goto out_release_region;
+
X memset(tp, 0, sizeof(*tp));
X dev->priv = tp;
X
@@ -499,8 +505,15 @@
X dev->get_stats = &rtl8129_get_stats;
X dev->set_multicast_list = &set_rx_mode;
X dev->do_ioctl = &mii_ioctl;
-
X return dev;
+
+out_release_region:
+ release_region(ioaddr, pci_tbl[chip_idx].io_size);
+out_free_dev:
+ unregister_netdev(dev);
+ kfree(dev);
+out:


+ return NULL;
X }
X

X /* Serial EEPROM section. */
@@ -660,17 +673,18 @@
X {
X struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
X long ioaddr = dev->base_addr;
- int i;
+ int i, retval;
+
+ MOD_INC_USE_COUNT;
X

X /* Soft reset the chip. */

X outb(CmdReset, ioaddr + ChipCmd);
X
- if (request_irq(dev->irq, &rtl8129_interrupt, SA_SHIRQ, dev->name, dev)) {
- return -EAGAIN;
+ if ((retval = request_irq(dev->irq, &rtl8129_interrupt, SA_SHIRQ, dev->name, dev))) {
+ MOD_DEC_USE_COUNT;


+ return retval;
X }
X

- MOD_INC_USE_COUNT;
-
X tp->tx_bufs = pci_alloc_consistent(tp->pdev,
X TX_BUF_SIZE * NUM_TX_DESC,
X &tp->tx_bufs_dma);
@@ -690,6 +704,7 @@
X if (rtl8129_debug > 0)
X printk(KERN_ERR "%s: Couldn't allocate a %d byte receive ring.\n",
X dev->name, RX_BUF_LEN);
+ MOD_DEC_USE_COUNT;
X return -ENOMEM;
X }
X rtl8129_init_ring(dev);
@@ -1226,8 +1241,9 @@
X /* Malloc up new buffer, compatible with net-2e. */
X /* Omit the four octet CRC from the length. */
X struct sk_buff *skb;


+ int pkt_size = rx_size - 4;
X

- skb = dev_alloc_skb(rx_size + 2);
+ skb = dev_alloc_skb(pkt_size + 2);


X if (skb == NULL) {

X printk(KERN_WARNING"%s: Memory squeeze, deferring packet.\n",
X dev->name);
@@ -1238,12 +1254,12 @@


X }
X skb->dev = dev;

X skb_reserve(skb, 2); /* 16 byte align the IP fields. */
- if (ring_offset+rx_size+4 > RX_BUF_LEN) {
+ if (ring_offset+rx_size > RX_BUF_LEN) {
X int semi_count = RX_BUF_LEN - ring_offset - 4;
X memcpy(skb_put(skb, semi_count), &rx_ring[ring_offset + 4],
X semi_count);
- memcpy(skb_put(skb, rx_size-semi_count), rx_ring,
- rx_size-semi_count);
+ memcpy(skb_put(skb, pkt_size-semi_count), rx_ring,
+ pkt_size-semi_count);
X if (rtl8129_debug > 4) {
X int i;
X printk(KERN_DEBUG"%s: Frame wrap @%d",
@@ -1256,17 +1272,17 @@
X } else {
X #if 1 /* USE_IP_COPYSUM */
X eth_copy_and_sum(skb, &rx_ring[ring_offset + 4],
- rx_size, 0);
- skb_put(skb, rx_size);
+ pkt_size, 0);
+ skb_put(skb, pkt_size);
X #else
- memcpy(skb_put(skb, rx_size), &rx_ring[ring_offset + 4],
- rx_size);
+ memcpy(skb_put(skb, pkt_size), &rx_ring[ring_offset + 4],
+ pkt_size);
X #endif
X }
X skb->protocol = eth_type_trans(skb, dev);
X netif_rx(skb);
X #if LINUX_VERSION_CODE > 0x20119
- tp->stats.rx_bytes += rx_size;


+ tp->stats.rx_bytes += pkt_size;

X #endif
X tp->stats.rx_packets++;
X }
@@ -1292,6 +1308,8 @@
X
X netif_stop_queue(dev);
X
+ del_timer_sync(&tp->timer);
+
X if (rtl8129_debug > 1)
X printk(KERN_DEBUG"%s: Shutting down ethercard, status was 0x%4.4x.\n",
X dev->name, inw(ioaddr + IntrStatus));
@@ -1305,8 +1323,6 @@
X /* Update the error counts. */
X tp->stats.rx_missed_errors += inl(ioaddr + RxMissed);
X outl(0, ioaddr + RxMissed);
-
- del_timer(&tp->timer);
X
X free_irq(dev->irq, dev);
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/setup.c linux/drivers/net/setup.c
--- v2.4.0-test8/linux/drivers/net/setup.c Tue May 23 08:21:51 2000
+++ linux/drivers/net/setup.c Fri Sep 22 14:21:16 2000
@@ -1,3 +1,4 @@
+
X /*
X * New style setup code for the network devices
X */
@@ -22,6 +23,7 @@
X extern int awc4500_365_probe(void);
X extern int arcnet_init(void);
X extern int scc_enet_init(void);
+extern int fec_enet_init(void);
X extern int dlci_setup(void);
X extern int lapbeth_init(void);
X extern int sdla_setup(void);
@@ -75,6 +77,9 @@
X #if defined(CONFIG_SCC_ENET)
X {scc_enet_init, 0},
X #endif
+#if defined(CONFIG_FEC_ENET)
+ {fec_enet_init, 0},
+#endif
X #if defined(CONFIG_COMX)
X {comx_init, 0},
X #endif
@@ -162,58 +167,8 @@
X }
X
X
-static void __init appletalk_device_init(void)
-{
-#if defined(CONFIG_IPDDP)
- extern int ipddp_init(struct net_device *dev);
- static struct net_device dev_ipddp = {
- "ipddp0" __PAD6,


- 0, 0, 0, 0,
- 0x0, 0,

- 0, 0, 0, NULL, ipddp_init
- };
-
- dev_ipddp.init(&dev_ipddp);
-#endif /* CONFIG_IPDDP */
-}
-
-static void special_device_init(void)
+static void __init special_device_init(void)
X {
-#ifdef CONFIG_DUMMY
- {
- extern int dummy_init(struct net_device *dev);
- static struct net_device dummy_dev = {
- "dummy" __PAD5, 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NULL, dummy_init,
- };
- register_netdev(&dummy_dev);
- }
-#endif
-#ifdef CONFIG_EQUALIZER
- {
- extern int eql_init(struct net_device *dev);
- static struct net_device eql_dev =
- {
- "eql" __PAD3, /* Master device for IP traffic load balancing */
- 0x0, 0x0, 0x0, 0x0, /* recv end/start; mem end/start */
- 0, /* base I/O address */
- 0, /* IRQ */
- 0, 0, 0, /* flags */
- NULL, /* next device */
- eql_init /* set up the rest */
- };
- register_netdev(&eql_dev);
- }
-#endif
-#ifdef CONFIG_APBIF
- {
- extern int bif_init(struct net_device *dev);
- static struct net_device bif_dev =
- {
- "bif" __PAD3, 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NULL, bif_init
- };
- register_netdev(&bif_dev);
- }
-#endif
X #ifdef CONFIG_NET_SB1000
X {
X extern int sb1000_probe(struct net_device *dev);
@@ -224,15 +179,6 @@
X register_netdev(&sb1000_dev);
X }
X #endif
-#ifdef CONFIG_BONDING
- {
- extern int bond_init(struct net_device *dev);
- static struct net_device bond_dev = {
- "bond" __PAD4, 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NULL, bond_init,
- };
- register_netdev(&bond_dev);
- }
-#endif
X }
X
X /*
@@ -245,8 +191,6 @@
X network_probe();
X /* Line disciplines */
X network_ldisc_init();
- /* Appletalk */
- appletalk_device_init();
X /* Special devices */
X special_device_init();
X /* That kicks off the legacy init functions */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sis900.c linux/drivers/net/sis900.c
--- v2.4.0-test8/linux/drivers/net/sis900.c Wed Aug 9 14:24:09 2000
+++ linux/drivers/net/sis900.c Tue Sep 19 08:31:27 2000
@@ -1,6 +1,6 @@
X /* sis900.c: A SiS 900/7016 PCI Fast Ethernet driver for Linux.
X Copyright 1999 Silicon Integrated System Corporation
- Revision: 1.07.01 Aug. 08 2000
+ Revision: 1.07.04 Sep. 6 2000
X
X Modified from the driver which is originally written by Donald Becker.
X
@@ -18,7 +18,9 @@
X preliminary Rev. 1.0 Jan. 18, 1998
X http://www.sis.com.tw/support/databook.htm
X
- Rev 1.07.01 Aug. 08 2000 Ollie Lho minor update fro SiS 630E and SiS 630E A1
+ Rev 1.07.04 Sep. 6 2000 Lei-Chun Chang added ICS1893 PHY support
+ Rev 1.07.03 Aug. 24 2000 Lei-Chun Chang (lcc...@sis.com.tw) modified 630E eqaulizer workaroung rule
+ Rev 1.07.01 Aug. 08 2000 Ollie Lho minor update for SiS 630E and SiS 630E A1
X Rev 1.07 Mar. 07 2000 Ollie Lho bug fix in Rx buffer ring
X Rev 1.06.04 Feb. 11 2000 Jeff Garzik <jga...@mandrakesoft.com> softnet and init for kernel 2.4
X Rev 1.06.03 Dec. 23 1999 Ollie Lho Third release
@@ -54,7 +56,7 @@
X #include "sis900.h"
X
X static const char *version =
-"sis900.c: v1.07.01 08/08/2000\n";
+"sis900.c: v1.07.04 09/06/2000\n";
X
X static int max_interrupt_work = 20;
X static int multicast_filter_limit = 128;
@@ -88,6 +90,7 @@
X
X static void sis900_read_mode(struct net_device *net_dev, int phy_addr, int *speed, int *duplex);
X static void amd79c901_read_mode(struct net_device *net_dev, int phy_addr, int *speed, int *duplex);
+static void ics1893_read_mode(struct net_device *net_dev, int phy_addr, int *speed, int *duplex);
X
X static struct mii_chip_info {
X const char * name;
@@ -99,6 +102,7 @@
X {"SiS 7014 Physical Layer Solution", 0x0016, 0xf830,sis900_read_mode},
X {"AMD 79C901 10BASE-T PHY", 0x0000, 0x35b9, amd79c901_read_mode},
X {"AMD 79C901 HomePNA PHY", 0x0000, 0x35c8, amd79c901_read_mode},
+ {"ICS 1893 Integrated PHYceiver" , 0x0015, 0xf441,ics1893_read_mode},
X {0,},
X };
X
@@ -166,6 +170,7 @@
X static u16 sis900_compute_hashtable_index(u8 *addr);
X static void set_rx_mode(struct net_device *net_dev);
X static void sis900_reset(struct net_device *net_dev);
+static void sis630e_set_eq(struct net_device *net_dev);
X
X /* walk through every ethernet PCI devices to see if some of them are matched with our card list*/
X static int __init sis900_probe (struct pci_dev *pci_dev, const struct pci_device_id *pci_id)
@@ -242,29 +247,6 @@


X return 1;
X }
X

-/* SiS630E A1, The Mac address is hardcoded in the RFCR register so it is actually not necessary to
- probe the MAC address */
-static int sis630ea1_get_mac_addr(struct pci_dev * pci_dev, struct net_device *net_dev)
-{
- long ioaddr = pci_resource_start(pci_dev, 0);
- u32 reg;
- int i;
-
- /* reload MAC address */
- reg = inl(ioaddr + cr);
- outl(reg | RELOAD, ioaddr + cr);
-
- reg = inl(ioaddr + cr);
- outl(reg & ~RELOAD, ioaddr + cr);
-
- for (i = 0; i < 3; i++) {
- outl((u32)(0x00000004+i) << RFADDR_shift, ioaddr + rfcr);
- ((u16 *)(net_dev->dev_addr))[i] = inl(ioaddr + rfdr);
- }
-
- return 1;
-}
-
X static struct net_device * __init sis900_mac_probe (struct pci_dev * pci_dev, char * card_name)
X {
X struct sis900_private *sis_priv;
@@ -278,10 +260,10 @@
X return NULL;
X
X pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &revision);
- if (revision == SIS630E_REV)
+ if (revision == SIS630E_REV || revision == SIS630EA1_REV)
+ ret = sis630e_get_mac_addr(pci_dev, net_dev);
+ else if (revision == SIS630S_REV)
X ret = sis630e_get_mac_addr(pci_dev, net_dev);
- else if (revision == SIS630EA1_REV)
- ret = sis630ea1_get_mac_addr(pci_dev, net_dev);
X else
X ret = sis900_get_mac_addr(pci_dev, net_dev);
X
@@ -301,7 +283,7 @@
X unregister_netdevice(net_dev);
X return NULL;
X }
-
+
X sis_priv = net_dev->priv;
X memset(sis_priv, 0, sizeof(struct sis900_private));
X
@@ -311,7 +293,7 @@
X net_dev->irq = irq;
X sis_priv->pci_dev = pci_dev;
X spin_lock_init(&sis_priv->lock);
-
+
X /* probe for mii transciver */
X if (sis900_mii_probe(net_dev) == 0) {
X unregister_netdev(net_dev);
@@ -366,7 +348,7 @@
X printk(KERN_INFO
X "%s: %s transceiver found at address %d.\n",
X net_dev->name, mii_chip_table[i].name,
- phy_addr);;
+ phy_addr);
X if ((mii_phy = kmalloc(sizeof(struct mii_phy), GFP_KERNEL)) != NULL) {
X mii_phy->chip_info = mii_chip_table+i;
X mii_phy->phy_addr = phy_addr;
@@ -559,12 +541,18 @@
X {
X struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
X long ioaddr = net_dev->base_addr;
+ u8 revision;
X
X MOD_INC_USE_COUNT;


X
X /* Soft reset the chip. */

X sis900_reset(net_dev);
X
+ /* Equalizer workaroung Rule */
+ pci_read_config_byte(sis_priv->pci_dev, PCI_CLASS_REVISION, &revision);
+ if (revision == SIS630E_REV || revision == SIS630EA1_REV)
+ sis630e_set_eq(net_dev);
+
X if (request_irq(net_dev->irq, &sis900_interrupt, SA_SHIRQ, net_dev->name, net_dev)) {
X MOD_DEC_USE_COUNT;
X return -EAGAIN;
@@ -700,6 +688,64 @@
X printk(KERN_INFO "%s: RX descriptor register loaded with: %8.8x\n",
X net_dev->name, inl(ioaddr + rxdp));
X }
+
+/* 630E equalizer workaroung rule(Cyrus Huang 08/15)
+ PHY register 14h(Test)
+ Bit 14: 0 -- Automatically dectect (default)
+ 1 -- Manually set Equalizer filter
+ Bit 13: 0 -- (Default)
+ 1 -- Speed up convergence of equalizer setting
+ Bit 9 : 0 -- (Default)
+ 1 -- Disable Baseline Wander
+ Bit 3~7 -- Equalizer filter setting
+
+ Link ON: Set Bit 9, 13 to 1, Bit 14 to 0
+ Then calculate equalizer value
+ Then set equalizer value, and set Bit 14 to 1, Bit 9 to 0
+ Link Off:Set Bit 13 to 1, Bit 14 to 0
+
+ Calculate Equalizer value:
+ When Link is ON and Bit 14 is 0, SIS900PHY will auto-dectect proper equalizer value.
+ When the equalizer is stable, this value is not a fixed value. It will be within
+ a small range(eg. 7~9). Then we get a minimum and a maximum value(eg. min=7, max=9)
+ 0 <= max <= 4 --> set equalizer to max
+ 5 <= max <= 14 --> set equalizer to max+1 or
+ set equalizer to max+2 if max == min
+ max >= 15 --> set equalizer to max+5 or
+ set equalizer to max+6 if max == min
+*/
+static void sis630e_set_eq(struct net_device *net_dev)
+{
+ struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
+ u16 reg14h, eq_value, max_value=0, min_value=0;
+ int i, maxcount=10;
+
+ if (sis_priv->LinkOn == TRUE) {
+ reg14h=mdio_read(net_dev, sis_priv->cur_phy, MII_RESV);
+ mdio_write(net_dev, sis_priv->cur_phy, MII_RESV, (0x2200 | reg14h) & 0xBFFF);
+ for (i=0; i < maxcount; i++) {
+ eq_value=(0x00F8 & mdio_read(net_dev, sis_priv->cur_phy, MII_RESV)) >> 3;
+ max_value=(eq_value > max_value) ? eq_value : max_value;
+ min_value=(eq_value < min_value) ? eq_value : min_value;
+ }
+ if (max_value < 5)
+ eq_value=max_value;
+ else if (max_value >= 5 && max_value < 15)
+ eq_value=(max_value == min_value) ? max_value+2 : max_value+1;
+ else if (max_value >= 15)
+ eq_value=(max_value == min_value) ? max_value+6 : max_value+5;
+ reg14h=mdio_read(net_dev, sis_priv->cur_phy, MII_RESV);
+ reg14h=(reg14h & 0xFF07) | ((eq_value << 3) & 0x00F8);
+ reg14h=(reg14h | 0x6000) & 0xFDFF;
+ mdio_write(net_dev, sis_priv->cur_phy, MII_RESV, reg14h);
+ }
+ else {
+ reg14h=mdio_read(net_dev, sis_priv->cur_phy, MII_RESV);
+ mdio_write(net_dev, sis_priv->cur_phy, MII_RESV, (reg14h | 0x2000) & 0xBFFF);


+ }
+ return;
+}
+

X /* on each timer ticks we check two things, Link Status (ON/OFF) and
X Link Mode (10/100/Full/Half)
X */
@@ -710,6 +756,7 @@
X struct mii_phy *mii_phy = sis_priv->mii;
X static int next_tick = 5*HZ;
X u16 status;
+ u8 revision;
X
X status = mdio_read(net_dev, sis_priv->cur_phy, MII_STATUS);


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 064'
echo 'File patch-2.4.0-test9 is continued in part 065'
echo "065" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part067

#!/bin/sh -x
# this is part 067 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 067; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

X
X /*
X * perform a local reset of the port's tx path
@@ -1311,16 +1322,16 @@
X * - reset the RAM Butter sync tx queue
X * - reset the MAC Tx FIFO
X */
- SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff,Q_CSR), CSR_SET_RESET);
- SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff,Q_CSR), CSR_SET_RESET);
- SK_OUT8(IoC, RB_ADDR(pPrt->PXaQOff,RB_CTRL), RB_RST_SET);
- SK_OUT8(IoC, RB_ADDR(pPrt->PXsQOff,RB_CTRL), RB_RST_SET);
+ SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_SET_RESET);
+ SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_SET_RESET);
+ SK_OUT8(IoC, RB_ADDR(pPrt->PXaQOff, RB_CTRL), RB_RST_SET);
+ SK_OUT8(IoC, RB_ADDR(pPrt->PXsQOff, RB_CTRL), RB_RST_SET);
X /* Note: MFF_RST_SET does NOT reset the XMAC! */
X SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_SET);
X
X /* switch Link and Tx LED off, stop the LED counters */
X /* Link LED is switched off by the RLMT and the Diag itself */
- SkGeXmitLED(pAC, IoC, MR_ADDR(Port,TX_LED_INI), SK_LED_DIS);
+ SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_DIS);
X }
X
X if (Dir & SK_STOP_RX) {
@@ -1331,7 +1342,7 @@
X * stop the transfer of received packets.
X */
X /* stop the port's receive queue */
- SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff,Q_CSR), CSR_STOP);
+ SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_STOP);
X i = 100;
X do {
X /*
@@ -1368,12 +1379,12 @@
X * - reset the RAM Buffer receive queue
X * - reset the MAC Rx FIFO
X */
- SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff,Q_CSR), CSR_SET_RESET);
- SK_OUT8(IoC, RB_ADDR(pPrt->PRxQOff,RB_CTRL), RB_RST_SET);
+ SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_SET_RESET);
+ SK_OUT8(IoC, RB_ADDR(pPrt->PRxQOff, RB_CTRL), RB_RST_SET);
X SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_SET);
X
X /* switch Rx LED off, stop the LED counter */
- SkGeXmitLED(pAC, IoC, MR_ADDR(Port,RX_LED_INI), SK_LED_DIS);
+ SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_DIS);
X
X }
X
@@ -1391,7 +1402,8 @@
X if (AllPortsDis) {
X pAC->GIni.GIAnyPortAct = SK_FALSE;
X }
-}
+} /* SkGeStopPort */
+
X
X /******************************************************************************
X *
@@ -1444,7 +1456,88 @@
X
X pAC->GIni.GIPortUsage = SK_RED_LINK;
X pAC->GIni.GIAnyPortAct = SK_FALSE;
-}
+} /* SkGeInit0*/
+
+#ifdef SK_PCI_RESET
+
+/******************************************************************************
+ *
+ * SkGePciReset() - Reset PCI interface
+ *
+ * Description:
+ * o Read PCI configuration.
+ * o Change power state to 3.
+ * o Change power state to 0.
+ * o Restore PCI configuration.
+ *
+ * Returns:
+ * 0: Success.
+ * 1: Power state could not be changed to 3.
+ */
+static int SkGePciReset(
+SK_AC *pAC, /* adapter context */
+SK_IOC IoC) /* IO context */
+{
+ int i;
+ SK_U16 PmCtlSts;
+ SK_U32 Bp1;
+ SK_U32 Bp2;
+ SK_U16 PciCmd;
+ SK_U8 Cls;
+ SK_U8 Lat;
+ SK_U8 ConfigSpace[PCI_CFG_SIZE];
+
+ /*
+ * Note: Switching to D3 state is like a software reset.
+ * Switching from D3 to D0 is a hardware reset.
+ * We have to save and restore the configuration space.
+ */
+ for (i = 0; i < PCI_CFG_SIZE; i++) {
+ SkPciReadCfgDWord(pAC, i*4, &ConfigSpace[i]);
+ }
+
+ /* We know the RAM Interface Arbiter is enabled. */
+ SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PCI_PM_STATE_D3);
+ SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts);
+ if ((PmCtlSts & PCI_PM_STATE) != PCI_PM_STATE_D3) {
+ return (1);
+ }
+
+ /*
+ * Return to D0 state.
+ */
+ SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PCI_PM_STATE_D0);
+
+ /* Check for D0 state. */
+ SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts);
+ if ((PmCtlSts & PCI_PM_STATE) != PCI_PM_STATE_D0) {
+ return (1);
+ }
+
+ /*
+ * Check PCI Config Registers.
+ */
+ SkPciReadCfgWord(pAC, PCI_COMMAND, &PciCmd);
+ SkPciReadCfgByte(pAC, PCI_CACHE_LSZ, &Cls);
+ SkPciReadCfgDWord(pAC, PCI_BASE_1ST, &Bp1);
+ SkPciReadCfgDWord(pAC, PCI_BASE_2ND, &Bp2);
+ SkPciReadCfgByte(pAC, PCI_LAT_TIM, &lat);
+ if (PciCmd != 0 || Cls != 0 || (Bp1 & 0xfffffff0L) != 0 || Bp2 != 1 ||
+ Lat != 0 ) {
+ return (0);
+ }
+
+ /*
+ * Restore Config Space.
+ */
+ for (i = 0; i < PCI_CFG_SIZE; i++) {
+ SkPciWriteCfgDWord(pAC, i*4, ConfigSpace[i]);
+ }
+
+ return (0);
+} /* SkGePciReset */
+
+#endif /* SK_PCI_RESET */
X
X /******************************************************************************
X *
@@ -1477,6 +1570,10 @@
X
X RetVal = 0;
X
+#ifdef SK_PCI_RESET
+ (void)SkGePciReset(pAC, IoC);
+#endif /* SK_PCI_RESET */
+
X /* Do the reset */
X SK_OUT8(IoC, B0_CTST, CS_RST_SET);
X
@@ -1486,7 +1583,7 @@
X /* Reset all error bits in the PCI STATUS register */
X /*
X * Note: Cfg cycles cannot be used, because they are not
- * available on some platforms after 'boot time'.
+ * available on some platforms after 'boot time'.
X */
X SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON);
X SK_IN16(IoC, PCI_C(PCI_STATUS), &Word);
@@ -1547,12 +1644,13 @@
X break;
X }
X }
- SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_INIT,
+ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
X ("PHY type: %d PHY addr: %x\n", pAC->GIni.GP[i].PhyType,
- pAC->GIni.GP[i].PhyAddr)) ;
+ pAC->GIni.GP[i].PhyAddr));
X
X return (RetVal);
-}
+} /* SkGeInit1*/
+
X
X /******************************************************************************
X *
@@ -1588,8 +1686,7 @@
X pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX;
X
X /* Create an Error Log Entry */
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E017,
- SKERR_HWI_E017MSG);
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E017, SKERR_HWI_E017MSG);
X }
X SK_OUT32(IoC, B28_DPT_INI, pAC->GIni.GIPollTimerVal);
X SK_OUT8(IoC, B28_DPT_CTRL, DPT_START);
@@ -1607,9 +1704,9 @@
X SkGeInitPktArb(pAC, IoC);
X
X /* enable the Tx Arbiters */
- SK_OUT8(IoC, MR_ADDR(MAC_1,TXA_CTRL), TXA_ENA_ARB);
+ SK_OUT8(IoC, MR_ADDR(MAC_1, TXA_CTRL), TXA_ENA_ARB);
X if (pAC->GIni.GIMacsFound > 1) {
- SK_OUT8(IoC, MR_ADDR(MAC_2,TXA_CTRL), TXA_ENA_ARB);
+ SK_OUT8(IoC, MR_ADDR(MAC_2, TXA_CTRL), TXA_ENA_ARB);
X }
X
X /* enable the RAM Interface Arbiter */
@@ -1621,7 +1718,7 @@
X pPrt->PRxCmd |= XM_RX_BIG_PK_OK;
X }
X }
-}
+} /* SkGeInit2 */
X
X /******************************************************************************
X *
@@ -1660,24 +1757,24 @@
X int SkGeInit(
X SK_AC *pAC, /* adapter context */
X SK_IOC IoC, /* IO context */
-int Level) /* initialization level */
+int Level) /* initialization level */
X {
X int RetVal; /* return value */
X SK_U32 DWord;
X
X RetVal = 0;
- SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_INIT,
- ("SkGeInit(Level %d)\n",Level)) ;
+ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT,
+ ("SkGeInit(Level %d)\n", Level));
X
X switch (Level) {
X case SK_INIT_DATA:
X /* Initialization Level 0 */
- SkGeInit0(pAC,IoC) ;
+ SkGeInit0(pAC, IoC);
X pAC->GIni.GILevel = SK_INIT_DATA;
X break;
X case SK_INIT_IO:
X /* Initialization Level 1 */
- RetVal = SkGeInit1(pAC,IoC) ;
+ RetVal = SkGeInit1(pAC, IoC);
X
X /* Check if the adapter seems to be accessable */
X SK_OUT32(IoC, B2_IRQM_INI, 0x11335577L);
@@ -1701,13 +1798,12 @@
X /* Initialization Level 2 */
X if (pAC->GIni.GILevel != SK_INIT_IO) {
X #ifndef SK_DIAG
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E002,
- SKERR_HWI_E002MSG);
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E002, SKERR_HWI_E002MSG);
X #endif
X RetVal = 4;
X break;
X }
- SkGeInit2(pAC,IoC) ;
+ SkGeInit2(pAC, IoC);
X
X /* Level 2 successfully passed */
X pAC->GIni.GILevel = SK_INIT_RUN;
@@ -1715,12 +1811,13 @@
X default:
X /* Create an Error Log Entry */
X SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E003, SKERR_HWI_E003MSG);
- RetVal = 3 ;
+ RetVal = 3;
X break;
X }
X
X return (RetVal);
-}
+} /* SkGeInit*/
+
X
X /******************************************************************************
X *
@@ -1740,6 +1837,9 @@
X int i;
X SK_U16 Word;
X
+ /* Ensure I2C is ready. */
+ SkI2cWaitIrq(pAC, IoC);
+
X /* Stop all current transfer activity */
X for (i = 0; i < pAC->GIni.GIMacsFound; i++) {
X if (pAC->GIni.GP[i].PState != SK_PRT_STOP &&
@@ -1761,7 +1861,8 @@
X
X /* Do the reset, all LEDs are switched off now */
X SK_OUT8(IoC, B0_CTST, CS_RST_SET);
-}
+} /* SkGeDeInit*/
+
X
X /******************************************************************************
X *
@@ -1795,13 +1896,13 @@
X int SkGeInitPort(
X SK_AC *pAC, /* adapter context */
X SK_IOC IoC, /* IO context */
-int Port) /* Port to configure */
+int Port) /* Port to configure */
X {
X SK_GEPORT *pPrt;
X
X pPrt = &pAC->GIni.GP[Port];
X
- if (SkGeCheckQSize(pAC,Port) != 0) {
+ if (SkGeCheckQSize(pAC, Port) != 0) {
X SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E004, SKERR_HWI_E004MSG);
X return (1);
X }
@@ -1817,8 +1918,8 @@
X * If 1000BT Phy needs LED initialization than swap
X * LED and XMAC initialization order
X */
- SkGeXmitLED(pAC, IoC, MR_ADDR(Port,TX_LED_INI), SK_LED_ENA);
- SkGeXmitLED(pAC, IoC, MR_ADDR(Port,RX_LED_INI), SK_LED_ENA);
+ SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA);
+ SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_ENA);
X /* The Link LED is initialized by RLMT or Diagnostics itself */
X
X /* Do NOT initialize the Link Sync Counter */
@@ -1844,4 +1945,4 @@
X pAC->GIni.GIAnyPortAct = SK_TRUE;
X
X return (0);
-}
+} /* SkGeInitPort */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/skgepnmi.c linux/drivers/net/sk98lin/skgepnmi.c
--- v2.4.0-test8/linux/drivers/net/sk98lin/skgepnmi.c Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/skgepnmi.c Fri Sep 15 14:34:19 2000
@@ -2,8 +2,8 @@
X *
X * Name: skgepnmi.c
X * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.69 $
- * Date: $Date: 1999/10/18 11:42:15 $
+ * Version: $Revision: 1.78 $
+ * Date: $Date: 2000/09/12 10:44:58 $
X * Purpose: Private Network Management Interface
X *
X ****************************************************************************/
@@ -13,8 +13,6 @@
X * (C)Copyright 1998,1999 SysKonnect,
X * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
X *
- * See the file "skge.c" for further information.
- *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
X * the Free Software Foundation; either version 2 of the License, or
@@ -29,6 +27,43 @@
X * History:
X *
X * $Log: skgepnmi.c,v $
+ * Revision 1.78 2000/09/12 10:44:58 cgoos
+ * Fixed SK_PNMI_STORE_U32 calls with typecasted argument.
+ *
+ * Revision 1.77 2000/09/07 08:10:19 rwahl
+ * - Modified algorithm for 64bit NDIS statistic counters;
+ * returns 64bit or 32bit value depending on passed buffer
+ * size. Indicate capability for 64bit NDIS counter, if passed
+ * buffer size is zero. OID_GEN_XMIT_ERROR, OID_GEN_RCV_ERROR,
+ * and OID_GEN_RCV_NO_BUFFER handled as 64bit counter, too.
+ * - corrected OID_SKGE_RLMT_PORT_PREFERRED.
+ *
+ * Revision 1.76 2000/08/03 15:23:39 rwahl
+ * - Correction for FrameTooLong counter has to be moved to OID handling
+ * routines (instead of statistic counter routine).
+ * - Fix in XMAC Reset Event handling: Only offset counter for hardware
+ * statistic registers are updated.
+ *
+ * Revision 1.75 2000/08/01 16:46:05 rwahl
+ * - Added StatRxLongFrames counter and correction of FrameTooLong counter.
+ * - Added directive to control width (default = 32bit) of NDIS statistic
+ * counters (SK_NDIS_64BIT_CTR).
+ *
+ * Revision 1.74 2000/07/04 11:41:53 rwahl
+ * - Added volition connector type.
+ *
+ * Revision 1.73 2000/03/15 16:33:10 rwahl
+ * Fixed bug 10510; wrong reset of virtual port statistic counters.
+ *
+ * Revision 1.72 1999/12/06 16:15:53 rwahl
+ * Fixed problem of instance range for current and factory MAC address.
+ *
+ * Revision 1.71 1999/12/06 10:14:20 rwahl
+ * Fixed bug 10476; set operation for PHY_OPERATION_MODE.
+ *
+ * Revision 1.70 1999/11/22 13:33:34 cgoos
+ * Changed license header to GPL.
+ *
X * Revision 1.69 1999/10/18 11:42:15 rwahl
X * Added typecasts for checking event dependent param (debug only).
X *

@@ -297,7 +332,8 @@
X

X
X static const char SysKonnectFileId[] =
- "@(#) $Id: skgepnmi.c,v 1.69 1999/10/18 11:42:15 rwahl Exp $ (C) SysKonnect.";
+ "@(#) $Id: skgepnmi.c,v 1.78 2000/09/12 10:44:58 cgoos Exp $"
+ " (C) SysKonnect.";
X
X #include "h/skdrv1st.h"
X #include "h/sktypes.h"
@@ -982,6 +1018,11 @@
X sizeof(SK_PNMI_STAT),
X SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxUnicastOkCts),
X SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_UNICAST},
+ {OID_SKGE_STAT_RX_LONGFRAMES,
+ SK_PNMI_MAC_ENTRIES,
+ sizeof(SK_PNMI_STAT),
+ SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxLongFramesCts),
+ SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_LONGFRAMES},
X {OID_SKGE_STAT_RX_PFLOWC,
X SK_PNMI_MAC_ENTRIES,
X sizeof(SK_PNMI_STAT),
@@ -1197,7 +1238,7 @@
X 0,
X SK_PNMI_MAI_OFF(RlmtPortActive),
X SK_PNMI_RO, Rlmt, 0},
- {OID_SKGE_RLMT_PORT_PREFERED,
+ {OID_SKGE_RLMT_PORT_PREFERRED,
X 1,
X 0,
X SK_PNMI_MAI_OFF(RlmtPortPreferred),
@@ -1353,7 +1394,8 @@
X /* 62 */ {TRUE, XM_RXF_1023B},
X /* 63 */ {TRUE, XM_RXF_MAX_SZ},
X /* 64 */ {FALSE, 0},
- /* 65 */ {FALSE, 0}
+ /* 65 */ {FALSE, 0},
+ /* 66 */ {TRUE, 0}
X };
X
X
@@ -1520,6 +1562,10 @@
X pAC->Pnmi.Connector = 5;
X break;
X
+ case 'V':
+ pAC->Pnmi.Connector = 6;
+ break;
+
X default:
X pAC->Pnmi.Connector = 1;
X break;
@@ -2074,8 +2120,13 @@
X case SK_PNMI_HRX_OCTETLOW:
X case SK_PNMI_HRX_IRLENGTH:
X case SK_PNMI_HRX_RESERVED22:
+
+ /*
+ * the following counters aren't be handled (id > 63)
+ */
X case SK_PNMI_HTX_SYNC:
X case SK_PNMI_HTX_SYNC_OCTET:
+ case SK_PNMI_HRX_LONGFRAMES:


X break;
X
X default:

@@ -2270,7 +2321,7 @@
X */
X pAC->Pnmi.MacUpdatedFlag ++;
X
- for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
+ for (CounterIndex = 0; CounterIndex < SK_PNMI_SCNT_NOT;
X CounterIndex ++) {
X
X if (!StatAddress[CounterIndex].GetOffset) {
@@ -2985,9 +3036,9 @@
X SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
X unsigned int TableIndex) /* Index to the Id table */
X {
- int Ret;
- SK_U32 StatVal;
-
+ int Ret;
+ SK_U64 StatVal;
+ SK_BOOL Is64BitReq = SK_FALSE;
X
X /*
X * Only the active Mac is returned
@@ -3022,11 +3073,28 @@
X break;
X
X default:
- if (*pLen < 4) {
+#ifndef SK_NDIS_64BIT_CTR
+ if (*pLen < sizeof(SK_U32)) {
+ *pLen = sizeof(SK_U32);
+ return (SK_PNMI_ERR_TOO_SHORT);
+ }
X
- *pLen = 4;
+#else /* SK_NDIS_64BIT_CTR */
+
+ /*
+ * for compatibility, at least 32bit are required for oid
+ */
+ if (*pLen < sizeof(SK_U32)) {
+ /*
+ * but indicate handling for 64bit values,
+ * if insufficient space is provided
+ */
+ *pLen = sizeof(SK_U64);
X return (SK_PNMI_ERR_TOO_SHORT);
X }
+
+ Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
+#endif /* SK_NDIS_64BIT_CTR */
X break;
X }
X
@@ -3059,10 +3127,21 @@
X break;
X
X default:
- StatVal = (SK_U32)GetStatVal(pAC, IoC, 0,
- IdTable[TableIndex].Param);
- SK_PNMI_STORE_U32(pBuf, StatVal);
- *pLen = sizeof(SK_U32);
+ StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param);
+
+ /*
+ * by default 32bit values are evaluated
+ */
+ if (!Is64BitReq) {
+ SK_U32 StatVal32;
+ StatVal32 = (SK_U32)StatVal;
+ SK_PNMI_STORE_U32(pBuf, StatVal32);
+ *pLen = sizeof(SK_U32);
+ }
+ else {
+ SK_PNMI_STORE_U64(pBuf, StatVal);
+ *pLen = sizeof(SK_U64);
+ }
X break;
X }
X
@@ -3177,6 +3256,20 @@
X case OID_SKGE_STAT_RX_UTIL:
X return (SK_PNMI_ERR_GENERAL);
X */
+ /*
+ * Frames longer than IEEE 802.3 frame max size are counted
+ * by XMAC in frame_too_long counter even reception of long
+ * frames was enabled and the frame was correct.
+ * So correct the value by subtracting RxLongFrame counter.
+ */
+ case OID_SKGE_STAT_RX_TOO_LONG:
+ StatVal = GetStatVal(pAC, IoC, LogPortIndex,
+ IdTable[TableIndex].Param) -
+ GetStatVal(pAC, IoC, LogPortIndex,
+ SK_PNMI_HRX_LONGFRAMES);
+ SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
+ break;
+
X default:
X StatVal = GetStatVal(pAC, IoC, LogPortIndex,
X IdTable[TableIndex].Param);
@@ -3245,7 +3338,7 @@
X
X if ((Instance != (SK_U32)(-1))) {
X
- if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) {
+ if ((Instance < 1) || (Instance > LogPortMax)) {
X
X *pLen = 0;
X return (SK_PNMI_ERR_UNKNOWN_INST);
@@ -4289,6 +4382,7 @@
X SK_U64 Val64;
X SK_U64 Val64RxHwErrs = 0;
X SK_U64 Val64TxHwErrs = 0;
+ SK_BOOL Is64BitReq = SK_FALSE;
X char Buf[256];
X
X
@@ -4315,13 +4409,37 @@
X */
X switch (Id) {
X
+ case OID_GEN_XMIT_ERROR:
+ case OID_GEN_RCV_ERROR:
+ case OID_GEN_RCV_NO_BUFFER:
+#ifndef SK_NDIS_64BIT_CTR
+ if (*pLen < sizeof(SK_U32)) {
+ *pLen = sizeof(SK_U32);
+ return (SK_PNMI_ERR_TOO_SHORT);
+ }
+
+#else /* SK_NDIS_64BIT_CTR */
+
+ /*
+ * for compatibility, at least 32bit are required for oid
+ */
+ if (*pLen < sizeof(SK_U32)) {
+ /*
+ * but indicate handling for 64bit values,
+ * if insufficient space is provided
+ */
+ *pLen = sizeof(SK_U64);
+ return (SK_PNMI_ERR_TOO_SHORT);
+ }
+
+ Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
+#endif /* SK_NDIS_64BIT_CTR */
+ break;
+
X case OID_SKGE_PORT_NUMBER:
X case OID_SKGE_DEVICE_TYPE:
X case OID_SKGE_RESULT:
X case OID_SKGE_RLMT_MONITOR_NUMBER:
- case OID_GEN_XMIT_ERROR:
- case OID_GEN_RCV_ERROR:
- case OID_GEN_RCV_NO_BUFFER:
X case OID_GEN_TRANSMIT_QUEUE_LENGTH:
X case OID_SKGE_TRAP_NUMBER:
X case OID_SKGE_MDB_VERSION:
@@ -4420,7 +4538,8 @@
X GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL) +
X GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS) +
X GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT) +
- GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG)+
+ GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG)-
+ GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_LONGFRAMES)+
X GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS) +
X GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT);
X break;
@@ -4748,21 +4867,57 @@
X break;
X
X case OID_GEN_RCV_ERROR:
- Val32 = (SK_U32)(Val64RxHwErrs + pAC->Pnmi.RxNoBufCts);
- SK_PNMI_STORE_U32(pBuf, Val32);
- *pLen = sizeof(SK_U32);
+ Val64 = Val64RxHwErrs + pAC->Pnmi.RxNoBufCts;
+
+ /*
+ * by default 32bit values are evaluated
+ */
+ if (!Is64BitReq) {
+ SK_U32 Val32;
+ Val32 = (SK_U32)Val64;
+ SK_PNMI_STORE_U32(pBuf, Val32);
+ *pLen = sizeof(SK_U32);
+ }
+ else {
+ SK_PNMI_STORE_U64(pBuf, Val64);
+ *pLen = sizeof(SK_U64);
+ }
X break;
X
X case OID_GEN_XMIT_ERROR:
- Val32 = (SK_U32)(Val64TxHwErrs + pAC->Pnmi.TxNoBufCts);
- SK_PNMI_STORE_U32(pBuf, Val32);
- *pLen = sizeof(SK_U32);
+ Val64 = Val64TxHwErrs + pAC->Pnmi.TxNoBufCts;
+
+ /*
+ * by default 32bit values are evaluated
+ */
+ if (!Is64BitReq) {
+ SK_U32 Val32;
+ Val32 = (SK_U32)Val64;
+ SK_PNMI_STORE_U32(pBuf, Val32);
+ *pLen = sizeof(SK_U32);
+ }
+ else {
+ SK_PNMI_STORE_U64(pBuf, Val64);
+ *pLen = sizeof(SK_U64);
+ }
X break;
X
X case OID_GEN_RCV_NO_BUFFER:
- Val32 = (SK_U32)pAC->Pnmi.RxNoBufCts;
- SK_PNMI_STORE_U32(pBuf, Val32);
- *pLen = sizeof(SK_U32);
+ Val64 = pAC->Pnmi.RxNoBufCts;
+
+ /*
+ * by default 32bit values are evaluated
+ */
+ if (!Is64BitReq) {
+ SK_U32 Val32;
+ Val32 = (SK_U32)Val64;
+ SK_PNMI_STORE_U32(pBuf, Val32);
+ *pLen = sizeof(SK_U32);
+ }
+ else {
+ SK_PNMI_STORE_U64(pBuf, Val64);
+ *pLen = sizeof(SK_U64);
+ }
X break;
X
X case OID_GEN_TRANSMIT_QUEUE_LENGTH:
@@ -4853,7 +5008,7 @@
X
X case OID_SKGE_RLMT_MODE:
X case OID_SKGE_RLMT_PORT_ACTIVE:
- case OID_SKGE_RLMT_PORT_PREFERED:
+ case OID_SKGE_RLMT_PORT_PREFERRED:
X if (*pLen < sizeof(SK_U8)) {
X
X *pLen = sizeof(SK_U8);
@@ -4941,7 +5096,7 @@
X *pLen = sizeof(char);
X break;
X
- case OID_SKGE_RLMT_PORT_PREFERED:
+ case OID_SKGE_RLMT_PORT_PREFERRED:
X *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(
X pAC->Rlmt.MacPreferred);
X *pLen = sizeof(char);
@@ -5021,7 +5176,7 @@
X }
X break;
X
- case OID_SKGE_RLMT_PORT_PREFERED:
+ case OID_SKGE_RLMT_PORT_PREFERRED:
X /* Check if the buffer length is plausible */
X if (*pLen < sizeof(char)) {
X
@@ -5622,6 +5777,7 @@
X
X case OID_SKGE_LINK_MODE:
X case OID_SKGE_FLOWCTRL_MODE:
+ case OID_SKGE_PHY_OPERATION_MODE:
X if (*pLen < Limit - LogPortIndex) {
X
X *pLen = Limit - LogPortIndex;
@@ -5798,6 +5954,82 @@
X Offset += sizeof(char);
X break;
X
+ case OID_SKGE_PHY_OPERATION_MODE :
+ /* Check the value range */
+ Val8 = *(pBuf + Offset);
+ if (Val8 == 0) {
+ /* mode of this port remains unchanged */
+ Offset += sizeof(char);
+ break;
+ }
+ if (Val8 < SK_MS_MODE_AUTO ||
+ Val8 > SK_MS_MODE_SLAVE) {
+
+ *pLen = 0;
+ return (SK_PNMI_ERR_BAD_VALUE);
+ }
+
+ /* The preset ends here */
+ if (Action == SK_PNMI_PRESET) {
+
+ return (SK_PNMI_ERR_OK);
+ }
+
+ if (LogPortIndex == 0) {
+
+ /*
+ * The virtual port consists of all currently
+ * active ports. Find them and send an event
+ * with new master/slave (role) mode to SIRQ.
+ */
+ for (PhysPortIndex = 0;
+ PhysPortIndex < PhysPortMax;
+ PhysPortIndex ++) {
+
+ if (!pAC->Pnmi.Port[PhysPortIndex].
+ ActiveFlag) {
+
+ continue;
+ }
+
+ EventParam.Para32[0] = PhysPortIndex;
+ EventParam.Para32[1] = (SK_U32)Val8;
+ if (SkGeSirqEvent(pAC, IoC,
+ SK_HWEV_SET_ROLE,
+ EventParam) > 0) {
+
+ SK_ERR_LOG(pAC, SK_ERRCL_SW,
+ SK_PNMI_ERR052,
+ SK_PNMI_ERR052MSG);
+
+ *pLen = 0;
+ return (SK_PNMI_ERR_GENERAL);
+ }
+ }
+ }
+ else {
+ /*
+ * Send an event with the new master/slave
+ * (role) mode to the SIRQ module.
+ */
+ EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
+ pAC, LogPortIndex);
+ EventParam.Para32[1] = (SK_U32)Val8;
+ if (SkGeSirqEvent(pAC, IoC,
+ SK_HWEV_SET_ROLE, EventParam) > 0) {
+
+ SK_ERR_LOG(pAC, SK_ERRCL_SW,
+ SK_PNMI_ERR052,
+ SK_PNMI_ERR052MSG);
+
+ *pLen = 0;
+ return (SK_PNMI_ERR_GENERAL);
+ }
+ }
+
+ Offset += sizeof(char);
+ break;
+
X default:
X SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR045,
X SK_PNMI_ERR045MSG);
@@ -6670,6 +6902,12 @@
X 32);
X break;
X
+ case SK_PNMI_HRX_LONGFRAMES:
+ LowVal = (SK_U32)pAC->Pnmi.Port[PhysPortIndex].StatRxLongFrameCts;
+ HighVal = (SK_U32)
+ (pAC->Pnmi.Port[PhysPortIndex].StatRxLongFrameCts >> 32);
+ break;
+
X case SK_PNMI_HRX_FCS:
X /*
X * Broadcom filters fcs errors and counts it in
@@ -6765,11 +7003,16 @@
X SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
X StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[
X PhysPortIndex].StatSyncOctetsCts));
+ SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
+ StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[
+ PhysPortIndex].StatRxLongFrameCts));
X }
X
X /*
X * Clear local statistics
X */
+ SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0,
+ sizeof(pAC->Pnmi.VirtualCounterOffset));
X pAC->Pnmi.RlmtChangeCts = 0;
X pAC->Pnmi.RlmtChangeTime = 0;
X SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0,
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/skgesirq.c linux/drivers/net/sk98lin/skgesirq.c
--- v2.4.0-test8/linux/drivers/net/sk98lin/skgesirq.c Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/skgesirq.c Fri Sep 15 14:34:19 2000
@@ -2,8 +2,8 @@
X *
X * Name: skgesirq.c
X * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.46 $
- * Date: $Date: 1999/09/16 10:30:07 $
+ * Version: $Revision: 1.55 $
+ * Date: $Date: 2000/06/19 08:36:25 $
X * Purpose: Special IRQ module
X *
X ******************************************************************************/
@@ -13,8 +13,6 @@
X * (C)Copyright 1998,1999 SysKonnect,
X * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
X *
- * See the file "skge.c" for further information.
- *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
X * the Free Software Foundation; either version 2 of the License, or
@@ -29,6 +27,34 @@
X * History:
X *
X * $Log: skgesirq.c,v $
+ * Revision 1.55 2000/06/19 08:36:25 cgoos
+ * Changed comment.
+ *
+ * Revision 1.54 2000/05/22 08:45:57 malthoff
+ * Fix: #10523 is valid for all BCom PHYs.
+ *
+ * Revision 1.53 2000/05/19 10:20:30 cgoos
+ * Removed Solaris debug output code.
+ *
+ * Revision 1.52 2000/05/19 10:19:37 cgoos
+ * Added PHY state check in HWLinkDown.
+ * Move PHY interrupt code to IS_EXT_REG case in SkGeSirqIsr.
+ *
+ * Revision 1.51 2000/05/18 05:56:20 cgoos
+ * Fixed typo.
+ *
+ * Revision 1.50 2000/05/17 12:49:49 malthoff
+ * Fixes BCom link bugs (#10523).
+ *
+ * Revision 1.49 1999/12/17 11:02:50 gklug
+ * fix: read PHY_STAT of Broadcom chip more often to assure good status
+ *
+ * Revision 1.48 1999/12/06 10:01:17 cgoos
+ * Added SET function for Role.
+ *
+ * Revision 1.47 1999/11/22 13:34:24 cgoos
+ * Changed license header to GPL.
+ *
X * Revision 1.46 1999/09/16 10:30:07 cgoos
X * Removed debugging output statement from Linux.
X *
@@ -215,7 +241,7 @@
X
X */
X static const char SysKonnectFileId[] =
- "$Id: skgesirq.c,v 1.46 1999/09/16 10:30:07 cgoos Exp $" ;
+ "$Id: skgesirq.c,v 1.55 2000/06/19 08:36:25 cgoos Exp $" ;
X
X #include "h/skdrv1st.h" /* Driver Specific Definitions */
X #include "h/skgepnmi.h" /* PNMI Definitions */
@@ -385,6 +411,15 @@
X /* disable all PHY interrupts */
X switch (pAC->GIni.GP[Port].PhyType) {
X case SK_PHY_BCOM:
+ /* make sure that PHY is initialized */
+ if (pAC->GIni.GP[Port].PState) {
+ /* Workaround BCOM Errata (#10523) all BCom */
+ /* Disable Power Management if link is down */
+ PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL,
+ &Word);
+ PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL,
+ Word | PHY_B_AC_DIS_PM);
+ }
X PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_INT_MASK,
X 0xffff);
X break;
@@ -766,12 +801,11 @@
X }
X
X /*
- * I2C Ready interrupt
+ * external reg interrupt
X */
- if (Istatus & IS_I2C_READY) {
+ if (Istatus & IS_EXT_REG) {
X SK_U16 PhyInt;
X SK_U16 PhyIMsk;
- SK_BOOL IsPhyInt = SK_FALSE;
X int i;
X /* test IRQs from PHY */
X for (i=0; i<pAC->GIni.GIMacsFound; i++) {
@@ -794,7 +828,6 @@
X SkPhyIsrBcom(pAC, IoC, i,
X (SK_U16)
X (PhyInt & (~PhyIMsk)));
- IsPhyInt = SK_TRUE;
X }
X }
X else {
@@ -814,7 +847,6 @@
X i, PhyInt, PhyIMsk));
X SkPhyIsrLone(pAC, IoC, i,
X (SK_U16) (PhyInt & PhyIMsk));
- IsPhyInt = SK_TRUE;
X }
X break;
X case SK_PHY_NAT:
@@ -822,9 +854,13 @@
X break;
X }
X }
- if (!IsPhyInt) {
- SkI2cIsr(pAC, IoC);
- }
+ }
+
+ /*
+ * I2C Ready interrupt
+ */
+ if (Istatus & IS_I2C_READY) {
+ SkI2cIsr(pAC, IoC);
X }
X
X if (Istatus & IS_LNK_SYNC_M1) {
@@ -1328,8 +1364,23 @@
X SK_U16 PhyStat; /* Phy Status Register */
X int Done;
X SK_U16 ResAb;
+ SK_U16 SWord;
X
X pPrt = &pAC->GIni.GP[Port];
+
+ /* Check for No HCD Link events (#10523) */
+ PHY_READ(IoC, pPrt, Port, PHY_BCOM_INT_STAT, &Isrc);
+ if ((Isrc & PHY_B_IS_NO_HDCL) == PHY_B_IS_NO_HDCL) {
+
+ /* Workaround BCOM Errata */
+ /* enable and disable Loopback mode if NO HCD occurs */
+ PHY_READ(IoC, pPrt, Port, PHY_BCOM_CTRL, &SWord);
+ PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_CTRL, SWord | PHY_CT_LOOP);
+ PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_CTRL, SWord & ~PHY_CT_LOOP);
+ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+ ("No HCD Link event, Port %d\n", Port));
+ }
+
X PHY_READ(IoC, pPrt, Port, PHY_BCOM_STAT, &PhyStat);
X
X if (pPrt->PHWLinkUp) {
@@ -1338,7 +1389,7 @@
X
X pPrt->PIsave = 0;
X
- /* Now wait for each ports link */
+ /* Now wait for each port's link */
X if (pPrt->PLinkMode == SK_LMODE_HALF ||
X pPrt->PLinkMode == SK_LMODE_FULL) {
X AutoNeg = SK_FALSE;
@@ -1355,13 +1406,43 @@
X PHY_READ(IoC, pPrt, Port, PHY_BCOM_STAT, &PhyStat);
X
X SkXmAutoNegLipaBcom(pAC, IoC, Port, PhyStat);
- if ((PhyStat & PHY_ST_LSYNC) == 0){
- return(SK_HW_PS_NONE) ;
+
+ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+ ("AutoNeg:%d, PhyStat: %Xh.\n", AutoNeg, PhyStat));
+
+ PHY_READ(IoC, pPrt, Port, PHY_BCOM_1000T_STAT, &ResAb);
+
+ if ((PhyStat & PHY_ST_LSYNC) == 0) {
+ if (ResAb & (PHY_B_1000S_MSF)) {
+ /* Error */
+ SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
+ ("Master/Slave Fault port %d\n", Port));
+ pPrt->PAutoNegFail = SK_TRUE;
+ pPrt->PMSStatus = SK_MS_STAT_FAULT;
+ return (SK_AND_OTHER);
+ }
+ return (SK_HW_PS_NONE);
+ }
+
+ if (ResAb & (PHY_B_1000S_MSF)) {
+ /* Error */
+ SK_DBG_MSG(pAC,SK_DBGMOD_HWM,SK_DBGCAT_CTRL,
+ ("Master/Slave Fault port %d\n", Port));
+ pPrt->PAutoNegFail = SK_TRUE;
+ pPrt->PMSStatus = SK_MS_STAT_FAULT;
+ return (SK_AND_OTHER);
+ } else if (ResAb & PHY_B_1000S_MSR) {
+ pPrt->PMSStatus = SK_MS_STAT_MASTER;
+ } else {
+ pPrt->PMSStatus = SK_MS_STAT_SLAVE;
X }
+
+ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL,
+ ("AutoNeg:%d, PhyStat: %Xh.\n", AutoNeg, PhyStat));
X
X if (AutoNeg) {
X if (PhyStat & PHY_ST_AN_OVER) {
- SkHWLinkUp(pAC, IoC, Port) ;
+ SkHWLinkUp(pAC, IoC, Port);
X Done = SkXmAutoNegDone(pAC,IoC,Port);
X if (Done != SK_AND_OK) {
X /* Get PHY parameters, for debuging only */
@@ -1400,6 +1481,8 @@
X Port));
X }
X #endif
+
+#if 0
X PHY_READ(IoC, pPrt, Port, PHY_BCOM_1000T_STAT, &ResAb);
X if (ResAb & (PHY_B_1000S_MSF)) {
X /* Error */
@@ -1413,6 +1496,7 @@
X } else {
X pPrt->PMSStatus = SK_MS_STAT_SLAVE ;
X }
+#endif /* 0 */
X
X
X /*
@@ -1753,6 +1837,18 @@
X if (pAC->GIni.GP[Port].PFlowCtrlMode != Val8) {
X /* Set New Flow Control mode */
X pAC->GIni.GP[Port].PFlowCtrlMode = Val8;
+
+ /* Restart Port */
+ SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
+ SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
+ }
+ break;
+
+ case SK_HWEV_SET_ROLE:
+ Val8 = (SK_U8) Para.Para32[1];
+ if (pAC->GIni.GP[Port].PMSMode != Val8) {
+ /* Set New link mode */
+ pAC->GIni.GP[Port].PMSMode = Val8;
X
X /* Restart Port */
X SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/ski2c.c linux/drivers/net/sk98lin/ski2c.c
--- v2.4.0-test8/linux/drivers/net/sk98lin/ski2c.c Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/ski2c.c Fri Sep 15 14:34:19 2000
@@ -2,8 +2,8 @@
X *
X * Name: ski2c.c
X * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.41 $
- * Date: $Date: 1999/09/14 14:11:30 $
+ * Version: $Revision: 1.44 $
+ * Date: $Date: 2000/08/07 15:49:03 $
X * Purpose: Funktions to access Voltage and Temperature Sensor
X * (taken from Monalisa (taken from Concentrator))
X *
@@ -11,11 +11,9 @@
X
X /******************************************************************************
X *
- * (C)Copyright 1998,1999 SysKonnect,
+ * (C)Copyright 1998-2000 SysKonnect,
X * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
X *
- * See the file "skge.c" for further information.
- *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
X * the Free Software Foundation; either version 2 of the License, or
@@ -30,6 +28,16 @@
X * History:
X *
X * $Log: ski2c.c,v $
+ * Revision 1.44 2000/08/07 15:49:03 gklug
+ * fix: SK_INFAST only in NetWare driver
+ *
+ * Revision 1.43 2000/08/03 14:28:17 rassmann
+ * - Added function to wait for I2C being ready before resetting the board.
+ * - Replaced one duplicate "out of range" message with correct one.
+ *
+ * Revision 1.42 1999/11/22 13:35:12 cgoos
+ * Changed license header to GPL.
+ *
X * Revision 1.41 1999/09/14 14:11:30 malthoff
X * The 1000BT Dual Link adapter has got only one Fan.
X * The second Fan has been removed.
@@ -172,10 +180,10 @@
X
X
X /*
- i2C Protocol
+ I2C Protocol
X */
X static const char SysKonnectFileId[] =
- "$Id: ski2c.c,v 1.41 1999/09/14 14:11:30 malthoff Exp $" ;
+ "$Id: ski2c.c,v 1.44 2000/08/07 15:49:03 gklug Exp $";
X
X #include "h/skdrv1st.h" /* Driver Specific Definitions */
X #include "h/lm80.h"
@@ -193,9 +201,9 @@
X This file covers functions that allow to read write and do
X some bulk requests a specified I2C address.
X
- The Genesis has 2 I2C busses. One for the EEPROM which holds
+ The Genesis has 2 I2C buses. One for the EEPROM which holds
X the VPD Data and one for temperature and voltage sensor.
- The following picture shows the I2C busses, I2C devices and
+ The following picture shows the I2C buses, I2C devices and
X there control registers.
X
X Note: The VPD functions are in skvpd.c
@@ -292,13 +300,13 @@
X * serial data line simultaneously (ASIC: last bit of a byte = '1', I2C client
X * send an 'ACK'). See also Concentrator Bugreport No. 10192.
X */
-#define I2C_DATA_HIGH(IoC) SK_I2C_SET_BIT(IoC,I2C_DATA)
-#define I2C_DATA_LOW(IoC) SK_I2C_CLR_BIT(IoC,I2C_DATA)
-#define I2C_DATA_OUT(IoC) SK_I2C_SET_BIT(IoC,I2C_DATA_DIR)
-#define I2C_DATA_IN(IoC) SK_I2C_CLR_BIT(IoC,I2C_DATA_DIR|I2C_DATA)
-#define I2C_CLK_HIGH(IoC) SK_I2C_SET_BIT(IoC,I2C_CLK)
-#define I2C_CLK_LOW(IoC) SK_I2C_CLR_BIT(IoC,I2C_CLK|I2C_DATA_DIR)
-#define I2C_START_COND(IoC) SK_I2C_CLR_BIT(IoC,I2C_CLK)
+#define I2C_DATA_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA)
+#define I2C_DATA_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA)
+#define I2C_DATA_OUT(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA_DIR)
+#define I2C_DATA_IN(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR|I2C_DATA)
+#define I2C_CLK_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_CLK)
+#define I2C_CLK_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK|I2C_DATA_DIR)
+#define I2C_START_COND(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK)
X
X #define NS2CLKT(x) ((x*125L)/10000)
X
@@ -308,25 +316,24 @@
X * sending one bit
X */
X void SkI2cSndBit(
-SK_IOC IoC, /* IoContext */
+SK_IOC IoC, /* I/O Context */
X SK_U8 Bit) /* Bit to send */
X {
- I2C_DATA_OUT(IoC) ;
+ I2C_DATA_OUT(IoC);
X if (Bit) {
X I2C_DATA_HIGH(IoC);
X } else {
X I2C_DATA_LOW(IoC);
X }
- SkDgWaitTime(IoC,NS2BCLK(T_DATA_IN_SETUP));
+ SkDgWaitTime(IoC, NS2BCLK(T_DATA_IN_SETUP));
X I2C_CLK_HIGH(IoC);
- SkDgWaitTime(IoC,NS2BCLK(T_CLK_HIGH));
+ SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
X I2C_CLK_LOW(IoC);
-}
-
+} /* SkI2cSndBit*/
X
X
X /*
- * Signal a start to the i2C Bus.
+ * Signal a start to the I2C Bus.
X *
X * A start is signaled when data goes to low in a high clock cycle.
X *
@@ -334,66 +341,70 @@
X *
X * Status: not tested
X */
-void SkI2cStart(SK_IOC IoC) /* I/O Context */
+void SkI2cStart(
+SK_IOC IoC) /* I/O Context */
X {
X /* Init data and Clock to output lines */
X /* Set Data high */
- I2C_DATA_OUT(IoC) ;
- I2C_DATA_HIGH(IoC) ;
+ I2C_DATA_OUT(IoC);
+ I2C_DATA_HIGH(IoC);
X /* Set Clock high */
- I2C_CLK_HIGH(IoC) ;
+ I2C_CLK_HIGH(IoC);
X
- SkDgWaitTime(IoC,NS2BCLK(T_START_SETUP)) ;
+ SkDgWaitTime(IoC, NS2BCLK(T_START_SETUP));
X
X /* Set Data Low */
- I2C_DATA_LOW(IoC) ;
+ I2C_DATA_LOW(IoC);
X
- SkDgWaitTime(IoC,NS2BCLK(T_START_HOLD)) ;
+ SkDgWaitTime(IoC, NS2BCLK(T_START_HOLD));
X
X /* Clock low without Data to Input */
- I2C_START_COND(IoC) ;
+ I2C_START_COND(IoC);
X
- SkDgWaitTime(IoC,NS2BCLK(T_CLK_LOW)) ;
-}
+ SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW));
+} /* SkI2cStart */
X
X
-void SkI2cStop(SK_IOC IoC) /* I/O Context */
+void SkI2cStop(
+SK_IOC IoC) /* I/O Context */
X {
X /* Init data and Clock to output lines */
X /* Set Data low */
- I2C_DATA_OUT(IoC) ;
- I2C_DATA_LOW(IoC) ;
+ I2C_DATA_OUT(IoC);
+ I2C_DATA_LOW(IoC);
X
- SkDgWaitTime(IoC,NS2BCLK(T_CLK_2_DATA_OUT)) ;
+ SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
X
X /* Set Clock high */
- I2C_CLK_HIGH(IoC) ;
+ I2C_CLK_HIGH(IoC);
X
- SkDgWaitTime(IoC,NS2BCLK(T_STOP_SETUP)) ;
+ SkDgWaitTime(IoC, NS2BCLK(T_STOP_SETUP));
X
X /*
X * Set Data High: Do it by setting the Data Line to Input.
X * Because of a pull up resistor the Data Line
X * floods to high.
X */
- I2C_DATA_IN(IoC) ;
+ I2C_DATA_IN(IoC);
X
X /*
X * When I2C activity is stopped
X * o DATA should be set to input and
X * o CLOCK should be set to high!
X */
- SkDgWaitTime(IoC,NS2BCLK(T_BUS_IDLE)) ;
-}
+ SkDgWaitTime(IoC, NS2BCLK(T_BUS_IDLE));
+} /* SkI2cStop */
+
X
X /*
- * Receive just one bit via the i2C bus.
+ * Receive just one bit via the I2C bus.
X *
X * Note: Clock must be set to LOW before calling this function.
X *
X * Returns The received bit.
X */
-int SkI2cRcvBit(SK_IOC IoC) /* I/O Context */
+int SkI2cRcvBit(
+SK_IOC IoC) /* I/O Context */
X {
X int Bit;
X SK_U8 I2cSwCtrl;
@@ -401,13 +412,13 @@
X /* Init data as input line */
X I2C_DATA_IN(IoC);
X
- SkDgWaitTime(IoC,NS2BCLK(T_CLK_2_DATA_OUT)) ;
+ SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
X
X I2C_CLK_HIGH(IoC);
X
- SkDgWaitTime(IoC,NS2BCLK(T_CLK_HIGH)) ;
+ SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
X
- SK_I2C_GET_SW(IoC,&I2cSwCtrl) ;
+ SK_I2C_GET_SW(IoC, &I2cSwCtrl);
X if (I2cSwCtrl & I2C_DATA) {
X Bit = 1;
X } else {
@@ -415,10 +426,11 @@
X }
X
X I2C_CLK_LOW(IoC);
- SkDgWaitTime(IoC,NS2BCLK(T_CLK_LOW-T_CLK_2_DATA_OUT)) ;
+ SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW-T_CLK_2_DATA_OUT));
X
X return(Bit);
-}
+} /* SkI2cRcvBit */
+
X
X /*
X * Receive an ACK.
@@ -426,58 +438,64 @@
X * returns 0 If acknoledged
X * 1 in case of an error
X */
-int SkI2cRcvAck(SK_IOC IoC) /* I/O Context */
+int SkI2cRcvAck(
+SK_IOC IoC) /* I/O Context */
X {
X /*
X * Received bit must be zero.
X */
- return (SkI2cRcvBit(IoC) != 0) ;
-}
+ return (SkI2cRcvBit(IoC) != 0);
+} /* SkI2cRcvAck */
+
X
X /*
X * Send an NACK.
X */
-void SkI2cSndNAck(SK_IOC IoC) /* I/O Context */
+void SkI2cSndNAck(
+SK_IOC IoC) /* I/O Context */
X {
X /*
X * Received bit must be zero.
X */
- SkI2cSndBit(IoC,1) ;
-}
+ SkI2cSndBit(IoC, 1);
+} /* SkI2cSndNAck */
+
X
X /*
X * Send an ACK.
X */
-void SkI2cSndAck(SK_IOC IoC) /* I/O Context */
+void SkI2cSndAck(
+SK_IOC IoC) /* I/O Context */
X {
X /*
X * Received bit must be zero.
X *
X */
- SkI2cSndBit(IoC,0) ;
-}
+ SkI2cSndBit(IoC, 0);
+} /* SkI2cSndAck */
+
X
X /*
- * Send one byte to the i2C device and wait for ACK.
+ * Send one byte to the I2C device and wait for ACK.
X *
X * Return acknoleged status.
X */
X int SkI2cSndByte(
X SK_IOC IoC, /* I/O Context */
-int Byte) /* byte to send */
+int Byte) /* byte to send */
X {
X int i;
X
X for (i=0; i<8; i++) {
X if (Byte & (1<<(7-i))) {
- SkI2cSndBit(IoC,1) ;
+ SkI2cSndBit(IoC, 1);
X } else {
- SkI2cSndBit(IoC,0) ;
+ SkI2cSndBit(IoC, 0);
X }
X }
X
- return(SkI2cRcvAck(IoC)) ;
-}
+ return(SkI2cRcvAck(IoC));
+} /* SkI2cSndByte */
X
X
X /*
@@ -487,24 +505,24 @@
X */
X int SkI2cRcvByte(
X SK_IOC IoC, /* I/O Context */
-int Last) /* Last Byte Flag */
+int Last) /* Last Byte Flag */
X {
X int i;
X int Byte = 0;
X
X for (i=0; i<8; i++) {
- Byte <<= 1 ;
- Byte |= SkI2cRcvBit(IoC) ;
+ Byte <<= 1;
+ Byte |= SkI2cRcvBit(IoC);
X }
X
X if (Last) {
- SkI2cSndNAck(IoC) ;
+ SkI2cSndNAck(IoC);
X } else {
- SkI2cSndAck(IoC) ;
+ SkI2cSndAck(IoC);
X }
X
- return(Byte) ;
-}
+ return(Byte);
+} /* SkI2cRcvByte */
X
X
X /*
@@ -514,68 +532,106 @@
X */
X int SkI2cSndDev(
X SK_IOC IoC, /* I/O Context */
-int Addr, /* Device Address */
-int Rw) /* Read / Write Flag */
+int Addr, /* Device Address */
+int Rw) /* Read / Write Flag */
X {
- SkI2cStart(IoC) ;
- Rw = ~Rw ;
- Rw &= I2C_WRITE ;
- return(SkI2cSndByte(IoC, (Addr<<1) | Rw)) ;
-}
+ SkI2cStart(IoC);
+ Rw = ~Rw;
+ Rw &= I2C_WRITE;
+ return(SkI2cSndByte(IoC, (Addr<<1) | Rw));
+} /* SkI2cSndDev */
X
X #endif /* SK_DIAG */
X
X /*----------------- I2C CTRL Register Functions ----------*/
X
X /*
- * waits for a completetion of a I2C transfer
+ * waits for a completion of an I2C transfer
X *
X * returns 0: success, transfer completes
- * 1: error, transfer does not complete, I2C transfer
- * killed, wait loop terminated.
+ * 1: error, transfer does not complete, I2C transfer
+ * killed, wait loop terminated.
X */
X int SkI2cWait(
X SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* IoContext */
-int Event) /* complete event to wait for (I2C_READ or I2C_WRITE) */
+SK_IOC IoC, /* I/O Context */
+int Event) /* complete event to wait for (I2C_READ or I2C_WRITE) */
+{
+ SK_U64 StartTime;
+ SK_U32 I2cCtrl;
+
+ StartTime = SkOsGetTime(pAC);
+ do {
+ if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) {
+ SK_I2C_STOP(IoC);
+#ifndef SK_DIAG
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG);
+#endif /* !SK_DIAG */
+ return(1);
+ }
+ SK_I2C_GET_CTL(IoC, &I2cCtrl);
+ } while ((I2cCtrl & I2C_FLAG) == (SK_U32)Event << 31);
+
+ return(0);
+} /* SkI2cWait */
+
+
+/*
+ * waits for a completion of an I2C transfer
+ *
+ * Returns
+ * Nothing
+ */
+void SkI2cWaitIrq(
+SK_AC *pAC, /* Adapter Context */
+SK_IOC IoC) /* I/O Context */
X {
- SK_U64 StartTime ;
- SK_U32 I2cCtrl ;
+ SK_SENSOR *pSen;
+ SK_U64 StartTime;
+ SK_U32 IrqSrc;
X
- StartTime = SkOsGetTime(pAC) ;
+ pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
+
+ if (pSen->SenState == SK_SEN_IDLE) {
+ return;
+ }
+
+ StartTime = SkOsGetTime(pAC);
X do {
- if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC/16) {
- SK_I2C_STOP(IoC) ;
+ if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) {
+ SK_I2C_STOP(IoC);
X #ifndef SK_DIAG
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002,
- SKERR_I2C_E002MSG) ;
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG);
X #endif /* !SK_DIAG */
- return(1) ;
+ return;
X }
- SK_I2C_GET_CTL(IoC,&I2cCtrl) ;
- } while((I2cCtrl & I2C_FLAG) == (SK_U32)Event << 31) ;
+ SK_IN32(pAC, B0_ISRC, &IrqSrc);
+ } while ((IrqSrc & IS_I2C_READY) == 0);
X
- return(0) ;
-}
+ return;
+} /* SkI2cWaitIrq */
X
X #ifdef SK_DIAG
+
X /*
X * writes a single byte or 4 bytes into the I2C device
X *
X * returns 0: success
- * 1: error
+ * 1: error
X */
X int SkI2cWrite(
-SK_AC *pAC, /* Adapter Context */
+SK_AC *pAC, /* Adapter Context */
+SK_IOC IoC, /* I/O Context */
X SK_U32 I2cData, /* I2C Data to write */
-int I2cDev, /* I2C Device Address */
-int I2cReg, /* I2C Device Register Address */
-int I2cBurst) /* I2C Burst Flag ( 0 || I2C_BURST ) */
-{
- SK_OUT32(pAC,B2_I2C_DATA,I2cData) ;
- SK_I2C_CTL(pAC,I2C_WRITE,I2cDev,I2cReg,I2cBurst);
- return(SkI2cWait(pAC,pAC,I2C_WRITE)) ;
-}
+int I2cDev, /* I2C Device Address */
+int I2cReg, /* I2C Device Register Address */
+int I2cBurst) /* I2C Burst Flag ( 0 || I2C_BURST ) */
+{
+ SK_OUT32(IoC, B2_I2C_DATA, I2cData);
+ SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cReg, I2cBurst);
+ return(SkI2cWait(pAC, IoC, I2C_WRITE));
+} /* SkI2cWrite*/
+
X
X /*
X * reads a single byte or 4 bytes from the I2C device
@@ -583,39 +639,42 @@
X * returns the word read
X */
X SK_U32 SkI2cRead(
-SK_AC *pAC, /* Adapter Context */
-int I2cDev, /* I2C Device Address */
-int I2cReg, /* I2C Device Register Address */
-int I2cBurst) /* I2C Burst Flag ( 0 || I2C_BURST ) */
-{
- SK_U32 Data ;
-
- SK_OUT32(pAC,B2_I2C_DATA,0) ;
- SK_I2C_CTL(pAC,I2C_READ,I2cDev,I2cReg,I2cBurst);
- if (SkI2cWait(pAC,pAC,I2C_READ)) {
- w_print("I2c Transfer Timeout!\n");
- }
- SK_IN32(pAC,B2_I2C_DATA,&Data) ;
- return(Data) ;
-}
+SK_AC *pAC, /* Adapter Context */
+SK_IOC IoC, /* I/O Context */
+int I2cDev, /* I2C Device Address */
+int I2cReg, /* I2C Device Register Address */
+int I2cBurst) /* I2C Burst Flag ( 0 || I2C_BURST ) */
+{
+ SK_U32 Data;
+
+ SK_OUT32(IoC, B2_I2C_DATA, 0);
+ SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cReg, I2cBurst);
+ if (SkI2cWait(pAC, IoC, I2C_READ)) {
+ w_print("I2C Transfer Timeout!\n");
+ }
+ SK_IN32(IoC, B2_I2C_DATA, &Data);
+ return(Data);
+} /* SkI2cRead */
+
X #endif /* SK_DIAG */
X
+
X /*
- * read a sensors value
+ * read a sensor's value
X *
- * This function read a sensors value from the I2c sensor chip. The sensor
+ * This function read a sensors value from the I2C sensor chip. The sensor
X * is defined by its index into the sensors database in the struct pAC points
X * to.
X * Returns 1 if the read is completed
- * 0 if the read must be continued (I2c Bus still allocated)
+ * 0 if the read must be continued (I2C Bus still allocated)
X */
X int SkI2cReadSensor(
X SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* IoContext */
+SK_IOC IoC, /* I/O Context */
X SK_SENSOR *pSen) /* Sensor to be read */
X {
- return((*pSen->SenRead)(pAC,IoC,pSen)) ;
-}
+ return((*pSen->SenRead)(pAC, IoC, pSen));
+} /* SkI2cReadSensor*/
X
X /*
X * Do the Init state 0 initialization
@@ -639,7 +698,7 @@
X for (i=0; i < SK_MAX_SENSORS; i ++) {
X switch (i) {
X case 0:
- pAC->I2c.SenTable[i].SenDesc = "Temperature" ;
+ pAC->I2c.SenTable[i].SenDesc = "Temperature";
X pAC->I2c.SenTable[i].SenType = SK_SEN_TEMP;
X pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_ERRHIGH0;
X pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_ERRLOW0;
@@ -733,10 +792,11 @@
X pAC->I2c.SenTable[i].SenDev = LM80_ADDR;
X }
X
- /* Now we are INIT dataed */
+ /* Now we are "INIT data"ed */
X pAC->I2c.InitLevel = SK_INIT_DATA;
X return(0);
-}
+} /* SkI2cInit0*/
+
X
X /*
X * Do the init state 1 initialization
@@ -760,7 +820,7 @@
X */
X static int SkI2cInit1(
X SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC) /* IoContext needed in level 1 */
+SK_IOC IoC) /* I/O Context */
X {
X if (pAC->I2c.InitLevel != SK_INIT_DATA) {
X /* ReInit not needed in I2C module */
@@ -769,27 +829,27 @@
X
X SK_OUT32(IoC, B2_I2C_DATA, 0);
X SK_I2C_CTL(IoC, I2C_WRITE, LM80_ADDR, LM80_CFG, 0);
- (void)SkI2cWait(pAC, IoC, I2C_WRITE) ;
+ (void)SkI2cWait(pAC, IoC, I2C_WRITE);
X
X SK_OUT32(IoC, B2_I2C_DATA, 0xff);
X SK_I2C_CTL(IoC, I2C_WRITE, LM80_ADDR, LM80_IMSK_1, 0);
- (void)SkI2cWait(pAC, IoC, I2C_WRITE) ;
+ (void)SkI2cWait(pAC, IoC, I2C_WRITE);
X
X SK_OUT32(IoC, B2_I2C_DATA, 0xff);
X SK_I2C_CTL(IoC, I2C_WRITE, LM80_ADDR, LM80_IMSK_2, 0);
- (void)SkI2cWait(pAC, IoC, I2C_WRITE) ;
+ (void)SkI2cWait(pAC, IoC, I2C_WRITE);
X
X SK_OUT32(IoC, B2_I2C_DATA, 0x0);
X SK_I2C_CTL(IoC, I2C_WRITE, LM80_ADDR, LM80_FAN_CTRL, 0);
- (void)SkI2cWait(pAC, IoC, I2C_WRITE) ;
+ (void)SkI2cWait(pAC, IoC, I2C_WRITE);
X
X SK_OUT32(IoC, B2_I2C_DATA, 0);
X SK_I2C_CTL(IoC, I2C_WRITE, LM80_ADDR, LM80_TEMP_CTRL, 0);
- (void)SkI2cWait(pAC, IoC, I2C_WRITE) ;
+ (void)SkI2cWait(pAC, IoC, I2C_WRITE);
X
X SK_OUT32(IoC, B2_I2C_DATA, LM80_CFG_START);
X SK_I2C_CTL(IoC, I2C_WRITE, LM80_ADDR, LM80_CFG, 0);
- (void)SkI2cWait(pAC, IoC, I2C_WRITE) ;
+ (void)SkI2cWait(pAC, IoC, I2C_WRITE);
X
X /*
X * MaxSens has to be initialized here, because PhyType is not
@@ -820,14 +880,15 @@
X /* Now we are IO initialized */
X pAC->I2c.InitLevel = SK_INIT_IO;
X return(0);
-}
+} /* SkI2cInit1 */
+
X
X /*
X * Init level 2: Start first sensors read
X */
X static int SkI2cInit2(
X SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC) /* IoContext needed in level 1 */
+SK_IOC IoC) /* I/O Context */
X {
X int ReadComplete;
X SK_SENSOR *pSen;
@@ -839,18 +900,18 @@
X }
X
X pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
- ReadComplete = SkI2cReadSensor(pAC,IoC,pSen);
+ ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
X
X if (ReadComplete) {
- SK_ERR_LOG(pAC, SK_ERRCL_INIT, SKERR_I2C_E008,
- SKERR_I2C_E008MSG);
+ SK_ERR_LOG(pAC, SK_ERRCL_INIT, SKERR_I2C_E008, SKERR_I2C_E008MSG);
X }
X
X /* Now we are correctly initialized */
X pAC->I2c.InitLevel = SK_INIT_RUN;
X
X return(0);
-}
+} /* SkI2cInit2*/
+
X
X /*
X * Initialize I2C devices
@@ -871,27 +932,29 @@
X */
X int SkI2cInit(
X SK_AC *pAC, /* Adapter Context */
-SK_IOC IoC, /* IoContext needed in level 1 */
-int Level) /* Init Level */
+SK_IOC IoC, /* I/O Context needed in levels 1 and 2 */
+int Level) /* Init Level */
X {
X
X switch (Level) {
X case SK_INIT_DATA:
- return(SkI2cInit0(pAC)) ;
+ return(SkI2cInit0(pAC));
X case SK_INIT_IO:
- return(SkI2cInit1(pAC, IoC)) ;
+ return(SkI2cInit1(pAC, IoC));
X case SK_INIT_RUN:
- return(SkI2cInit2(pAC, IoC)) ;
+ return(SkI2cInit2(pAC, IoC));
X default:
X break;
X }
X
- return(0) ;
-}
+ return(0);
+} /* SkI2cInit */
+
X
X #ifndef SK_DIAG
+
X /*
- * Interrupt service function for the I2c Interface
+ * Interrupt service function for the I2C Interface
X *
X * Clears the Interrupt source
X *
@@ -900,23 +963,24 @@
X * Starts the timer if necessary.
X */
X void SkI2cIsr(
-SK_AC *pAC, /* Adapters context */
-SK_IOC IoC) /* Io Context */
+SK_AC *pAC, /* Adapter Context */
+SK_IOC IoC) /* I/O Context */
X {
X SK_EVPARA Para;
X
X /* Clear the interrupt source */
- SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ) ;
+ SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
X
X Para.Para64 = 0;
X SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_IRQ, Para);
-}
+} /* SkI2cIsr */
+
X
X /*
X * Check this sensors Value against the threshold and send events.
X */
X static void SkI2cCheckSensor(
-SK_AC *pAC, /* Adapters context */
+SK_AC *pAC, /* Adapter Context */
X SK_SENSOR *pSen)
X {
X SK_EVPARA ParaLocal;
@@ -929,12 +993,12 @@
X
X /* Check Dummy Reads first */
X if (pAC->I2c.DummyReads > 0) {
- pAC->I2c.DummyReads -- ;
+ pAC->I2c.DummyReads --;
X return;
X }
X
X /* Get the current time */
- CurrTime = SkOsGetTime(pAC) ;
+ CurrTime = SkOsGetTime(pAC);
X
X /* Set para to the most usefull setting:
X * The current sensor.
@@ -943,17 +1007,17 @@
X
X /* Check the Value against the thresholds */
X /* First: Error Thresholds */
- TooHigh = (pSen->SenValue > pSen->SenThreErrHigh) ;
- TooLow = (pSen->SenValue < pSen->SenThreErrLow) ;
+ TooHigh = (pSen->SenValue > pSen->SenThreErrHigh);
+ TooLow = (pSen->SenValue < pSen->SenThreErrLow);
X
- IsError = SK_FALSE ;
+ IsError = SK_FALSE;
X if (TooHigh || TooLow) {
- /* Error condition is satiesfied */
+ /* Error condition is satisfied */
X DoTrapSend = SK_TRUE;
X DoErrLog = SK_TRUE;
X
X /* Now error condition is satisfied */
- IsError = SK_TRUE ;
+ IsError = SK_TRUE;
X
X if (pSen->SenErrFlag == SK_SEN_ERR_ERR) {
X /* This state is the former one */
@@ -981,7 +1045,7 @@
X /* We came from a different state */
X /* -> Set Begin Time Stamp */
X pSen->SenBegErrTS = CurrTime;
- pSen->SenErrFlag = SK_SEN_ERR_ERR ;
+ pSen->SenErrFlag = SK_SEN_ERR_ERR;
X }
X
X if (DoTrapSend) {
@@ -993,7 +1057,7 @@
X SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
X SK_PNMI_EVT_SEN_ERR_UPP :
X SK_PNMI_EVT_SEN_ERR_LOW),
- ParaLocal) ;
+ ParaLocal);
X }
X
X if (DoErrLog) {
@@ -1016,12 +1080,12 @@
X
X /* Check the Value against the thresholds */
X /* 2nd: Warning thresholds */
- TooHigh = (pSen->SenValue > pSen->SenThreWarnHigh) ;
- TooLow = (pSen->SenValue < pSen->SenThreWarnLow) ;
+ TooHigh = (pSen->SenValue > pSen->SenThreWarnHigh);
+ TooLow = (pSen->SenValue < pSen->SenThreWarnLow);
X
X
X if (!IsError && (TooHigh || TooLow)) {
- /* Error condition is satiesfied */
+ /* Error condition is satisfied */
X DoTrapSend = SK_TRUE;
X DoErrLog = SK_TRUE;
X
@@ -1051,7 +1115,7 @@
X /* We came from a different state */
X /* -> Set Begin Time Stamp */
X pSen->SenBegWarnTS = CurrTime;
- pSen->SenErrFlag = SK_SEN_ERR_WARN ;
+ pSen->SenErrFlag = SK_SEN_ERR_WARN;
X }
X
X if (DoTrapSend) {
@@ -1063,7 +1127,7 @@
X SkEventQueue(pAC, SKGE_PNMI, (TooHigh ?
X SK_PNMI_EVT_SEN_WAR_UPP :
X SK_PNMI_EVT_SEN_WAR_LOW),
- ParaLocal) ;
+ ParaLocal);
X }
X
X if (DoErrLog) {
@@ -1074,8 +1138,8 @@
X SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009,
X SKERR_I2C_E009MSG);
X } else if (pSen->SenType == SK_SEN_VOLT) {
- SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009,
- SKERR_I2C_E009MSG);
+ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010,
+ SKERR_I2C_E010MSG);
X } else
X {
X SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014,
@@ -1087,7 +1151,7 @@
X /* Check for NO error at all */
X if (!IsError && !TooHigh && !TooLow) {
X /* Set o.k. Status if no error and no warning condition */
- pSen->SenErrFlag = SK_SEN_ERR_OK ;
+ pSen->SenErrFlag = SK_SEN_ERR_OK;
X }
X
X /* End of check against the thresholds */
@@ -1115,17 +1179,18 @@
X if (!pSen->SenInit) {
X SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG);
X }
-}
+} /* SkI2cCheckSensor*/
+
X
X /*
X * The only Event to be served is the timeout event
X *
X */
X int SkI2cEvent(
-SK_AC *pAC, /* Adapters context */
-SK_IOC IoC, /* Io Context */
-SK_U32 Event, /* Module specific Event */
-SK_EVPARA Para) /* Event specific Parameter */
+SK_AC *pAC, /* Adapter Context */
+SK_IOC IoC, /* I/O Context */
+SK_U32 Event, /* Module specific Event */
+SK_EVPARA Para) /* Event specific Parameter */
X {
X int ReadComplete;
X SK_SENSOR *pSen;
@@ -1141,7 +1206,7 @@
X
X if (ReadComplete) {
X /* Check sensor against defined thresholds */
- SkI2cCheckSensor (pAC, pSen) ;
+ SkI2cCheckSensor (pAC, pSen);
X
X /* Increment Current and set appropriate Timeout */
X Time = SK_I2C_TIM_SHORT;
@@ -1155,7 +1220,7 @@
X /* Start Timer */
X ParaLocal.Para64 = (SK_U64) 0;
X SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
- SKGE_I2C, SK_I2CEV_TIM, ParaLocal) ;
+ SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
X }
X break;
X case SK_I2CEV_CLEAR:
@@ -1176,6 +1241,6 @@
X }
X
X return(0);
-}
-#endif /* !SK_DIAG */
-/* End of File */
+} /* SkI2cEvent*/
+
+#endif /* !SK_DIAG */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/sklm80.c linux/drivers/net/sk98lin/sklm80.c
--- v2.4.0-test8/linux/drivers/net/sk98lin/sklm80.c Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/sklm80.c Fri Sep 15 14:34:19 2000
@@ -2,8 +2,8 @@
X *
X * Name: sklm80.c
X * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.16 $
- * Date: $Date: 1999/05/27 14:05:47 $
+ * Version: $Revision: 1.17 $
+ * Date: $Date: 1999/11/22 13:35:51 $
X * Purpose: Funktions to access Voltage and Temperature Sensor (LM80)
X *
X ******************************************************************************/
@@ -13,8 +13,6 @@
X * (C)Copyright 1998,1999 SysKonnect,
X * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
X *
- * See the file "skge.c" for further information.
- *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
X * the Free Software Foundation; either version 2 of the License, or
@@ -29,6 +27,9 @@
X * History:
X *
X * $Log: sklm80.c,v $
+ * Revision 1.17 1999/11/22 13:35:51 cgoos
+ * Changed license header to GPL.
+ *
X * Revision 1.16 1999/05/27 14:05:47 malthoff
X * Fans: Set SenVal to 0 if the fan value is 0 or 0xff. Both values
X * are outside the limits (0: div zero error, 0xff: value not in
@@ -92,7 +93,7 @@
X LM80 functions
X */
X static const char SysKonnectFileId[] =
- "$Id: sklm80.c,v 1.16 1999/05/27 14:05:47 malthoff Exp $" ;
+ "$Id: sklm80.c,v 1.17 1999/11/22 13:35:51 cgoos Exp $" ;
X
X #include "h/skdrv1st.h" /* Driver Specific Definitions */
X #include "h/lm80.h"
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/skqueue.c linux/drivers/net/sk98lin/skqueue.c
--- v2.4.0-test8/linux/drivers/net/sk98lin/skqueue.c Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/skqueue.c Fri Sep 15 14:34:19 2000
@@ -2,8 +2,8 @@
X *
X * Name: skqueue.c
X * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.14 $
- * Date: $Date: 1998/10/15 15:11:35 $
+ * Version: $Revision: 1.15 $
+ * Date: $Date: 1999/11/22 13:36:29 $
X * Purpose: Management of an event queue.
X *
X ******************************************************************************/
@@ -13,8 +13,6 @@
X * (C)Copyright 1998,1999 SysKonnect,
X * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
X *
- * See the file "skge.c" for further information.
- *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
X * the Free Software Foundation; either version 2 of the License, or
@@ -29,6 +27,9 @@
X * History:
X *
X * $Log: skqueue.c,v $
+ * Revision 1.15 1999/11/22 13:36:29 cgoos
+ * Changed license header to GPL.
+ *
X * Revision 1.14 1998/10/15 15:11:35 gklug
X * fix: ID_sccs to SysKonnectFileId
X *
@@ -81,7 +82,7 @@
X Event queue and dispatcher
X */
X static const char SysKonnectFileId[] =
- "$Header: /usr56/projects/ge/schedule/skqueue.c,v 1.14 1998/10/15 15:11:35 gklug Exp $" ;
+ "$Header: /usr56/projects/ge/schedule/skqueue.c,v 1.15 1999/11/22 13:36:29 cgoos Exp $" ;
X
X #include "h/skdrv1st.h" /* Driver Specific Definitions */
X #include "h/skqueue.h" /* Queue Definitions */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/skrlmt.c linux/drivers/net/sk98lin/skrlmt.c
--- v2.4.0-test8/linux/drivers/net/sk98lin/skrlmt.c Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/skrlmt.c Fri Sep 15 14:34:19 2000
@@ -2,8 +2,8 @@
X *
X * Name: skrlmt.c
X * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.48 $
- * Date: $Date: 1999/10/04 14:01:17 $
+ * Version: $Revision: 1.49 $
+ * Date: $Date: 1999/11/22 13:38:02 $
X * Purpose: Manage links on SK-NET Adapters, esp. redundant ones.
X *
X ******************************************************************************/
@@ -13,8 +13,6 @@
X * (C)Copyright 1998,1999 SysKonnect,
X * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
X *
- * See the file "skge.c" for further information.
- *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
X * the Free Software Foundation; either version 2 of the License, or
@@ -29,6 +27,10 @@
X * History:
X *
X * $Log: skrlmt.c,v $
+ * Revision 1.49 1999/11/22 13:38:02 cgoos
+ * Changed license header to GPL.
+ * Added initialization to some variables to avoid compiler warnings.
+ *
X * Revision 1.48 1999/10/04 14:01:17 rassmann


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 067'
echo 'File patch-2.4.0-test9 is continued in part 068'
echo "068" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part065

#!/bin/sh -x
# this is part 065 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 065; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

X status = mdio_read(net_dev, sis_priv->cur_phy, MII_STATUS);

@@ -721,6 +768,12 @@
X /* link stat change from ON to OFF */
X next_tick = HZ;
X sis_priv->LinkOn = FALSE;
+


+ /* Equalizer workaroung Rule */
+ pci_read_config_byte(sis_priv->pci_dev, PCI_CLASS_REVISION, &revision);
+ if (revision == SIS630E_REV || revision == SIS630EA1_REV)
+ sis630e_set_eq(net_dev);
+

X printk(KERN_INFO "%s: Media Link Off\n",
X net_dev->name);
X }
@@ -736,6 +789,12 @@
X /* link stat change forn OFF to ON, read and report link mode */
X sis_priv->LinkOn = TRUE;
X next_tick = 5*HZ;
+


+ /* Equalizer workaroung Rule */
+ pci_read_config_byte(sis_priv->pci_dev, PCI_CLASS_REVISION, &revision);
+ if (revision == SIS630E_REV || revision == SIS630EA1_REV)
+ sis630e_set_eq(net_dev);
+

X /* change what cur_phy means */
X if (mii_phy->phy_addr != sis_priv->cur_phy) {
X printk(KERN_INFO "%s: Changing transceiver to %s\n",
@@ -856,6 +915,37 @@
X printk(KERN_INFO "%s: Media Link Off\n", net_dev->name);
X }
X }
+/* ICS1893 PHY use Quick Poll Detailed Status Register to get its status */


+static void ics1893_read_mode(struct net_device *net_dev, int phy_addr, int *speed, int *duplex)

+{
+ int i = 0;

+ u32 status;
+
+ /* MII_QPDSTS is Latched, read twice in succession will reflect the current state */
+ for (i = 0; i < 2; i++)
+ status = mdio_read(net_dev, phy_addr, MII_QPDSTS);
+
+ if (status & MII_STSICS_SPD)
+ *speed = HW_SPEED_100_MBPS;
+ else
+ *speed = HW_SPEED_10_MBPS;
+
+ if (status & MII_STSICS_DPLX)
+ *duplex = FDX_CAPABLE_FULL_SELECTED;
+ else
+ *duplex = FDX_CAPABLE_HALF_SELECTED;
+
+ if (status & MII_STSICS_LINKSTS)
+ printk(KERN_INFO "%s: Media Link On %s %s-duplex \n",
+ net_dev->name,
+ *speed == HW_SPEED_100_MBPS ?
+ "100mbps" : "10mbps",
+ *duplex == FDX_CAPABLE_FULL_SELECTED ?
+ "full" : "half");
+ else
+ printk(KERN_INFO "%s: Media Link Off\n", net_dev->name);
+}
+
X static void sis900_tx_timeout(struct net_device *net_dev)


X {
X struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sis900.h linux/drivers/net/sis900.h
--- v2.4.0-test8/linux/drivers/net/sis900.h Wed Aug 9 14:24:09 2000
+++ linux/drivers/net/sis900.h Tue Sep 19 08:31:27 2000
@@ -165,7 +165,13 @@
X /* mii registers specific to SiS 900 */
X enum sis_mii_registers {
X MII_CONFIG1 = 0x0010, MII_CONFIG2 = 0x0011, MII_STSOUT = 0x0012,
- MII_MASK = 0x0013
+ MII_MASK = 0x0013, MII_RESV = 0x0014
+};
+
+/* mii registers specific to ICS 1893 */
+enum ics_mii_registers {
+ MII_EXTCTRL = 0x0010, MII_QPDSTS = 0x0011, MII_10BTOP = 0x0012,
+ MII_EXTCTRL2 = 0x0013
X };
X
X /* mii registers specific to AMD 79C901 */
@@ -212,13 +218,19 @@
X MII_STSOUT_SPD = 0x0080, MII_STSOUT_DPLX = 0x0040
X };
X
+enum mii_stsics_register_bits {
+ MII_STSICS_SPD = 0x8000, MII_STSICS_DPLX = 0x4000,
+ MII_STSICS_LINKSTS = 0x0001
+};
+
X enum mii_stssum_register_bits {
X MII_STSSUM_LINK = 0x0008, MII_STSSUM_DPLX = 0x0004,
X MII_STSSUM_AUTO = 0x0002, MII_STSSUM_SPD = 0x0001
X };
X
X enum sis630_revision_id {
- SIS630E_REV = 0x81, SIS630EA1_REV = 0x83
+ SIS630E_REV = 0x81, SIS630EA1_REV = 0x83,
+ SIS630S_REV = 0x82
X };
X
X #define FDX_CAPABLE_DUPLEX_UNKNOWN 0
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/h/lm80.h linux/drivers/net/sk98lin/h/lm80.h
--- v2.4.0-test8/linux/drivers/net/sk98lin/h/lm80.h Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/h/lm80.h Fri Sep 15 14:34:19 2000


@@ -2,8 +2,8 @@
X *

X * Name: lm80.h

X * Project: GEnesis, PCI Gigabit Ethernet Adapter

- * Version: $Revision: 1.2 $
- * Date: $Date: 1999/03/12 13:26:51 $
+ * Version: $Revision: 1.3 $
+ * Date: $Date: 1999/11/22 13:41:19 $
X * Purpose: Contains all defines for the LM80 Chip
X * (National Semiconductor).
X *
@@ -27,6 +27,9 @@
X *
X * History:
X * $Log: lm80.h,v $
+ * Revision 1.3 1999/11/22 13:41:19 cgoos


+ * Changed license header to GPL.
+ *

X * Revision 1.2 1999/03/12 13:26:51 malthoff
X * remove __STDC__.
X *
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/h/skaddr.h linux/drivers/net/sk98lin/h/skaddr.h
--- v2.4.0-test8/linux/drivers/net/sk98lin/h/skaddr.h Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/h/skaddr.h Fri Sep 15 14:34:19 2000
@@ -2,15 +2,15 @@
X *
X * Name: skaddr.h


X * Project: GEnesis, PCI Gigabit Ethernet Adapter

- * Version: $Revision: 1.19 $
- * Date: $Date: 1999/05/28 10:56:07 $
- * Purpose: Header file for Address Management (MC, UC, Prom)
+ * Version: $Revision: 1.23 $
+ * Date: $Date: 2000/08/10 11:27:50 $
+ * Purpose: Header file for Address Management (MC, UC, Prom).
X *
X ******************************************************************************/


X
X /******************************************************************************
X *
- * (C)Copyright 1998,1999 SysKonnect,
+ * (C)Copyright 1998-2000 SysKonnect,
X * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
X *

X * This program is free software; you can redistribute it and/or modify

@@ -27,6 +27,21 @@


X * History:
X *

X * $Log: skaddr.h,v $
+ * Revision 1.23 2000/08/10 11:27:50 rassmann
+ * Editorial changes.
+ * Preserving 32-bit alignment in structs for the adapter context.
+ *
+ * Revision 1.22 2000/08/07 11:10:40 rassmann
+ * Editorial changes.
+ *
+ * Revision 1.21 2000/05/04 09:39:59 rassmann
+ * Editorial changes.
+ * Corrected multicast address hashing.
+ *
+ * Revision 1.20 1999/11/22 13:46:14 cgoos


+ * Changed license header to GPL.

+ * Allowing overwrite for SK_ADDR_EQUAL.
+ *
X * Revision 1.19 1999/05/28 10:56:07 rassmann
X * Editorial changes.
X *
@@ -115,32 +130,33 @@
X #define __INC_SKADDR_H
X
X #ifdef __cplusplus
-xxxx /* not supported yet - force error */
+#error C++ is not yet supported.
X extern "C" {
X #endif /* cplusplus */
X
X /* defines ********************************************************************/
X
-#define SK_MAC_ADDR_LEN 6 /* Length of MAC address. */
-#define SK_MAX_ADDRS 14 /* #Addrs for exact match. */
+#define SK_MAC_ADDR_LEN 6 /* Length of MAC address. */
+#define SK_MAX_ADDRS 14 /* #Addrs for exact match. */
X
X /* ----- Common return values ----- */
X
-#define SK_ADDR_SUCCESS 0 /* Function returned successfully. */
-#define SK_ADDR_ILLEGAL_PORT 100 /* Port number too high. */
-#define SK_ADDR_TOO_EARLY 101 /* Function called too early. */
+#define SK_ADDR_SUCCESS 0 /* Function returned successfully. */
+#define SK_ADDR_ILLEGAL_PORT 100 /* Port number too high. */
+#define SK_ADDR_TOO_EARLY 101 /* Function called too early. */
X
X /* ----- Clear/Add flag bits ----- */
X
-#define SK_ADDR_PERMANENT 1 /* RLMT Address */
+#define SK_ADDR_PERMANENT 1 /* RLMT Address */
X
X /* ----- Additional Clear flag bits ----- */
X
-#define SK_MC_SW_ONLY 2 /* Do not update HW when clearing. */
+#define SK_MC_SW_ONLY 2 /* Do not update HW when clearing. */
X
X /* ----- Override flag bits ----- */
X
-#define SK_ADDR_VIRTUAL_ADDRESS 0
+#define SK_ADDR_LOGICAL_ADDRESS 0
+#define SK_ADDR_VIRTUAL_ADDRESS (SK_ADDR_LOGICAL_ADDRESS) /* old */
X #define SK_ADDR_PHYSICAL_ADDRESS 1
X
X /* ----- Override return values ----- */
@@ -151,7 +167,7 @@
X
X /* ----- Partitioning of excact match table ----- */
X
-#define SK_ADDR_EXACT_MATCHES 16 /* #Exact match entries. */
+#define SK_ADDR_EXACT_MATCHES 16 /* #Exact match entries. */
X
X #define SK_ADDR_FIRST_MATCH_RLMT 1
X #define SK_ADDR_LAST_MATCH_RLMT 2
@@ -160,21 +176,21 @@
X
X /* ----- SkAddrMcAdd/SkAddrMcUpdate return values ----- */
X
-#define SK_MC_FILTERING_EXACT 0 /* Exact filtering. */
-#define SK_MC_FILTERING_INEXACT 1 /* Inexact filtering. */
+#define SK_MC_FILTERING_EXACT 0 /* Exact filtering. */
+#define SK_MC_FILTERING_INEXACT 1 /* Inexact filtering. */
X
X /* ----- Additional SkAddrMcAdd return values ----- */
X
-#define SK_MC_ILLEGAL_ADDRESS 2 /* Illegal address. */
-#define SK_MC_ILLEGAL_PORT 3 /* Illegal port (not the active one). */
-#define SK_MC_RLMT_OVERFLOW 4 /* Too many RLMT mc addresses. */
+#define SK_MC_ILLEGAL_ADDRESS 2 /* Illegal address. */
+#define SK_MC_ILLEGAL_PORT 3 /* Illegal port (not the active one). */
+#define SK_MC_RLMT_OVERFLOW 4 /* Too many RLMT mc addresses. */
X
X /* Promiscuous mode bits ----- */
X
-#define SK_PROM_MODE_NONE 0 /* Normal receive. */
-#define SK_PROM_MODE_LLC 1 /* Receive all LLC frames. */
-#define SK_PROM_MODE_ALL_MC 2 /* Receive all multicast frames. */
-/* #define SK_PROM_MODE_NON_LLC 4 */ /* Receive all non-LLC frames. */
+#define SK_PROM_MODE_NONE 0 /* Normal receive. */
+#define SK_PROM_MODE_LLC 1 /* Receive all LLC frames. */
+#define SK_PROM_MODE_ALL_MC 2 /* Receive all multicast frames. */
+/* #define SK_PROM_MODE_NON_LLC 4 */ /* Receive all non-LLC frames. */
X
X /* Macros */
X
@@ -192,7 +208,7 @@
X *(SK_U32 *)&(((SK_U8 *)(A1))[2]) == *(SK_U32 *)&(((SK_U8 *)(A2))[2]) && \
X *(SK_U32 *)&(((SK_U8 *)(A1))[0]) == *(SK_U32 *)&(((SK_U8 *)(A2))[0]))
X #endif /* SK_ADDR_DWORD_COMPARE */
-#endif /* SK_ADDR_EQUAL */
+#endif /* SK_ADDR_EQUAL */
X
X /* typedefs *******************************************************************/
X
@@ -203,27 +219,28 @@
X /* SK_FILTER is used to ensure alignment of the filter. */
X typedef union s_InexactFilter {
X SK_U8 Bytes[8];
- SK_U64 Val; /* Dummy entry for alignment only. */
+ SK_U64 Val; /* Dummy entry for alignment only. */
X } SK_FILTER64;
X
X typedef struct s_AddrPort {
X
X /* ----- Public part (read-only) ----- */
X
- SK_MAC_ADDR PermanentMacAddress; /* Physical MAC Address. */
- SK_MAC_ADDR CurrentMacAddress; /* Physical MAC Address. */
- int PromMode; /* Promiscuous Mode. */
+ SK_MAC_ADDR CurrentMacAddress; /* Current physical MAC Address. */
+ SK_MAC_ADDR PermanentMacAddress; /* Permanent physical MAC Address. */
+ int PromMode; /* Promiscuous Mode. */
X
X /* ----- Private part ----- */
X
+ SK_MAC_ADDR PreviousMacAddress; /* Prev. phys. MAC Address. */
X SK_BOOL CurrentMacAddressSet; /* CurrentMacAddress is set. */
- SK_MAC_ADDR PreviousMacAddress; /* Prev. phys. MAC Address. */
+ SK_U8 Align01;
X SK_U32 FirstExactMatchRlmt;
X SK_U32 NextExactMatchRlmt;
X SK_U32 FirstExactMatchDrv;
X SK_U32 NextExactMatchDrv;
X SK_MAC_ADDR Exact[SK_ADDR_EXACT_MATCHES];
- SK_FILTER64 InexactFilter; /* For 64-bit hash register. */
+ SK_FILTER64 InexactFilter; /* For 64-bit hash register. */
X } SK_ADDR_PORT;
X
X typedef struct s_Addr {
@@ -232,22 +249,21 @@
X
X SK_ADDR_PORT Port[SK_MAX_MACS];
X SK_MAC_ADDR PermanentMacAddress; /* Logical MAC Address. */
- SK_MAC_ADDR CurrentMacAddress; /* Logical MAC Address. */
+ SK_MAC_ADDR CurrentMacAddress; /* Logical MAC Address. */
X
X /* ----- Private part ----- */
X
-#if 0
- SK_BOOL Initialized; /* Flag: Addr module is initialized. */
-#endif /* 0 */
+ SK_U32 ActivePort; /* View of module ADDR. */
X SK_BOOL CurrentMacAddressSet; /* CurrentMacAddress is set. */
- SK_U32 ActivePort; /* Vie of module ADDR. */
+ SK_U8 Align01;
+ SK_U16 Align02;
X } SK_ADDR;
X
X /* function prototypes ********************************************************/
X
X #ifndef SK_KR_PROTO
X
-/* Functions provided by SkRlmt */
+/* Functions provided by SkAddr */
X
X /* ANSI/C++ compliant function prototypes */


X
@@ -297,7 +313,7 @@
X

X /* Non-ANSI/C++ compliant function prototypes */
X
-xxxx /* not supported yet - force error */
+#error KR-style prototypes are not yet provided.
X
X #endif /* defined(SK_KR_PROTO)) */
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/h/skcsum.h linux/drivers/net/sk98lin/h/skcsum.h
--- v2.4.0-test8/linux/drivers/net/sk98lin/h/skcsum.h Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/h/skcsum.h Fri Sep 15 14:34:19 2000
@@ -1,9 +1,9 @@
X /******************************************************************************
X *
X * Name: skcsum.h
- * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.2 $
- * Date: $Date: 1998/09/04 12:16:34 $
+ * Project: GEnesis - SysKonnect SK-NET Gigabit Ethernet (SK-98xx)
+ * Version: $Revision: 1.7 $
+ * Date: $Date: 2000/06/29 13:17:05 $
X * Purpose: Store/verify Internet checksum in send/receive packets.
X *
X ******************************************************************************/
@@ -27,6 +27,25 @@


X * History:
X *

X * $Log: skcsum.h,v $
+ * Revision 1.7 2000/06/29 13:17:05 rassmann
+ * Corrected reception of a packet with UDP checksum == 0 (which means there
+ * is no UDP checksum).
+ *
+ * Revision 1.6 2000/02/28 12:33:44 cgoos
+ * Changed C++ style comments to C style.
+ *
+ * Revision 1.5 2000/02/21 12:10:05 cgoos
+ * Fixed license comment.
+ *
+ * Revision 1.4 2000/02/21 11:08:37 cgoos
+ * Merged changes back into common source.
+ *
+ * Revision 1.1 1999/07/26 14:47:49 mkarl
+ * changed from common source to windows specific source
+ * added return SKCS_STATUS_IP_CSUM_ERROR_UDP and
+ * SKCS_STATUS_IP_CSUM_ERROR_TCP to pass the NidsTester
+ * changes for Tx csum offload
+ *
X * Revision 1.2 1998/09/04 12:16:34 mhaveman
X * Checked in for Stephan to allow compilation.
X * -Added definition SK_CSUM_EVENT_CLEAR_PROTO_STATS to clear statistic
@@ -98,24 +117,32 @@
X *
X * SKCS_STATUS_UNKNOWN_IP_VERSION - Not an IP v4 frame.
X * SKCS_STATUS_IP_CSUM_ERROR - IP checksum error.
+ * SKCS_STATUS_IP_CSUM_ERROR_TCP - IP checksum error in TCP frame.
+ * SKCS_STATUS_IP_CSUM_ERROR_UDP - IP checksum error in UDP frame
X * SKCS_STATUS_IP_FRAGMENT - IP fragment (IP checksum ok).
X * SKCS_STATUS_IP_CSUM_OK - IP checksum ok (not a TCP or UDP frame).
X * SKCS_STATUS_TCP_CSUM_ERROR - TCP checksum error (IP checksum ok).
X * SKCS_STATUS_UDP_CSUM_ERROR - UDP checksum error (IP checksum ok).
X * SKCS_STATUS_TCP_CSUM_OK - IP and TCP checksum ok.
X * SKCS_STATUS_UDP_CSUM_OK - IP and UDP checksum ok.
+ * SKCS_STATUS_IP_CSUM_OK_NO_UDP - IP checksum OK and no UDP checksum.
X */
X #ifndef SKCS_OVERWRITE_STATUS /* User overwrite? */
X #define SKCS_STATUS int /* Define status type. */
X
X #define SKCS_STATUS_UNKNOWN_IP_VERSION 1
-#define SKCS_STATUS_IP_CSUM_ERROR 2
-#define SKCS_STATUS_IP_FRAGMENT 3
-#define SKCS_STATUS_IP_CSUM_OK 4
-#define SKCS_STATUS_TCP_CSUM_ERROR 5
-#define SKCS_STATUS_UDP_CSUM_ERROR 6
-#define SKCS_STATUS_TCP_CSUM_OK 7
-#define SKCS_STATUS_UDP_CSUM_OK 8
+#define SKCS_STATUS_IP_CSUM_ERROR 2
+#define SKCS_STATUS_IP_FRAGMENT 3
+#define SKCS_STATUS_IP_CSUM_OK 4
+#define SKCS_STATUS_TCP_CSUM_ERROR 5
+#define SKCS_STATUS_UDP_CSUM_ERROR 6
+#define SKCS_STATUS_TCP_CSUM_OK 7
+#define SKCS_STATUS_UDP_CSUM_OK 8
+/* needed for Microsoft */
+#define SKCS_STATUS_IP_CSUM_ERROR_UDP 9
+#define SKCS_STATUS_IP_CSUM_ERROR_TCP 10
+/* UDP checksum may be omitted */
+#define SKCS_STATUS_IP_CSUM_OK_NO_UDP 11
X #endif /* !SKCS_OVERWRITE_STATUS */
X
X /* Clear protocol statistics event. */
@@ -158,7 +185,7 @@
X SK_U64 RxUnableCts; /* Unable to verify receive checksum. */
X SK_U64 RxErrCts; /* Receive checksum error. */
X SK_U64 TxOkCts; /* Transmit checksum ok. */
- SK_U64 TxUnableCts; /* Unable to verify transmit checksum. */
+ SK_U64 TxUnableCts; /* Unable to calculate checksum in hw. */
X } SKCS_PROTO_STATS;
X
X /*
@@ -167,6 +194,9 @@
X typedef struct s_Csum {
X /* Enabled receive SK_PROTO_XXX bit flags. */
X unsigned ReceiveFlags;
+#ifdef TX_CSUM
+ unsigned TransmitFlags;
+#endif /* TX_CSUM */
X
X /* The protocol statistics structure; one per supported protocol. */
X SKCS_PROTO_STATS ProtoStats[SKCS_NUM_PROTOCOLS];
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/h/skdebug.h linux/drivers/net/sk98lin/h/skdebug.h
--- v2.4.0-test8/linux/drivers/net/sk98lin/h/skdebug.h Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/h/skdebug.h Fri Sep 15 14:34:19 2000


@@ -2,8 +2,8 @@
X *

X * Name: skdebug.h


X * Project: GEnesis, PCI Gigabit Ethernet Adapter

- * Version: $Revision: 1.9 $
- * Date: $Date: 1999/09/14 14:02:43 $
+ * Version: $Revision: 1.10 $
+ * Date: $Date: 1999/11/22 13:47:40 $
X * Purpose: SK specific DEBUG support
X *
X ******************************************************************************/
@@ -26,6 +26,9 @@
X *
X * History:
X * $Log: skdebug.h,v $
+ * Revision 1.10 1999/11/22 13:47:40 cgoos


+ * Changed license header to GPL.
+ *

X * Revision 1.9 1999/09/14 14:02:43 rwahl
X * Added SK_DBGMOD_PECP.
X *
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/h/skdrv1st.h linux/drivers/net/sk98lin/h/skdrv1st.h
--- v2.4.0-test8/linux/drivers/net/sk98lin/h/skdrv1st.h Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/h/skdrv1st.h Fri Sep 15 14:34:19 2000


@@ -2,8 +2,8 @@
X *

X * Name: skdrv1st.h


X * Project: GEnesis, PCI Gigabit Ethernet Adapter

- * Version: $Revision: 1.6 $
- * Date: $Date: 1999/07/27 08:03:33 $
+ * Version: $Revision: 1.8 $
+ * Date: $Date: 2000/02/21 12:19:18 $
X * Purpose: First header file for driver and all other modules
X *
X ******************************************************************************/
@@ -27,6 +27,15 @@


X * History:
X *

X * $Log: skdrv1st.h,v $
+ * Revision 1.8 2000/02/21 12:19:18 cgoos
+ * Added default for SK_DEBUG_CHKMOD/_CHKCAT
+ *
+ * Revision 1.7 1999/11/22 13:50:00 cgoos


+ * Changed license header to GPL.

+ * Added overwrite for several functions.
+ * Removed linux 2.0.x definitions.
+ * Removed PCI vendor ID definition (now in kernel).
+ *
X * Revision 1.6 1999/07/27 08:03:33 cgoos
X * Changed SK_IN/OUT macros to readX/writeX instead of memory
X * accesses (necessary for ALPHA).
@@ -175,6 +184,12 @@
X
X #ifdef DEBUG
X #define SK_DBG_PRINTF printk
+#ifndef SK_DEBUG_CHKMOD
+#define SK_DEBUG_CHKMOD 0
+#endif
+#ifndef SK_DEBUG_CHKCAT
+#define SK_DEBUG_CHKCAT 0
+#endif
X /* those come from the makefile */
X #define SK_DBG_CHKMOD(pAC) (SK_DEBUG_CHKMOD)
X #define SK_DBG_CHKCAT(pAC) (SK_DEBUG_CHKCAT)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/h/skerror.h linux/drivers/net/sk98lin/h/skerror.h
--- v2.4.0-test8/linux/drivers/net/sk98lin/h/skerror.h Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/h/skerror.h Fri Sep 15 14:34:19 2000


@@ -2,8 +2,8 @@
X *

X * Name: skerror.h


X * Project: GEnesis, PCI Gigabit Ethernet Adapter

- * Version: $Revision: 1.3 $
- * Date: $Date: 1999/09/14 14:04:42 $
+ * Version: $Revision: 1.4 $
+ * Date: $Date: 1999/11/22 13:51:59 $
X * Purpose: SK specific Error log support
X *
X ******************************************************************************/
@@ -26,6 +26,9 @@
X *
X * History:
X * $Log: skerror.h,v $
+ * Revision 1.4 1999/11/22 13:51:59 cgoos


+ * Changed license header to GPL.
+ *

X * Revision 1.3 1999/09/14 14:04:42 rwahl
X * Added error base SK_ERRBASE_PECP.
X * Changed error base for driver.
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/h/skgedrv.h linux/drivers/net/sk98lin/h/skgedrv.h
--- v2.4.0-test8/linux/drivers/net/sk98lin/h/skgedrv.h Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/h/skgedrv.h Fri Sep 15 14:34:19 2000


@@ -2,8 +2,8 @@
X *

X * Name: skgedrv.h


X * Project: GEnesis, PCI Gigabit Ethernet Adapter

- * Version: $Revision: 1.3 $
- * Date: $Date: 1998/12/01 13:31:39 $
+ * Version: $Revision: 1.4 $
+ * Date: $Date: 1999/11/22 13:52:46 $
X * Purpose: Interface with the driver
X *
X ******************************************************************************/
@@ -27,6 +27,9 @@


X * History:
X *

X * $Log: skgedrv.h,v $
+ * Revision 1.4 1999/11/22 13:52:46 cgoos


+ * Changed license header to GPL.
+ *

X * Revision 1.3 1998/12/01 13:31:39 cgoos
X * SWITCH INTERN Event added.
X *
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/h/skgehw.h linux/drivers/net/sk98lin/h/skgehw.h
--- v2.4.0-test8/linux/drivers/net/sk98lin/h/skgehw.h Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/h/skgehw.h Fri Sep 15 14:34:19 2000


@@ -2,8 +2,8 @@
X *

X * Name: skgehw.h


X * Project: GEnesis, PCI Gigabit Ethernet Adapter

- * Version: $Revision: 1.33 $
- * Date: $Date: 1999/08/27 11:17:10 $
+ * Version: $Revision: 1.35 $
+ * Date: $Date: 2000/05/19 10:17:13 $
X * Purpose: Defines and Macros for the Gigabit Ethernet Adapter Product
X * Family
X *
@@ -27,6 +27,12 @@
X *
X * History:
X * $Log: skgehw.h,v $
+ * Revision 1.35 2000/05/19 10:17:13 cgoos
+ * Added inactivity check in PHY_READ (in DEBUG mode only).
+ *
+ * Revision 1.34 1999/11/22 13:53:40 cgoos


+ * Changed license header to GPL.
+ *

X * Revision 1.33 1999/08/27 11:17:10 malthoff
X * It's more savely to put bracket around marco parameters.
X * Brackets added for PHY_READ and PHY_WRITE.
@@ -1627,19 +1633,44 @@
X * written.
X *
X * usage: PHY_READ(IoC, pPort, MAC_1, PHY_CTRL, Value);
+ * Warning: a PHY_READ on an uninitialized PHY (PHY still in reset) never
+ * comes back. This is checked in DEBUG mode.
X */
+#ifndef DEBUG
+#define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) { \
+ SK_U16 Mmu; \
+ \
+ XM_OUT16((IoC),(Mac), XM_PHY_ADDR, (PhyReg)|(pPort)->PhyAddr); \
+ XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \
+ if ((pPort)->PhyType != SK_PHY_XMAC) { \
+ do { \
+ XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \
+ } while ((Mmu & XM_MMU_PHY_RDY) == 0); \
+ XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \
+ } \
+}
+#else
X #define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) { \
X SK_U16 Mmu; \
+ int __i = 0; \
X \
X XM_OUT16((IoC),(Mac), XM_PHY_ADDR, (PhyReg)|(pPort)->PhyAddr); \
X XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \
X if ((pPort)->PhyType != SK_PHY_XMAC) { \
X do { \
X XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \
+ __i++; \
+ if (__i > 10000) { \
+ SK_DBG_PRINTF("*****************************\n"); \
+ SK_DBG_PRINTF("PHY_READ on uninitialized PHY\n"); \
+ SK_DBG_PRINTF("*****************************\n"); \
+ break; \
+ } \
X } while ((Mmu & XM_MMU_PHY_RDY) == 0); \
X XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \
X } \
X }
+#endif
X
X #define PHY_WRITE(IoC, pPort, Mac, PhyReg, Val) { \
X SK_U16 Mmu; \
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/h/skgehwt.h linux/drivers/net/sk98lin/h/skgehwt.h
--- v2.4.0-test8/linux/drivers/net/sk98lin/h/skgehwt.h Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/h/skgehwt.h Fri Sep 15 14:34:19 2000


@@ -2,8 +2,8 @@
X *

X * Name: skhwt.h


X * Project: GEnesis, PCI Gigabit Ethernet Adapter

- * Version: $Revision: 1.4 $
- * Date: $Date: 1998/08/19 09:50:58 $
+ * Version: $Revision: 1.5 $
+ * Date: $Date: 1999/11/22 13:54:24 $
X * Purpose: Defines for the hardware timer functions
X *
X ******************************************************************************/
@@ -27,6 +27,9 @@


X * History:
X *

X * $Log: skgehwt.h,v $
+ * Revision 1.5 1999/11/22 13:54:24 cgoos


+ * Changed license header to GPL.
+ *

X * Revision 1.4 1998/08/19 09:50:58 gklug
X * fix: remove struct keyword from c-code (see CCC) add typedefs
X *
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/h/skgei2c.h linux/drivers/net/sk98lin/h/skgei2c.h
--- v2.4.0-test8/linux/drivers/net/sk98lin/h/skgei2c.h Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/h/skgei2c.h Fri Sep 15 14:34:19 2000


@@ -2,8 +2,8 @@
X *

X * Name: skgei2c.h


X * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.16 $

- * Date: $Date: 1999/11/12 08:24:10 $


+ * Version: $Revision: 1.17 $

+ * Date: $Date: 1999/11/22 13:55:25 $
X * Purpose: Special genesis defines for I2C


X * (taken from Monalisa (taken from Concentrator))
X *

@@ -28,6 +28,9 @@


X * History:
X *

X * $Log: skgei2c.h,v $
+ * Revision 1.17 1999/11/22 13:55:25 cgoos


+ * Changed license header to GPL.
+ *

X * Revision 1.16 1999/11/12 08:24:10 malthoff
X * Change voltage warning and error limits
X * (warning +-5%, error +-10%).
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/h/skgeinit.h linux/drivers/net/sk98lin/h/skgeinit.h
--- v2.4.0-test8/linux/drivers/net/sk98lin/h/skgeinit.h Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/h/skgeinit.h Fri Sep 15 14:34:19 2000
@@ -2,15 +2,15 @@
X *
X * Name: skgeinit.h


X * Project: GEnesis, PCI Gigabit Ethernet Adapter

- * Version: $Revision: 1.44 $
- * Date: $Date: 1999/10/26 07:34:15 $
+ * Version: $Revision: 1.46 $
+ * Date: $Date: 2000/08/10 11:28:00 $
X * Purpose: Structures and prototypes for the GE Init Module
X *
X ******************************************************************************/


X
X /******************************************************************************
X *
- * (C)Copyright 1998,1999 SysKonnect,
+ * (C)Copyright 1998-2000 SysKonnect,
X * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
X *

X * This program is free software; you can redistribute it and/or modify

@@ -27,6 +27,13 @@


X * History:
X *

X * $Log: skgeinit.h,v $
+ * Revision 1.46 2000/08/10 11:28:00 rassmann
+ * Editorial changes.
+ * Preserving 32-bit alignment in structs for the adapter context.
+ *
+ * Revision 1.45 1999/11/22 13:56:19 cgoos


+ * Changed license header to GPL.
+ *

X * Revision 1.44 1999/10/26 07:34:15 malthoff
X * The define SK_LNK_ON has been lost in v1.41.
X *
@@ -443,61 +450,63 @@
X SK_TIMER PWaTimer; /* Workaround Timer */
X #endif
X SK_U64 PPrevShorts; /* Previous short Counter checking */
- SK_U64 PPrevRx; /* Previous RxOk Counter checking */
- SK_U64 PPrevFcs; /* Previous FCS Error Counter checking */
- SK_U64 PRxLim; /* Previous RxOk Counter checking */
- int PLinkResCt; /* Link Restart Counter */
- int PAutoNegTimeOut;/* AutoNegotiation timeout current value */
- int PRxQSize; /* Port Rx Queue Size in kB */
- int PXSQSize; /* Port Synchronous Transmit Queue Size in kB */
- int PXAQSize; /* Port Asynchronous Transmit Queue Size in kB*/
+ SK_U64 PPrevRx; /* Previous RxOk Counter checking */
+ SK_U64 PPrevFcs; /* Previous FCS Error Counter checking */
+ SK_U64 PRxLim; /* Previous RxOk Counter checking */
+ int PLinkResCt; /* Link Restart Counter */
+ int PAutoNegTimeOut;/* AutoNegotiation timeout current value */
+ int PRxQSize; /* Port Rx Queue Size in kB */
+ int PXSQSize; /* Port Synchronous Transmit Queue Size in kB */
+ int PXAQSize; /* Port Asynchronous Transmit Queue Size in kB*/
X SK_U32 PRxQRamStart; /* Receive Queue RAM Buffer Start Address */
- SK_U32 PRxQRamEnd; /* Receive Queue RAM Buffer End Address */
+ SK_U32 PRxQRamEnd; /* Receive Queue RAM Buffer End Address */
X SK_U32 PXsQRamStart; /* Sync Tx Queue RAM Buffer Start Address */
- SK_U32 PXsQRamEnd; /* Sync Tx Queue RAM Buffer End Address */
+ SK_U32 PXsQRamEnd; /* Sync Tx Queue RAM Buffer End Address */
X SK_U32 PXaQRamStart; /* Async Tx Queue RAM Buffer Start Address */
- SK_U32 PXaQRamEnd; /* Async Tx Queue RAM Buffer End Address */
- int PRxQOff; /* Rx Queue Address Offset */
- int PXsQOff; /* Synchronous Tx Queue Address Offset */
- int PXaQOff; /* Asynchronous Tx Queue Address Offset */
- SK_U16 PRxCmd; /* Port Receive Command Configuration Value */
- SK_U16 PIsave; /* Saved Interrupt status word */
- SK_U16 PSsave; /* Saved PHY status word */
- SK_BOOL PHWLinkUp; /* The hardware Link is up (wireing) */
- SK_BOOL PState; /* Is port initialized ? */
+ SK_U32 PXaQRamEnd; /* Async Tx Queue RAM Buffer End Address */
+ int PRxQOff; /* Rx Queue Address Offset */
+ int PXsQOff; /* Synchronous Tx Queue Address Offset */
+ int PXaQOff; /* Asynchronous Tx Queue Address Offset */
+ SK_U16 PRxCmd; /* Port Receive Command Configuration Value */
+ SK_U16 PIsave; /* Saved Interrupt status word */
+ SK_U16 PSsave; /* Saved PHY status word */
+ SK_BOOL PHWLinkUp; /* The hardware Link is up (wireing) */
+ SK_BOOL PState; /* Is port initialized ? */
X SK_BOOL PLinkBroken; /* Is Link broken ? */
- SK_BOOL PCheckPar; /* Do we check for parity errors ? */
- SK_U8 PLinkCap; /* Link Capabilities */
+ SK_BOOL PCheckPar; /* Do we check for parity errors ? */
+ SK_U8 PLinkCap; /* Link Capabilities */
X SK_U8 PLinkModeConf; /* Link Mode configured */
- SK_U8 PLinkMode; /* Link Mode currently used */
- SK_U8 PLinkModeStatus; /* Link Mode Status */
+ SK_U8 PLinkMode; /* Link Mode currently used */
+ SK_U8 PLinkModeStatus;/* Link Mode Status */
X SK_U8 PFlowCtrlCap; /* Flow Control Capabilities */
X SK_U8 PFlowCtrlMode; /* Flow Control Mode */
- SK_U8 PFlowCtrlStatus; /* Flow Control Status */
- SK_U8 PMSCap; /* Master/Slave Capabilities */
- SK_U8 PMSMode; /* Master/Slave Mode */
- SK_U8 PMSStatus; /* Master/Slave Status */
+ SK_U8 PFlowCtrlStatus;/* Flow Control Status */
+ SK_U8 PMSCap; /* Master/Slave Capabilities */
+ SK_U8 PMSMode; /* Master/Slave Mode */
+ SK_U8 PMSStatus; /* Master/Slave Status */
X SK_U8 PAutoNegFail; /* Autonegotiation fail flag */
X SK_U8 PLipaAutoNeg; /* Autonegotiation possible with Link Partner */
+ SK_U16 PhyAddr; /* MDIO/MDC PHY address */
X int PhyType; /* PHY used on this port */
- SK_U16 PhyAddr; /* MDIO/MDC PHY address */
X } SK_GEPORT;
X
X /*
X * Gigabit Ethernet Initalization Struct
- * (has to be included in the adapter context
+ * (has to be included in the adapter context)
X */
X typedef struct s_GeInit {
- int GIMacsFound; /* Number of MACs found on this adapter */
- int GIPciHwRev; /* PCI HW Revision Number */
- SK_U32 GIRamOffs; /* RAM Address Offset for addr calculation */
- int GIRamSize; /* The RAM size of the adapter in kB */
- int GIHstClkFact; /* Host Clock Factor (62.5 / HstClk * 100) */
- int GIPortUsage; /* driver port usage: SK_RED_LINK/SK_MUL_LINK */
- SK_U32 GIPollTimerVal; /* Descriptor Poll Timer Init Val in clk ticks*/
- int GILevel; /* Initialization Level Completed */
- SK_BOOL GIAnyPortAct; /* Is True if one or more port is initialized */
- SK_GEPORT GP[SK_MAX_MACS]; /* Port Dependent Information */
+ int GIMacsFound; /* Number of MACs found on this adapter */
+ int GIPciHwRev; /* PCI HW Revision Number */
+ SK_U32 GIRamOffs; /* RAM Address Offset for addr calculation */
+ int GIRamSize; /* The RAM size of the adapter in kB */
+ int GIHstClkFact; /* Host Clock Factor (62.5 / HstClk * 100) */
+ int GIPortUsage; /* driver port usage: SK_RED_LINK/SK_MUL_LINK */
+ SK_U32 GIPollTimerVal; /* Descriptor Poll Timer Init Val in clk ticks*/
+ int GILevel; /* Initialization Level Completed */
+ SK_GEPORT GP[SK_MAX_MACS];/* Port Dependent Information */
+ SK_BOOL GIAnyPortAct; /* Is True if one or more port is initialized */
+ SK_U8 Align01;
+ SK_U16 Align02;
X } SK_GEINIT;
X
X /*
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/h/skgepnm2.h linux/drivers/net/sk98lin/h/skgepnm2.h
--- v2.4.0-test8/linux/drivers/net/sk98lin/h/skgepnm2.h Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/h/skgepnm2.h Fri Sep 15 14:34:19 2000


@@ -2,8 +2,8 @@
X *

X * Name: skgepnm2.h


X * Project: GEnesis, PCI Gigabit Ethernet Adapter

- * Version: $Revision: 1.24 $
- * Date: $Date: 1999/04/13 15:11:11 $
+ * Version: $Revision: 1.28 $
+ * Date: $Date: 2000/08/03 15:12:48 $
X * Purpose: Defines for Private Network Management Interface
X *
X ****************************************************************************/
@@ -27,6 +27,20 @@


X * History:
X *

X * $Log: skgepnm2.h,v $
+ * Revision 1.28 2000/08/03 15:12:48 rwahl
+ * - Additional comment for MAC statistic data structure.
+ *
+ * Revision 1.27 2000/08/01 16:10:18 rwahl
+ * - Added mac statistic data structure for StatRxLongFrame counter.
+ *
+ * Revision 1.26 2000/03/31 13:51:34 rwahl
+ * Added SK_UPTR cast to offset calculation for PNMI struct fields;
+ * missing cast caused compiler warnings by Win64 compiler.
+ *
+ * Revision 1.25 1999/11/22 13:57:41 cgoos


+ * Changed license header to GPL.

+ * Allowing overwrite for SK_PNMI_STORE/_READ defines.
+ *
X * Revision 1.24 1999/04/13 15:11:11 mhaveman
X * Changed copyright.
X *
@@ -203,6 +217,8 @@
X
X /*
X * MAC statistic data structures
+ * Only for the first 64 counters: the number relates to the bit in the
+ * XMAC overflow status register
X */
X #define SK_PNMI_HTX 0
X #define SK_PNMI_HTX_OCTET 1
@@ -274,6 +290,8 @@
X #define SK_PNMI_HTX_SYNC 64
X #define SK_PNMI_HTX_SYNC_OCTET 65
X
+#define SK_PNMI_HRX_LONGFRAMES 66
+
X #define SK_PNMI_MAX_IDX (SK_PNMI_CNT_NO)
X
X /*
@@ -288,25 +306,25 @@
X /*
X * SK_PNMI_STRUCT_DATA copy offset evaluation macros
X */
-#define SK_PNMI_OFF(e) ((SK_U32)&(((SK_PNMI_STRUCT_DATA *)0)->e))
-#define SK_PNMI_MAI_OFF(e) ((SK_U32)&(((SK_PNMI_STRUCT_DATA *)0)->e))
-#define SK_PNMI_VPD_OFF(e) ((SK_U32)&(((SK_PNMI_VPD *)0)->e))
-#define SK_PNMI_SEN_OFF(e) ((SK_U32)&(((SK_PNMI_SENSOR *)0)->e))
-#define SK_PNMI_CHK_OFF(e) ((SK_U32)&(((SK_PNMI_CHECKSUM *)0)->e))
-#define SK_PNMI_STA_OFF(e) ((SK_U32)&(((SK_PNMI_STAT *)0)->e))
-#define SK_PNMI_CNF_OFF(e) ((SK_U32)&(((SK_PNMI_CONF *)0)->e))
-#define SK_PNMI_RLM_OFF(e) ((SK_U32)&(((SK_PNMI_RLMT *)0)->e))
-#define SK_PNMI_MON_OFF(e) ((SK_U32)&(((SK_PNMI_RLMT_MONITOR *)0)->e))
-#define SK_PNMI_TRP_OFF(e) ((SK_U32)&(((SK_PNMI_TRAP *)0)->e))
+#define SK_PNMI_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_STRUCT_DATA *)0)->e))
+#define SK_PNMI_MAI_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_STRUCT_DATA *)0)->e))
+#define SK_PNMI_VPD_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_VPD *)0)->e))
+#define SK_PNMI_SEN_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_SENSOR *)0)->e))
+#define SK_PNMI_CHK_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_CHECKSUM *)0)->e))
+#define SK_PNMI_STA_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_STAT *)0)->e))
+#define SK_PNMI_CNF_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_CONF *)0)->e))
+#define SK_PNMI_RLM_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_RLMT *)0)->e))
+#define SK_PNMI_MON_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_RLMT_MONITOR *)0)->e))
+#define SK_PNMI_TRP_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_TRAP *)0)->e))
X
X #define SK_PNMI_SET_STAT(b,s,o) {SK_U32 Val32; char *pVal; \
X Val32 = (s); \
- pVal = (char *)(b) + ((SK_U32) \
+ pVal = (char *)(b) + ((SK_U32)(SK_UPTR) \
X &(((SK_PNMI_STRUCT_DATA *)0)-> \
X ReturnStatus.ErrorStatus)); \
X SK_PNMI_STORE_U32(pVal, Val32); \
X Val32 = (o); \
- pVal = (char *)(b) + ((SK_U32) \
+ pVal = (char *)(b) + ((SK_U32)(SK_UPTR) \
X &(((SK_PNMI_STRUCT_DATA *)0)-> \
X ReturnStatus.ErrorOffset)); \
X SK_PNMI_STORE_U32(pVal, Val32);}
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/h/skgepnmi.h linux/drivers/net/sk98lin/h/skgepnmi.h
--- v2.4.0-test8/linux/drivers/net/sk98lin/h/skgepnmi.h Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/h/skgepnmi.h Fri Sep 15 14:34:19 2000


@@ -2,8 +2,8 @@
X *

X * Name: skgepnmi.h


X * Project: GEnesis, PCI Gigabit Ethernet Adapter

- * Version: $Revision: 1.37 $
- * Date: $Date: 1999/09/14 14:25:32 $


+ * Version: $Revision: 1.44 $

+ * Date: $Date: 2000/09/07 07:35:27 $
X * Purpose: Defines for Private Network Management Interface
X *
X ****************************************************************************/
@@ -27,6 +27,34 @@


X * History:
X *

X * $Log: skgepnmi.h,v $
+ * Revision 1.44 2000/09/07 07:35:27 rwahl
+ * - removed NDIS counter specific data type.
+ * - fixed spelling for OID_SKGE_RLMT_PORT_PREFERRED.
+ *
+ * Revision 1.43 2000/08/04 11:41:08 rwahl
+ * - Fixed compiler warning (port is always >= 0) for macros
+ * SK_PNMI_CNT_RX_LONGFRAMES & SK_PNMI_CNT_SYNC_OCTETS
+ *
+ * Revision 1.42 2000/08/03 15:14:07 rwahl
+ * - Corrected error in driver macros addressing a physical port.
+ *
+ * Revision 1.41 2000/08/01 16:22:29 rwahl
+ * - Changed MDB version to 3.1.
+ * - Added definitions for StatRxLongFrames counter.
+ * - Added macro to be used by driver to count long frames received.


+ * - Added directive to control width (default = 32bit) of NDIS statistic
+ * counters (SK_NDIS_64BIT_CTR).
+ *

+ * Revision 1.40 2000/03/31 13:51:34 rwahl
+ * Added SK_UPTR cast to offset calculation for PNMI struct fields;
+ * missing cast caused compiler warnings by Win64 compiler.
+ *
+ * Revision 1.39 1999/12/06 10:09:47 rwahl
+ * Added new error log message.
+ *
+ * Revision 1.38 1999/11/22 13:57:55 cgoos


+ * Changed license header to GPL.
+ *

X * Revision 1.37 1999/09/14 14:25:32 rwahl
X * Set MDB version for 1000Base-T (sensors, Master/Slave) changes.
X *
@@ -164,7 +192,7 @@
X /*
X * Management Database Version
X */
-#define SK_PNMI_MDB_VERSION 0x00030000 /* 3.0 */
+#define SK_PNMI_MDB_VERSION 0x00030001 /* 3.1 */
X
X
X /*
@@ -383,6 +411,7 @@
X #define OID_SKGE_STAT_RX_511 0xFF020154
X #define OID_SKGE_STAT_RX_1023 0xFF020155
X #define OID_SKGE_STAT_RX_MAX 0xFF020156
+#define OID_SKGE_STAT_RX_LONGFRAMES 0xFF020157
X
X #define OID_SKGE_PHYS_CUR_ADDR 0xFF010120
X #define OID_SKGE_PHYS_FAC_ADDR 0xFF010121
@@ -405,7 +434,7 @@
X #define OID_SKGE_RLMT_MODE 0xFF010140
X #define OID_SKGE_RLMT_PORT_NUMBER 0xFF010141
X #define OID_SKGE_RLMT_PORT_ACTIVE 0xFF010142
-#define OID_SKGE_RLMT_PORT_PREFERED 0xFF010143
+#define OID_SKGE_RLMT_PORT_PREFERRED 0xFF010143
X #define OID_SKGE_RLMT_CHANGE_CTS 0xFF020160
X #define OID_SKGE_RLMT_CHANGE_TIME 0xFF020161
X #define OID_SKGE_RLMT_CHANGE_ESTIM 0xFF020162
@@ -559,6 +588,8 @@
X #define SK_PNMI_ERR050MSG "MacUpdate: Cannot update statistic counter"
X #define SK_PNMI_ERR051 (SK_ERRBASE_PNMI + 51)
X #define SK_PNMI_ERR051MSG "SkPnmiEvent: Port switch suspicious"
+#define SK_PNMI_ERR052 (SK_ERRBASE_PNMI + 52)
+#define SK_PNMI_ERR052MSG "MacPrivateConf: SK_HWEV_SET_ROLE returned not 0"
X
X /*
X * Management counter macros called by the driver
@@ -592,9 +623,16 @@
X
X #define SK_PNMI_CNT_SYNC_OCTETS(pAC,p,v) \
X { \
- if (((p) >= 0) && ((p) < SK_MAX_MACS)) { \
- ((pAC)->Pnmi.StatSyncCts[p])++; \
- (pAC)->Pnmi.StatSyncOctetsCts[p] += (SK_U64)(v); \
+ if ((p) < SK_MAX_MACS) { \
+ ((pAC)->Pnmi.Port[p].StatSyncCts)++; \
+ (pAC)->Pnmi.Port[p].StatSyncOctetsCts += (SK_U64)(v); \
+ } \
+ }
+
+#define SK_PNMI_CNT_RX_LONGFRAMES(pAC,p) \
+ { \
+ if ((p) < SK_MAX_MACS) { \
+ ((pAC)->Pnmi.Port[p].StatRxLongFrameCts)++; \
X } \
X }
X
@@ -687,6 +725,7 @@
X SK_U64 StatRxBroadcastOkCts;
X SK_U64 StatRxMulticastOkCts;
X SK_U64 StatRxUnicastOkCts;
+ SK_U64 StatRxLongFramesCts;
X SK_U64 StatRxPauseMacCtrlCts;
X SK_U64 StatRxMacCtrlCts;
X SK_U64 StatRxPauseMacCtrlErrorCts;
@@ -809,8 +848,9 @@
X } SK_PNMI_STRUCT_DATA;
X
X #define SK_PNMI_STRUCT_SIZE (sizeof(SK_PNMI_STRUCT_DATA))
-#define SK_PNMI_MIN_STRUCT_SIZE ((unsigned int)&(((SK_PNMI_STRUCT_DATA *)0)->\
- VpdFreeBytes)) /*
+#define SK_PNMI_MIN_STRUCT_SIZE ((unsigned int)(SK_UPTR)\
+ &(((SK_PNMI_STRUCT_DATA *)0)->VpdFreeBytes))
+ /*
X * ReturnStatus field
X * must be located
X * before VpdFreeBytes
@@ -822,7 +862,7 @@
X #define SK_PNMI_MAX_PROTOS 3
X
X #define SK_PNMI_SCNT_NOT 64
-#define SK_PNMI_CNT_NO 66
+#define SK_PNMI_CNT_NO 67
X
X /*
X * Estimate data structure
@@ -843,6 +883,7 @@
X SK_U64 CounterOffset[SK_PNMI_CNT_NO];
X SK_U64 StatSyncCts;
X SK_U64 StatSyncOctetsCts;
+ SK_U64 StatRxLongFrameCts;
X SK_BOOL ActiveFlag;
X } SK_PNMI_PORT;
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/h/skgesirq.h linux/drivers/net/sk98lin/h/skgesirq.h
--- v2.4.0-test8/linux/drivers/net/sk98lin/h/skgesirq.h Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/h/skgesirq.h Fri Sep 15 14:34:19 2000


@@ -2,8 +2,8 @@
X *

X * Name: skgesirq.h


X * Project: GEnesis, PCI Gigabit Ethernet Adapter

- * Version: $Revision: 1.18 $
- * Date: $Date: 1999/05/19 07:32:59 $
+ * Version: $Revision: 1.20 $
+ * Date: $Date: 1999/12/06 10:00:44 $
X * Purpose: SK specific Gigabit Ethernet special IRQ functions
X *
X ******************************************************************************/
@@ -26,6 +26,12 @@
X *
X * History:
X * $Log: skgesirq.h,v $
+ * Revision 1.20 1999/12/06 10:00:44 cgoos
+ * Added SET event for role.
+ *
+ * Revision 1.19 1999/11/22 13:58:26 cgoos


+ * Changed license header to GPL.
+ *

X * Revision 1.18 1999/05/19 07:32:59 cgoos
X * Changes for 1000Base-T.
X *
@@ -99,6 +105,7 @@
X #define SK_HWEV_UPDATE_STAT 5 /* Update Statistics by PNMI */
X #define SK_HWEV_SET_LMODE 6 /* Set Link Mode by PNMI */
X #define SK_HWEV_SET_FLOWMODE 7 /* Set Flow Control Mode by PNMI */
+#define SK_HWEV_SET_ROLE 8 /* Set Master/Slave (Role) by PNMI */
X
X #define SK_WA_ACT_TIME (5000000L) /* 5 sec */
X #define SK_WA_INA_TIME (100000L) /* 100 msec */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/h/ski2c.h linux/drivers/net/sk98lin/h/ski2c.h
--- v2.4.0-test8/linux/drivers/net/sk98lin/h/ski2c.h Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/h/ski2c.h Fri Sep 15 14:34:19 2000


@@ -2,8 +2,8 @@
X *

X * Name: ski2c.h


X * Project: GEnesis, PCI Gigabit Ethernet Adapter

- * Version: $Revision: 1.27 $
- * Date: $Date: 1999/05/20 09:23:10 $
+ * Version: $Revision: 1.29 $
+ * Date: $Date: 2000/08/03 14:28:17 $
X * Purpose: Defines to access Voltage and Temperature Sensor


X * (taken from Monalisa (taken from Concentrator))
X *

@@ -28,6 +28,13 @@


X * History:
X *

X * $Log: ski2c.h,v $
+ * Revision 1.29 2000/08/03 14:28:17 rassmann


+ * - Added function to wait for I2C being ready before resetting the board.
+ * - Replaced one duplicate "out of range" message with correct one.
+ *

+ * Revision 1.28 1999/11/22 13:55:46 cgoos


+ * Changed license header to GPL.
+ *

X * Revision 1.27 1999/05/20 09:23:10 cgoos
X * Changes for 1000Base-T (Fan sensors).
X *
@@ -254,9 +261,9 @@
X
X extern int SkI2cReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen);
X #ifndef SK_DIAG
-extern int SkI2cEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event,
- SK_EVPARA Para);
+extern int SkI2cEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para);
X extern int SkI2cInit(SK_AC *pAC, SK_IOC IoC, int Level);
+extern void SkI2cWaitIrq(SK_AC *pAC, SK_IOC IoC);
X extern void SkI2cIsr(SK_AC *pAC, SK_IOC IoC);
X
X #endif
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/h/skqueue.h linux/drivers/net/sk98lin/h/skqueue.h
--- v2.4.0-test8/linux/drivers/net/sk98lin/h/skqueue.h Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/h/skqueue.h Fri Sep 15 14:34:19 2000


@@ -2,8 +2,8 @@
X *

X * Name: skqueue.h


X * Project: GEnesis, PCI Gigabit Ethernet Adapter

- * Version: $Revision: 1.12 $
- * Date: $Date: 1998/09/08 08:48:01 $
+ * Version: $Revision: 1.13 $
+ * Date: $Date: 1999/11/22 13:59:05 $
X * Purpose: Defines for the Event queue
X *
X ******************************************************************************/
@@ -27,6 +27,9 @@


X * History:
X *

X * $Log: skqueue.h,v $
+ * Revision 1.13 1999/11/22 13:59:05 cgoos


+ * Changed license header to GPL.
+ *

X * Revision 1.12 1998/09/08 08:48:01 gklug
X * add: init level handling
X *
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/h/skrlmt.h linux/drivers/net/sk98lin/h/skrlmt.h
--- v2.4.0-test8/linux/drivers/net/sk98lin/h/skrlmt.h Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/h/skrlmt.h Fri Sep 15 14:34:19 2000


@@ -2,8 +2,8 @@
X *

X * Name: skrlmt.h


X * Project: GEnesis, PCI Gigabit Ethernet Adapter

- * Version: $Revision: 1.26 $
- * Date: $Date: 1999/10/04 14:01:19 $
+ * Version: $Revision: 1.27 $
+ * Date: $Date: 1999/11/22 13:59:56 $
X * Purpose: Header file for Redundant Link ManagemenT.
X *
X ******************************************************************************/
@@ -27,6 +27,9 @@


X * History:
X *

X * $Log: skrlmt.h,v $
+ * Revision 1.27 1999/11/22 13:59:56 cgoos


+ * Changed license header to GPL.
+ *

X * Revision 1.26 1999/10/04 14:01:19 rassmann
X * Corrected reaction to reception of BPDU frames.
X * Added parameter descriptions to "For Readme" section skrlmt.txt.
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/h/sktimer.h linux/drivers/net/sk98lin/h/sktimer.h
--- v2.4.0-test8/linux/drivers/net/sk98lin/h/sktimer.h Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/h/sktimer.h Fri Sep 15 14:34:19 2000


@@ -2,8 +2,8 @@
X *

X * Name: sktimer.h


X * Project: GEnesis, PCI Gigabit Ethernet Adapter

- * Version: $Revision: 1.8 $
- * Date: $Date: 1998/09/08 08:48:02 $
+ * Version: $Revision: 1.9 $
+ * Date: $Date: 1999/11/22 14:00:29 $
X * Purpose: Defines for the timer functions
X *
X ******************************************************************************/
@@ -27,6 +27,9 @@


X * History:
X *

X * $Log: sktimer.h,v $
+ * Revision 1.9 1999/11/22 14:00:29 cgoos


+ * Changed license header to GPL.
+ *

X * Revision 1.8 1998/09/08 08:48:02 gklug
X * add: init level handling
X *
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/h/sktypes.h linux/drivers/net/sk98lin/h/sktypes.h
--- v2.4.0-test8/linux/drivers/net/sk98lin/h/sktypes.h Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/h/sktypes.h Fri Sep 15 14:34:19 2000


@@ -2,8 +2,8 @@
X *

X * Name: sktypes.h


X * Project: GEnesis, PCI Gigabit Ethernet Adapter

- * Version: $Revision: 1.1 $
- * Date: $Date: 1999/02/16 07:41:40 $
+ * Version: $Revision: 1.2 $
+ * Date: $Date: 1999/11/22 14:01:58 $
X * Purpose: Define data types for Linux
X *
X ******************************************************************************/
@@ -27,6 +27,10 @@


X * History:
X *

X * $Log: sktypes.h,v $
+ * Revision 1.2 1999/11/22 14:01:58 cgoos


+ * Changed license header to GPL.

+ * Now using Linux' fixed size types instead of standard types.
+ *
X * Revision 1.1 1999/02/16 07:41:40 cgoos
X * First version.
X *
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/h/skvpd.h linux/drivers/net/sk98lin/h/skvpd.h
--- v2.4.0-test8/linux/drivers/net/sk98lin/h/skvpd.h Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/h/skvpd.h Fri Sep 15 14:34:19 2000
@@ -2,15 +2,15 @@
X *
X * Name: skvpd.h


X * Project: GEnesis, PCI Gigabit Ethernet Adapter

- * Version: $Revision: 1.8 $
- * Date: $Date: 1999/03/11 14:26:40 $
+ * Version: $Revision: 1.10 $
+ * Date: $Date: 2000/08/10 11:29:07 $
X * Purpose: Defines and Macros for VPD handling
X *
X ******************************************************************************/


X
X /******************************************************************************
X *
- * (C)Copyright 1998,1999 SysKonnect,
+ * (C)Copyright 1998-2000 SysKonnect,
X * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
X *

X * This program is free software; you can redistribute it and/or modify

@@ -27,6 +27,15 @@


X * History:
X *

X * $Log: skvpd.h,v $
+ * Revision 1.10 2000/08/10 11:29:07 rassmann
+ * Editorial changes.
+ * Preserving 32-bit alignment in structs for the adapter context.
+ * Removed unused function VpdWriteDword() (#if 0).
+ * Made VpdReadKeyword() available for SKDIAG only.
+ *
+ * Revision 1.9 1999/11/22 14:02:27 cgoos


+ * Changed license header to GPL.
+ *

X * Revision 1.8 1999/03/11 14:26:40 malthoff
X * Replace __STDC__ with SK_KR_PROTO.
X *
@@ -112,40 +121,42 @@
X
X /* VPD status */
X /* bit 7..1 reserved */
-#define VPD_VALID (1<<0) /* VPD data buffer, vpd_free_ro, */
- /* and vpd_free_rw valid */
+#define VPD_VALID (1<<0) /* VPD data buffer, vpd_free_ro, */
+ /* and vpd_free_rw valid */
X
X /*
X * VPD structs
X */
X typedef struct s_vpd_status {
- unsigned short vpd_status ; /* VPD status, description see above */
- int vpd_free_ro ; /* unused bytes in read only area */
- int vpd_free_rw ; /* bytes available in read/write area */
+ unsigned short Align01; /* Alignment */
+ unsigned short vpd_status; /* VPD status, description see above */
+ int vpd_free_ro; /* unused bytes in read only area */
+ int vpd_free_rw; /* bytes available in read/write area */
X } SK_VPD_STATUS;
X
X typedef struct s_vpd {
- SK_VPD_STATUS v ; /* VPD status structure */
- char vpd_buf[VPD_SIZE] ; /* VPD buffer */
+ SK_VPD_STATUS v; /* VPD status structure */
+ char vpd_buf[VPD_SIZE]; /* VPD buffer */
X } SK_VPD;
X
X typedef struct s_vpd_para {
- unsigned int p_len ; /* parameter length */
- char *p_val ; /* points to the value */
+ unsigned int p_len; /* parameter length */
+ char *p_val; /* points to the value */
X } SK_VPD_PARA;
X
X /*
X * structure of Large Resource Type Identifiers
X */
-/* was removed, because of alignment problems */
+
+/* was removed because of alignment problems */
X
X /*
X * sturcture of VPD keywords
X */
X typedef struct s_vpd_key {
- char p_key[2] ; /* 2 bytes ID string */
- unsigned char p_len ; /* 1 byte length */
- char p_val ; /* start of the value string */
+ char p_key[2]; /* 2 bytes ID string */
+ unsigned char p_len; /* 1 byte length */
+ char p_val; /* start of the value string */
X } SK_VPD_KEY;
X
X
@@ -169,39 +180,39 @@
X #define VPD_IN32(pAC,IoC,Addr,pVal) SK_IN32(IoC,PCI_C(Addr),pVal)
X #endif /* VPD_DO_IO */
X #else /* SKDIAG */
-#define VPD_OUT8(pAC,Ioc,Addr,Val) { \
+#define VPD_OUT8(pAC,Ioc,Addr,Val) { \
X if ((pAC)->DgT.DgUseCfgCycle) \
- SkPciWriteCfgByte(pAC,Addr,Val) ; \
- else \
+ SkPciWriteCfgByte(pAC,Addr,Val); \
+ else \
X SK_OUT8(pAC,PCI_C(Addr),Val); \
X }
-#define VPD_OUT16(pAC,Ioc,Addr,Val) { \
+#define VPD_OUT16(pAC,Ioc,Addr,Val) { \
X if ((pAC)->DgT.DgUseCfgCycle) \
- SkPciWriteCfgWord(pAC,Addr,Val) ; \
+ SkPciWriteCfgWord(pAC,Addr,Val); \
X else \
X SK_OUT16(pAC,PCI_C(Addr),Val); \
X }
-#define VPD_OUT32(pAC,Ioc,Addr,Val) { \
+#define VPD_OUT32(pAC,Ioc,Addr,Val) { \
X if ((pAC)->DgT.DgUseCfgCycle) \
- SkPciWriteCfgDWord(pAC,Addr,Val) ; \
+ SkPciWriteCfgDWord(pAC,Addr,Val); \
X else \
X SK_OUT32(pAC,PCI_C(Addr),Val); \
X }
-#define VPD_IN8(pAC,Ioc,Addr,pVal) { \
+#define VPD_IN8(pAC,Ioc,Addr,pVal) { \
X if ((pAC)->DgT.DgUseCfgCycle) \
- SkPciReadCfgByte(pAC,Addr,pVal) ; \
+ SkPciReadCfgByte(pAC,Addr,pVal); \
X else \
X SK_IN8(pAC,PCI_C(Addr),pVal); \
X }
-#define VPD_IN16(pAC,Ioc,Addr,pVal) { \
+#define VPD_IN16(pAC,Ioc,Addr,pVal) { \
X if ((pAC)->DgT.DgUseCfgCycle) \
- SkPciReadCfgWord(pAC,Addr,pVal) ; \
+ SkPciReadCfgWord(pAC,Addr,pVal); \
X else \
X SK_IN16(pAC,PCI_C(Addr),pVal); \
X }
-#define VPD_IN32(pAC,Ioc,Addr,pVal) { \
+#define VPD_IN32(pAC,Ioc,Addr,pVal) { \
X if ((pAC)->DgT.DgUseCfgCycle) \
- SkPciReadCfgDWord(pAC,Addr,pVal) ; \
+ SkPciReadCfgDWord(pAC,Addr,pVal); \
X else \
X SK_IN32(pAC,PCI_C(Addr),pVal); \
X }
@@ -210,50 +221,52 @@
X /* function prototypes ********************************************************/
X
X #ifndef SK_KR_PROTO
+#ifdef SKDIAG
X extern SK_U32 VpdReadDWord(
X SK_AC *pAC,
X SK_IOC IoC,
- int addr) ;
+ int addr);
+#endif /* SKDIAG */
X
X extern int VpdSetupPara(
X SK_AC *pAC,
X char *key,
X char *buf,
- int len,
- int type,
- int op) ;
+ int len,
+ int type,
+ int op);
X
X extern SK_VPD_STATUS *VpdStat(
X SK_AC *pAC,
- SK_IOC IoC) ;
+ SK_IOC IoC);
X
X extern int VpdKeys(
X SK_AC *pAC,
X SK_IOC IoC,
X char *buf,
- int *len,
- int *elements) ;
+ int *len,
+ int *elements);
X
X extern int VpdRead(
X SK_AC *pAC,
X SK_IOC IoC,
X char *key,
X char *buf,
- int *len) ;
+ int *len);
X
X extern SK_BOOL VpdMayWrite(
- char *key) ;
+ char *key);
X
X extern int VpdWrite(
X SK_AC *pAC,
X SK_IOC IoC,
X char *key,
- char *buf) ;
+ char *buf);
X
X extern int VpdDelete(
X SK_AC *pAC,
X SK_IOC IoC,
- char *key) ;
+ char *key);
X
X extern int VpdUpdate(
X SK_AC *pAC,
@@ -262,34 +275,34 @@
X extern void VpdErrLog(
X SK_AC *pAC,
X SK_IOC IoC,
- char *msg) ;
+ char *msg);
X
X #ifdef SKDIAG
X extern int VpdReadBlock(
X SK_AC *pAC,
X SK_IOC IoC,
X char *buf,
- int addr,
- int len) ;
+ int addr,
+ int len);
X
X extern int VpdWriteBlock(
X SK_AC *pAC,
X SK_IOC IoC,
X char *buf,
- int addr,
- int len) ;
+ int addr,
+ int len);
X #endif /* SKDIAG */
X #else /* SK_KR_PROTO */
-extern SK_U32 VpdReadDWord() ;
-extern int VpdSetupPara() ;
-extern SK_VPD_STATUS *VpdStat() ;
-extern int VpdKeys() ;
-extern int VpdRead() ;
-extern SK_BOOL VpdMayWrite() ;
-extern int VpdWrite() ;
-extern int VpdDelete() ;
-extern int VpdUpdate() ;
-extern void VpdErrLog() ;
+extern SK_U32 VpdReadDWord();
+extern int VpdSetupPara();
+extern SK_VPD_STATUS *VpdStat();
+extern int VpdKeys();
+extern int VpdRead();
+extern SK_BOOL VpdMayWrite();
+extern int VpdWrite();
+extern int VpdDelete();
+extern int VpdUpdate();
+extern void VpdErrLog();
X #endif /* SK_KR_PROTO */
X
X #endif /* __INC_SKVPD_H_ */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/h/xmac_ii.h linux/drivers/net/sk98lin/h/xmac_ii.h
--- v2.4.0-test8/linux/drivers/net/sk98lin/h/xmac_ii.h Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/h/xmac_ii.h Fri Sep 15 14:34:19 2000


@@ -2,8 +2,8 @@
X *

X * Name: xmac_ii.h


X * Project: GEnesis, PCI Gigabit Ethernet Adapter

- * Version: $Revision: 1.25 $
- * Date: $Date: 1999/08/12 19:19:38 $
+ * Version: $Revision: 1.27 $
+ * Date: $Date: 2000/05/17 11:00:46 $
X * Purpose: Defines and Macros for XaQti's Gigabit Ethernet Controller
X *
X ******************************************************************************/
@@ -27,6 +27,12 @@


X * History:
X *

X * $Log: xmac_ii.h,v $
+ * Revision 1.27 2000/05/17 11:00:46 malthoff
+ * Add bit for enable/disable power management in BCOM chip.
+ *
+ * Revision 1.26 1999/11/22 14:03:00 cgoos


+ * Changed license header to GPL.
+ *

X * Revision 1.25 1999/08/12 19:19:38 malthoff
X * Add PHY_B_AC_TX_TST bit according to BCOM A1 errata sheet.
X *
@@ -930,7 +936,9 @@
X #define PHY_B_AC_TX_TST (1<<10) /* Bit 10: tx test bit, always 1 */
X /* Bit 9.. 8: reserved */
X #define PHY_B_AC_DIS_PRF (1<<7) /* Bit 7: dis part resp filter */
- /* Bit 6.. 4: reserved */
+ /* Bit 6: reserved */
+#define PHY_B_AC_DIS_PM (1<<5) /* Bit 5: dis power management */
+ /* Bit 4: reserved */
X #define PHY_B_AC_DIAG (1<<3) /* Bit 3: Diagnostic Mode */
X /* Bit 2.. 0: reserved */
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/skaddr.c linux/drivers/net/sk98lin/skaddr.c
--- v2.4.0-test8/linux/drivers/net/sk98lin/skaddr.c Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/skaddr.c Fri Sep 15 14:34:19 2000
@@ -2,19 +2,17 @@
X *
X * Name: skaddr.c


X * Project: GEnesis, PCI Gigabit Ethernet Adapter

- * Version: $Revision: 1.33 $
- * Date: $Date: 1999/05/28 10:56:06 $
- * Purpose: Manage Addresses (Multicast and Unicast) and Promiscuous Mode
+ * Version: $Revision: 1.36 $
+ * Date: $Date: 2000/08/07 11:10:39 $
+ * Purpose: Manage Addresses (Multicast and Unicast) and Promiscuous Mode.
X *
X ******************************************************************************/


X
X /******************************************************************************
X *
- * (C)Copyright 1998,1999 SysKonnect,
+ * (C)Copyright 1998-2000 SysKonnect,
X * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
X *
- * See the file "skge.c" for further information.
- *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
X * the Free Software Foundation; either version 2 of the License, or

@@ -29,6 +27,16 @@


X * History:
X *

X * $Log: skaddr.c,v $
+ * Revision 1.36 2000/08/07 11:10:39 rassmann
+ * Editorial changes.
+ *
+ * Revision 1.35 2000/05/04 09:38:41 rassmann
+ * Editorial changes.
+ * Corrected multicast address hashing.
+ *
+ * Revision 1.34 1999/11/22 13:23:44 cgoos


+ * Changed license header to GPL.
+ *

X * Revision 1.33 1999/05/28 10:56:06 rassmann
X * Editorial changes.
X *
@@ -164,13 +172,13 @@
X
X #ifndef lint


X static const char SysKonnectFileId[] =

- "@(#) $Id: skaddr.c,v 1.33 1999/05/28 10:56:06 rassmann Exp $ (C) SysKonnect.";
+ "@(#) $Id: skaddr.c,v 1.36 2000/08/07 11:10:39 rassmann Exp $ (C) SysKonnect.";
X #endif /* !defined(lint) */
X
X #define __SKADDR_C
X
X #ifdef __cplusplus
-xxxx /* not supported yet - force error */
+#error C++ is not yet supported.
X extern "C" {
X #endif /* cplusplus */
X
@@ -179,19 +187,9 @@
X
X /* defines ********************************************************************/
X
-#define SK_ADDR_CHEAT YES /* Cheat. */
-
-/*
- * G32:
- * POLY equ 04C11DB6h ; CRC polynominal term
- * bit-reversed: 6DB88320
- */
X
X #define CRC32_POLY 0xEDB88320UL /* CRC32-Poly - XMAC: Little Endian */
-#if 0
-#define CRC32_POLY 0x6DB88320UL /* CRC32-Poly - XMAC: Little Endian */
-#endif /* 0 */
-#define HASH_BITS 6 /* #bits in hash */
+#define HASH_BITS 6 /* #bits in hash */
X #define SK_MC_BIT 0x01
X
X /* Error numbers and messages. */
@@ -219,13 +217,6 @@
X
X /* functions ******************************************************************/
X
-#if 0
-void SkAddrDummy(void)
-{
- SkAddrInit(NULL, NULL, 0);
-} /* SkAddrDummy */
-#endif /* 0 */
-
X /******************************************************************************
X *
X * SkAddrInit - initialize data, set state to init
@@ -236,7 +227,7 @@
X * ============
X *
X * This routine clears the multicast tables and resets promiscuous mode.
- * Some entries are reserved for the "logical board address", the
+ * Some entries are reserved for the "logical MAC address", the
X * SK-RLMT multicast address, and the BPDU multicast address.
X *
X *
@@ -263,12 +254,12 @@
X int SkAddrInit(
X SK_AC *pAC, /* the adapter context */
X SK_IOC IoC, /* I/O context */


-int Level) /* initialization level */
+int Level) /* initialization level */
X {

- int j;
- SK_U32 i;
- SK_U8 *InAddr;
- SK_U16 *OutAddr;
+ int j;
+ SK_U32 i;
+ SK_U8 *InAddr;
+ SK_U16 *OutAddr;
X SK_ADDR_PORT *pAPort;


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 065'
echo 'File patch-2.4.0-test9 is continued in part 066'
echo "066" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part066

#!/bin/sh -x
# this is part 066 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 066; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&
X

X switch (Level) {
@@ -279,20 +270,15 @@
X pAPort = &pAC->Addr.Port[i];
X pAPort->PromMode = SK_PROM_MODE_NONE;
X
- pAPort->FirstExactMatchRlmt =
- SK_ADDR_FIRST_MATCH_RLMT;
- pAPort->FirstExactMatchDrv =
- SK_ADDR_FIRST_MATCH_DRV;
- pAPort->NextExactMatchRlmt =
- SK_ADDR_FIRST_MATCH_RLMT;
- pAPort->NextExactMatchDrv =
- SK_ADDR_FIRST_MATCH_DRV;
+ pAPort->FirstExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
+ pAPort->FirstExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
+ pAPort->NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
+ pAPort->NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
X
X #if 0
- /* Not here ... */
+ /* Don't do this here ... */
X
X /* Reset Promiscuous mode. */
-
X (void)SkAddrPromiscuousChange(
X pAC,
X IoC,
@@ -325,8 +311,7 @@
X }
X #endif /* DEBUG */
X
- /* Read permanent virtual address from Control Register File. */
-
+ /* Read permanent logical MAC address from Control Register File. */
X for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
X InAddr = (SK_U8 *)&pAC->Addr.PermanentMacAddress.a[j];
X SK_IN8(IoC, B2_MAC_1 + j, InAddr);
@@ -334,17 +319,15 @@
X
X if (!pAC->Addr.CurrentMacAddressSet) {
X /*
- * Set the current virtual MAC address
+ * Set the current logical MAC address
X * to the permanent one.
X */
-
X pAC->Addr.CurrentMacAddress =
X pAC->Addr.PermanentMacAddress;
X pAC->Addr.CurrentMacAddressSet = SK_TRUE;
X }
X
- /* Set the current virtual MAC address. */
-
+ /* Set the current logical MAC address. */
X pAC->Addr.Port[pAC->Addr.ActivePort].Exact[0] =
X pAC->Addr.CurrentMacAddress;
X
@@ -354,27 +337,27 @@
X SK_DBGMOD_ADDR,
X SK_DBGCAT_INIT,
X ("Permanent MAC Address: %02X %02X %02X %02X %02X %02X\n",
- pAC->Addr.PermanentMacAddress.a[0],
- pAC->Addr.PermanentMacAddress.a[1],
- pAC->Addr.PermanentMacAddress.a[2],
- pAC->Addr.PermanentMacAddress.a[3],
- pAC->Addr.PermanentMacAddress.a[4],
- pAC->Addr.PermanentMacAddress.a[5]))
+ pAC->Addr.PermanentMacAddress.a[0],
+ pAC->Addr.PermanentMacAddress.a[1],
+ pAC->Addr.PermanentMacAddress.a[2],
+ pAC->Addr.PermanentMacAddress.a[3],
+ pAC->Addr.PermanentMacAddress.a[4],
+ pAC->Addr.PermanentMacAddress.a[5]))
X SK_DBG_MSG(
X pAC,
X SK_DBGMOD_ADDR,
X SK_DBGCAT_INIT,
- ("Virtual MAC Address: %02X %02X %02X %02X %02X %02X\n",
- pAC->Addr.CurrentMacAddress.a[0],
- pAC->Addr.CurrentMacAddress.a[1],
- pAC->Addr.CurrentMacAddress.a[2],
- pAC->Addr.CurrentMacAddress.a[3],
- pAC->Addr.CurrentMacAddress.a[4],
- pAC->Addr.CurrentMacAddress.a[5]))
+ ("Logical MAC Address: %02X %02X %02X %02X %02X %02X\n",
+ pAC->Addr.CurrentMacAddress.a[0],
+ pAC->Addr.CurrentMacAddress.a[1],
+ pAC->Addr.CurrentMacAddress.a[2],
+ pAC->Addr.CurrentMacAddress.a[3],
+ pAC->Addr.CurrentMacAddress.a[4],
+ pAC->Addr.CurrentMacAddress.a[5]))
X #endif /* DEBUG */
X
X #if 0
- /* Not here ... */
+ /* Don't do this here ... */
X
X (void)SkAddrMcUpdate(pAC, IoC, pAC->Addr.ActivePort);
X #endif /* 0 */
@@ -386,10 +369,8 @@
X * Read permanent port addresses from
X * Control Register File.
X */
-
X for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
- InAddr = (SK_U8 *)
- &pAPort->PermanentMacAddress.a[j];
+ InAddr = (SK_U8 *)&pAPort->PermanentMacAddress.a[j];
X SK_IN8(IoC, B2_MAC_2 + 8 * i + j, InAddr);
X }
X
@@ -399,16 +380,12 @@
X * MAC address of this port to its permanent
X * MAC address.
X */
-
- pAPort->CurrentMacAddress =
- pAPort->PermanentMacAddress;
- pAPort->PreviousMacAddress =
- pAPort->PermanentMacAddress;
+ pAPort->CurrentMacAddress = pAPort->PermanentMacAddress;
+ pAPort->PreviousMacAddress = pAPort->PermanentMacAddress;
X pAPort->CurrentMacAddressSet = SK_TRUE;
X }
X
X /* Set port's current MAC addresses. */
-
X OutAddr = (SK_U16 *)&pAPort->CurrentMacAddress.a[0];
X XM_OUTADDR(IoC, i, XM_SA, OutAddr);
X
@@ -484,7 +461,7 @@
X SK_AC *pAC, /* adapter context */


X SK_IOC IoC, /* I/O context */

X SK_U32 PortIdx, /* Index of affected port */
-int Flags) /* permanent/non-perm, sw-only */
+int Flags) /* permanent/non-perm, sw-only */


X {
X int i;
X

@@ -495,9 +472,7 @@
X if (Flags & SK_ADDR_PERMANENT) {
X
X /* Clear RLMT multicast addresses. */
-
- pAC->Addr.Port[PortIdx].NextExactMatchRlmt =
- SK_ADDR_FIRST_MATCH_RLMT;
+ pAC->Addr.Port[PortIdx].NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT;
X }
X else { /* not permanent => DRV */
X
@@ -509,8 +484,7 @@
X
X /* Clear DRV multicast addresses. */
X
- pAC->Addr.Port[PortIdx].NextExactMatchDrv =
- SK_ADDR_FIRST_MATCH_DRV;
+ pAC->Addr.Port[PortIdx].NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV;
X }
X
X if (!(Flags & SK_MC_SW_ONLY)) {
@@ -521,7 +495,7 @@
X } /* SkAddrMcClear */
X
X #ifndef SK_ADDR_CHEAT
-// RA;:;:
+
X /******************************************************************************
X *
X * SkCrc32McHash - hash multicast address
@@ -548,15 +522,13 @@
X
X Crc = 0xFFFFFFFFUL;
X for (Idx = 0; Idx < SK_MAC_ADDR_LEN; Idx++) {
- Data = *pMc++;
+ Data = *pMc++;
X for (Bit = 0; Bit < 8; Bit++, Data >>= 1) {
- Crc = (Crc >> 1) ^
- (((Crc ^ Data) & 1) ? CRC32_POLY : 0);
+ Crc = (Crc >> 1) ^ (((Crc ^ Data) & 1) ? CRC32_POLY : 0);
X }
X }
X
X return (Crc & ((1 << HASH_BITS) - 1));
-
X } /* SkCrc32McHash */
X
X #endif /* not SK_ADDR_CHEAT */
@@ -593,7 +565,7 @@


X SK_IOC IoC, /* I/O context */

X SK_U32 PortIdx, /* Port Index */
X SK_MAC_ADDR *pMc, /* multicast address to be added */
-int Flags) /* permanent/non-permanent */
+int Flags) /* permanent/non-permanent */
X {
X int i;
X SK_U8 Inexact;
@@ -628,11 +600,9 @@
X }
X
X /* Not PERMANENT => DRV */
-
X if (PortIdx != pAC->Addr.ActivePort) {
X
X /* Only RLMT is allowed to do this. */
-
X return (SK_MC_ILLEGAL_PORT);
X }
X
@@ -647,41 +617,31 @@
X if (pAC->Addr.Port[PortIdx].NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) {
X
X /* Set exact match entry. */
-
X pAC->Addr.Port[PortIdx].Exact[
X pAC->Addr.Port[PortIdx].NextExactMatchDrv++] = *pMc;
X
X /* Clear InexactFilter. */
-
X for (i = 0; i < 8; i++) {
- pAC->Addr.Port[PortIdx
- ].InexactFilter.Bytes[i] = 0;
+ pAC->Addr.Port[PortIdx].InexactFilter.Bytes[i] = 0;
X }
X }
X else {
X if (!(pMc->a[0] & SK_MC_BIT)) {
-
X /*
X * Hashing only possible with
X * multicast addresses.
X */
-
X return (SK_MC_ILLEGAL_ADDRESS);
X }
X #ifndef SK_ADDR_CHEAT
X /* Compute hash value of address. */
-RA;:;: untested
- HashBit = SkCrc32McHash(&pMc->a[0]);
+ HashBit = 63 - SkCrc32McHash(&pMc->a[0]);
X
X /* Add bit to InexactFilter. */
-
X pAC->Addr.Port[PortIdx].InexactFilter.Bytes[HashBit / 8] |=
X 1 << (HashBit % 8);
-
X #else /* SK_ADDR_CHEAT */
-
X /* Set all bits in InexactFilter. */
-
X for (i = 0; i < 8; i++) {
X pAC->Addr.Port[PortIdx].InexactFilter.Bytes[i] = 0xFF;
X }
@@ -727,10 +687,10 @@


X SK_IOC IoC, /* I/O context */

X SK_U32 PortIdx) /* Port Index */
X {
- SK_U32 i;
- SK_U8 Inexact;
- SK_U16 *OutAddr;
- SK_U16 LoMode; /* Lower 16 bits of XMAC Mode Reg. */
+ SK_U32 i;
+ SK_U8 Inexact;
+ SK_U16 *OutAddr;
+ SK_U16 LoMode; /* Lower 16 bits of XMAC Mode Reg. */
X SK_ADDR_PORT *pAPort;
X
X if (PortIdx >= (SK_U32)pAC->GIni.GIMacsFound) {
@@ -753,18 +713,16 @@
X ("Next0 on Port %d: %d\n", PortIdx, Next0[PortIdx]))
X #endif /* DEBUG */
X
- for (i = 0; /* Also program the virtual address. */
+ for (i = 0; /* Also program the logical MAC address. */
X i < pAPort->NextExactMatchRlmt;
X i++) {
X
X /* Set exact match address i on HW. */
-
X OutAddr = (SK_U16 *)&pAPort->Exact[i].a[0];
X XM_OUTADDR(IoC, PortIdx, XM_EXM(i), OutAddr);
X }
X
X /* Clear other permanent exact match addresses on HW. */
-
X if (pAPort->NextExactMatchRlmt <= SK_ADDR_LAST_MATCH_RLMT) {
X SkXmClrExactAddr(
X pAC,
@@ -774,17 +732,12 @@
X SK_ADDR_LAST_MATCH_RLMT);
X }
X
- for (i = pAPort->FirstExactMatchDrv;
- i < pAPort->NextExactMatchDrv;
- i++) {
-
+ for (i = pAPort->FirstExactMatchDrv; i < pAPort->NextExactMatchDrv; i++) {
X OutAddr = (SK_U16 *)&pAPort->Exact[i].a[0];
X XM_OUTADDR(IoC, PortIdx, XM_EXM(i), OutAddr);
-
X }
X
X /* Clear other non-permanent exact match addresses on HW. */
-
X if (pAPort->NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) {
X SkXmClrExactAddr(
X pAC,
@@ -794,67 +747,51 @@
X SK_ADDR_LAST_MATCH_DRV);
X }
X
- for (Inexact = 0xFF, i = 0; i < 8; i++) {
- Inexact &= pAPort->InexactFilter.Bytes[i];
+ for (Inexact = 0, i = 0; i < 8; i++) {
+ Inexact |= pAPort->InexactFilter.Bytes[i];
X }
- if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) {
X
+ if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) {
X /* Set all bits in 64-bit hash register. */
-
X XM_OUTHASH(IoC, PortIdx, XM_HSM, &OnesHash);
X
X /* Set bit 15 in mode register. */
-
X XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
X LoMode |= XM_MD_ENA_HSH;
X XM_OUT16(IoC, PortIdx, XM_MODE, LoMode);
X }
- else if (Inexact != 0xFF) {
-
- /* Clear bit 15 in mode register. */
+ else if (Inexact != 0) {
+ /* Set 64-bit hash register to InexactFilter. */
+ XM_OUTHASH(IoC, PortIdx, XM_HSM, &pAPort->InexactFilter.Bytes[0]);
X
+ /* Set bit 15 in mode register. */
X XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
- LoMode &= ~XM_MD_ENA_HSH;
+ LoMode |= XM_MD_ENA_HSH;
X XM_OUT16(IoC, PortIdx, XM_MODE, LoMode);
X }
X else {
- /* Set 64-bit hash register to InexactFilter. */
-
- XM_OUTHASH(
- IoC,
- PortIdx,
- XM_HSM,
- &pAPort->InexactFilter.Bytes[0]);
-
- /* Set bit 15 in mode register. */
-
+ /* Clear bit 15 in mode register. */
X XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
- LoMode |= XM_MD_ENA_HSH;
+ LoMode &= ~XM_MD_ENA_HSH;
X XM_OUT16(IoC, PortIdx, XM_MODE, LoMode);
X }
X
X if (pAPort->PromMode != SK_PROM_MODE_NONE) {
- (void)SkAddrPromiscuousChange(
- pAC,
- IoC,
- PortIdx,
- pAPort->PromMode);
+ (void)SkAddrPromiscuousChange(pAC, IoC, PortIdx, pAPort->PromMode);
X }
X
X /* Set port's current MAC address. */
-
X OutAddr = (SK_U16 *)&pAPort->CurrentMacAddress.a[0];
X XM_OUTADDR(IoC, PortIdx, XM_SA, OutAddr);
X
X #ifdef DEBUG
- for (i = 0; /* Also program the virtual address. */
+ for (i = 0; /* Also program the logical MAC address. */
X i < pAPort->NextExactMatchRlmt;
X i++) {
X SK_U8 InAddr8[6];
X SK_U16 *InAddr;
X
X /* Get exact match address i from port PortIdx. */
-
X InAddr = (SK_U16 *)&InAddr8[0];
X XM_INADDR(IoC, PortIdx, XM_EXM(i), InAddr);
X SK_DBG_MSG(
@@ -880,10 +817,6 @@
X #endif /* DEBUG */
X
X /* Determine return value. */
-
- for (Inexact = 0, i = 0; i < 8; i++) {
- Inexact |= pAPort->InexactFilter.Bytes[i];
- }
X if (Inexact == 0 && pAPort->PromMode == 0) {
X return (SK_MC_FILTERING_EXACT);
X }
@@ -915,7 +848,7 @@


X SK_IOC IoC, /* I/O context */

X SK_U32 PortIdx, /* Port Index */
X SK_MAC_ADDR *pNewAddr, /* new MAC address */
-int Flags) /* logical/physical address */
+int Flags) /* logical/physical MAC address */
X {
X SK_U32 i;
X SK_U16 *OutAddr;
@@ -957,7 +890,7 @@
X return (SK_ADDR_TOO_EARLY);
X }
X
- if (Flags & SK_ADDR_PHYSICAL_ADDRESS) { /* Physical address. */
+ if (Flags & SK_ADDR_PHYSICAL_ADDRESS) { /* Physical MAC address. */
X if (SK_ADDR_EQUAL(pNewAddr->a, pAC->Addr.CurrentMacAddress.a)) {
X return (SK_ADDR_DUPLICATE_ADDRESS);
X }
@@ -984,16 +917,14 @@
X pAC->Addr.Port[PortIdx].CurrentMacAddress = *pNewAddr;
X
X /* Change port's address. */
-
X OutAddr = (SK_U16 *)pNewAddr;
X XM_OUTADDR(IoC, PortIdx, XM_SA, OutAddr);
X
X /* Report address change to RLMT. */
-
X Para.Para32[0] = PortIdx;
X SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para);
X }
- else { /* Logical Address. */
+ else { /* Logical MAC address. */
X if (SK_ADDR_EQUAL(pNewAddr->a, pAC->Addr.CurrentMacAddress.a)) {
X return (SK_ADDR_SUCCESS);
X }
@@ -1019,27 +950,26 @@
X SK_DBGMOD_ADDR,
X SK_DBGCAT_CTRL,
X ("Permanent MAC Address: %02X %02X %02X %02X %02X %02X\n",
- pAC->Addr.PermanentMacAddress.a[0],
- pAC->Addr.PermanentMacAddress.a[1],
- pAC->Addr.PermanentMacAddress.a[2],
- pAC->Addr.PermanentMacAddress.a[3],
- pAC->Addr.PermanentMacAddress.a[4],
- pAC->Addr.PermanentMacAddress.a[5]))
+ pAC->Addr.PermanentMacAddress.a[0],
+ pAC->Addr.PermanentMacAddress.a[1],
+ pAC->Addr.PermanentMacAddress.a[2],
+ pAC->Addr.PermanentMacAddress.a[3],
+ pAC->Addr.PermanentMacAddress.a[4],
+ pAC->Addr.PermanentMacAddress.a[5]))
X SK_DBG_MSG(
X pAC,
X SK_DBGMOD_ADDR,
X SK_DBGCAT_CTRL,
- ("New Virtual MAC Address: %02X %02X %02X %02X %02X %02X\n",
- pAC->Addr.CurrentMacAddress.a[0],
- pAC->Addr.CurrentMacAddress.a[1],
- pAC->Addr.CurrentMacAddress.a[2],
- pAC->Addr.CurrentMacAddress.a[3],
- pAC->Addr.CurrentMacAddress.a[4],
- pAC->Addr.CurrentMacAddress.a[5]))
+ ("New logical MAC Address: %02X %02X %02X %02X %02X %02X\n",
+ pAC->Addr.CurrentMacAddress.a[0],
+ pAC->Addr.CurrentMacAddress.a[1],
+ pAC->Addr.CurrentMacAddress.a[2],
+ pAC->Addr.CurrentMacAddress.a[3],
+ pAC->Addr.CurrentMacAddress.a[4],
+ pAC->Addr.CurrentMacAddress.a[5]))
X #endif /* DEBUG */
X
X /* Write address to first exact match entry of active port. */
-
X (void)SkAddrMcUpdate(pAC, IoC, PortIdx);
X }
X
@@ -1066,25 +996,24 @@
X * SK_ADDR_ILLEGAL_PORT
X */
X int SkAddrPromiscuousChange(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* I/O context */
-SK_U32 PortIdx, /* port whose promiscuous mode changes */
-int NewPromMode) /* new promiscuous mode */


+SK_AC *pAC, /* adapter context */

+SK_IOC IoC, /* I/O context */
+SK_U32 PortIdx, /* port whose promiscuous mode changes */
+int NewPromMode) /* new promiscuous mode */
X {
- int i;
+ int i;
X SK_BOOL InexactModeBit;
X SK_U8 Inexact;
X SK_U8 HwInexact;
X SK_FILTER64 HwInexactFilter;
X SK_U16 LoMode; /* Lower 16 bits of XMAC Mode Register. */
- int CurPromMode = SK_PROM_MODE_NONE;
+ int CurPromMode = SK_PROM_MODE_NONE;
X
X if (PortIdx >= (SK_U32)pAC->GIni.GIMacsFound) {
X return (SK_ADDR_ILLEGAL_PORT);
X }
X
X /* Read CurPromMode from Hardware. */
-
X XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
X
X if (LoMode & XM_MD_ENA_PROM) {
@@ -1095,18 +1024,15 @@
X Inexact &= pAC->Addr.Port[PortIdx].InexactFilter.Bytes[i];
X }
X if (Inexact == 0xFF) {
- CurPromMode |= (pAC->Addr.Port[PortIdx].PromMode &
- SK_PROM_MODE_ALL_MC);
+ CurPromMode |= (pAC->Addr.Port[PortIdx].PromMode & SK_PROM_MODE_ALL_MC);
X }
X else {
X /* Read InexactModeBit (bit 15 in mode register). */
-
X XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
-
- InexactModeBit = (LoMode & XM_MD_ENA_HSH) != 0;
+
+ InexactModeBit = (LoMode & XM_MD_ENA_HSH) != 0;
X
X /* Read 64-bit hash register from HW. */
-
X XM_INHASH(IoC, PortIdx, XM_HSM, &HwInexactFilter.Bytes[0]);
X
X for (HwInexact = 0xFF, i = 0; i < 8; i++) {
@@ -1126,43 +1052,34 @@
X
X if ((NewPromMode & SK_PROM_MODE_ALL_MC) &&
X !(CurPromMode & SK_PROM_MODE_ALL_MC)) { /* All MC. */
-
X /* Set all bits in 64-bit hash register. */
-
X XM_OUTHASH(IoC, PortIdx, XM_HSM, &OnesHash);
X
X /* Set bit 15 in mode register. */
-
X XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
X LoMode |= XM_MD_ENA_HSH;
X XM_OUT16(IoC, PortIdx, XM_MODE, LoMode);
X }
X else if ((CurPromMode & SK_PROM_MODE_ALL_MC) &&
X !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm MC. */
-
X for (Inexact = 0, i = 0; i < 8; i++) {
- Inexact |=
- pAC->Addr.Port[PortIdx].InexactFilter.Bytes[i];
+ Inexact |= pAC->Addr.Port[PortIdx].InexactFilter.Bytes[i];
X }
X if (Inexact == 0) {
X /* Clear bit 15 in mode register. */
-
X XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
X LoMode &= ~XM_MD_ENA_HSH;
X XM_OUT16(IoC, PortIdx, XM_MODE, LoMode);
X }
X else {
X /* Set 64-bit hash register to InexactFilter. */
-
X XM_OUTHASH(
X IoC,
X PortIdx,
X XM_HSM,
- &pAC->Addr.Port[PortIdx
- ].InexactFilter.Bytes[0]);
+ &pAC->Addr.Port[PortIdx].InexactFilter.Bytes[0]);
X
X /* Set bit 15 in mode register. */
-
X XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
X LoMode |= XM_MD_ENA_HSH;
X XM_OUT16(IoC, PortIdx, XM_MODE, LoMode);
@@ -1171,29 +1088,27 @@
X
X if ((NewPromMode & SK_PROM_MODE_LLC) &&
X !(CurPromMode & SK_PROM_MODE_LLC)) { /* Prom. LLC */
-
X /* Set promiscuous bit in mode register. */
-
X XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
+
X #if 0
X /* Receive MAC frames. */
-
X LoMode |= XM_MD_RX_MCTRL;
X #endif /* 0 */
+
X LoMode |= XM_MD_ENA_PROM;
X XM_OUT16(IoC, PortIdx, XM_MODE, LoMode);
X }
X else if ((CurPromMode & SK_PROM_MODE_LLC) &&
X !(NewPromMode & SK_PROM_MODE_LLC)) { /* Norm. LLC. */
-
X /* Clear promiscuous bit in mode register. */
-
X XM_IN16(IoC, PortIdx, XM_MODE, &LoMode);
+
X #if 0
X /* Don't receive MAC frames. */
-
X LoMode &= ~XM_MD_RX_MCTRL;
X #endif /* 0 */
+
X LoMode &= ~XM_MD_ENA_PROM;
X XM_OUT16(IoC, PortIdx, XM_MODE, LoMode);
X }
@@ -1218,12 +1133,12 @@
X * SK_ADDR_ILLEGAL_PORT
X */
X int SkAddrSwap(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* I/O context */


+SK_AC *pAC, /* adapter context */

+SK_IOC IoC, /* I/O context */
X SK_U32 FromPortIdx, /* Port1 Index */
-SK_U32 ToPortIdx) /* Port2 Index */
+SK_U32 ToPortIdx) /* Port2 Index */
X {
- int i;
+ int i;
X SK_U8 Byte;
X SK_MAC_ADDR MacAddr;
X SK_U32 DWord;


@@ -1263,8 +1178,7 @@
X }

X
X i = pAC->Addr.Port[FromPortIdx].PromMode;
- pAC->Addr.Port[FromPortIdx].PromMode =
- pAC->Addr.Port[ToPortIdx].PromMode;
+ pAC->Addr.Port[FromPortIdx].PromMode = pAC->Addr.Port[ToPortIdx].PromMode;
X pAC->Addr.Port[ToPortIdx].PromMode = i;
X
X DWord = pAC->Addr.Port[FromPortIdx].FirstExactMatchRlmt;
@@ -1287,7 +1201,7 @@
X pAC->Addr.Port[ToPortIdx].NextExactMatchDrv;
X pAC->Addr.Port[ToPortIdx].NextExactMatchDrv = DWord;
X
- pAC->Addr.ActivePort = ToPortIdx;
+ pAC->Addr.ActivePort = ToPortIdx;
X
X (void)SkAddrMcUpdate(pAC, IoC, FromPortIdx);
X (void)SkAddrMcUpdate(pAC, IoC, ToPortIdx);
@@ -1298,3 +1212,4 @@
X #ifdef __cplusplus
X }
X #endif /* __cplusplus */
+
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/skcsum.c linux/drivers/net/sk98lin/skcsum.c
--- v2.4.0-test8/linux/drivers/net/sk98lin/skcsum.c Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/skcsum.c Fri Sep 15 14:34:19 2000


@@ -2,19 +2,17 @@
X *

X * Name: skcsum.c


X * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.3 $

- * Date: $Date: 1999/05/10 08:39:33 $


+ * Version: $Revision: 1.7 $
+ * Date: $Date: 2000/06/29 13:17:05 $
X * Purpose: Store/verify Internet checksum in send/receive packets.
X *
X ******************************************************************************/

X
X /******************************************************************************
X *
- * (C)Copyright 1998,1999 SysKonnect,
+ * (C)Copyright 1998-2000 SysKonnect,
X * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
X *
- * See the file "skge.c" for further information.
- *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
X * the Free Software Foundation; either version 2 of the License, or

@@ -29,6 +27,23 @@


X * History:
X *

X * $Log: skcsum.c,v $


+ * Revision 1.7 2000/06/29 13:17:05 rassmann
+ * Corrected reception of a packet with UDP checksum == 0 (which means there
+ * is no UDP checksum).
+ *

+ * Revision 1.6 2000/02/21 12:35:10 cgoos
+ * Fixed license header comment.
+ *
+ * Revision 1.5 2000/02/21 11:05:19 cgoos
+ * Merged changes back to common source.
+ * Fixed rx path for BIG ENDIAN architecture.
+ *
+ * Revision 1.1 1999/07/26 15:28:12 mkarl


+ * added return SKCS_STATUS_IP_CSUM_ERROR_UDP and
+ * SKCS_STATUS_IP_CSUM_ERROR_TCP to pass the NidsTester
+ * changed from common source to windows specific source

+ * therefore restarting with v1.0
+ *
X * Revision 1.3 1999/05/10 08:39:33 mkarl
X * prevent overflows in SKCS_HTON16
X * fixed a bug in pseudo header checksum calculation
@@ -48,7 +63,7 @@
X
X #ifndef lint
X static const char SysKonnectFileId[] = "@(#)"
- "$Id: skcsum.c,v 1.3 1999/05/10 08:39:33 mkarl Exp $"
+ "$Id: skcsum.c,v 1.7 2000/06/29 13:17:05 rassmann Exp $"
X " (C) SysKonnect.";
X #endif /* !lint */
X
@@ -94,13 +109,13 @@


X /* defines ********************************************************************/
X

X /* The size of an Ethernet MAC header. */
-#define SKCS_ETHERNET_MAC_HEADER_SIZE (6+6+2)
+#define SKCS_ETHERNET_MAC_HEADER_SIZE (6+6+2)
X
X /* The size of the used topology's MAC header. */
X #define SKCS_MAC_HEADER_SIZE SKCS_ETHERNET_MAC_HEADER_SIZE
X
X /* The size of the IP header without any option fields. */
-#define SKCS_IP_HEADER_SIZE 20
+#define SKCS_IP_HEADER_SIZE 20
X
X /*
X * Field offsets within the IP header.
@@ -110,23 +125,31 @@
X #define SKCS_OFS_IP_HEADER_VERSION_AND_LENGTH 0
X
X /* "Total Length". */
-#define SKCS_OFS_IP_TOTAL_LENGTH 2
+#define SKCS_OFS_IP_TOTAL_LENGTH 2
X
X /* "Flags" "Fragment Offset". */
X #define SKCS_OFS_IP_FLAGS_AND_FRAGMENT_OFFSET 6
X
X /* "Next Level Protocol" identifier. */
-#define SKCS_OFS_IP_NEXT_LEVEL_PROTOCOL 9
+#define SKCS_OFS_IP_NEXT_LEVEL_PROTOCOL 9
X
X /* Source IP address. */
-#define SKCS_OFS_IP_SOURCE_ADDRESS 12
+#define SKCS_OFS_IP_SOURCE_ADDRESS 12
X
X /* Destination IP address. */
-#define SKCS_OFS_IP_DESTINATION_ADDRESS 16
+#define SKCS_OFS_IP_DESTINATION_ADDRESS 16
+
+
+/*
+ * Field offsets within the UDP header.
+ */
+
+/* UDP checksum. */
+#define SKCS_OFS_UDP_CHECKSUM 6
X
X /* IP "Next Level Protocol" identifiers (see RFC 790). */
-#define SKCS_PROTO_ID_TCP 6 /* Transport Control Protocol */
-#define SKCS_PROTO_ID_UDP 17 /* User Datagram Protocol */
+#define SKCS_PROTO_ID_TCP 6 /* Transport Control Protocol */
+#define SKCS_PROTO_ID_UDP 17 /* User Datagram Protocol */
X
X /* IP "Don't Fragment" bit. */
X #define SKCS_IP_DONT_FRAGMENT SKCS_HTON16(0x4000)
@@ -224,8 +247,8 @@
X * of the TCP or UDP pseudo header is returned here.
X */
X void SkCsGetSendInfo(
-SK_AC *pAc, /* Adapter context struct. */
-void *pIpHeader, /* IP header. */
+SK_AC *pAc, /* Adapter context struct. */
+void *pIpHeader, /* IP header. */
X SKCS_PACKET_INFO *pPacketInfo) /* Packet information struct. */
X {
X /* Internet Header Version found in IP header. */
@@ -397,7 +420,8 @@
X SKCS_OC_ADD(pPacketInfo->PseudoHeaderChecksum, PseudoHeaderChecksum, 0);
X
X NextLevelProtoStats->TxOkCts++; /* Success. */
-}
+} /* SkCsGetSendInfo */
+


X
X /******************************************************************************
X *

@@ -415,7 +439,8 @@
X * pAc - Pointer to adapter context struct.
X *
X * pIpHeader - Pointer to IP header. Must be at least the length in bytes
- * of the received IP header including any option fields.
+ * of the received IP header including any option fields. For UDP packets,
+ * 8 additional bytes are needed to access the UDP checksum.
X *
X * Note: The actual length of the IP header is stored in the lower four
X * bits of the first octet of the IP header as the number of 4-byte words,
@@ -431,18 +456,20 @@
X * Returns:


X * SKCS_STATUS_UNKNOWN_IP_VERSION - Not an IP v4 frame.
X * SKCS_STATUS_IP_CSUM_ERROR - IP checksum error.
+ * SKCS_STATUS_IP_CSUM_ERROR_TCP - IP checksum error in TCP frame.
+ * SKCS_STATUS_IP_CSUM_ERROR_UDP - IP checksum error in UDP frame
X * SKCS_STATUS_IP_FRAGMENT - IP fragment (IP checksum ok).
X * SKCS_STATUS_IP_CSUM_OK - IP checksum ok (not a TCP or UDP frame).
X * SKCS_STATUS_TCP_CSUM_ERROR - TCP checksum error (IP checksum ok).
X * SKCS_STATUS_UDP_CSUM_ERROR - UDP checksum error (IP checksum ok).
X * SKCS_STATUS_TCP_CSUM_OK - IP and TCP checksum ok.
X * SKCS_STATUS_UDP_CSUM_OK - IP and UDP checksum ok.
+ * SKCS_STATUS_IP_CSUM_OK_NO_UDP - IP checksum OK and no UDP checksum.
X *

- * Note: The SKCS_STATUS_XXX values returned here are *not* defined by
- * the CSUM module but must be defined in some header file by the module
- * using CSUM. In this way, the calling module can assign return values
- * for its own needs, e.g. by assigning bit flags to the individual
- * protocols.
+ * Note: If SKCS_OVERWRITE_STATUS is defined, the SKCS_STATUS_XXX values
+ * returned here can be defined in some header file by the module using CSUM.
+ * In this way, the calling module can assign return values for its own needs,
+ * e.g. by assigning bit flags to the individual protocols.
X */
X SKCS_STATUS SkCsGetReceiveInfo(
X SK_AC *pAc, /* Adapter context struct. */


@@ -544,30 +571,36 @@
X

X /* Adjust the IP header and IP data checksums. */
X
- SKCS_OC_ADD(IpHeaderChecksum,
- IpHeaderChecksum, IpOptionsChecksum);
+ SKCS_OC_ADD(IpHeaderChecksum, IpHeaderChecksum, IpOptionsChecksum);
X
- SKCS_OC_SUB(IpDataChecksum,
- IpDataChecksum, IpOptionsChecksum);
+ SKCS_OC_SUB(IpDataChecksum, IpDataChecksum, IpOptionsChecksum);
X }
X
- /* Check if the IP header checksum is ok. */
X /*
- * NOTE: We must check the IP header checksum even if the caller does
- * not want us to do so because we cannot do any further processing of
- * the packet without a valid IP checksum.
+ * Check if the IP header checksum is ok.
+ *
+ * NOTE: We must check the IP header checksum even if the caller just wants
+ * us to check upper-layer checksums, because we cannot do any further
+ * processing of the packet without a valid IP checksum.
X */
+
+ /* Get the next level protocol identifier. */
+
+ NextLevelProtocol = *(SK_U8 *)
+ SKCS_IDX(pIpHeader, SKCS_OFS_IP_NEXT_LEVEL_PROTOCOL);
X
X if (IpHeaderChecksum != 0xFFFF) {
X pAc->Csum.ProtoStats[SKCS_PROTO_STATS_IP].RxErrCts++;
+ /* the NDIS tester wants to know the upper level protocol too */
+ if (NextLevelProtocol == SKCS_PROTO_ID_TCP) {
+ return(SKCS_STATUS_IP_CSUM_ERROR_TCP);
+ }
+ else if (NextLevelProtocol == SKCS_PROTO_ID_UDP) {
+ return(SKCS_STATUS_IP_CSUM_ERROR_UDP);
+ }
X return (SKCS_STATUS_IP_CSUM_ERROR);
X }
X
- /* Get the next level protocol identifier. */
-
- NextLevelProtocol =
- *(SK_U8 *) SKCS_IDX(pIpHeader, SKCS_OFS_IP_NEXT_LEVEL_PROTOCOL);
-
X /*
X * Check if this is a TCP or UDP frame and if we should calculate the
X * TCP/UDP pseudo header checksum.
@@ -579,14 +612,12 @@
X if ((pAc->Csum.ReceiveFlags & SKCS_PROTO_TCP) != 0 &&
X NextLevelProtocol == SKCS_PROTO_ID_TCP) {
X /* TCP/IP frame. */
- NextLevelProtoStats =
- &pAc->Csum.ProtoStats[SKCS_PROTO_STATS_TCP];
+ NextLevelProtoStats = &pAc->Csum.ProtoStats[SKCS_PROTO_STATS_TCP];
X }
X else if ((pAc->Csum.ReceiveFlags & SKCS_PROTO_UDP) != 0 &&
X NextLevelProtocol == SKCS_PROTO_ID_UDP) {
X /* UDP/IP frame. */
- NextLevelProtoStats =
- &pAc->Csum.ProtoStats[SKCS_PROTO_STATS_UDP];
+ NextLevelProtoStats = &pAc->Csum.ProtoStats[SKCS_PROTO_STATS_UDP];


X }
X else {
X /*

@@ -615,6 +646,24 @@
X }
X
X /*
+ * 08-May-2000 ra
+ *
+ * From RFC 768 (UDP)
+ * If the computed checksum is zero, it is transmitted as all ones (the
+ * equivalent in one's complement arithmetic). An all zero transmitted
+ * checksum value means that the transmitter generated no checksum (for
+ * debugging or for higher level protocols that don't care).
+ */
+
+ if (NextLevelProtocol == SKCS_PROTO_ID_UDP &&
+ *(SK_U16*)SKCS_IDX(pIpHeader, IpHeaderLength + 6) == 0x0000) {
+
+ NextLevelProtoStats->RxOkCts++;
+
+ return (SKCS_STATUS_IP_CSUM_OK_NO_UDP);
+ }
+
+ /*
X * Calculate the TCP/UDP checksum.
X */
X
@@ -639,7 +688,7 @@
X SKCS_OFS_IP_DESTINATION_ADDRESS + 0) +
X (unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
X SKCS_OFS_IP_DESTINATION_ADDRESS + 2) +
- (unsigned long) (NextLevelProtocol << 8) +
+ (unsigned long) SKCS_HTON16(NextLevelProtocol) +
X (unsigned long) SKCS_HTON16(IpDataLength) +
X
X /* Add the TCP/UDP header checksum. */
@@ -672,7 +721,8 @@
X
X return (NextLevelProtocol == SKCS_PROTO_ID_TCP ?
X SKCS_STATUS_TCP_CSUM_ERROR : SKCS_STATUS_UDP_CSUM_ERROR);
-}
+} /* SkCsGetReceiveInfo */
+


X
X /******************************************************************************
X *

@@ -702,7 +752,7 @@
X * Returns the two hardware checksum start offsets.
X */
X void SkCsSetReceiveFlags(
-SK_AC *pAc, /* Adapter context struct. */
+SK_AC *pAc, /* Adapter context struct. */
X unsigned ReceiveFlags, /* New receive flags. */
X unsigned *pChecksum1Offset, /* Offset for hardware checksum 1. */
X unsigned *pChecksum2Offset) /* Offset for hardware checksum 2. */
@@ -719,9 +769,10 @@
X * if there are any IP header options in the actual packet.
X */
X *pChecksum2Offset = SKCS_MAC_HEADER_SIZE + SKCS_IP_HEADER_SIZE;
-}
+} /* SkCsSetReceiveFlags */
X
X #ifndef SkCsCalculateChecksum
+
X /******************************************************************************
X *
X * SkCsCalculateChecksum - calculate checksum for specified data
@@ -783,7 +834,8 @@
X /* Note: All bits beyond the 16-bit limit are now zero. */
X
X return ((unsigned) Checksum);
-}
+} /* SkCsCalculateChecksum */
+
X #endif /* SkCsCalculateChecksum */
X
X /******************************************************************************
@@ -833,7 +885,7 @@
X memset(&pAc->Csum.ProtoStats[0], 0,
X sizeof(pAc->Csum.ProtoStats));
X }
- else { /* Clear for individual protocol. */
+ else { /* Clear for individual protocol. */
X memset(&pAc->Csum.ProtoStats[ProtoIndex], 0,
X sizeof(pAc->Csum.ProtoStats[ProtoIndex]));
X }
@@ -842,6 +894,6 @@
X break;
X }
X return (0); /* Success. */
-}
+} /* SkCsEvent */
X
X #endif /* SK_USE_CSUM */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/skge.c linux/drivers/net/sk98lin/skge.c
--- v2.4.0-test8/linux/drivers/net/sk98lin/skge.c Sun Aug 6 22:20:09 2000
+++ linux/drivers/net/sk98lin/skge.c Fri Sep 15 14:34:19 2000


@@ -2,8 +2,8 @@
X *

X * Name: skge.c


X * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.27 $

- * Date: $Date: 1999/11/25 09:06:28 $


+ * Version: $Revision: 1.29 $

+ * Date: $Date: 2000/02/21 13:31:56 $
X * Purpose: The main driver source module
X *
X ******************************************************************************/
@@ -46,6 +46,25 @@


X * History:
X *

X * $Log: skge.c,v $
+ * Kernel 2.4.x specific:
+ * Revision 1.xx 2000/09/12 13:31:56 cgoos
+ * Fixed missign "dev=NULL in skge_probe.
+ * Added counting for jumbo frames (corrects error statistic).
+ * Removed VLAN tag check (enables VLAN support).
+ *
+ * Kernel 2.2.x specific:
+ * Revision 1.29 2000/02/21 13:31:56 cgoos
+ * Fixed "unused" warning for UltraSPARC change.
+ *
+ * Partially kernel 2.2.x specific:
+ * Revision 1.28 2000/02/21 10:32:36 cgoos
+ * Added fixes for UltraSPARC.
+ * Now printing RlmtMode and PrefPort setting at startup.
+ * Changed XmitFrame return value.
+ * Fixed rx checksum calculation for BIG ENDIAN systems.
+ * Fixed rx jumbo frames counted as ierrors.
+ *
+ *
X * Revision 1.27 1999/11/25 09:06:28 cgoos
X * Changed base_addr to unsigned long.
X *
@@ -225,7 +244,7 @@
X
X static const char SysKonnectFileId[] = "@(#)" __FILE__ " (C) SysKonnect.";
X static const char SysKonnectBuildNumber[] =
- "@(#)SK-BUILD: 3.02 (19991111) PL: 01";
+ "@(#)SK-BUILD: 3.05 (20000907) PL: 01";
X
X #include <linux/module.h>
X #include <linux/init.h>
@@ -235,10 +254,10 @@
X
X /* defines ******************************************************************/
X
-#define BOOT_STRING "sk98lin: Network Device Driver v3.02\n" \
- "Copyright (C) 1999 SysKonnect"
+#define BOOT_STRING "sk98lin: Network Device Driver v3.05\n" \
+ "Copyright (C) 1999-2000 SysKonnect"
X
-#define VER_STRING "3.02"
+#define VER_STRING "3.05"
X
X
X /* for debuging on x86 only */
@@ -373,6 +392,8 @@
X PCI_DEVICE_ID_SYSKONNECT_GE, pdev)) != NULL) {
X if (pci_enable_device(pdev))
X continue;
+
+ dev = NULL;
X dev = init_etherdev(dev, sizeof(SK_AC));
X
X if (dev == NULL) {
@@ -785,6 +806,14 @@
X ProductStr(pAC);
X printk("%s: %s\n", dev->name, pAC->DeviceStr);
X
+ /* Print configuration settings */
+ printk(" PrefPort:%c RlmtMode:%s\n",
+ 'A' + pAC->Rlmt.PrefPort,
+ (pAC->RlmtMode==0) ? "ChkLink" :
+ ((pAC->RlmtMode==1) ? "ChkLink" :
+ ((pAC->RlmtMode==3) ? "ChkOth" :
+ ((pAC->RlmtMode==7) ? "ChkSeg" : "Error"))));
+
X SkGeYellowLED(pAC, pAC->IoBase, 1);
X
X /*
@@ -1936,6 +1965,10 @@
X } /* frame > SK_COPY_TRESHOLD */
X
X FrameStat = pRxd->FrameStat;
+ if ((FrameStat & XMR_FS_LNG_ERR) != 0) {
+ /* jumbo frame, count to correct statistic */
+ SK_PNMI_CNT_RX_LONGFRAMES(pAC, pRxPort->PortIndex);
+ }
X pRxd = pRxd->pNextRxd;
X pRxPort->pRxdRingHead = pRxd;
X pRxPort->RxdRingFree ++;
@@ -1947,9 +1980,9 @@
X pRxPort->RxdRingFree));
X
X if ((Control & RX_CTRL_STAT_VALID) == RX_CTRL_STAT_VALID &&
- (FrameStat &
- (XMR_FS_ANY_ERR | XMR_FS_1L_VLAN | XMR_FS_2L_VLAN))
- == 0) {
+ (FrameStat & XMR_FS_ANY_ERR) == 0) {
+ // was the following, changed to allow VLAN support
+ // (XMR_FS_ANY_ERR | XMR_FS_1L_VLAN | XMR_FS_2L_VLAN)
X SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
X SK_DBGCAT_DRV_RX_PROGRESS,("V"));
X ForRlmt = SK_RLMT_RX_PROTOCOL;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/skgehwt.c linux/drivers/net/sk98lin/skgehwt.c
--- v2.4.0-test8/linux/drivers/net/sk98lin/skgehwt.c Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/skgehwt.c Fri Sep 15 14:34:19 2000


@@ -2,8 +2,8 @@
X *

X * Name: skgehwt.c


X * Project: GEnesis, PCI Gigabit Ethernet Adapter
- * Version: $Revision: 1.12 $

- * Date: $Date: 1998/10/15 15:11:34 $


+ * Version: $Revision: 1.13 $

+ * Date: $Date: 1999/11/22 13:31:12 $
X * Purpose: Hardware Timer.
X *
X ******************************************************************************/
@@ -13,8 +13,6 @@
X * (C)Copyright 1998,1999 SysKonnect,


X * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
X *
- * See the file "skge.c" for further information.
- *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
X * the Free Software Foundation; either version 2 of the License, or

@@ -29,6 +27,9 @@


X * History:
X *

X * $Log: skgehwt.c,v $
+ * Revision 1.13 1999/11/22 13:31:12 cgoos


+ * Changed license header to GPL.
+ *

X * Revision 1.12 1998/10/15 15:11:34 gklug


X * fix: ID_sccs to SysKonnectFileId
X *

@@ -76,7 +77,7 @@


X Event queue and dispatcher
X */

X static const char SysKonnectFileId[] =

- "$Header: /usr56/projects/ge/schedule/skgehwt.c,v 1.12 1998/10/15 15:11:34 gklug Exp $" ;
+ "$Header: /usr56/projects/ge/schedule/skgehwt.c,v 1.13 1999/11/22 13:31:12 cgoos Exp $" ;


X
X #include "h/skdrv1st.h" /* Driver Specific Definitions */

X #include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/skgeinit.c linux/drivers/net/sk98lin/skgeinit.c
--- v2.4.0-test8/linux/drivers/net/sk98lin/skgeinit.c Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/skgeinit.c Fri Sep 15 14:34:19 2000


@@ -2,19 +2,17 @@
X *

X * Name: skgeinit.c


X * Project: GEnesis, PCI Gigabit Ethernet Adapter

- * Version: $Revision: 1.54 $
- * Date: $Date: 1999/10/26 07:32:54 $
+ * Version: $Revision: 1.57 $
+ * Date: $Date: 2000/08/03 14:55:28 $
X * Purpose: Contains functions to initialize the GE HW


X *
X ******************************************************************************/
X
X /******************************************************************************
X *
- * (C)Copyright 1998,1999 SysKonnect,
+ * (C)Copyright 1998-2000 SysKonnect,
X * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
X *
- * See the file "skge.c" for further information.
- *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
X * the Free Software Foundation; either version 2 of the License, or
@@ -29,6 +27,16 @@
X * History:
X *

X * $Log: skgeinit.c,v $
+ * Revision 1.57 2000/08/03 14:55:28 rassmann
+ * Waiting for I2C to be ready before de-initializing adapter
+ * (prevents sensors from hanging up).
+ *
+ * Revision 1.56 2000/07/27 12:16:48 gklug
+ * fix: Stop Port check of the STOP bit does now take 2/18 sec as wanted
+ *
+ * Revision 1.55 1999/11/22 13:32:26 cgoos


+ * Changed license header to GPL.
+ *

X * Revision 1.54 1999/10/26 07:32:54 malthoff
X * Initialize PHWLinkUp with SK_FALSE. Required for Diagnostics.
X *
@@ -199,7 +207,7 @@
X * DoInitRamQueue(), and SkGeCfgSync().
X * Add coding for SkGeInitMacArb(), SkGeInitPktArb(),
X * SkGeInitMacFifo(), SkGeInitRamBufs(),
- * SkGeInitRamIface(), and SkGeInitBmu().
+ * SkGeInitRamIface(), and SkGeInitBmu().
X *
X * Revision 1.11 1998/09/29 08:26:29 malthoff
X * bug fix: SkGeInit0() 'i' should be increment.
@@ -275,7 +283,7 @@
X /* local variables ************************************************************/
X

X static const char SysKonnectFileId[] =

- "@(#)$Id: skgeinit.c,v 1.54 1999/10/26 07:32:54 malthoff Exp $ (C) SK ";
+ "@(#)$Id: skgeinit.c,v 1.57 2000/08/03 14:55:28 rassmann Exp $ (C) SK ";
X
X struct s_QOffTab {
X int RxQOff; /* Receive Queue Address Offset */
@@ -283,7 +291,7 @@
X int XaQOff; /* Async Tx Queue Address Offset */
X };
X static struct s_QOffTab QOffTab[] = {
- { Q_R1, Q_XS1, Q_XA1 }, { Q_R2, Q_XS2, Q_XA2 }
+ {Q_R1, Q_XS1, Q_XA1}, {Q_R2, Q_XS2, Q_XA2}
X };
X
X
@@ -303,7 +311,7 @@
X void SkGePollRxD(
X SK_AC *pAC, /* adapter context */
X SK_IOC IoC, /* IO context */
-int Port, /* Port Index (MAC_1 + n) */
+int Port, /* Port Index (MAC_1 + n) */
X SK_BOOL PollRxD) /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */
X {
X SK_GEPORT *pPrt;
@@ -311,12 +319,13 @@


X pPrt = &pAC->GIni.GP[Port];
X

X if (PollRxD) {
- SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff,Q_CSR), CSR_ENA_POL);
+ SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_ENA_POL);
X }
X else {
- SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff,Q_CSR), CSR_DIS_POL);
+ SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_DIS_POL);
X }
-}
+} /* SkGePollRxD */
+


X
X /******************************************************************************
X *

@@ -334,7 +343,7 @@
X void SkGePollTxD(
X SK_AC *pAC, /* adapter context */
X SK_IOC IoC, /* IO context */
-int Port, /* Port Index (MAC_1 + n) */
+int Port, /* Port Index (MAC_1 + n) */
X SK_BOOL PollTxD) /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */
X {
X SK_GEPORT *pPrt;
@@ -350,12 +359,12 @@
X }
X
X if (pPrt->PXSQSize != 0) {
- SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff,Q_CSR), DWord);
+ SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), DWord);
X }
X if (pPrt->PXAQSize != 0) {
- SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff,Q_CSR), DWord);
+ SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), DWord);
X }
-}
+} /* SkGePollTxD */
X
X
X /******************************************************************************
@@ -374,17 +383,18 @@
X void SkGeYellowLED(
X SK_AC *pAC, /* adapter context */
X SK_IOC IoC, /* IO context */
-int State) /* yellow LED state, 0 = OFF, 0 != ON */
+int State) /* yellow LED state, 0 = OFF, 0 != ON */
X {
X if (State == 0) {
X /* Switch yellow LED OFF */
- SK_OUT8(IoC, B0_LED, LED_STAT_OFF) ;
+ SK_OUT8(IoC, B0_LED, LED_STAT_OFF);
X }
X else {
X /* Switch yellow LED ON */
- SK_OUT8(IoC, B0_LED, LED_STAT_ON) ;
+ SK_OUT8(IoC, B0_LED, LED_STAT_ON);
X }
-}
+} /* SkGeYellowLED */
+


X
X /******************************************************************************
X *

@@ -398,7 +408,7 @@
X * 'Led' must contain the address offset of the LEDs INI register.
X *
X * Usage:
- * SkGeXmitLED(pAC, IoC, MR_ADDR(Port,TX_LED_INI), SK_LED_ENA);
+ * SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA);
X *
X * Returns:
X * nothing
@@ -406,31 +416,31 @@
X void SkGeXmitLED(
X SK_AC *pAC, /* adapter context */
X SK_IOC IoC, /* IO context */
-int Led, /* offset to the LED Init Value register */
-int Mode) /* Mode may be SK_LED_DIS, SK_LED_ENA, SK_LED_TST */
+int Led, /* offset to the LED Init Value register */
+int Mode) /* Mode may be SK_LED_DIS, SK_LED_ENA, SK_LED_TST */
X {
X SK_U32 LedIni;
X
X switch (Mode) {
X case SK_LED_ENA:
X LedIni = SK_XMIT_DUR * (SK_U32)pAC->GIni.GIHstClkFact / 100;
- SK_OUT32(IoC, Led+XMIT_LED_INI, LedIni);
- SK_OUT8(IoC, Led+XMIT_LED_CTRL, LED_START);
- break ;
+ SK_OUT32(IoC, Led + XMIT_LED_INI, LedIni);
+ SK_OUT8(IoC, Led + XMIT_LED_CTRL, LED_START);
+ break;
X case SK_LED_TST:
- SK_OUT8(IoC, Led+XMIT_LED_TST, LED_T_ON);
- SK_OUT32(IoC, Led+XMIT_LED_CNT, 100);
- SK_OUT8(IoC, Led+XMIT_LED_CTRL, LED_START);
- break ;
+ SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_ON);
+ SK_OUT32(IoC, Led + XMIT_LED_CNT, 100);
+ SK_OUT8(IoC, Led + XMIT_LED_CTRL, LED_START);
+ break;
X case SK_LED_DIS:
X default:
X /*
X * Do NOT stop the LED Timer here. The LED might be
X * in on state. But it needs to go off.
X */
- SK_OUT32(IoC, Led+XMIT_LED_CNT, 0);
- SK_OUT8(IoC, Led+XMIT_LED_TST, LED_T_OFF);
- break ;
+ SK_OUT32(IoC, Led + XMIT_LED_CNT, 0);
+ SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_OFF);
+ break;
X }
X
X /*
@@ -440,7 +450,8 @@
X * (Broadcom: It may be that PHY_B_PEC_EN_LTR has to be set.)
X * (In this case it has to be added here. But we will see. XXX)
X */
-}
+} /* SkGeXmitLED */
+


X
X /******************************************************************************
X *

@@ -461,12 +472,12 @@
X * 1: configuration error
X */
X static int DoCalcAddr(
-SK_AC *pAC, /* adapter context */
-SK_GEPORT *pPrt, /* port index */
-int QuSize, /* size of the queue to configure in kB */
-SK_U32 *StartVal, /* start value for address calculation */
-SK_U32 *QuStartAddr, /* start addr to calculate */
-SK_U32 *QuEndAddr) /* end address to calculate */


+SK_AC *pAC, /* adapter context */

+SK_GEPORT *pPrt, /* port index */
+int QuSize, /* size of the queue to configure in kB */
+SK_U32 *StartVal, /* start value for address calculation */
+SK_U32 *QuStartAddr, /* start addr to calculate */
+SK_U32 *QuEndAddr) /* end address to calculate */
X {
X SK_U32 EndVal;
X SK_U32 NextStart;


@@ -494,7 +505,7 @@
X

X *StartVal = NextStart;
X return (Rtv);
-}
+} /* DoCalcAddr */
X
X
X /******************************************************************************
@@ -521,8 +532,8 @@
X * 1: Queue Size Configuration invalid
X */
X static int SkGeCheckQSize(
-SK_AC *pAC, /* adapter context */
-int Port) /* port index */


+SK_AC *pAC, /* adapter context */

+int Port) /* port index */
X {
X SK_GEPORT *pPrt;
X int UsedMem;
@@ -540,9 +551,7 @@
X (pPrt->PXSQSize & QZ_UNITS) ||
X (pPrt->PXAQSize & QZ_UNITS)) {
X
- SK_ERR_LOG(pAC, SK_ERRCL_SW,
- SKERR_HWI_E012,
- SKERR_HWI_E012MSG);
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG);
X Rtv = 1;
X goto CheckQSizeEnd;
X }
@@ -550,9 +559,7 @@
X UsedMem += pPrt->PRxQSize + pPrt->PXSQSize + pPrt->PXAQSize;
X
X if (i == Port && pPrt->PRxQSize < SK_MIN_RXQ_SIZE) {
- SK_ERR_LOG(pAC, SK_ERRCL_SW,
- SKERR_HWI_E011,
- SKERR_HWI_E011MSG);
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E011, SKERR_HWI_E011MSG);
X Rtv = 1;
X goto CheckQSizeEnd;
X }
@@ -584,17 +591,15 @@
X Rtv |= Rtv2;
X
X if (Rtv) {
- SK_ERR_LOG(pAC, SK_ERRCL_SW,
- SKERR_HWI_E013,
- SKERR_HWI_E013MSG);
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E013, SKERR_HWI_E013MSG);


X break;
X }
X }
X

-
X CheckQSizeEnd:
X return (Rtv);
-}
+} /* SkGeCheckQSize */
+


X
X /******************************************************************************
X *

@@ -633,7 +638,8 @@
X * There is not start or enable buttom to push, therefore
X * the MAC arbiter is configured and enabled now.
X */
-}
+} /* SkGeInitMacArb */
+


X
X /******************************************************************************
X *

@@ -666,10 +672,11 @@
X SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1);
X }
X else {
- SK_OUT16(IoC, B3_PA_CTRL,(PA_ENA_TO_TX1|PA_ENA_TO_TX2));
+ SK_OUT16(IoC, B3_PA_CTRL,(PA_ENA_TO_TX1 | PA_ENA_TO_TX2));
X }
X }
-}
+} /* SkGeInitPktArb */
+


X
X /******************************************************************************
X *

@@ -684,7 +691,7 @@
X static void SkGeInitMacFifo(


X SK_AC *pAC, /* adapter context */
X SK_IOC IoC, /* IO context */

-int Port) /* Port Index (MAC_1 + n) */
+int Port) /* Port Index (MAC_1 + n) */
X {
X /*
X * For each FIFO:
@@ -707,7 +714,8 @@
X if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) {
X SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_FLUSH);
X }
-}
+} /* SkGeInitMacFifo */
+


X
X /******************************************************************************
X *

@@ -731,7 +739,7 @@
X void SkGeLoadLnkSyncCnt(
X SK_AC *pAC, /* adapter context */
X SK_IOC IoC, /* IO context */
-int Port, /* Port Index (MAC_1 + n) */
+int Port, /* Port Index (MAC_1 + n) */
X SK_U32 CntVal) /* Counter value */
X {
X SK_U32 OrgIMsk;
@@ -740,7 +748,7 @@
X SK_BOOL IrqPend;
X
X /* stop counter */
- SK_OUT8(IoC, MR_ADDR(Port,LNK_SYNC_CTRL), LED_STOP);
+ SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_STOP);
X
X /*
X * ASIC problem:
@@ -770,17 +778,18 @@
X }
X
X /* load counter */
- SK_OUT32(IoC, MR_ADDR(Port,LNK_SYNC_INI), CntVal);
+ SK_OUT32(IoC, MR_ADDR(Port, LNK_SYNC_INI), CntVal);
X
X /* start counter */
- SK_OUT8(IoC, MR_ADDR(Port,LNK_SYNC_CTRL), LED_START);
+ SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_START);
X
X if (!IrqPend) {
X /* clear the unexpected IRQ, and restore the interrupt mask */
- SK_OUT8(IoC, MR_ADDR(Port,LNK_SYNC_CTRL), LED_CLR_IRQ);
+ SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_CLR_IRQ);
X SK_OUT32(IoC, B0_IMSK, OrgIMsk);
X }
-}
+} /* SkGeLoadLnkSyncCnt*/
+


X
X /******************************************************************************
X *

@@ -813,10 +822,10 @@
X int SkGeCfgSync(
X SK_AC *pAC, /* adapter context */
X SK_IOC IoC, /* IO context */
-int Port, /* Port Index (MAC_1 + n) */
+int Port, /* Port Index (MAC_1 + n) */
X SK_U32 IntTime, /* Interval Timer Value in units of 8ns */
X SK_U32 LimCount, /* Number of bytes to transfer during IntTime */
-int SyncMode) /* Sync Mode: TXA_ENA_ALLOC | TXA_DIS_ALLOC | 0 */
+int SyncMode) /* Sync Mode: TXA_ENA_ALLOC | TXA_DIS_ALLOC | 0 */
X {
X int Rtv;
X
@@ -836,8 +845,7 @@
X IntTime = (IntTime / 2) * pAC->GIni.GIHstClkFact / 100;
X LimCount = LimCount / 8;
X if (IntTime > TXA_MAX_VAL || LimCount > TXA_MAX_VAL) {
- SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010,
- SKERR_HWI_E010MSG);
+ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG);
X Rtv = 1;
X goto CfgSyncEnd;
X }
@@ -852,14 +860,14 @@
X * - start 'Rate Control' and disable 'Force Sync'
X * if Interval Timer or Limit Counter not zero.
X */
- SK_OUT8(IoC, MR_ADDR(Port,TXA_CTRL),
+ SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
X TXA_ENA_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
- SK_OUT32(IoC, MR_ADDR(Port,TXA_ITI_INI), IntTime);
- SK_OUT32(IoC, MR_ADDR(Port,TXA_LIM_INI), LimCount);
- SK_OUT8(IoC, MR_ADDR(Port,TXA_CTRL),
+ SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), IntTime);
+ SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), LimCount);
+ SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
X (SyncMode & (TXA_ENA_ALLOC|TXA_DIS_ALLOC)));
X if (IntTime != 0 || LimCount != 0) {
- SK_OUT8(IoC, MR_ADDR(Port,TXA_CTRL),
+ SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
X TXA_DIS_FSYNC|TXA_START_RC);
X }
X }
@@ -870,7 +878,8 @@
X
X CfgSyncEnd:
X return (Rtv);
-}
+} /* SkGeCfgSync */
+


X
X /******************************************************************************
X *

@@ -884,12 +893,12 @@
X * nothing
X */
X static void DoInitRamQueue(
-SK_AC *pAC, /* adapter context */
-SK_IOC IoC, /* IO context */
-int QuIoOffs, /* Queue IO Address Offset */


+SK_AC *pAC, /* adapter context */

+SK_IOC IoC, /* IO context */
+int QuIoOffs, /* Queue IO Address Offset */
X SK_U32 QuStartAddr, /* Queue Start Address */
-SK_U32 QuEndAddr, /* Queue End Address */
-int QuType) /* Queue Type (SK_RX_SRAM_Q|SK_RX_BRAM_Q|SK_TX_RAM_Q) */
+SK_U32 QuEndAddr, /* Queue End Address */
+int QuType) /* Queue Type (SK_RX_SRAM_Q|SK_RX_BRAM_Q|SK_TX_RAM_Q) */
X {
X SK_U32 RxUpThresVal;
X SK_U32 RxLoThresVal;
@@ -904,13 +913,13 @@
X QuEndAddr = QuEndAddr / 8;
X
X /* release local reset */
- SK_OUT8(IoC, RB_ADDR(QuIoOffs,RB_CTRL), RB_RST_CLR);
+ SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_RST_CLR);
X
X /* configure addresses */
- SK_OUT32(IoC, RB_ADDR(QuIoOffs,RB_START), QuStartAddr);
- SK_OUT32(IoC, RB_ADDR(QuIoOffs,RB_END), QuEndAddr);
- SK_OUT32(IoC, RB_ADDR(QuIoOffs,RB_WP), QuStartAddr);
- SK_OUT32(IoC, RB_ADDR(QuIoOffs,RB_RP), QuStartAddr);
+ SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_START), QuStartAddr);
+ SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_END), QuEndAddr);
+ SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_WP), QuStartAddr);
+ SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RP), QuStartAddr);
X
X switch (QuType) {
X case SK_RX_SRAM_Q:
@@ -921,10 +930,9 @@
X case SK_RX_BRAM_Q:
X /* write threshold for Rx Queue */
X
- SK_OUT32(IoC, RB_ADDR(QuIoOffs,RB_RX_UTPP),
- RxUpThresVal);
- SK_OUT32(IoC, RB_ADDR(QuIoOffs,RB_RX_LTPP),
- RxLoThresVal);
+ SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_UTPP), RxUpThresVal);
+ SK_OUT32(IoC, RB_ADDR(QuIoOffs,RB_RX_LTPP), RxLoThresVal);
+
X /* the high priority threshold not used */
X break;
X case SK_TX_RAM_Q:
@@ -939,20 +947,20 @@
X * enable Store & Forward Mode for the
X * Tx Side
X */
- SK_OUT8(IoC, RB_ADDR(QuIoOffs,RB_CTRL),
- RB_ENA_STFWD);
+ SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_STFWD);
X }
X break;
X }
X
X /* set queue operational */
- SK_OUT8(IoC, RB_ADDR(QuIoOffs,RB_CTRL), RB_ENA_OP_MD);
+ SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_OP_MD);
X }
X else {
X /* ensure the queue is still disabled */
- SK_OUT8(IoC, RB_ADDR(QuIoOffs,RB_CTRL), RB_RST_SET);
+ SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_RST_SET);
X }
-}
+} /* DoInitRamQueue*/
+


X
X /******************************************************************************
X *

@@ -967,7 +975,7 @@
X static void SkGeInitRamBufs(


X SK_AC *pAC, /* adapter context */
X SK_IOC IoC, /* IO context */

-int Port) /* Port Index (MAC_1 + n) */
+int Port) /* Port Index (MAC_1 + n) */
X {
X SK_GEPORT *pPrt;
X int RxQType;
@@ -987,7 +995,8 @@
X pPrt->PXsQRamEnd, SK_TX_RAM_Q);
X DoInitRamQueue(pAC, IoC, pPrt->PXaQOff, pPrt->PXaQRamStart,
X pPrt->PXaQRamEnd, SK_TX_RAM_Q);
-}
+} /* SkGeInitRamBufs */
+


X
X /******************************************************************************
X *

@@ -1022,7 +1031,8 @@
X SK_OUT8(IoC, B3_RI_RTO_R2, SK_RI_TO_53);
X SK_OUT8(IoC, B3_RI_RTO_XA2, SK_RI_TO_53);
X SK_OUT8(IoC, B3_RI_RTO_XS2, SK_RI_TO_53);
-}
+} /* SkGeInitRamIface */
+


X
X /******************************************************************************
X *

@@ -1037,33 +1047,34 @@
X static void SkGeInitBmu(


X SK_AC *pAC, /* adapter context */
X SK_IOC IoC, /* IO context */

-int Port) /* Port Index (MAC_1 + n) */
+int Port) /* Port Index (MAC_1 + n) */


X {
X SK_GEPORT *pPrt;
X
X pPrt = &pAC->GIni.GP[Port];
X

X /* Rx Queue: Release all local resets and set the watermark */
- SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff,Q_CSR), CSR_CLR_RESET);
- SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff,Q_F), SK_BMU_RX_WM);
+ SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_CLR_RESET);
+ SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_F), SK_BMU_RX_WM);
X
X /*
X * Tx Queue: Release all local resets if the queue is used!
X * set watermark
X */
X if (pPrt->PXSQSize != 0) {
- SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff,Q_CSR), CSR_CLR_RESET);
- SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff,Q_F), SK_BMU_TX_WM);
+ SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_CLR_RESET);
+ SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_F), SK_BMU_TX_WM);
X }
X if (pPrt->PXAQSize != 0) {
- SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff,Q_CSR), CSR_CLR_RESET);
- SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff,Q_F), SK_BMU_TX_WM);
+ SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_CLR_RESET);
+ SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_F), SK_BMU_TX_WM);
X }
X /*
X * Do NOT enable the descriptor poll timers here, because
X * the descriptor addresses are not specified yet.
X */
-}
+} /* SkGeInitBmu */
+


X
X /******************************************************************************
X *

@@ -1081,17 +1092,18 @@
X static SK_U32 TestStopBit(
X SK_AC *pAC, /* Adapter Context */
X SK_IOC IoC, /* IO Context */
-int QuIoOffs) /* Queue IO Address Offset */
+int QuIoOffs) /* Queue IO Address Offset */
X {
X SK_U32 QuCsr; /* CSR contents */
X
- SK_IN32(IoC, Q_ADDR(QuIoOffs,Q_CSR), &QuCsr);
+ SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr);
X if ((QuCsr & (CSR_STOP|CSR_SV_IDLE)) == 0) {
- SK_OUT32(IoC, Q_ADDR(QuIoOffs,Q_CSR), CSR_STOP);
- SK_IN32(IoC, Q_ADDR(QuIoOffs,Q_CSR), &QuCsr);
+ SK_OUT32(IoC, Q_ADDR(QuIoOffs, Q_CSR), CSR_STOP);
+ SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr);
X }
X return (QuCsr);
-}
+} /* TestStopBit*/
+


X
X /******************************************************************************
X *

@@ -1173,10 +1185,10 @@
X */
X void SkGeStopPort(


X SK_AC *pAC, /* adapter context */

-SK_IOC IoC, /* IO context */
-int Port, /* port to stop (MAC_1 + n) */
-int Dir, /* Direction to Stop (SK_STOP_RX, SK_STOP_TX, SK_STOP_ALL) */
-int RstMode)/* Reset Mode (SK_SOFT_RST, SK_HARD_RST) */
+SK_IOC IoC, /* I/O context */
+int Port, /* port to stop (MAC_1 + n) */
+int Dir, /* Direction to Stop (SK_STOP_RX, SK_STOP_TX, SK_STOP_ALL) */
+int RstMode)/* Reset Mode (SK_SOFT_RST, SK_HARD_RST) */
X {
X #ifndef SK_DIAG
X SK_EVPARA Para;
@@ -1196,8 +1208,7 @@
X if (Dir & SK_STOP_TX) {
X /* disable the XMACs receiver and transmitter */
X XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
- XM_OUT16(IoC, Port, XM_MMU_CMD,
- Word & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX));
+ XM_OUT16(IoC, Port, XM_MMU_CMD, Word & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX));
X
X /* dummy read to ensure writing */
X XM_IN16(IoC, Port, XM_MMU_CMD, &Word);
@@ -1207,8 +1218,8 @@
X * If the BMU is in the reset state CSR_STOP will terminate
X * immediately.
X */
- SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff,Q_CSR), CSR_STOP);
- SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff,Q_CSR), CSR_STOP);
+ SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_STOP);
+ SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_STOP);
X
X ToutStart = SkOsGetTime(pAC);
X ToutCnt = 0;
@@ -1231,17 +1242,16 @@
X * transmit FIFO !
X */
X XM_IN32(IoC, Port, XM_MODE, &DWord);
- DWord |= XM_MD_FTF ;
+ DWord |= XM_MD_FTF;
X XM_OUT32(IoC, Port, XM_MODE, DWord);
X
X XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff);
X XaCsr = TestStopBit(pAC, IoC, pPrt->PXaQOff);
X
- if (ToutStart + (SK_TICKS_PER_SEC / 18) <
- SkOsGetTime(pAC)) {
-
+ if (ToutStart + (SK_TICKS_PER_SEC / 18) >= SkOsGetTime(pAC)) {
X /*
X * Timeout of 1/18 second reached.
+ * This needs to be checked at 1/18 sec only.
X */
X ToutCnt++;
X switch (ToutCnt) {
@@ -1253,35 +1263,36 @@
X */
X ToutStart = SkOsGetTime(pAC);
X if (XsCsr & CSR_STOP) {
- SK_OUT32(IoC,
- Q_ADDR(pPrt->PXsQOff,
- Q_CSR), CSR_START);
+ SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_START);
X }
X if (XaCsr & CSR_STOP) {
- SK_OUT32(IoC,
- Q_ADDR(pPrt->PXaQOff,
- Q_CSR), CSR_START);
+ SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_START);
X }
X break;
X case 2:
- default: /* Fatal Error, Loop aborted */
+ default:
+ /* Might be a problem when the driver event handler
+ * calls StopPort again.
+ * XXX.
+ */
+ /* Fatal Error, Loop aborted */


X /* Create an Error Log Entry */

- SK_ERR_LOG(pAC, SK_ERRCL_HW,
+ SK_ERR_LOG(
+ pAC,
+ SK_ERRCL_HW,
X SKERR_HWI_E018,
X SKERR_HWI_E018MSG);
X #ifndef SK_DIAG
X Para.Para64 = Port;
- SkEventQueue(pAC, SKGE_DRV,
- SK_DRV_PORT_FAIL, Para);
+ SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para);


X #endif /* !SK_DIAG */

X return;
X }
X }
X

X /*
- * because of the ASIC problem report entry from 21.08.98
- * it is required to wait until CSR_STOP is reset and
- * CSR_SV_IDLE is set.
+ * Because of the ASIC problem report entry from 21.08.1998 it is
+ * required to wait until CSR_STOP is reset and CSR_SV_IDLE is set.
X */
X } while ((XsCsr & (CSR_STOP|CSR_SV_IDLE)) != CSR_SV_IDLE ||
X (XaCsr & (CSR_STOP|CSR_SV_IDLE)) != CSR_SV_IDLE);
@@ -1298,10 +1309,10 @@
X * Stop Interval Timer and Limit Counter of Tx Arbiter,
X * also disable Force Sync bit and Enable Alloc bit.
X */
- SK_OUT8(IoC, MR_ADDR(Port,TXA_CTRL),
+ SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL),
X TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
- SK_OUT32(IoC, MR_ADDR(Port,TXA_ITI_INI), 0x00000000L);
- SK_OUT32(IoC, MR_ADDR(Port,TXA_LIM_INI), 0x00000000L);
+ SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), 0x00000000L);
+ SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), 0x00000000L);


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 066'
echo 'File patch-2.4.0-test9 is continued in part 067'
echo "067" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part068

#!/bin/sh -x
# this is part 068 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 068; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

X * Corrected reaction to reception of BPDU frames.
X * Added parameter descriptions to "For Readme" section skrlmt.txt.

@@ -216,7 +218,7 @@
X
X #ifndef lint


X static const char SysKonnectFileId[] =

- "@(#) $Id: skrlmt.c,v 1.48 1999/10/04 14:01:17 rassmann Exp $ (C) SysKonnect.";
+ "@(#) $Id: skrlmt.c,v 1.49 1999/11/22 13:38:02 cgoos Exp $ (C) SysKonnect.";


X #endif /* !defined(lint) */
X

X #define __SKRLMT_C
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/sktimer.c linux/drivers/net/sk98lin/sktimer.c
--- v2.4.0-test8/linux/drivers/net/sk98lin/sktimer.c Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/sktimer.c Fri Sep 15 14:34:19 2000


@@ -2,8 +2,8 @@
X *

X * Name: sktimer.c


X * Project: GEnesis, PCI Gigabit Ethernet Adapter

- * Version: $Revision: 1.11 $
- * Date: $Date: 1998/12/17 13:24:13 $
+ * Version: $Revision: 1.12 $
+ * Date: $Date: 1999/11/22 13:38:51 $
X * Purpose: High level timer functions.


X *
X ******************************************************************************/
@@ -13,8 +13,6 @@
X * (C)Copyright 1998,1999 SysKonnect,
X * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
X *
- * See the file "skge.c" for further information.
- *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
X * the Free Software Foundation; either version 2 of the License, or
@@ -29,6 +27,9 @@
X * History:
X *

X * $Log: sktimer.c,v $
+ * Revision 1.12 1999/11/22 13:38:51 cgoos


+ * Changed license header to GPL.
+ *

X * Revision 1.11 1998/12/17 13:24:13 gklug
X * fix: restart problem: do NOT destroy timer queue if init 1 is done
X *
@@ -75,7 +76,7 @@


X Event queue and dispatcher
X */
X static const char SysKonnectFileId[] =

- "$Header: /usr56/projects/ge/schedule/sktimer.c,v 1.11 1998/12/17 13:24:13 gklug Exp $" ;
+ "$Header: /usr56/projects/ge/schedule/sktimer.c,v 1.12 1999/11/22 13:38:51 cgoos Exp $" ;


X
X #include "h/skdrv1st.h" /* Driver Specific Definitions */

X #include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/skvpd.c linux/drivers/net/sk98lin/skvpd.c
--- v2.4.0-test8/linux/drivers/net/sk98lin/skvpd.c Wed Jul 5 10:56:13 2000
+++ linux/drivers/net/sk98lin/skvpd.c Fri Sep 15 14:34:19 2000
@@ -2,19 +2,17 @@
X *
X * Name: skvpd.c


X * Project: GEnesis, PCI Gigabit Ethernet Adapter

- * Version: $Revision: 1.24 $
- * Date: $Date: 1999/03/11 14:25:49 $
+ * Version: $Revision: 1.27 $
+ * Date: $Date: 2000/08/10 11:29:06 $
X * Purpose: Shared software to read and write VPD data
X *
X ******************************************************************************/


X
X /******************************************************************************
X *
- * (C)Copyright 1998,1999 SysKonnect,
+ * (C)Copyright 1998-2000 SysKonnect,
X * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
X *
- * See the file "skge.c" for further information.
- *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
X * the Free Software Foundation; either version 2 of the License, or

@@ -29,6 +27,18 @@


X * History:
X *

X * $Log: skvpd.c,v $
+ * Revision 1.27 2000/08/10 11:29:06 rassmann


+ * Editorial changes.
+ * Preserving 32-bit alignment in structs for the adapter context.
+ * Removed unused function VpdWriteDword() (#if 0).
+ * Made VpdReadKeyword() available for SKDIAG only.

+ *
+ * Revision 1.26 2000/06/13 08:00:01 mkarl
+ * additional cast to avoid compile problems in 64 bit environment
+ *
+ * Revision 1.25 1999/11/22 13:39:32 cgoos


+ * Changed license header to GPL.
+ *

X * Revision 1.24 1999/03/11 14:25:49 malthoff


X * Replace __STDC__ with SK_KR_PROTO.
X *

@@ -62,7 +72,7 @@
X *
X * Revision 1.14 1998/10/28 07:20:38 gklug
X * chg: Interface functions to use IoC as parameter as well
- * fix: VpdRead/WriteDWord now return SK_U32
+ * fix: VpdRead/WriteDWord now returns SK_U32
X * chg: VPD_IN/OUT names conform to SK_IN/OUT
X * add: usage of VPD_IN/OUT8 macros
X * add: VpdRead/Write Stream functions to r/w a stream of data
@@ -120,7 +130,7 @@
X Please refer skvpd.txt for infomation how to include this module


X */
X static const char SysKonnectFileId[] =

- "@(#)$Id: skvpd.c,v 1.24 1999/03/11 14:25:49 malthoff Exp $ (C) SK" ;
+ "@(#)$Id: skvpd.c,v 1.27 2000/08/10 11:29:06 rassmann Exp $ (C) SK";


X
X #include "h/skdrv1st.h"
X #include "h/sktypes.h"

@@ -134,9 +144,9 @@
X static SK_VPD_PARA *vpd_find_para(


X SK_AC *pAC,
X char *key,

- SK_VPD_PARA *p) ;
+ SK_VPD_PARA *p);


X #else /* SK_KR_PROTO */

-static SK_VPD_PARA *vpd_find_para() ;
+static SK_VPD_PARA *vpd_find_para();


X #endif /* SK_KR_PROTO */
X

X /*
@@ -151,28 +161,29 @@
X SK_IOC IoC, /* IO Context */
X int event) /* event to wait for (VPD_READ / VPD_write) completion*/
X {
- SK_U64 start_time ;
- SK_U16 state ;
+ SK_U64 start_time;
+ SK_U16 state;
X
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
- ("vpd wait for %s\n",event?"Write":"Read")) ;
- start_time = SkOsGetTime(pAC) ;
+ ("vpd wait for %s\n",event?"Write":"Read"));
+ start_time = SkOsGetTime(pAC);
X do {
X if (SkOsGetTime(pAC) - start_time > SK_TICKS_PER_SEC/16) {
- VPD_STOP(pAC,IoC) ;
+ VPD_STOP(pAC,IoC);
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,
X SK_DBGCAT_FATAL|SK_DBGCAT_ERR,
- ("ERROR:vpd wait timeout\n")) ;
- return(1) ;
+ ("ERROR:vpd wait timeout\n"));
+ return(1);
X }
- VPD_IN16(pAC,IoC,PCI_VPD_ADR_REG,&state) ;
+ VPD_IN16(pAC,IoC,PCI_VPD_ADR_REG,&state);
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
- ("state = %x, event %x\n",state,event)) ;
- } while((int)(state & PCI_VPD_FLAG) == event) ;
+ ("state = %x, event %x\n",state,event));
+ } while((int)(state & PCI_VPD_FLAG) == event);
X
- return(0) ;
+ return(0);
X }
X
+#ifdef SKDIAG
X
X /*
X * Read the dword at address 'addr' from the VPD EEPROM.
@@ -189,27 +200,31 @@
X SK_IOC IoC, /* IO Context */
X int addr) /* VPD address */
X {
- SK_U32 Rtv ;
+ SK_U32 Rtv;
X
X /* start VPD read */
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
- ("vpd read dword at 0x%x\n",addr)) ;
- addr &= ~VPD_WRITE ; /* ensure the R/W bit is set to read */
+ ("vpd read dword at 0x%x\n",addr));
+ addr &= ~VPD_WRITE; /* ensure the R/W bit is set to read */
X
- VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, (SK_U16) addr) ;
+ VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, (SK_U16) addr);
X
X /* ignore return code here */
- (void)VpdWait(pAC,IoC,VPD_READ) ;
+ (void)VpdWait(pAC,IoC,VPD_READ);
X
X /* Don't swap here, it's a data stream of bytes */
- Rtv = 0 ;
+ Rtv = 0;
X
- VPD_IN32(pAC,IoC,PCI_VPD_DAT_REG,&Rtv) ;
+ VPD_IN32(pAC,IoC,PCI_VPD_DAT_REG,&Rtv);
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
- ("vpd read dword data = 0x%x\n",Rtv)) ;
- return (Rtv) ;
+ ("vpd read dword data = 0x%x\n",Rtv));
+ return (Rtv);
X }
X
+#endif // SKDIAG
+
+#if 0
+
X /*
X Write the dword 'data' at address 'addr' into the VPD EEPROM, and
X verify that the data is written.


@@ -229,11 +244,10 @@
X

X
X Returns 0: success
- 1: error, I2C transfer does not terminate
- 2: error, data verify error
+ 1: error, I2C transfer does not terminate
+ 2: error, data verify error
X
X */
-#if 0 /* unused */
X static int VpdWriteDWord(
X SK_AC *pAC, /* pAC pointer */
X SK_IOC IoC, /* IO Context */
@@ -243,29 +257,30 @@
X /* start VPD write */
X /* Don't swap here, it's a data stream of bytes */
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
- ("vpd write dword at addr 0x%x, data = 0x%x\n",addr,data)) ;
- VPD_OUT32(pAC,IoC,PCI_VPD_DAT_REG, (SK_U32)data) ;
+ ("vpd write dword at addr 0x%x, data = 0x%x\n",addr,data));
+ VPD_OUT32(pAC,IoC,PCI_VPD_DAT_REG, (SK_U32)data);
X /* But do it here */
- addr |= VPD_WRITE ;
+ addr |= VPD_WRITE;
X
- VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, (SK_U16)(addr | VPD_WRITE)) ;
+ VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, (SK_U16)(addr | VPD_WRITE));
X
X /* this may take up to 10,6 ms */
X if (VpdWait(pAC,IoC,VPD_WRITE)) {
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
- ("Write Timed Out\n")) ;
- return(1) ;
- } ;
+ ("Write Timed Out\n"));
+ return(1);
+ };
X
X /* verify data */
X if (VpdReadDWord(pAC,IoC,addr) != data) {
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR|SK_DBGCAT_FATAL,
- ("Data Verify Error\n")) ;
- return(2) ;
+ ("Data Verify Error\n"));
+ return(2);
X }
- return(0) ;
-}
-#endif /* unused */
+ return(0);
+} /* VpdWriteDWord */
+


+#endif /* 0 */
X

X /*
X * Read one Stream of 'len' bytes of VPD data, starting at 'addr' from
@@ -280,12 +295,12 @@
X int Addr, /* VPD start address */
X int Len) /* number of bytes to read / to write */
X {
- int i ;
- int j ;
- SK_U16 AdrReg ;
- int Rtv ;
+ int i;
+ int j;
+ SK_U16 AdrReg;
+ int Rtv;
X SK_U8 * pComp; /* Compare pointer */
- SK_U8 Data ; /* Input Data for Compare */
+ SK_U8 Data; /* Input Data for Compare */
X
X /* Init Compare Pointer */
X pComp = (SK_U8 *) buf;
@@ -297,56 +312,56 @@
X * So it is initialized even if only a few bytes
X * are written.
X */
- AdrReg = (SK_U16) Addr ;
- AdrReg &= ~VPD_WRITE ; /* READ operation */
+ AdrReg = (SK_U16) Addr;
+ AdrReg &= ~VPD_WRITE; /* READ operation */
X
- VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, AdrReg) ;
+ VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, AdrReg);
X
X /* ignore return code here */
- Rtv = VpdWait(pAC,IoC,VPD_READ) ;
+ Rtv = VpdWait(pAC,IoC,VPD_READ);
X if (Rtv != 0) {
- return(i) ;
+ return(i);
X }
X }
X
X /* Write current Byte */
X VPD_OUT8(pAC,IoC,PCI_VPD_DAT_REG+(i%sizeof(SK_U32)),
- *(SK_U8*)buf) ;
+ *(SK_U8*)buf);
X
X if (((i%sizeof(SK_U32)) == 3) || (i == (Len - 1))) {
X /* New Address needs to be written to VPD_ADDR reg */
- AdrReg = (SK_U16) Addr ;
+ AdrReg = (SK_U16) Addr;
X Addr += sizeof(SK_U32);
- AdrReg |= VPD_WRITE ; /* WRITE operation */
+ AdrReg |= VPD_WRITE; /* WRITE operation */
X
- VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, AdrReg) ;
+ VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, AdrReg);
X
X /* Wait for termination */
- Rtv = VpdWait(pAC,IoC,VPD_WRITE) ;
+ Rtv = VpdWait(pAC,IoC,VPD_WRITE);
X if (Rtv != 0) {
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
- ("Write Timed Out\n")) ;
- return(i - (i%sizeof(SK_U32))) ;
+ ("Write Timed Out\n"));
+ return(i - (i%sizeof(SK_U32)));
X }
X
X /*
X * Now re-read to verify
X */
- AdrReg &= ~VPD_WRITE ; /* READ operation */
+ AdrReg &= ~VPD_WRITE; /* READ operation */
X
- VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, AdrReg) ;
+ VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, AdrReg);
X
X /* Wait for termination */
- Rtv = VpdWait(pAC,IoC,VPD_READ) ;
+ Rtv = VpdWait(pAC,IoC,VPD_READ);
X if (Rtv != 0) {
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
- ("Verify Timed Out\n")) ;
- return(i - (i%sizeof(SK_U32))) ;
+ ("Verify Timed Out\n"));
+ return(i - (i%sizeof(SK_U32)));
X }
X
X for (j = 0; j <= (int) (i%sizeof(SK_U32));
X j ++, pComp ++ ) {
- VPD_IN8(pAC,IoC,PCI_VPD_DAT_REG+j, &Data) ;
+ VPD_IN8(pAC,IoC,PCI_VPD_DAT_REG+j, &Data);
X if (Data != *pComp) {
X /* Verify Error */
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,
@@ -376,31 +391,31 @@
X int Addr, /* VPD start address */
X int Len) /* number of bytes to read / to write */
X {
- int i ;
- SK_U16 AdrReg ;
- int Rtv ;
+ int i;
+ SK_U16 AdrReg;
+ int Rtv;
X
X for (i=0; i < Len; i ++, buf++) {
X if ((i%sizeof(SK_U32)) == 0) {
X /* New Address needs to be written to VPD_ADDR reg */
- AdrReg = (SK_U16) Addr ;
+ AdrReg = (SK_U16) Addr;
X Addr += sizeof(SK_U32);
- AdrReg &= ~VPD_WRITE ; /* READ operation */
+ AdrReg &= ~VPD_WRITE; /* READ operation */
X
- VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, AdrReg) ;
+ VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG, AdrReg);
X
X /* ignore return code here */
- Rtv = VpdWait(pAC,IoC,VPD_READ) ;
+ Rtv = VpdWait(pAC,IoC,VPD_READ);
X if (Rtv != 0) {
- return(i) ;
+ return(i);
X }
X
X }
X VPD_IN8(pAC,IoC,PCI_VPD_DAT_REG+(i%sizeof(SK_U32)),
- (SK_U8 *)buf) ;
+ (SK_U8 *)buf);
X }
X
- return(Len) ;
+ return(Len);
X }
X
X /*
@@ -417,29 +432,29 @@
X int len, /* number of bytes to read / to write */
X int dir) /* transfer direction may be VPD_READ or VPD_WRITE */
X {
- int Rtv ; /* Return value */
- int vpd_rom_size ;
- SK_U32 our_reg2 ;
+ int Rtv; /* Return value */
+ int vpd_rom_size;
+ SK_U32 our_reg2;
X
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
X ("vpd %s block, addr = 0x%x, len = %d\n",
- dir?"write":"read",addr,len)) ;
+ dir?"write":"read",addr,len));
X
X if (len == 0)
- return (0) ;
+ return (0);
X
- VPD_IN32(pAC,IoC,PCI_OUR_REG_2,&our_reg2) ;
+ VPD_IN32(pAC,IoC,PCI_OUR_REG_2,&our_reg2);
X vpd_rom_size = 256 << ((our_reg2 & PCI_VPD_ROM_SZ) >> 14);
X if (addr > vpd_rom_size - 4) {
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR|SK_DBGCAT_FATAL,
X ("Address error: 0x%x, exp. < 0x%x\n",
- addr, vpd_rom_size - 4)) ;
- return (0) ;
+ addr, vpd_rom_size - 4));
+ return (0);
X }
X if (addr + len > vpd_rom_size) {
- len = vpd_rom_size - addr ;
+ len = vpd_rom_size - addr;
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
- ("Warning: len was cut to %d\n",len)) ;
+ ("Warning: len was cut to %d\n",len));
X }
X
X if (dir == VPD_READ) {
@@ -448,7 +463,7 @@
X Rtv = VpdWriteStream(pAC, IoC, buf, addr, len);
X }
X
- return (Rtv) ;
+ return (Rtv);
X }
X
X #ifdef SKDIAG
@@ -465,7 +480,7 @@
X int addr, /* start reading at the VPD address */
X int len) /* number of bytes to read */
X {
- return (VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_READ)) ;
+ return (VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_READ));
X }
X
X /*
@@ -480,7 +495,7 @@
X int addr, /* start writing at the VPD address */
X int len) /* number of bytes to write */
X {
- return (VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_WRITE)) ;
+ return (VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_WRITE));
X }


X #endif /* SKDIAG */
X

@@ -497,64 +512,64 @@
X SK_AC *pAC, /* Adapters context */
X SK_IOC IoC) /* IO Context */
X {
- SK_VPD_PARA *r, rp ; /* RW or RV */
- int i ;
- unsigned char x ;
+ SK_VPD_PARA *r, rp; /* RW or RV */
+ int i;
+ unsigned char x;
X
- SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_INIT,("VpdInit .. ")) ;
+ SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_INIT,("VpdInit .. "));
X /* read the VPD data into the VPD buffer */
X if (VpdTransferBlock(pAC,IoC,pAC->vpd.vpd_buf,0,VPD_SIZE,VPD_READ)
X != VPD_SIZE) {
X
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
- ("Block Read Error\n")) ;
- return(1) ;
+ ("Block Read Error\n"));
+ return(1);
X }
X
X /* find the end tag of the RO area */
X if (!(r = vpd_find_para(pAC,VPD_RV,&rp))) {
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
- ("Encoding Error: RV Tag not found\n")) ;
- return (1) ;
+ ("Encoding Error: RV Tag not found\n"));
+ return (1);
X }
X if (r->p_val + r->p_len > pAC->vpd.vpd_buf + VPD_SIZE/2) {
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
- ("Encoding Error: Invalid VPD struct size\n")) ;
- return (1) ;
+ ("Encoding Error: Invalid VPD struct size\n"));
+ return (1);
X }
- pAC->vpd.v.vpd_free_ro = r->p_len - 1 ;
+ pAC->vpd.v.vpd_free_ro = r->p_len - 1;
X
X /* test the checksum */
X for (i = 0, x = 0; (unsigned)i<=(unsigned)VPD_SIZE/2 - r->p_len; i++) {
- x += pAC->vpd.vpd_buf[i] ;
+ x += pAC->vpd.vpd_buf[i];
X }
X if (x != 0) {
X /* checksum error */
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
- ("VPD Checksum Error\n")) ;
- return (1) ;
+ ("VPD Checksum Error\n"));
+ return (1);
X }
X
X /* find and check the end tag of the RW area */
X if (!(r = vpd_find_para(pAC,VPD_RW,&rp))) {
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
- ("Encoding Error: RV Tag not found\n")) ;
- return (1) ;
+ ("Encoding Error: RV Tag not found\n"));
+ return (1);
X }
X if (r->p_val < pAC->vpd.vpd_buf + VPD_SIZE/2) {
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
- ("Encoding Error: Invalid VPD struct size\n")) ;
- return (1) ;
+ ("Encoding Error: Invalid VPD struct size\n"));
+ return (1);
X }
- pAC->vpd.v.vpd_free_rw = r->p_len ;
+ pAC->vpd.v.vpd_free_rw = r->p_len;
X
X /* everything seems to be ok */
- pAC->vpd.v.vpd_status |= VPD_VALID ;
+ pAC->vpd.v.vpd_status |= VPD_VALID;
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_INIT,
X ("done. Free RO = %d, Free RW = %d\n",
- pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw)) ;
+ pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw));
X
- return(0) ;
+ return(0);
X }
X
X /*
@@ -570,62 +585,62 @@
X SK_VPD_PARA *p) /* parameter description struct */
X {
X char *v ; /* points to vpd buffer */
- int max ; /* Maximum Number of Iterations */
+ int max; /* Maximum Number of Iterations */
X
- v = pAC->vpd.vpd_buf ;
- max = 128 ;
+ v = pAC->vpd.vpd_buf;
+ max = 128;
X
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
- ("vpd find para %s .. ",key)) ;
+ ("vpd find para %s .. ",key));
X
X /* check mandatory resource type ID string (Product Name) */
X if (*v != (char) RES_ID) {
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
- ("Error: 0x%x missing\n",RES_ID)) ;
- return (0) ;
+ ("Error: 0x%x missing\n",RES_ID));
+ return (0);
X }
X
X if (strcmp(key,VPD_NAME) == 0) {
- p->p_len = VPD_GET_RES_LEN(v) ;
- p->p_val = VPD_GET_VAL(v) ;
+ p->p_len = VPD_GET_RES_LEN(v);
+ p->p_val = VPD_GET_VAL(v);
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
- ("found, len = %d\n",p->p_len)) ;
- return(p) ;
+ ("found, len = %d\n",p->p_len));
+ return(p);
X }
X
- v += 3 + VPD_GET_RES_LEN(v) + 3 ;
- for ( ; ; ) {
+ v += 3 + VPD_GET_RES_LEN(v) + 3;
+ for (;; ) {
X if (SK_MEMCMP(key,v,2) == 0) {
- p->p_len = VPD_GET_VPD_LEN(v) ;
- p->p_val = VPD_GET_VAL(v) ;
+ p->p_len = VPD_GET_VPD_LEN(v);
+ p->p_val = VPD_GET_VAL(v);
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
- ("found, len = %d\n",p->p_len)) ;
- return (p) ;
+ ("found, len = %d\n",p->p_len));
+ return (p);
X }
X
X /* exit when reaching the "RW" Tag or the maximum of itera. */
- max-- ;
+ max--;
X if (SK_MEMCMP(VPD_RW,v,2) == 0 || max == 0) {
- break ;
+ break;
X }
X
X if (SK_MEMCMP(VPD_RV,v,2) == 0) {
- v += 3 + VPD_GET_VPD_LEN(v) + 3 ; /* skip VPD-W */
+ v += 3 + VPD_GET_VPD_LEN(v) + 3; /* skip VPD-W */
X } else {
- v += 3 + VPD_GET_VPD_LEN(v) ;
+ v += 3 + VPD_GET_VPD_LEN(v);
X }
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
- ("scanning '%c%c' len = %d\n",v[0],v[1],v[2])) ;
+ ("scanning '%c%c' len = %d\n",v[0],v[1],v[2]));
X }
X
X #ifdef DEBUG
- SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,("not found\n")) ;
+ SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,("not found\n"));
X if (max == 0) {
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
- ("Key/Len Encoding error\n")) ;
+ ("Key/Len Encoding error\n"));
X }
X #endif
- return (0) ;
+ return (0);
X }
X
X /*
@@ -639,24 +654,24 @@
X char *end, /* end of memory block to move */
X int n) /* number of bytes the memory block has to be moved */
X {
- char *p ;
- int i ; /* number of byte copied */
+ char *p;
+ int i; /* number of byte copied */
X
X if (n == 0)
- return ;
+ return;
X
- i = end - start + 1 ;
+ i = (int) (end - start + 1);
X if (n < 0) {
- p = start + n ;
+ p = start + n;
X while (i != 0) {
- *p++ = *start++ ;
- i-- ;
+ *p++ = *start++;
+ i--;
X }
X } else {
- p = end + n ;
+ p = end + n;
X while (i != 0) {
- *p-- = *end-- ;
- i-- ;
+ *p-- = *end--;
+ i--;
X }
X }
X }
@@ -672,13 +687,13 @@
X int len, /* length of the value string */
X char *ip) /* inseration point */
X {
- SK_VPD_KEY *p ;
+ SK_VPD_KEY *p;
X
- p = (SK_VPD_KEY *) ip ;
- p->p_key[0] = key[0] ;
- p->p_key[1] = key[1] ;
- p->p_len = (unsigned char) len ;
- SK_MEMCPY(&p->p_val,buf,len) ;
+ p = (SK_VPD_KEY *) ip;
+ p->p_key[0] = key[0];
+ p->p_key[1] = key[1];
+ p->p_len = (unsigned char) len;
+ SK_MEMCPY(&p->p_val,buf,len);
X }
X
X /*
@@ -692,46 +707,46 @@
X SK_AC *pAC, /* common data base */
X char *etp) /* end pointer input position */
X {
- SK_VPD_KEY *p ;
- unsigned char x ;
- int i ;
+ SK_VPD_KEY *p;
+ unsigned char x;
+ int i;
X
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
- ("vpd modify endtag at 0x%x = '%c%c'\n",etp,etp[0],etp[1])) ;
+ ("vpd modify endtag at 0x%x = '%c%c'\n",etp,etp[0],etp[1]));
X
- p = (SK_VPD_KEY *) etp ;
+ p = (SK_VPD_KEY *) etp;
X
X if (p->p_key[0] != 'R' || (p->p_key[1] != 'V' && p->p_key[1] != 'W')) {
X /* something wrong here, encoding error */
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
- ("Encoding Error: invalid end tag\n")) ;
- return(1) ;
+ ("Encoding Error: invalid end tag\n"));
+ return(1);
X }
X if (etp > pAC->vpd.vpd_buf + VPD_SIZE/2) {
X /* create "RW" tag */
- p->p_len = (unsigned char)(pAC->vpd.vpd_buf+VPD_SIZE-etp-3-1) ;
- pAC->vpd.v.vpd_free_rw = (int) p->p_len ;
- i = pAC->vpd.v.vpd_free_rw ;
- etp += 3 ;
+ p->p_len = (unsigned char)(pAC->vpd.vpd_buf+VPD_SIZE-etp-3-1);
+ pAC->vpd.v.vpd_free_rw = (int) p->p_len;
+ i = pAC->vpd.v.vpd_free_rw;
+ etp += 3;
X } else {
X /* create "RV" tag */
- p->p_len = (unsigned char)(pAC->vpd.vpd_buf+VPD_SIZE/2-etp-3) ;
- pAC->vpd.v.vpd_free_ro = (int) p->p_len - 1 ;
+ p->p_len = (unsigned char)(pAC->vpd.vpd_buf+VPD_SIZE/2-etp-3);
+ pAC->vpd.v.vpd_free_ro = (int) p->p_len - 1;
X
X /* setup checksum */
X for (i = 0, x = 0; i < VPD_SIZE/2 - p->p_len; i++) {
- x += pAC->vpd.vpd_buf[i] ;
+ x += pAC->vpd.vpd_buf[i];
X }
- p->p_val = (char) 0 - x ;
- i = pAC->vpd.v.vpd_free_ro ;
- etp += 4 ;
+ p->p_val = (char) 0 - x;
+ i = pAC->vpd.v.vpd_free_ro;
+ etp += 4;
X }
X while (i) {
- *etp++ = 0x00 ;
- i-- ;
+ *etp++ = 0x00;
+ i--;
X }
X
- return (0) ;
+ return (0);
X }
X
X /*
@@ -756,76 +771,76 @@
X int type, /* VPD_RO_KEY or VPD_RW_KEY */
X int op) /* operation to do: ADD_KEY or OWR_KEY */
X {
- SK_VPD_PARA vp ;
- char *etp ; /* end tag position */
- int free ; /* remaining space in selected area */
- char *ip ; /* input position inside the VPD buffer */
- int rtv ; /* return code */
- int head ; /* additional haeder bytes to move */
- int found ; /* additinoal bytes if the keyword was found */
+ SK_VPD_PARA vp;
+ char *etp; /* end tag position */
+ int free; /* remaining space in selected area */
+ char *ip; /* input position inside the VPD buffer */
+ int rtv; /* return code */
+ int head; /* additional haeder bytes to move */
+ int found; /* additinoal bytes if the keyword was found */
X
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
- ("vpd setup para key = %s, val = %s\n",key,buf)) ;
+ ("vpd setup para key = %s, val = %s\n",key,buf));
X
- rtv = 0 ;
- ip = 0 ;
+ rtv = 0;
+ ip = 0;
X if (type == VPD_RW_KEY) {
X /* end tag is "RW" */
- free = pAC->vpd.v.vpd_free_rw ;
- etp = pAC->vpd.vpd_buf + (VPD_SIZE - free - 1 - 3) ;
+ free = pAC->vpd.v.vpd_free_rw;
+ etp = pAC->vpd.vpd_buf + (VPD_SIZE - free - 1 - 3);
X } else {
X /* end tag is "RV" */
- free = pAC->vpd.v.vpd_free_ro ;
- etp = pAC->vpd.vpd_buf + (VPD_SIZE/2 - free - 4) ;
+ free = pAC->vpd.v.vpd_free_ro;
+ etp = pAC->vpd.vpd_buf + (VPD_SIZE/2 - free - 4);
X }
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
X ("Free RO = %d, Free RW = %d\n",
- pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw)) ;
+ pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw));
X
- head = 0 ;
- found = 0 ;
+ head = 0;
+ found = 0;
X if (op == OWR_KEY) {
X if (vpd_find_para(pAC,key,&vp)) {
- found = 3 ;
- ip = vp.p_val - 3 ;
- free += vp.p_len + 3 ;
+ found = 3;
+ ip = vp.p_val - 3;
+ free += vp.p_len + 3;
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
- ("Overwrite Key\n")) ;
+ ("Overwrite Key\n"));
X } else {
- op = ADD_KEY ;
+ op = ADD_KEY;
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_CTRL,
- ("Add Key\n")) ;
+ ("Add Key\n"));
X }
X }
X if (op == ADD_KEY) {
- ip = etp ;
- vp.p_len = 0 ;
- head = 3 ;
+ ip = etp;
+ vp.p_len = 0;
+ head = 3;
X }
X
X if (len + 3 > free) {
X if (free < 7) {
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
X ("VPD Buffer Overflow, keyword not written\n"));
- return (4) ;
+ return (4);
X }
X /* cut it again */
- len = free - 3 ;
- rtv = 2 ;
+ len = free - 3;
+ rtv = 2;
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
- ("VPD Buffer Full, Keyword was cut\n")) ;
+ ("VPD Buffer Full, Keyword was cut\n"));
X }
X
- vpd_move_para(ip + vp.p_len + found, etp+2, len-vp.p_len+head) ;
- vpd_insert_key(key, buf, len, ip) ;
+ vpd_move_para(ip + vp.p_len + found, etp+2, len-vp.p_len+head);
+ vpd_insert_key(key, buf, len, ip);
X if (vpd_mod_endtag(pAC, etp + len - vp.p_len + head)) {
- pAC->vpd.v.vpd_status &= ~VPD_VALID ;
+ pAC->vpd.v.vpd_status &= ~VPD_VALID;
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
- ("VPD Encoding Error\n")) ;
- return(6) ;
+ ("VPD Encoding Error\n"));
+ return(6);
X }
X
- return (rtv) ;
+ return (rtv);
X }
X
X
@@ -833,7 +848,7 @@
X * Read the contents of the VPD EEPROM and copy it to the
X * VPD buffer if not already done.
X *
- * return: A pointer to the vpd_status structure. The structure contain
+ * return: A pointer to the vpd_status structure. The structure contains
X * this fields.
X */
X SK_VPD_STATUS *VpdStat(
@@ -841,9 +856,9 @@
X SK_IOC IoC) /* IO Context */
X {
X if (!(pAC->vpd.v.vpd_status & VPD_VALID)) {
- (void)VpdInit(pAC,IoC) ;
+ (void)VpdInit(pAC,IoC);
X }
- return(&pAC->vpd.v) ;
+ return(&pAC->vpd.v);
X }
X
X
@@ -876,67 +891,67 @@
X int *len, /* buffer length */
X int *elements) /* number of keywords returned */
X {
- char *v ;
- int n ;
+ char *v;
+ int n;
X
- SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_RX,("list vpd keys .. ")) ;
- *elements = 0 ;
+ SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_RX,("list vpd keys .. "));
+ *elements = 0;
X if (!(pAC->vpd.v.vpd_status & VPD_VALID)) {
X if (VpdInit(pAC,IoC) != 0 ) {
- *len = 0 ;
+ *len = 0;
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
- ("VPD Init Error, terminated\n")) ;
- return(6) ;
+ ("VPD Init Error, terminated\n"));
+ return(6);
X }
X }
X
X if ((signed)strlen(VPD_NAME) + 1 <= *len) {
- v = pAC->vpd.vpd_buf ;
- strcpy(buf,VPD_NAME) ;
- n = strlen(VPD_NAME) + 1 ;
- buf += n ;
- *elements = 1 ;
+ v = pAC->vpd.vpd_buf;
+ strcpy(buf,VPD_NAME);
+ n = strlen(VPD_NAME) + 1;
+ buf += n;
+ *elements = 1;
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_RX,
- ("'%c%c' ",v[0],v[1])) ;
+ ("'%c%c' ",v[0],v[1]));
X } else {
- *len = 0 ;
+ *len = 0;
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
- ("buffer overflow\n")) ;
- return(2) ;
+ ("buffer overflow\n"));
+ return(2);
X }
X
- v += 3 + VPD_GET_RES_LEN(v) + 3 ;
- for ( ; ; ) {
+ v += 3 + VPD_GET_RES_LEN(v) + 3;
+ for (;; ) {
X /* exit when reaching the "RW" Tag */
X if (SK_MEMCMP(VPD_RW,v,2) == 0) {
- break ;
+ break;
X }
X
X if (SK_MEMCMP(VPD_RV,v,2) == 0) {
- v += 3 + VPD_GET_VPD_LEN(v) + 3 ; /* skip VPD-W */
- continue ;
+ v += 3 + VPD_GET_VPD_LEN(v) + 3; /* skip VPD-W */
+ continue;
X }
X
X if (n+3 <= *len) {
- SK_MEMCPY(buf,v,2) ;
- buf += 2 ;
- *buf++ = '\0' ;
- n += 3 ;
- v += 3 + VPD_GET_VPD_LEN(v) ;
- *elements += 1 ;
+ SK_MEMCPY(buf,v,2);
+ buf += 2;
+ *buf++ = '\0';
+ n += 3;
+ v += 3 + VPD_GET_VPD_LEN(v);
+ *elements += 1;
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_RX,
- ("'%c%c' ",v[0],v[1])) ;
+ ("'%c%c' ",v[0],v[1]));
X } else {
- *len = n ;
+ *len = n;
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
- ("buffer overflow\n")) ;
- return (2) ;
+ ("buffer overflow\n"));
+ return (2);
X }
X }
X
- SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_RX,("\n")) ;
- *len = n ;
- return(0) ;
+ SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_RX,("\n"));
+ *len = n;
+ return(0);
X }
X
X
@@ -960,34 +975,34 @@
X char *buf, /* buffer where to copy the keyword value */
X int *len) /* buffer length */
X {
- SK_VPD_PARA *p, vp ;
+ SK_VPD_PARA *p, vp;
X
- SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_RX,("vpd read %s .. ",key)) ;
+ SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_RX,("vpd read %s .. ",key));
X if (!(pAC->vpd.v.vpd_status & VPD_VALID)) {
X if (VpdInit(pAC,IoC) != 0 ) {
- *len = 0 ;
+ *len = 0;
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
- ("vpd init error\n")) ;
- return(6) ;
+ ("vpd init error\n"));
+ return(6);
X }
X }
X
X if ((p = vpd_find_para(pAC,key,&vp))) {
X if (p->p_len > (*(unsigned *)len)-1) {
- p->p_len = *len - 1 ;
+ p->p_len = *len - 1;
X }
- SK_MEMCPY(buf,p->p_val,p->p_len) ;
- buf[p->p_len] = '\0' ;
- *len = p->p_len ;
+ SK_MEMCPY(buf,p->p_val,p->p_len);
+ buf[p->p_len] = '\0';
+ *len = p->p_len;
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_RX,
X ("%c%c%c%c.., len = %d\n",
- buf[0],buf[1],buf[2],buf[3],*len)) ;
+ buf[0],buf[1],buf[2],buf[3],*len));
X } else {
- *len = 0 ;
- SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,("not found\n")) ;
- return (1) ;
+ *len = 0;
+ SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,("not found\n"));
+ return (1);
X }
- return (0) ;
+ return (0);
X }
X
X
@@ -1005,9 +1020,9 @@
X key[1] < '0' || key[1] > 'Z' ||
X (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) {
X
- return (SK_FALSE) ;
+ return (SK_FALSE);
X }
- return (SK_TRUE) ;
+ return (SK_TRUE);
X }
X
X /*
@@ -1029,46 +1044,46 @@
X char *key, /* keyword to write (allowed values "Yx", "Vx") */
X char *buf) /* buffer where the keyword value can be read from */
X {
- int len ; /* lenght of the keyword to write */
- int rtv ; /* return code */
- int rtv2 ;
+ int len; /* lenght of the keyword to write */
+ int rtv; /* return code */
+ int rtv2;
X
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,
- ("vpd write %s = %s\n",key,buf)) ;
+ ("vpd write %s = %s\n",key,buf));
X
X if ((*key != 'Y' && *key != 'V') ||
X key[1] < '0' || key[1] > 'Z' ||
X (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) {
X
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
- ("illegal key tag, keyword not written\n")) ;
- return (5) ;
+ ("illegal key tag, keyword not written\n"));
+ return (5);
X }
X
X if (!(pAC->vpd.v.vpd_status & VPD_VALID)) {
X if (VpdInit(pAC,IoC) != 0 ) {
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
- ("vpd init error\n")) ;
- return(6) ;
+ ("vpd init error\n"));
+ return(6);
X }
X }
X
- rtv = 0 ;
- len = strlen(buf) ;
+ rtv = 0;
+ len = strlen(buf);
X if (len > VPD_MAX_LEN) {
X /* cut it */
- len = VPD_MAX_LEN ;
- rtv = 2 ;
+ len = VPD_MAX_LEN;
+ rtv = 2;
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
- ("keyword to long, cut after %d bytes\n",VPD_MAX_LEN)) ;
+ ("keyword to long, cut after %d bytes\n",VPD_MAX_LEN));
X }
X if ((rtv2 = VpdSetupPara(pAC,key,buf,len,VPD_RW_KEY,OWR_KEY)) != 0) {
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
- ("vpd write error\n")) ;
- return(rtv2) ;
+ ("vpd write error\n"));
+ return(rtv2);
X }
X
- return (rtv) ;
+ return (rtv);
X }
X
X /*
@@ -1088,15 +1103,15 @@
X SK_IOC IoC, /* IO Context */
X char *key) /* keyword to read (e.g. "MN") */
X {
- SK_VPD_PARA *p, vp ;
- char *etp ;
+ SK_VPD_PARA *p, vp;
+ char *etp;
X
- SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("vpd delete key %s\n",key)) ;
+ SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("vpd delete key %s\n",key));
X if (!(pAC->vpd.v.vpd_status & VPD_VALID)) {
X if (VpdInit(pAC,IoC) != 0 ) {
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
- ("vpd init error\n")) ;
- return(6) ;
+ ("vpd init error\n"));
+ return(6);
X }
X }
X
@@ -1104,27 +1119,27 @@
X if (p->p_val < pAC->vpd.vpd_buf + VPD_SIZE/2) {
X /* try to delete read only keyword */
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
- ("cannot delete RO keyword\n")) ;
- return (5) ;
+ ("cannot delete RO keyword\n"));
+ return (5);
X }
X
- etp = pAC->vpd.vpd_buf + (VPD_SIZE-pAC->vpd.v.vpd_free_rw-1-3) ;
+ etp = pAC->vpd.vpd_buf + (VPD_SIZE-pAC->vpd.v.vpd_free_rw-1-3);
X
X vpd_move_para(vp.p_val+vp.p_len, etp+2,
- - ((int)(vp.p_len + 3))) ;
+ - ((int)(vp.p_len + 3)));
X if (vpd_mod_endtag(pAC, etp - vp.p_len - 3)) {
- pAC->vpd.v.vpd_status &= ~VPD_VALID ;
+ pAC->vpd.v.vpd_status &= ~VPD_VALID;
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
- ("vpd encoding error\n")) ;
- return(6) ;
+ ("vpd encoding error\n"));
+ return(6);
X }
X } else {
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
- ("keyword not found\n")) ;
- return (1) ;
+ ("keyword not found\n"));
+ return (1);
X }
X
- return (0) ;
+ return (0);
X }
X
X /*
@@ -1138,18 +1153,18 @@
X SK_AC *pAC, /* Adapters context */
X SK_IOC IoC) /* IO Context */
X {
- SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("vpd update .. ")) ;
+ SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("vpd update .. "));
X if (pAC->vpd.v.vpd_status & VPD_VALID) {
X if (VpdTransferBlock(pAC,IoC,pAC->vpd.vpd_buf + VPD_SIZE/2,
X VPD_SIZE/2, VPD_SIZE/2, VPD_WRITE) != VPD_SIZE/2) {
X
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
- ("transfer timed out\n")) ;
- return(3) ;
+ ("transfer timed out\n"));
+ return(3);
X }
X }
- SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("done\n")) ;
- return (0) ;
+ SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("done\n"));
+ return (0);
X }
X
X
@@ -1169,32 +1184,32 @@
X SK_IOC IoC, /* IO Context */
X char *msg) /* error log message */
X {
- SK_VPD_PARA *v, vf ; /* VF */
- int len ;
+ SK_VPD_PARA *v, vf; /* VF */
+ int len;
X
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,
- ("vpd error log msg %s\n",msg)) ;
+ ("vpd error log msg %s\n",msg));
X if (!(pAC->vpd.v.vpd_status & VPD_VALID)) {
X if (VpdInit(pAC,IoC) != 0 ) {
X SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR,
- ("vpd init error\n")) ;
- return ;
+ ("vpd init error\n"));
+ return;
X }
X }
X
- len = strlen(msg) ;
+ len = strlen(msg);
X if (len > VPD_MAX_LEN) {
X /* cut it */
- len = VPD_MAX_LEN ;
+ len = VPD_MAX_LEN;
X }
X if ((v = vpd_find_para(pAC,VPD_VF,&vf))) {
- SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("overwrite VL\n")) ;
- (void)VpdSetupPara(pAC,VPD_VL,msg,len,VPD_RW_KEY,OWR_KEY) ;
+ SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("overwrite VL\n"));
+ (void)VpdSetupPara(pAC,VPD_VL,msg,len,VPD_RW_KEY,OWR_KEY);
X } else {
- SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("write VF\n")) ;
- (void)VpdSetupPara(pAC,VPD_VF,msg,len,VPD_RW_KEY,ADD_KEY) ;
+ SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("write VF\n"));
+ (void)VpdSetupPara(pAC,VPD_VF,msg,len,VPD_RW_KEY,ADD_KEY);
X }
X
- (void)VpdUpdate(pAC,IoC) ;
+ (void)VpdUpdate(pAC,IoC);
X }
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sk98lin/skxmac2.c linux/drivers/net/sk98lin/skxmac2.c
--- v2.4.0-test8/linux/drivers/net/sk98lin/skxmac2.c Tue Nov 23 10:15:42 1999
+++ linux/drivers/net/sk98lin/skxmac2.c Fri Sep 15 14:34:19 2000


@@ -2,8 +2,8 @@
X *

X * Name: skxmac2.c


X * Project: GEnesis, PCI Gigabit Ethernet Adapter

- * Version: $Revision: 1.49 $
- * Date: $Date: 1999/11/22 08:12:13 $
+ * Version: $Revision: 1.53 $
+ * Date: $Date: 2000/07/27 12:22:11 $
X * Purpose: Contains functions to initialize the XMAC II


X *
X ******************************************************************************/
@@ -13,8 +13,6 @@
X * (C)Copyright 1998,1999 SysKonnect,
X * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
X *
- * See the file "skge.c" for further information.
- *
X * This program is free software; you can redistribute it and/or modify
X * it under the terms of the GNU General Public License as published by
X * the Free Software Foundation; either version 2 of the License, or

@@ -29,6 +27,18 @@


X * History:
X *

X * $Log: skxmac2.c,v $
+ * Revision 1.53 2000/07/27 12:22:11 gklug
+ * fix: possible endless loop in XmHardRst.
+ *
+ * Revision 1.52 2000/05/22 08:48:31 malthoff
+ * Fix: #10523 errata valid for all BCOM PHYs.
+ *
+ * Revision 1.51 2000/05/17 12:52:18 malthoff
+ * Fixes BCom link errata (#10523).
+ *
+ * Revision 1.50 1999/11/22 13:40:14 cgoos


+ * Changed license header to GPL.
+ *

X * Revision 1.49 1999/11/22 08:12:13 malthoff
X * Add workaround for power consumption feature of Bcom C0 chip.
X *
@@ -224,7 +234,7 @@


X /* local variables ************************************************************/

X
X static const char SysKonnectFileId[] =

- "@(#)$Id: skxmac2.c,v 1.49 1999/11/22 08:12:13 malthoff Exp $ (C) SK ";
+ "@(#)$Id: skxmac2.c,v 1.53 2000/07/27 12:22:11 gklug Exp $ (C) SK ";
X
X /* BCOM PHY magic pattern list */
X typedef struct s_PhyHack {
@@ -558,6 +568,10 @@
X * register (Timing requirements: Broadcom: 400ns, Level One:
X * none, National: 80ns).
X *
+ * ATTENTION:
+ * It is absolutely neccessary to reset the SW_RST Bit first
+ * before calling this function.
+ *


X * Returns:
X * nothing

X */
@@ -568,6 +582,7 @@
X {
X SK_U16 Word;
X int i;
+ int TOut;
X SK_U32 Reg;
X
X for (i=0; i<4; i++) {
@@ -575,12 +590,25 @@
X /* bit contains buttoms to press */
X SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1),
X (SK_U16) MFF_CLR_MAC_RST);
- SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1),
- (SK_U16) MFF_SET_MAC_RST);
+
+ TOut = 0;
X do {
+ TOut ++;
+ if (TOut > 10000) {
+ /*
+ * Adapter seems to be in RESET state.
+ * Registers cannot be written.
+ */
+ return;
+ }
+
+ SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1),
+ (SK_U16) MFF_SET_MAC_RST);
X SK_IN16(IoC,MR_ADDR(Port,TX_MFF_CTRL1), &Word);
X } while ((Word & MFF_SET_MAC_RST) == 0);
X }
+
+ /* For external PHYs there must be special handling */
X if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) {
X
X /* reset external PHY */
@@ -696,6 +724,11 @@
X i++;
X }
X }
+ /* Workaround BCOM Errata (#10523) for all BCom PHYs*/
+ /* Disable Power Management after reset */
+ PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, &SWord);
+ PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL,
+ SWord | PHY_B_AC_DIS_PM);
X
X /*
X * PHY LED initialization is performed in
@@ -1845,6 +1878,7 @@
X SK_GEPORT *pPrt;
X SK_U16 Reg ; /* 16bit register value */
X SK_U16 IntMask; /* XMac interrupt mask */


+ SK_U16 SWord;
X
X pPrt = &pAC->GIni.GP[Port];

X
@@ -1892,6 +1926,11 @@
X }
X switch (pPrt->PhyType) {
X case SK_PHY_BCOM:
+ /* Workaround BCOM Errata (#10523) for all BCom Phys */
+ /* Enable Power Management after link up */
+ PHY_READ(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL, &SWord);
+ PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_AUX_CTRL,
+ SWord & ~PHY_B_AC_DIS_PM);


X PHY_WRITE(IoC, pPrt, Port, PHY_BCOM_INT_MASK,

X PHY_B_DEF_MSK);
X break;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/skfp/skfddi.c linux/drivers/net/skfp/skfddi.c
--- v2.4.0-test8/linux/drivers/net/skfp/skfddi.c Tue Jul 11 11:12:24 2000
+++ linux/drivers/net/skfp/skfddi.c Fri Sep 15 14:34:36 2000
@@ -1654,7 +1654,8 @@
X
X virt = mac_drv_get_space(smc, size);
X
- size = (u_int) ((0 - (unsigned long) virt) & 15UL);
+ size = (u_int) (16 - (((unsigned long) virt) & 15UL));
+ size = size % 16;
X
X PRINTK("Allocate %u bytes alignment gap ", size);
X PRINTK("for descriptor memory.\n");
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sundance.c linux/drivers/net/sundance.c
--- v2.4.0-test8/linux/drivers/net/sundance.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/sundance.c Sun Sep 24 12:12:33 2000
@@ -0,0 +1,1271 @@
+/* sundance.c: A Linux device driver for the Sundance ST201 "Alta". */
+/*
+ Written 1999-2000 by Donald Becker.


+
+ This software may be used and distributed according to the terms of

+ the GNU General Public License (GPL), incorporated herein by reference.


+ Drivers based on or derived from this code fall under the GPL and must
+ retain the authorship, copyright and license notice. This file is not
+ a complete program and may only be used when the entire operating
+ system is licensed under the GPL.
+
+ The author may be reached as bec...@scyld.com, or C/O
+ Scyld Computing Corporation
+ 410 Severn Ave., Suite 210
+ Annapolis MD 21403
+

+ Support and updates available at

+ http://www.scyld.com/network/sundance.html
+*/
+
+/* These identify the driver base version and may not be removed. */
+static const char version1[] =
+"sundance.c:v1.01 4/09/00 Written by Donald Becker\n";
+static const char version2[] =
+" http://www.scyld.com/network/sundance.html\n";


+
+/* The user-configurable values.
+ These may be modified when a driver module is loaded.*/

+
+static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */

+/* Maximum events (Rx packets, etc.) to handle at each interrupt. */

+static int max_interrupt_work = 20;


+static int mtu = 0;

+/* Maximum number of multicast addresses to filter (vs. rx-all-multicast).
+ Typical is a 64 element hash table based on the Ethernet CRC. */
+static int multicast_filter_limit = 32;


+
+/* Set the copy breakpoint for the copy-only-tiny-frames scheme.

+ Setting to > 1518 effectively disables this feature.
+ This chip can receive into offset buffers, so the Alpha does not
+ need a copy-align. */


+static int rx_copybreak = 0;
+

+/* Used to pass the media type, etc.

+ Both 'options[]' and 'full_duplex[]' should exist for driver
+ interoperability.
+ The media type is usually passed in 'options[]'.


+*/
+#define MAX_UNITS 8 /* More are supported, limit only on options */
+static int options[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
+static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};

+
+/* Operational parameters that are set at compile time. */
+
+/* Keep the ring sizes a power of two for compile efficiency.
+ The compiler will convert <unsigned>'%'<2^N> into a bit mask.
+ Making the Tx ring too large decreases the effectiveness of channel

+ bonding and packet priority, and more than 128 requires modifying the
+ Tx error recovery.
+ Large receive rings merely waste memory. */
+#define TX_RING_SIZE 16
+#define TX_QUEUE_LEN 10 /* Limit ring entries actually used. */
+#define RX_RING_SIZE 32


+
+/* Operational parameters that usually are not changed. */
+/* Time in jiffies before concluding the transmitter is hung. */

+#define TX_TIMEOUT (2*HZ)
+
+#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/
+
+#ifndef __KERNEL__
+#define __KERNEL__
+#endif
+#if !defined(__OPTIMIZE__)
+#warning You must compile this file with the correct options!
+#warning See the last lines of the source file.
+#error You must compile this driver with "-O".
+#endif
+
+/* Include files, designed to support most kernel versions 2.0.0 and later. */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/timer.h>


+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/malloc.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>

+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>

+#include <linux/init.h>


+#include <asm/processor.h> /* Processor type for cache alignment. */
+#include <asm/bitops.h>
+#include <asm/io.h>
+

+#include <linux/spinlock.h>
+
+
+/* Condensed operations for readability. */
+#define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr))
+#define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr))
+
+


+MODULE_AUTHOR("Donald Becker <bec...@scyld.com>");

+MODULE_DESCRIPTION("Sundance Alta Ethernet driver");
+MODULE_PARM(max_interrupt_work, "i");
+MODULE_PARM(mtu, "i");
+MODULE_PARM(debug, "i");
+MODULE_PARM(rx_copybreak, "i");


+MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");

+MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+


+/*
+ Theory of Operation
+
+I. Board Compatibility
+

+This driver is designed for the Sundance Technologies "Alta" ST201 chip.


+
+II. Board-specific settings
+

+III. Driver operation
+
+IIIa. Ring buffers
+

+This driver uses two statically allocated fixed-size descriptor lists
+formed into rings by a branch from the final descriptor to the beginning of
+the list. The ring sizes are set at compile time by RX/TX_RING_SIZE.

+Some chips explicitly use only 2^N sized rings, while others use a
+'next descriptor' pointer that the driver forms into rings.


+
+IIIb/c. Transmit/Receive Structure
+

+This driver uses a zero-copy receive and transmit scheme.


+The driver allocates full frame size skbuffs for the Rx ring buffers at

+open() time and passes the skb->data field to the chip as receive data


+buffers. When an incoming frame is less than RX_COPYBREAK bytes long,
+a fresh skbuff is allocated and the frame is copied to the new skbuff.
+When the incoming frame is larger, the skbuff is passed directly up the

+protocol stack. Buffers consumed this way are replaced by newly allocated
+skbuffs in a later phase of receives.


+
+The RX_COPYBREAK value is chosen to trade-off the memory wasted by
+using a full-sized skbuff for small frames vs. the copying costs of larger

+frames. New boards are typically used in generously configured machines


+and the underfilled buffers have negligible impact compared to the benefit of
+a single allocation size, so the default value of zero results in never

+copying packets. When copying is done, the cost is usually mitigated by using
+a combined copy/checksum routine. Copying also preloads the cache, which is
+most useful with small frames.
+
+A subtle aspect of the operation is that the IP header at offset 14 in an
+ethernet frame isn't longword aligned for further processing.
+Unaligned buffers are permitted by the Sundance hardware, so
+frames are received into the skbuff at an offset of "+2", 16-byte aligning
+the IP header.
+
+IIId. Synchronization
+


+The driver runs as two independent, single-threaded flows of control. One
+is the send-packet routine, which enforces single-threaded use by the
+dev->tbusy flag. The other thread is the interrupt handler, which is single

+threaded by the hardware and interrupt handling software.


+
+The send packet thread has partial control over the Tx ring and 'dev->tbusy'
+flag. It sets the tbusy flag whenever it's queuing a Tx packet. If the next
+queue slot is empty, it clears the tbusy flag when finished otherwise it sets

+the 'lp->tx_full' flag.


+
+The interrupt handler has exclusive control over the Rx ring and records stats
+from the Tx ring. After reaping the stats, it marks the Tx queue entry as

+empty by incrementing the dirty_tx mark. Iff the 'lp->tx_full' flag is set, it


+clears both the tx_full and tbusy flags.
+
+IV. Notes
+

+IVb. References
+
+The Sundance ST201 datasheet, preliminary version.
+http://cesdis.gsfc.nasa.gov/linux/misc/100mbps.html
+http://cesdis.gsfc.nasa.gov/linux/misc/NWay.html
+
+IVc. Errata
+
+*/
+
+
+
+enum pci_id_flags_bits {
+ /* Set PCI command register bits before calling probe1(). */
+ PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
+ /* Read and map the single following PCI BAR. */
+ PCI_ADDR0=0<<4, PCI_ADDR1=1<<4, PCI_ADDR2=2<<4, PCI_ADDR3=3<<4,
+ PCI_ADDR_64BITS=0x100, PCI_NO_ACPI_WAKE=0x200, PCI_NO_MIN_LATENCY=0x400,
+};
+enum chip_capability_flags {CanHaveMII=1, };
+#ifdef USE_IO_OPS
+#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_IO | PCI_ADDR0)
+#else
+#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR1)
+#endif
+
+static struct pci_device_id sundance_pci_tbl[] __devinitdata = {
+ { 0x1186, 0x1002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ { 0x13F0, 0x0201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },
+ { 0, }
+};
+MODULE_DEVICE_TABLE(pci, sundance_pci_tbl);
+
+struct pci_id_info {
+ const char *name;
+ struct match_info {
+ int pci, pci_mask, subsystem, subsystem_mask;
+ int revision, revision_mask; /* Only 8 bits. */
+ } id;
+ enum pci_id_flags_bits pci_flags;
+ int io_size; /* Needed for I/O region check or ioremap(). */
+ int drv_flags; /* Driver use, intended as capability flags. */
+};
+static struct pci_id_info pci_id_tbl[] = {
+ {"OEM Sundance Technology ST201", {0x10021186, 0xffffffff, },
+ PCI_IOTYPE, 128, CanHaveMII},
+ {"Sundance Technology Alta", {0x020113F0, 0xffffffff, },
+ PCI_IOTYPE, 128, CanHaveMII},
+ {0,}, /* 0 terminated list. */
+};
+
+/* This driver was written to use PCI memory space, however x86-oriented
+ hardware often uses I/O space accesses. */
+#ifdef USE_IO_OPS


+#undef readb
+#undef readw
+#undef readl
+#undef writeb
+#undef writew
+#undef writel

+#define readb inb
+#define readw inw
+#define readl inl
+#define writeb outb
+#define writew outw
+#define writel outl
+#endif
+
+/* Offsets to the device registers.
+ Unlike software-only systems, device drivers interact with complex hardware.
+ It's not useful to define symbolic names for every register bit in the
+ device. The name can only partially document the semantics and make
+ the driver longer and more difficult to read.
+ In general, only the important configuration values or bits changed
+ multiple times should be defined symbolically.
+*/
+enum alta_offsets {
+ DMACtrl=0x00, TxListPtr=0x04, TxDMACtrl=0x08, TxDescPoll=0x0a,
+ RxDMAStatus=0x0c, RxListPtr=0x10, RxDMACtrl=0x14, RxDescPoll=0x16,
+ LEDCtrl=0x1a, ASICCtrl=0x30,
+ EEData=0x34, EECtrl=0x36, TxThreshold=0x3c,
+ FlashAddr=0x40, FlashData=0x44, TxStatus=0x46, DownCounter=0x48,
+ IntrClear=0x4a, IntrEnable=0x4c, IntrStatus=0x4e,
+ MACCtrl0=0x50, MACCtrl1=0x52, StationAddr=0x54,
+ MaxTxSize=0x5A, RxMode=0x5c, MIICtrl=0x5e,
+ MulticastFilter0=0x60, MulticastFilter1=0x64,
+ RxOctetsLow=0x68, RxOctetsHigh=0x6a, TxOctetsLow=0x6c, TxOctetsHigh=0x6e,
+ TxFramesOK=0x70, RxFramesOK=0x72, StatsCarrierError=0x74,
+ StatsLateColl=0x75, StatsMultiColl=0x76, StatsOneColl=0x77,
+ StatsTxDefer=0x78, RxMissed=0x79, StatsTxXSDefer=0x7a, StatsTxAbort=0x7b,
+ StatsBcastTx=0x7c, StatsBcastRx=0x7d, StatsMcastTx=0x7e, StatsMcastRx=0x7f,
+ /* Aliased and bogus values! */
+ RxStatus=0x0c,


+};
+
+/* Bits in the interrupt status/mask registers. */
+enum intr_status_bits {

+ IntrSummary=0x0001, IntrPCIErr=0x0002, IntrMACCtrl=0x0008,
+ IntrTxDone=0x0004, IntrRxDone=0x0010, IntrRxStart=0x0020,
+ IntrDrvRqst=0x0040,
+ StatsMax=0x0080, LinkChange=0x0100,
+ IntrTxDMADone=0x0200, IntrRxDMADone=0x0400,
+};
+
+/* Bits in the RxMode register. */
+enum rx_mode_bits {
+ AcceptAllIPMulti=0x20, AcceptMultiHash=0x10, AcceptAll=0x08,
+ AcceptBroadcast=0x04, AcceptMulticast=0x02, AcceptMyPhys=0x01,
+};
+/* Bits in MACCtrl. */
+enum mac_ctrl0_bits {
+ EnbFullDuplex=0x20, EnbRcvLargeFrame=0x40,
+ EnbFlowCtrl=0x100, EnbPassRxCRC=0x200,
+};
+enum mac_ctrl1_bits {
+ StatsEnable=0x0020, StatsDisable=0x0040, StatsEnabled=0x0080,
+ TxEnable=0x0100, TxDisable=0x0200, TxEnabled=0x0400,
+ RxEnable=0x0800, RxDisable=0x1000, RxEnabled=0x2000,
+};
+
+/* The Rx and Tx buffer descriptors. */
+/* Note that using only 32 bit fields simplifies conversion to big-endian
+ architectures. */
+struct netdev_desc {
+ u32 next_desc;
+ u32 status;
+ struct desc_frag { u32 addr, length; } frag[1];
+};
+
+/* Bits in netdev_desc.status */
+enum desc_status_bits {
+ DescOwn=0x8000, DescEndPacket=0x4000, DescEndRing=0x2000,
+ LastFrag=0x80000000, DescIntrOnTx=0x8000, DescIntrOnDMADone=0x80000000,


+};
+
+#define PRIV_ALIGN 15 /* Required alignment mask */

+/* Use __attribute__((aligned (L1_CACHE_BYTES))) to maintain alignment
+ within the structure. */
+struct netdev_private {
+ /* Descriptor rings first for alignment. */
+ struct netdev_desc rx_ring[RX_RING_SIZE];
+ struct netdev_desc tx_ring[TX_RING_SIZE];


+ /* The addresses of receive-in-place skbuffs. */
+ struct sk_buff* rx_skbuff[RX_RING_SIZE];

+ /* The saved address of a sent-in-place packet/buffer, for later free(). */


+ struct sk_buff* tx_skbuff[TX_RING_SIZE];

+ struct net_device_stats stats;
+ struct timer_list timer; /* Media monitoring timer. */
+ /* Frequently used values: keep some adjacent for cache effect. */
+ spinlock_t lock;
+ int chip_id, drv_flags;
+ /* Note: Cache paragraph grouped variables. */
+ struct netdev_desc *rx_head_desc;


+ unsigned int cur_rx, dirty_rx; /* Producer/consumer ring indices */

+ unsigned int rx_buf_sz; /* Based on MTU+slack. */

+ spinlock_t txlock; /* Group with Tx control cache line. */
+ struct netdev_desc *last_tx; /* Last Tx descriptor used. */


+ unsigned int cur_tx, dirty_tx;

+ unsigned int tx_full:1; /* The Tx queue is full. */

+ /* These values are keep track of the transceiver/media in use. */


+ unsigned int full_duplex:1; /* Full-duplex operation requested. */
+ unsigned int duplex_lock:1;
+ unsigned int medialock:1; /* Do not sense media. */
+ unsigned int default_port:4; /* Last dev->if_port value. */

+ /* Multicast and receive mode. */
+ spinlock_t mcastlock; /* SMP lock multicast updates. */
+ u16 mcast_filter[4];


+ /* MII transceiver section. */
+ int mii_cnt; /* MII device addresses. */
+ u16 advertising; /* NWay media advertisement */
+ unsigned char phys[2]; /* MII device addresses. */

+};
+
+/* The station address location in the EEPROM. */
+#define EEPROM_SA_OFFSET 0x10
+
+static int eeprom_read(long ioaddr, int location);
+static int mdio_read(struct net_device *dev, int phy_id, int location);
+static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
+static int netdev_open(struct net_device *dev);
+static void check_duplex(struct net_device *dev);
+static void netdev_timer(unsigned long data);


+static void tx_timeout(struct net_device *dev);

+static void init_ring(struct net_device *dev);
+static int start_tx(struct sk_buff *skb, struct net_device *dev);
+static void intr_handler(int irq, void *dev_instance, struct pt_regs *regs);
+static void netdev_error(struct net_device *dev, int intr_status);
+static int netdev_rx(struct net_device *dev);
+static void netdev_error(struct net_device *dev, int intr_status);
+static void set_rx_mode(struct net_device *dev);
+static struct net_device_stats *get_stats(struct net_device *dev);
+static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static int netdev_close(struct net_device *dev);
+
+
+
+static int __devinit sundance_probe1 (struct pci_dev *pdev,


+ const struct pci_device_id *ent)

+{
+ struct net_device *dev;
+ struct netdev_private *np;
+ static int card_idx;
+ int chip_idx = ent->driver_data;


+ int irq = pdev->irq;

+ int i, option = card_idx < MAX_UNITS ? options[card_idx] : 0;
+ long ioaddr;


+
+ if (pci_enable_device(pdev))
+ return -EIO;
+ pci_set_master(pdev);
+

+ dev = init_etherdev(NULL, sizeof(*np));


+ if (!dev)
+ return -ENOMEM;
+

+#ifdef USE_IO_OPS


+ ioaddr = pci_resource_start(pdev, 0);

+ if (!request_region(ioaddr, pci_id_tbl[chip_idx].io_size, dev->name))
+ goto err_out_netdev;
+#else
+ ioaddr = pci_resource_start(pdev, 1);
+ if (!request_mem_region(ioaddr, pci_id_tbl[chip_idx].io_size, dev->name))
+ goto err_out_netdev;
+ ioaddr = (long) ioremap (ioaddr, pci_id_tbl[chip_idx].io_size);
+ if (!ioaddr)
+ goto err_out_iomem;
+#endif
+
+ printk(KERN_INFO "%s: %s at 0x%lx, ",
+ dev->name, pci_id_tbl[chip_idx].name, ioaddr);
+
+ for (i = 0; i < 3; i++)


+ ((u16 *)dev->dev_addr)[i] =

+ le16_to_cpu(eeprom_read(ioaddr, i + EEPROM_SA_OFFSET));


+ for (i = 0; i < 5; i++)
+ printk("%2.2x:", dev->dev_addr[i]);

+ printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq);


+
+ dev->base_addr = ioaddr;

+ dev->irq = irq;
+
+ np = dev->priv;
+ np->chip_id = chip_idx;
+ np->drv_flags = pci_id_tbl[chip_idx].drv_flags;
+ spin_lock_init(&np->lock);
+


+ if (dev->mem_start)
+ option = dev->mem_start;
+

+ /* The lower four bits are the media type. */
+ if (option > 0) {

+ if (option & 0x200)

+ np->full_duplex = 1;
+ np->default_port = option & 15;
+ if (np->default_port)
+ np->medialock = 1;


+ }
+ if (card_idx < MAX_UNITS && full_duplex[card_idx] > 0)

+ np->full_duplex = 1;
+
+ if (np->full_duplex)
+ np->duplex_lock = 1;
+
+ /* The chip-specific entries in the device structure. */
+ dev->open = &netdev_open;
+ dev->hard_start_xmit = &start_tx;
+ dev->stop = &netdev_close;
+ dev->get_stats = &get_stats;


+ dev->set_multicast_list = &set_rx_mode;

+ dev->do_ioctl = &mii_ioctl;

+ dev->tx_timeout = &tx_timeout;


+ dev->watchdog_timeo = TX_TIMEOUT;

+


+ if (mtu)
+ dev->mtu = mtu;
+

+ if (1) {


+ int phy, phy_idx = 0;

+ np->phys[0] = 1; /* Default setting */
+ for (phy = 0; phy < 32 && phy_idx < 4; phy++) {
+ int mii_status = mdio_read(dev, phy, 1);
+ if (mii_status != 0xffff && mii_status != 0x0000) {
+ np->phys[phy_idx++] = phy;
+ np->advertising = mdio_read(dev, phy, 4);


+ printk(KERN_INFO "%s: MII PHY found at address %d, status "

+ "0x%4.4x advertising %4.4x.\n",
+ dev->name, phy, mii_status, np->advertising);
+ }
+ }
+ np->mii_cnt = phy_idx;
+ if (phy_idx == 0)
+ printk(KERN_INFO "%s: No MII transceiver found!, ASIC status %x\n",
+ dev->name, readl(ioaddr + ASICCtrl));
+ }
+
+ /* Perhaps move the reset here? */
+ /* Reset the chip to erase previous misconfiguration. */
+ if (debug > 1)
+ printk("ASIC Control is %x.\n", readl(ioaddr + ASICCtrl));
+ writew(0x007f, ioaddr + ASICCtrl + 2);
+ if (debug > 1)
+ printk("ASIC Control is now %x.\n", readl(ioaddr + ASICCtrl));


+
+ card_idx++;
+ return 0;
+

+#ifndef USE_IO_OPS
+err_out_iomem:
+ release_mem_region(pci_resource_start(pdev, 1),
+ pci_id_tbl[chip_idx].io_size);
+#endif
+err_out_netdev:
+ unregister_netdev (dev);
+ kfree (dev);


+ return -ENODEV;
+}
+
+

+/* Read the EEPROM and MII Management Data I/O (MDIO) interfaces. */
+static int eeprom_read(long ioaddr, int location)
+{
+ int boguscnt = 1000; /* Typical 190 ticks. */
+ writew(0x0200 | (location & 0xff), ioaddr + EECtrl);
+ do {
+ if (! (readw(ioaddr + EECtrl) & 0x8000)) {
+ return readw(ioaddr + EEData);
+ }
+ } while (--boguscnt > 0);


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 068'
echo 'File patch-2.4.0-test9 is continued in part 069'
echo "069" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part069

#!/bin/sh -x
# this is part 069 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 069; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ return 0;
+}
+

+/* MII transceiver control section.
+ Read and write the MII registers using software-generated serial
+ MDIO protocol. See the MII specifications or DP83840A data sheet
+ for details.
+
+ The maximum data clock rate is 2.5 Mhz. The minimum timing is usually
+ met by back-to-back 33Mhz PCI cycles. */
+#define mdio_delay() readb(mdio_addr)
+
+/* Set iff a MII transceiver on any interface requires mdio preamble.
+ This only set with older tranceivers, so the extra
+ code size of a per-interface flag is not worthwhile. */
+static char mii_preamble_required = 0;
+
+enum mii_reg_bits {
+ MDIO_ShiftClk=0x0001, MDIO_Data=0x0002, MDIO_EnbOutput=0x0004,
+};
+#define MDIO_EnbIn (0)
+#define MDIO_WRITE0 (MDIO_EnbOutput)
+#define MDIO_WRITE1 (MDIO_Data | MDIO_EnbOutput)
+
+/* Generate the preamble required for initial synchronization and
+ a few older transceivers. */
+static void mdio_sync(long mdio_addr)
+{
+ int bits = 32;
+
+ /* Establish sync by sending at least 32 logic ones. */
+ while (--bits >= 0) {
+ writeb(MDIO_WRITE1, mdio_addr);
+ mdio_delay();
+ writeb(MDIO_WRITE1 | MDIO_ShiftClk, mdio_addr);
+ mdio_delay();
+ }
+}
+


+static int mdio_read(struct net_device *dev, int phy_id, int location)

+{
+ long mdio_addr = dev->base_addr + MIICtrl;
+ int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
+ int i, retval = 0;
+
+ if (mii_preamble_required)
+ mdio_sync(mdio_addr);
+
+ /* Shift the read command bits out. */
+ for (i = 15; i >= 0; i--) {
+ int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
+
+ writeb(dataval, mdio_addr);
+ mdio_delay();
+ writeb(dataval | MDIO_ShiftClk, mdio_addr);
+ mdio_delay();
+ }
+ /* Read the two transition, 16 data, and wire-idle bits. */
+ for (i = 19; i > 0; i--) {
+ writeb(MDIO_EnbIn, mdio_addr);
+ mdio_delay();
+ retval = (retval << 1) | ((readb(mdio_addr) & MDIO_Data) ? 1 : 0);
+ writeb(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
+ mdio_delay();
+ }
+ return (retval>>1) & 0xffff;
+}
+


+static void mdio_write(struct net_device *dev, int phy_id, int location, int value)

+{
+ long mdio_addr = dev->base_addr + MIICtrl;
+ int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
+ int i;
+
+ if (mii_preamble_required)
+ mdio_sync(mdio_addr);
+
+ /* Shift the command bits out. */
+ for (i = 31; i >= 0; i--) {
+ int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
+
+ writeb(dataval, mdio_addr);
+ mdio_delay();
+ writeb(dataval | MDIO_ShiftClk, mdio_addr);
+ mdio_delay();
+ }
+ /* Clear out extra bits. */
+ for (i = 2; i > 0; i--) {
+ writeb(MDIO_EnbIn, mdio_addr);
+ mdio_delay();
+ writeb(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
+ mdio_delay();
+ }


+ return;
+}
+
+

+static int netdev_open(struct net_device *dev)

+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;


+ long ioaddr = dev->base_addr;

+ int i;
+
+ /* Do we need to reset the chip??? */
+
+ MOD_INC_USE_COUNT;
+
+ if (request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev)) {


+ MOD_DEC_USE_COUNT;
+ return -EAGAIN;
+ }
+

+ if (debug > 1)
+ printk(KERN_DEBUG "%s: netdev_open() irq %d.\n",
+ dev->name, dev->irq);
+
+ init_ring(dev);
+
+ writel(virt_to_bus(np->rx_ring), ioaddr + RxListPtr);
+ /* The Tx list pointer is written as packets are queued. */
+


+ for (i = 0; i < 6; i++)
+ writeb(dev->dev_addr[i], ioaddr + StationAddr + i);
+

+ /* Initialize other registers. */
+ /* Configure the PCI bus bursts and FIFO thresholds. */


+
+ if (dev->if_port == 0)

+ dev->if_port = np->default_port;
+
+ np->full_duplex = np->duplex_lock;
+ np->mcastlock = (spinlock_t) SPIN_LOCK_UNLOCKED;
+
+ set_rx_mode(dev);
+ writew(0, ioaddr + DownCounter);
+ /* Set the chip to poll every N*320nsec. */
+ writeb(100, ioaddr + RxDescPoll);
+ writeb(127, ioaddr + TxDescPoll);
+ netif_start_queue(dev);
+
+ /* Enable interrupts by setting the interrupt mask. */
+ writew(IntrRxDone | IntrRxDMADone | IntrPCIErr | IntrDrvRqst | IntrTxDone
+ | StatsMax | LinkChange, ioaddr + IntrEnable);
+
+ writew(StatsEnable | RxEnable | TxEnable, ioaddr + MACCtrl1);
+
+ if (debug > 2)
+ printk(KERN_DEBUG "%s: Done netdev_open(), status: Rx %x Tx %x "
+ "MAC Control %x, %4.4x %4.4x.\n",
+ dev->name, readl(ioaddr + RxStatus), readb(ioaddr + TxStatus),
+ readl(ioaddr + MACCtrl0),
+ readw(ioaddr + MACCtrl1), readw(ioaddr + MACCtrl0));


+
+ /* Set the timer to check for link beat. */

+ init_timer(&np->timer);
+ np->timer.expires = jiffies + 3*HZ;
+ np->timer.data = (unsigned long)dev;
+ np->timer.function = &netdev_timer; /* timer handler */
+ add_timer(&np->timer);


+
+ return 0;
+}
+

+static void check_duplex(struct net_device *dev)

+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;


+ long ioaddr = dev->base_addr;

+ int mii_reg5 = mdio_read(dev, np->phys[0], 5);
+ int negotiated = mii_reg5 & np->advertising;
+ int duplex;
+
+ if (np->duplex_lock || mii_reg5 == 0xffff)
+ return;
+ duplex = (negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040;
+ if (np->full_duplex != duplex) {
+ np->full_duplex = duplex;
+ if (debug)
+ printk(KERN_INFO "%s: Setting %s-duplex based on MII #%d "
+ "negotiated capability %4.4x.\n", dev->name,
+ duplex ? "full" : "half", np->phys[0], negotiated);
+ writew(duplex ? 0x20 : 0, ioaddr + MACCtrl0);
+ }
+}
+


+static void netdev_timer(unsigned long data)

+{


+ struct net_device *dev = (struct net_device *)data;

+ struct netdev_private *np = (struct netdev_private *)dev->priv;


+ long ioaddr = dev->base_addr;
+ int next_tick = 10*HZ;
+

+ if (debug > 3) {
+ printk(KERN_DEBUG "%s: Media selection timer tick, intr status %4.4x, "
+ "Tx %x Rx %x.\n",
+ dev->name, readw(ioaddr + IntrEnable),
+ readb(ioaddr + TxStatus), readl(ioaddr + RxStatus));
+ }
+ check_duplex(dev);
+ np->timer.expires = jiffies + next_tick;
+ add_timer(&np->timer);
+}
+


+static void tx_timeout(struct net_device *dev)

+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;


+ long ioaddr = dev->base_addr;
+

+ printk(KERN_WARNING "%s: Transmit timed out, status %2.2x,"
+ " resetting...\n", dev->name, readb(ioaddr + TxStatus));
+
+#ifndef __alpha__
+ {
+ int i;
+ printk(KERN_DEBUG " Rx ring %8.8x: ", (int)np->rx_ring);


+ for (i = 0; i < RX_RING_SIZE; i++)

+ printk(" %8.8x", (unsigned int)np->rx_ring[i].status);
+ printk("\n"KERN_DEBUG" Tx ring %8.8x: ", (int)np->tx_ring);


+ for (i = 0; i < TX_RING_SIZE; i++)

+ printk(" %4.4x", np->tx_ring[i].status);


+ printk("\n");
+ }
+#endif
+

+ /* Perhaps we should reinitialize the hardware here. */


+ dev->if_port = 0;

+ /* Stop and restart the chip's Tx processes . */


+
+ /* Trigger an immediate transmit demand. */

+ writew(IntrRxDone | IntrRxDMADone | IntrPCIErr | IntrDrvRqst | IntrTxDone
+ | StatsMax | LinkChange, ioaddr + IntrEnable);


+
+ dev->trans_start = jiffies;

+ np->stats.tx_errors++;


+ return;
+}
+
+

+/* Initialize the Rx and Tx rings, along with various 'dev' bits. */

+static void init_ring(struct net_device *dev)

+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ int i;
+
+ np->tx_full = 0;
+ np->cur_rx = np->cur_tx = 0;
+ np->dirty_rx = np->dirty_tx = 0;
+
+ np->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32);
+ np->rx_head_desc = &np->rx_ring[0];


+
+ /* Initialize all Rx descriptors. */

+ for (i = 0; i < RX_RING_SIZE; i++) {
+ np->rx_ring[i].next_desc = virt_to_le32desc(&np->rx_ring[i+1]);
+ np->rx_ring[i].status = 0;
+ np->rx_ring[i].frag[0].length = 0;
+ np->rx_skbuff[i] = 0;
+ }
+ /* Wrap the ring. */
+ np->rx_ring[i-1].next_desc = virt_to_le32desc(&np->rx_ring[0]);


+
+ /* Fill in the Rx buffers. Handle allocation failure gracefully. */
+ for (i = 0; i < RX_RING_SIZE; i++) {

+ struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz);
+ np->rx_skbuff[i] = skb;


+ if (skb == NULL)
+ break;
+ skb->dev = dev; /* Mark as being used by this device. */
+ skb_reserve(skb, 2); /* 16 byte align the IP header. */

+ np->rx_ring[i].frag[0].addr = virt_to_le32desc(skb->tail);
+ np->rx_ring[i].frag[0].length = cpu_to_le32(np->rx_buf_sz | LastFrag);
+ }
+ np->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
+
+ for (i = 0; i < TX_RING_SIZE; i++) {
+ np->tx_skbuff[i] = 0;
+ np->tx_ring[i].status = 0;


+ }
+ return;
+}
+

+static int start_tx(struct sk_buff *skb, struct net_device *dev)

+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ struct netdev_desc *txdesc;
+ unsigned entry;
+
+ /* Note: Ordering is important here, set the field with the
+ "ownership" bit last, and only then increment cur_tx. */


+
+ /* Calculate the next Tx descriptor entry. */

+ entry = np->cur_tx % TX_RING_SIZE;
+ np->tx_skbuff[entry] = skb;
+ txdesc = &np->tx_ring[entry];
+
+ txdesc->next_desc = 0;
+ /* Note: disable the interrupt generation here before releasing. */
+ txdesc->status =
+ cpu_to_le32((entry<<2) | DescIntrOnDMADone | DescIntrOnTx);
+ txdesc->frag[0].addr = virt_to_le32desc(skb->data);
+ txdesc->frag[0].length = cpu_to_le32(skb->len | LastFrag);
+ if (np->last_tx)
+ np->last_tx->next_desc = virt_to_le32desc(txdesc);
+ np->last_tx = txdesc;
+ np->cur_tx++;
+
+ /* On some architectures: explicitly flush cache lines here. */
+
+ if (np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 1) {
+ /* do nothing */
+ } else {
+ np->tx_full = 1;
+ netif_stop_queue(dev);
+ }
+ /* Side effect: The read wakes the potentially-idle transmit channel. */
+ if (readl(dev->base_addr + TxListPtr) == 0)
+ writel(virt_to_bus(&np->tx_ring[entry]), dev->base_addr + TxListPtr);


+
+ dev->trans_start = jiffies;
+

+ if (debug > 4) {
+ printk(KERN_DEBUG "%s: Transmit frame #%d queued in slot %d.\n",
+ dev->name, np->cur_tx, entry);


+ }
+ return 0;
+}
+
+/* The interrupt handler does all of the Rx thread work and cleans up
+ after the Tx thread. */

+static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
+{
+ struct net_device *dev = (struct net_device *)dev_instance;
+ struct netdev_private *np;
+ long ioaddr;
+ int boguscnt = max_interrupt_work;


+
+ ioaddr = dev->base_addr;

+ np = (struct netdev_private *)dev->priv;
+ spin_lock(&np->lock);
+
+ do {
+ int intr_status = readw(ioaddr + IntrStatus);
+ writew(intr_status & (IntrRxDone | IntrRxDMADone | IntrPCIErr |
+ IntrDrvRqst |IntrTxDone|IntrTxDMADone |
+ StatsMax | LinkChange),
+ ioaddr + IntrStatus);
+
+ if (debug > 4)
+ printk(KERN_DEBUG "%s: Interrupt, status %4.4x.\n",


+ dev->name, intr_status);
+
+ if (intr_status == 0)

+ break;
+
+ if (intr_status & (IntrRxDone|IntrRxDMADone))
+ netdev_rx(dev);


+
+ if (intr_status & IntrTxDone) {

+ int boguscnt = 32;
+ int tx_status = readw(ioaddr + TxStatus);
+ while (tx_status & 0x80) {
+ if (debug > 4)
+ printk("%s: Transmit status is %2.2x.\n",
+ dev->name, tx_status);
+ if (tx_status & 0x1e) {
+ np->stats.tx_errors++;
+ if (tx_status & 0x10) np->stats.tx_fifo_errors++;
+#ifdef ETHER_STATS
+ if (tx_status & 0x08) np->stats.collisions16++;
+#else
+ if (tx_status & 0x08) np->stats.collisions++;
+#endif
+ if (tx_status & 0x04) np->stats.tx_fifo_errors++;
+ if (tx_status & 0x02) np->stats.tx_window_errors++;
+ /* This reset has not been verified!. */
+ if (tx_status & 0x10) { /* Reset the Tx. */
+ writew(0x001c, ioaddr + ASICCtrl + 2);
+#if 0 /* Do we need to reset the Tx pointer here? */
+ writel(virt_to_bus(&np->tx_ring[np->dirty_tx]),
+ dev->base_addr + TxListPtr);
+#endif
+ }
+ if (tx_status & 0x1e) /* Restart the Tx. */
+ writew(TxEnable, ioaddr + MACCtrl1);
+ }
+ /* Yup, this is a documentation bug. It cost me *hours*. */
+ writew(0, ioaddr + TxStatus);
+ tx_status = readb(ioaddr + TxStatus);


+ if (--boguscnt < 0)
+ break;
+ }

+ }
+ for (; np->cur_tx - np->dirty_tx > 0; np->dirty_tx++) {
+ int entry = np->dirty_tx % TX_RING_SIZE;
+ if ( ! (np->tx_ring[entry].status & 0x00010000))


+ break;
+ /* Free the original skb. */

+ dev_kfree_skb_irq(np->tx_skbuff[entry]);
+ np->tx_skbuff[entry] = 0;
+ }
+ if (np->tx_full
+ && np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 4) {
+ /* The ring is no longer full, clear tbusy. */
+ np->tx_full = 0;
+ netif_wake_queue(dev);
+ }
+


+ /* Abnormal error summary/uncommon events handlers. */

+ if (intr_status & (IntrDrvRqst | IntrPCIErr | LinkChange | StatsMax))
+ netdev_error(dev, intr_status);


+
+ if (--boguscnt < 0) {

+ get_stats(dev);


+ printk(KERN_WARNING "%s: Too much work at interrupt, "

+ "status=0x%4.4x / 0x%4.4x.\n",
+ dev->name, intr_status, readw(ioaddr + IntrClear));
+ /* Re-enable us in 3.2msec. */
+ writew(1000, ioaddr + DownCounter);
+ writew(IntrDrvRqst, ioaddr + IntrEnable);


+ break;
+ }
+ } while (1);
+

+ if (debug > 3)
+ printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
+ dev->name, readw(ioaddr + IntrStatus));
+
+ spin_unlock(&np->lock);
+}
+
+/* This routine is logically part of the interrupt handler, but separated


+ for clarity and better register allocation. */

+static int netdev_rx(struct net_device *dev)

+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ int entry = np->cur_rx % RX_RING_SIZE;
+ int boguscnt = np->dirty_rx + RX_RING_SIZE - np->cur_rx;
+
+ if (debug > 4) {
+ printk(KERN_DEBUG " In netdev_rx(), entry %d status %4.4x.\n",
+ entry, np->rx_ring[entry].status);


+ }
+
+ /* If EOP is set on the next entry, it's a new packet. Send it up. */

+ while (np->rx_head_desc->status & DescOwn) {
+ struct netdev_desc *desc = np->rx_head_desc;
+ u32 frame_status = le32_to_cpu(desc->status);
+ int pkt_len = frame_status & 0x1fff; /* Chip omits the CRC. */
+
+ if (debug > 4)
+ printk(KERN_DEBUG " netdev_rx() status was %8.8x.\n",


+ frame_status);
+ if (--boguscnt < 0)
+ break;

+ if (frame_status & 0x001f4000) {
+ /* There was a error. */
+ if (debug > 2)
+ printk(KERN_DEBUG " netdev_rx() Rx error was %8.8x.\n",
+ frame_status);
+ np->stats.rx_errors++;
+ if (frame_status & 0x00100000) np->stats.rx_length_errors++;
+ if (frame_status & 0x00010000) np->stats.rx_fifo_errors++;
+ if (frame_status & 0x00060000) np->stats.rx_frame_errors++;
+ if (frame_status & 0x00080000) np->stats.rx_crc_errors++;
+ if (frame_status & 0x00100000) {
+ printk(KERN_WARNING "%s: Oversized Ethernet frame,"
+ " status %8.8x.\n",
+ dev->name, frame_status);
+ }


+ } else {
+ struct sk_buff *skb;
+

+#ifndef final_version
+ if (debug > 4)
+ printk(KERN_DEBUG " netdev_rx() normal Rx pkt length %d"
+ ", bogus_cnt %d.\n",
+ pkt_len, boguscnt);


+#endif
+ /* Check if the packet is long enough to accept without copying
+ to a minimally-sized skbuff. */
+ if (pkt_len < rx_copybreak
+ && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {

+ skb->dev = dev;
+ skb_reserve(skb, 2); /* 16 byte align the IP header */

+ eth_copy_and_sum(skb, np->rx_skbuff[entry]->tail, pkt_len, 0);
+ skb_put(skb, pkt_len);
+ } else {
+ skb_put(skb = np->rx_skbuff[entry], pkt_len);
+ np->rx_skbuff[entry] = NULL;
+ }


+ skb->protocol = eth_type_trans(skb, dev);

+ /* Note: checksum -> skb->ip_summed = CHECKSUM_UNNECESSARY; */


+ netif_rx(skb);
+ dev->last_rx = jiffies;
+ }

+ entry = (++np->cur_rx) % RX_RING_SIZE;
+ np->rx_head_desc = &np->rx_ring[entry];


+ }
+
+ /* Refill the Rx ring buffers. */

+ for (; np->cur_rx - np->dirty_rx > 0; np->dirty_rx++) {
+ struct sk_buff *skb;
+ entry = np->dirty_rx % RX_RING_SIZE;
+ if (np->rx_skbuff[entry] == NULL) {
+ skb = dev_alloc_skb(np->rx_buf_sz);
+ np->rx_skbuff[entry] = skb;


+ if (skb == NULL)
+ break; /* Better luck next round. */
+ skb->dev = dev; /* Mark as being used by this device. */
+ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */

+ np->rx_ring[entry].frag[0].addr = virt_to_le32desc(skb->tail);
+ }
+ /* Perhaps we need not reset this field. */
+ np->rx_ring[entry].frag[0].length =
+ cpu_to_le32(np->rx_buf_sz | LastFrag);
+ np->rx_ring[entry].status = 0;
+ }
+
+ /* No need to restart Rx engine, it will poll. */


+ return 0;
+}
+

+static void netdev_error(struct net_device *dev, int intr_status)

+{
+ long ioaddr = dev->base_addr;

+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+
+ if (intr_status & IntrDrvRqst) {
+ /* Stop the down counter and turn interrupts back on. */
+ printk("%s: Turning interrupts back on.\n", dev->name);
+ writew(0, ioaddr + DownCounter);
+ writew(IntrRxDone | IntrRxDMADone | IntrPCIErr | IntrDrvRqst |
+ IntrTxDone | StatsMax | LinkChange, ioaddr + IntrEnable);
+ }
+ if (intr_status & LinkChange) {
+ printk(KERN_ERR "%s: Link changed: Autonegotiation advertising"
+ " %4.4x partner %4.4x.\n", dev->name,
+ mdio_read(dev, np->phys[0], 4),
+ mdio_read(dev, np->phys[0], 5));
+ check_duplex(dev);


+ }
+ if (intr_status & StatsMax) {

+ get_stats(dev);
+ }
+ if (intr_status & IntrPCIErr) {
+ printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n",
+ dev->name, intr_status);
+ /* We must do a global reset of DMA to continue. */
+ }
+}
+


+static struct net_device_stats *get_stats(struct net_device *dev)

+{
+ long ioaddr = dev->base_addr;

+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ int i;
+


+ /* We should lock this segment of code for SMP eventually, although
+ the vulnerability window is very small and statistics are
+ non-critical. */

+ /* The chip only need report frame silently dropped. */
+ np->stats.rx_missed_errors += readb(ioaddr + RxMissed);
+ np->stats.tx_packets += readw(ioaddr + TxFramesOK);
+ np->stats.rx_packets += readw(ioaddr + RxFramesOK);
+ np->stats.collisions += readb(ioaddr + StatsLateColl);
+ np->stats.collisions += readb(ioaddr + StatsMultiColl);
+ np->stats.collisions += readb(ioaddr + StatsOneColl);
+ readb(ioaddr + StatsCarrierError);
+ readb(ioaddr + StatsTxDefer);
+ for (i = StatsTxDefer; i <= StatsMcastRx; i++)
+ readb(ioaddr + i);
+ np->stats.tx_bytes += readw(ioaddr + TxOctetsLow);
+ np->stats.tx_bytes += readw(ioaddr + TxOctetsHigh) << 16;
+ np->stats.rx_bytes += readw(ioaddr + RxOctetsLow);
+ np->stats.rx_bytes += readw(ioaddr + RxOctetsHigh) << 16;
+
+ return &np->stats;
+}
+
+/* The little-endian AUTODIN II ethernet CRC calculations.
+ A big-endian version is also available.
+ This is slow but compact code. Do not use this routine for bulk data,
+ use a table-based routine instead.
+ This is common code and should be moved to net/core/crc.c.
+ Chips may use the upper or lower CRC bits, and may reverse and/or invert
+ them. Select the endian-ness that results in minimal calculations.
+*/


+static unsigned const ethernet_polynomial_le = 0xedb88320U;
+static inline unsigned ether_crc_le(int length, unsigned char *data)
+{
+ unsigned int crc = 0xffffffff; /* Initial value. */
+ while(--length >= 0) {
+ unsigned char current_octet = *data++;
+ int bit;
+ for (bit = 8; --bit >= 0; current_octet >>= 1) {
+ if ((crc ^ current_octet) & 1) {
+ crc >>= 1;
+ crc ^= ethernet_polynomial_le;
+ } else
+ crc >>= 1;
+ }
+ }
+ return crc;
+}
+

+static void set_rx_mode(struct net_device *dev)

+{
+ long ioaddr = dev->base_addr;

+ u16 mc_filter[4]; /* Multicast hash filter */
+ u32 rx_mode;
+ int i;
+


+ if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
+ /* Unconditionally log net taps. */
+ printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);

+ memset(mc_filter, 0xff, sizeof(mc_filter));
+ rx_mode = AcceptBroadcast | AcceptMulticast | AcceptAll | AcceptMyPhys;
+ } else if ((dev->mc_count > multicast_filter_limit)
+ || (dev->flags & IFF_ALLMULTI)) {


+ /* Too many to match, or accept all multicasts. */

+ memset(mc_filter, 0xff, sizeof(mc_filter));
+ rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
+ } else if (dev->mc_count) {
+ struct dev_mc_list *mclist;
+ memset(mc_filter, 0, sizeof(mc_filter));


+ for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
+ i++, mclist = mclist->next) {

+ set_bit(ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x3f,
+ mc_filter);
+ }

+ rx_mode = AcceptBroadcast | AcceptMultiHash | AcceptMyPhys;
+ } else {
+ writeb(AcceptBroadcast | AcceptMyPhys, ioaddr + RxMode);
+ return;
+ }
+ for (i = 0; i < 4; i++)
+ writew(mc_filter[i], ioaddr + MulticastFilter0 + i*2);
+ writeb(rx_mode, ioaddr + RxMode);
+}
+


+static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)

+{


+ u16 *data = (u16 *)&rq->ifr_data;
+
+ switch(cmd) {
+ case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */

+ data[0] = ((struct netdev_private *)dev->priv)->phys[0] & 0x1f;


+ /* Fall Through */
+ case SIOCDEVPRIVATE+1: /* Read the specified MII register. */

+ data[3] = mdio_read(dev, data[0] & 0x1f, data[1] & 0x1f);


+ return 0;
+ case SIOCDEVPRIVATE+2: /* Write the specified MII register */

+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+ mdio_write(dev, data[0] & 0x1f, data[1] & 0x1f, data[2]);
+ return 0;
+ default:
+ return -EOPNOTSUPP;


+ }
+}
+
+static int netdev_close(struct net_device *dev)
+{

+ long ioaddr = dev->base_addr;

+ struct netdev_private *np = (struct netdev_private *)dev->priv;


+ int i;
+
+ netif_stop_queue(dev);
+

+ if (debug > 1) {
+ printk(KERN_DEBUG "%s: Shutting down ethercard, status was Tx %2.2x "
+ "Rx %4.4x Int %2.2x.\n",
+ dev->name, readb(ioaddr + TxStatus),
+ readl(ioaddr + RxStatus), readw(ioaddr + IntrStatus));
+ printk(KERN_DEBUG "%s: Queue pointers were Tx %d / %d, Rx %d / %d.\n",
+ dev->name, np->cur_tx, np->dirty_tx, np->cur_rx, np->dirty_rx);


+ }
+
+ /* Disable interrupts by clearing the interrupt mask. */

+ writew(0x0000, ioaddr + IntrEnable);


+
+ /* Stop the chip's Tx and Rx processes. */

+ writew(TxDisable | RxDisable | StatsDisable, ioaddr + MACCtrl1);
+
+#ifdef __i386__
+ if (debug > 2) {


+ printk("\n"KERN_DEBUG" Tx ring at %8.8x:\n",

+ (int)virt_to_bus(np->tx_ring));
+ for (i = 0; i < TX_RING_SIZE; i++)
+ printk(" #%d desc. %4.4x %8.8x %8.8x.\n",
+ i, np->tx_ring[i].status, np->tx_ring[i].frag[0].addr,
+ np->tx_ring[i].frag[0].length);


+ printk("\n"KERN_DEBUG " Rx ring %8.8x:\n",

+ (int)virt_to_bus(np->rx_ring));
+ for (i = 0; i < /*RX_RING_SIZE*/4 ; i++) {
+ printk(KERN_DEBUG " #%d desc. %4.4x %4.4x %8.8x\n",
+ i, np->rx_ring[i].status, np->rx_ring[i].frag[0].addr,
+ np->rx_ring[i].frag[0].length);


+ }
+ }
+#endif /* __i386__ debugging only */
+
+ free_irq(dev->irq, dev);
+

+ del_timer_sync(&np->timer);


+
+ /* Free all the skbuffs in the Rx queue. */

+ for (i = 0; i < RX_RING_SIZE; i++) {
+ np->rx_ring[i].status = 0;
+ np->rx_ring[i].frag[0].addr = 0xBADF00D0; /* An invalid address. */
+ if (np->rx_skbuff[i]) {
+ dev_kfree_skb(np->rx_skbuff[i]);
+ }
+ np->rx_skbuff[i] = 0;
+ }
+ for (i = 0; i < TX_RING_SIZE; i++) {
+ if (np->tx_skbuff[i])
+ dev_kfree_skb(np->tx_skbuff[i]);
+ np->tx_skbuff[i] = 0;
+ }
+


+ MOD_DEC_USE_COUNT;
+
+ return 0;
+}
+

+static void __devexit sundance_remove1 (struct pci_dev *pdev)
+{
+ struct net_device *dev = pdev->driver_data;


+
+ /* No need to check MOD_IN_USE, as sys_delete_module() checks. */

+ while (dev) {
+ struct netdev_private *np = (void *)(dev->priv);
+ unregister_netdev(dev);
+#ifdef USE_IO_OPS
+ release_region(dev->base_addr, pci_id_tbl[np->chip_id].io_size);
+#else
+ release_mem_region(pci_resource_start(pdev, 1),
+ pci_id_tbl[np->chip_id].io_size);
+ iounmap((char *)(dev->base_addr));
+#endif
+ kfree(dev);
+ }
+
+ pdev->driver_data = NULL;
+}
+
+static struct pci_driver sundance_driver = {
+ name: "sundance",
+ id_table: sundance_pci_tbl,
+ probe: sundance_probe1,
+ remove: sundance_remove1,
+};
+
+static int __init sundance_init(void)
+{
+ return pci_module_init(&sundance_driver);
+}
+
+static void __exit sundance_exit(void)
+{
+ pci_unregister_driver(&sundance_driver);
+}
+
+module_init(sundance_init);
+module_exit(sundance_exit);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/sunlance.c linux/drivers/net/sunlance.c
--- v2.4.0-test8/linux/drivers/net/sunlance.c Sun Aug 13 12:01:54 2000
+++ linux/drivers/net/sunlance.c Sun Sep 17 09:41:29 2000
@@ -1332,6 +1332,7 @@


X /* Make certain the data structures used by the LANCE are aligned. */

X dev->priv = (void *)(((unsigned long)dev->priv + 7) & ~7);


X lp = (struct lance_private *) dev->priv;
+ spin_lock_init(&lp->lock);
X

X /* Copy the IDPROM ethernet address to the device structure, later we
X * will copy the address in the device structure to the lance
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/tokenring/tms380tr.c linux/drivers/net/tokenring/tms380tr.c
--- v2.4.0-test8/linux/drivers/net/tokenring/tms380tr.c Tue Jul 11 11:12:24 2000
+++ linux/drivers/net/tokenring/tms380tr.c Fri Sep 22 14:21:17 2000
@@ -96,6 +96,7 @@
X #include <linux/errno.h>
X #include <linux/init.h>
X #include <linux/pci.h>
+#include <linux/delay.h>
X
X #include <linux/netdevice.h>
X #include <linux/etherdevice.h>
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/tulip/tulip_core.c linux/drivers/net/tulip/tulip_core.c
--- v2.4.0-test8/linux/drivers/net/tulip/tulip_core.c Fri Sep 8 12:34:58 2000
+++ linux/drivers/net/tulip/tulip_core.c Mon Sep 18 14:57:01 2000
@@ -1092,7 +1092,7 @@


X
X dev->base_addr = ioaddr;
X dev->irq = irq;

- pdev->driver_data = dev;
+ pci_set_drvdata(pdev, dev);
X

X #ifdef TULIP_FULL_DUPLEX
X tp->full_duplex = 1;
@@ -1393,7 +1393,7 @@
X
X static void tulip_suspend (struct pci_dev *pdev)


X {
- struct net_device *dev = pdev->driver_data;
+ struct net_device *dev = pci_get_drvdata(pdev);
X

X if (dev && netif_device_present (dev)) {
X netif_device_detach (dev);
@@ -1405,7 +1405,7 @@
X
X static void tulip_resume(struct pci_dev *pdev)


X {
- struct net_device *dev = pdev->driver_data;
+ struct net_device *dev = pci_get_drvdata(pdev);
X

X pci_enable_device(pdev);
X if (dev && !netif_device_present (dev)) {
@@ -1417,7 +1417,7 @@
X
X static void __devexit tulip_remove_one (struct pci_dev *pdev)


X {
- struct net_device *dev = pdev->driver_data;
+ struct net_device *dev = pci_get_drvdata(pdev);
X

X if (dev) {
X struct tulip_private *tp = (struct tulip_private *)dev->priv;
@@ -1432,6 +1432,8 @@


X release_region (pci_resource_start (pdev, 0),
X pci_resource_len (pdev, 0));

X kfree(dev);
+
+ pci_set_drvdata(pdev, NULL);
X }
X }
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/tun.c linux/drivers/net/tun.c
--- v2.4.0-test8/linux/drivers/net/tun.c Wed Aug 23 09:30:13 2000
+++ linux/drivers/net/tun.c Fri Sep 22 15:19:30 2000
@@ -12,7 +12,7 @@
X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
X * GNU General Public License for more details.
X *
- * $Id: tun.c,v 1.1 2000/08/23 05:59:28 davem Exp $
+ * $Id: tun.c,v 1.2 2000/09/22 12:40:31 maxk Exp $
X */
X
X /*
@@ -20,7 +20,7 @@
X * Modifications for 2.3.99-pre5 kernel.
X */
X
-#define TUN_VER "1.1"
+#define TUN_VER "1.2"


X
X #include <linux/module.h>
X

@@ -32,12 +32,12 @@
X #include <linux/poll.h>
X #include <linux/fcntl.h>
X #include <linux/init.h>
-#include <linux/devfs_fs_kernel.h>
X #include <linux/random.h>
X
+#include <linux/skbuff.h>
X #include <linux/netdevice.h>
X #include <linux/etherdevice.h>
-#include <linux/skbuff.h>
+#include <linux/miscdevice.h>
X #include <linux/rtnetlink.h>


X #include <linux/if.h>
X #include <linux/if_arp.h>

@@ -497,38 +497,29 @@
X fasync: tun_chr_fasync
X };
X
-static devfs_handle_t devfs_handle = NULL;
+static struct miscdevice tun_miscdev=
+{
+ TUN_MINOR,
+ "net/tun",
+ &tun_fops
+};
X
X int __init tun_init(void)
X {
X printk(KERN_INFO "Universal TUN/TAP device driver %s "
X "(C)1999-2000 Maxim Krasnyansky\n", TUN_VER);
X
- if (devfs_register_chrdev(TUN_MAJOR, "tun", &tun_fops)) {
- printk(KERN_ERR "tun: Can't register char device %d\n",
- TUN_MAJOR);
+ if (misc_register(&tun_miscdev)) {
+ printk(KERN_ERR "tun: Can't register misc device %d\n", TUN_MINOR);


X return -EIO;
X }
X

- devfs_handle = devfs_register(NULL, "net/tun", DEVFS_FL_DEFAULT,
- TUN_MAJOR, 0,
- S_IFCHR | S_IRUSR | S_IWUSR,
- &tun_fops, NULL);
-
-#ifdef MODULE
X return 0;
-#else
- /* If driver is not module, tun_init will be called from Space.c.
- * Return non-zero not to register fake device.
- */
- return 1;
-#endif
X }
X
X void tun_cleanup(void)
X {
- devfs_unregister_chrdev(TUN_MAJOR,"tun");
- devfs_unregister(devfs_handle);
+ misc_deregister(&tun_miscdev);
X }
X
X module_init(tun_init);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/wan/Makefile linux/drivers/net/wan/Makefile
--- v2.4.0-test8/linux/drivers/net/wan/Makefile Mon Aug 14 10:19:03 2000
+++ linux/drivers/net/wan/Makefile Sun Oct 1 19:53:56 2000
@@ -35,6 +35,8 @@
X obj-$(CONFIG_COMX_PROTO_FR) += comx-proto-fr.o
X obj-$(CONFIG_COSA) += syncppp.o cosa.o
X obj-$(CONFIG_LANMEDIA) += syncppp.o
+obj-$(CONFIG_SYNCLINK_SYNCPPP) += syncppp.o
+obj-$(CONFIG_X25_ASY) += x25_asy.o
X
X ifeq ($(CONFIG_LANMEDIA),y)
X SUB_DIRS += lmc
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/wan/comx-hw-comx.c linux/drivers/net/wan/comx-hw-comx.c
--- v2.4.0-test8/linux/drivers/net/wan/comx-hw-comx.c Sun May 21 20:34:37 2000
+++ linux/drivers/net/wan/comx-hw-comx.c Mon Oct 2 12:00:16 2000
@@ -9,6 +9,9 @@
X *
X * Copyright (C) 1995-2000 ITConsult-Pro Co. <in...@itc.hu>
X *
+ * Contributors:
+ * Arnaldo Carvalho de Melo <ac...@conectiva.com.br> - 0.86
+ *


X * This program is free software; you can redistribute it and/or

X * modify it under the terms of the GNU General Public License
X * as published by the Free Software Foundation; either version
@@ -37,13 +40,12 @@
X * Version 0.85 (00/01/14):
X * - some additional workarounds :/
X * - printk cleanups
+ * Version 0.86 (00/08/15):
+ * - resource release on failure at COMX_init
X */
X
-#define VERSION "0.85"
+#define VERSION "0.86"
X
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/delay.h>
X #include <linux/module.h>
X #include <linux/version.h>
X #include <linux/types.h>
@@ -52,6 +54,9 @@
X #include <linux/proc_fs.h>
X #include <linux/ioport.h>
X #include <linux/init.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
X
X #include "comx.h"
X #include "comxhw.h"
@@ -1224,7 +1229,7 @@
X
X if ((new_file = create_proc_entry(FILENAME_IO, S_IFREG | 0644, ch->procdir))
X == NULL) {
- return -EIO;
+ goto cleanup_HW_privdata;
X }
X new_file->data = (void *)new_file;
X new_file->read_proc = &comxhw_read_proc;
@@ -1234,7 +1239,7 @@
X
X if ((new_file = create_proc_entry(FILENAME_IRQ, S_IFREG | 0644, ch->procdir))
X == NULL) {
- return -EIO;
+ goto cleanup_filename_io;
X }
X new_file->data = (void *)new_file;
X new_file->read_proc = &comxhw_read_proc;
@@ -1244,7 +1249,7 @@
X
X if ((new_file = create_proc_entry(FILENAME_CHANNEL, S_IFREG | 0644,
X ch->procdir)) == NULL) {
- return -EIO;
+ goto cleanup_filename_irq;
X }
X new_file->data = (void *)new_file;
X new_file->read_proc = &comxhw_read_proc;
@@ -1255,7 +1260,7 @@
X if (ch->hardware == &hicomx_hw || ch->hardware == &cmx_hw) {
X if ((new_file = create_proc_entry(FILENAME_CLOCK, S_IFREG | 0644,
X ch->procdir)) == NULL) {
- return -EIO;
+ goto cleanup_filename_channel;
X }
X new_file->data = (void *)new_file;
X new_file->read_proc = &comxhw_read_proc;
@@ -1266,7 +1271,7 @@
X
X if ((new_file = create_proc_entry(FILENAME_MEMADDR, S_IFREG | 0644,
X ch->procdir)) == NULL) {
- return -EIO;
+ goto cleanup_filename_clock;
X }
X new_file->data = (void *)new_file;
X new_file->read_proc = &comxhw_read_proc;
@@ -1276,7 +1281,7 @@
X
X if ((new_file = create_proc_entry(FILENAME_TWIN, S_IFREG | 0444,
X ch->procdir)) == NULL) {
- return -EIO;
+ goto cleanup_filename_memaddr;
X }
X new_file->data = (void *)new_file;
X new_file->read_proc = &comxhw_read_proc;
@@ -1285,7 +1290,7 @@
X
X if ((new_file = create_proc_entry(FILENAME_FIRMWARE, S_IFREG | 0644,
X ch->procdir)) == NULL) {
- return -EIO;
+ goto cleanup_filename_twin;
X }
X new_file->data = (void *)new_file;
X new_file->read_proc = &comxhw_read_proc;
@@ -1326,6 +1331,23 @@
X
X MOD_INC_USE_COUNT;
X return 0;
+
+cleanup_filename_twin:
+ remove_proc_entry(FILENAME_TWIN, ch->procdir);
+cleanup_filename_memaddr:
+ remove_proc_entry(FILENAME_MEMADDR, ch->procdir);
+cleanup_filename_clock:
+ if (ch->hardware == &hicomx_hw || ch->hardware == &cmx_hw)
+ remove_proc_entry(FILENAME_CLOCK, ch->procdir);
+cleanup_filename_channel:
+ remove_proc_entry(FILENAME_CHANNEL, ch->procdir);
+cleanup_filename_irq:
+ remove_proc_entry(FILENAME_IRQ, ch->procdir);
+cleanup_filename_io:
+ remove_proc_entry(FILENAME_IO, ch->procdir);
+cleanup_HW_privdata:
+ kfree(ch->HW_privdata);


+ return -EIO;
X }
X

X /* Called on echo valami >boardtype */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/wan/comx-hw-locomx.c linux/drivers/net/wan/comx-hw-locomx.c
--- v2.4.0-test8/linux/drivers/net/wan/comx-hw-locomx.c Sun May 21 20:34:37 2000
+++ linux/drivers/net/wan/comx-hw-locomx.c Mon Sep 18 15:02:03 2000
@@ -7,6 +7,9 @@
X * Based on skeleton code and old LoCOMX driver by Tivadar Szemethy <t...@itc.hu>
X * and the hostess_sv11 driver
X *
+ * Contributors:
+ * Arnaldo Carvalho de Melo <ac...@conectiva.com.br> (0.14)
+ *
X * Copyright (C) 1999 ITConsult-Pro Co. <in...@itc.hu>
X *


X * This program is free software; you can redistribute it and/or

@@ -27,9 +30,11 @@
X * Version 0.13 (99/07/08):
X * - Fix the transmitter status check
X * - Handle the net device statistics better
+ * Version 0.14 (00/08/15):
+ * - resource release on failure at LOCOMX_init
X */
X
-#define VERSION "0.13"
+#define VERSION "0.14"
X
X #include <linux/module.h>
X #include <linux/version.h>
@@ -385,7 +390,7 @@
X /* Register /proc files */
X if ((new_file = create_proc_entry(FILENAME_IO, S_IFREG | 0644,
X ch->procdir)) == NULL) {
- return -EIO;
+ goto cleanup_HW_privdata;
X }
X new_file->data = (void *)new_file;
X new_file->read_proc = &locomx_read_proc;
@@ -394,7 +399,7 @@
X
X if ((new_file = create_proc_entry(FILENAME_IRQ, S_IFREG | 0644,
X ch->procdir)) == NULL) {
- return -EIO;
+ goto cleanup_filename_io;
X }
X new_file->data = (void *)new_file;
X new_file->read_proc = &locomx_read_proc;
@@ -432,6 +437,11 @@
X /* O.K. Count one more user on this module */
X MOD_INC_USE_COUNT;
X return 0;
+cleanup_filename_io:
+ remove_proc_entry(FILENAME_IO, ch->procdir);
+cleanup_HW_privdata:
+ kfree(ch->HW_privdata);
+ return -EIO;
X }
X
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/wan/comx-hw-mixcom.c linux/drivers/net/wan/comx-hw-mixcom.c
--- v2.4.0-test8/linux/drivers/net/wan/comx-hw-mixcom.c Sun May 21 20:34:37 2000
+++ linux/drivers/net/wan/comx-hw-mixcom.c Mon Sep 18 15:02:03 2000
@@ -8,6 +8,9 @@
X *
X * Copyright (C) 1998-1999 ITConsult-Pro Co. <in...@itc.hu>
X *
+ * Contributors:
+ * Arnaldo Carvalho de Melo <ac...@conectiva.com.br> (0.65)
+ *


X * This program is free software; you can redistribute it and/or

X * modify it under the terms of the GNU General Public License
X * as published by the Free Software Foundation; either version
@@ -29,9 +32,12 @@
X *
X * Version 0.64 (99/12/01):
X * - some more cosmetical fixes
+ *
+ * Version 0.65 (00/08/15)
+ * - resource release on failure at MIXCOM_init
X */
X
-#define VERSION "0.64"
+#define VERSION "0.65"
X
X #include <linux/module.h>
X #include <linux/version.h>
@@ -819,7 +825,7 @@
X
X if ((new_file = create_proc_entry(FILENAME_IO, S_IFREG | 0644,
X ch->procdir)) == NULL) {
- return -EIO;
+ goto cleanup_HW_privdata;
X }
X new_file->data = (void *)new_file;
X new_file->read_proc = &mixcom_read_proc;
@@ -828,7 +834,7 @@
X
X if ((new_file = create_proc_entry(FILENAME_IRQ, S_IFREG | 0644,
X ch->procdir)) == NULL) {
- return -EIO;
+ goto cleanup_filename_io;
X }
X new_file->data = (void *)new_file;
X new_file->read_proc = &mixcom_read_proc;
@@ -848,7 +854,7 @@
X
X if ((new_file = create_proc_entry(FILENAME_CHANNEL, S_IFREG | 0644,
X ch->procdir)) == NULL) {
- return -EIO;
+ goto cleanup_filename_irq;
X }
X new_file->data = (void *)new_file;
X new_file->read_proc = &mixcom_read_proc;


@@ -857,7 +863,7 @@
X

X if ((new_file = create_proc_entry(FILENAME_TWIN, S_IFREG | 0444,
X ch->procdir)) == NULL) {
- return -EIO;
+ goto cleanup_filename_channel;
X }
X new_file->data = (void *)new_file;
X new_file->read_proc = &mixcom_read_proc;
@@ -881,6 +887,15 @@
X
X MOD_INC_USE_COUNT;
X return 0;
+cleanup_filename_channel:
+ remove_proc_entry(FILENAME_CHANNEL, ch->procdir);
+cleanup_filename_irq:
+ remove_proc_entry(FILENAME_IRQ, ch->procdir);
+cleanup_filename_io:
+ remove_proc_entry(FILENAME_IO, ch->procdir);
+cleanup_HW_privdata:
+ kfree(ch->HW_privdata);
+ return -EIO;
X }
X
X static int MIXCOM_exit(struct net_device *dev)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/wan/comx-proto-fr.c linux/drivers/net/wan/comx-proto-fr.c
--- v2.4.0-test8/linux/drivers/net/wan/comx-proto-fr.c Sun May 21 20:34:37 2000
+++ linux/drivers/net/wan/comx-proto-fr.c Mon Sep 18 15:02:03 2000
@@ -6,6 +6,9 @@
X * Maintainer: Gergely Madarasz <go...@itc.hu>
X *
X * Copyright (C) 1998-1999 ITConsult-Pro Co. <in...@itc.hu>
+ *
+ * Contributors:
+ * Arnaldo Carvalho de Melo <ac...@conectiva.com.br> (0.73)
X *


X * This program is free software; you can redistribute it and/or

X * modify it under the terms of the GNU General Public License
@@ -25,9 +28,13 @@
X * Version 0.72 (99/07/09):
X * - handle slave tbusy with master tbusy (should be fixed)
X * - fix the keepalive timer addition/deletion
+ *
+ * Version 0.73 (00/08/15)
+ * - resource release on failure at fr_master_init and
+ * fr_slave_init
X */
X
-#define VERSION "0.72"
+#define VERSION "0.73"
X
X #include <linux/module.h>
X #include <linux/version.h>
@@ -793,7 +800,7 @@
X
X if ((new_file = create_proc_entry(FILENAME_DLCI, S_IFREG | 0644,
X ch->procdir)) == NULL) {
- return -ENOMEM;
+ goto cleanup_LINE_privdata;
X }
X new_file->data = (void *)new_file;
X new_file->read_proc = &fr_read_proc;
@@ -803,7 +810,7 @@
X
X if ((new_file = create_proc_entry(FILENAME_KEEPALIVE, S_IFREG | 0644,
X ch->procdir)) == NULL) {
- return -ENOMEM;
+ goto cleanup_filename_dlci;
X }
X new_file->data = (void *)new_file;
X new_file->read_proc = &fr_read_proc;
@@ -815,6 +822,11 @@
X
X MOD_INC_USE_COUNT;
X return 0;
+cleanup_filename_dlci:
+ remove_proc_entry(FILENAME_DLCI, ch->procdir);
+cleanup_LINE_privdata:
+ kfree(fr);
+ return -EIO;
X }
X
X static int fr_slave_init(struct net_device *dev)
@@ -847,7 +859,7 @@
X
X if ((new_file = create_proc_entry(FILENAME_DLCI, S_IFREG | 0644,
X ch->procdir)) == NULL) {
- return -ENOMEM;
+ goto cleanup_LINE_privdata;
X }
X
X new_file->data = (void *)new_file;
@@ -858,7 +870,7 @@
X
X if ((new_file = create_proc_entry(FILENAME_MASTER, S_IFREG | 0644,
X ch->procdir)) == NULL) {
- return -EIO;
+ goto cleanup_filename_dlci;
X }
X new_file->data = (void *)new_file;
X new_file->read_proc = &fr_read_proc;
@@ -867,6 +879,11 @@
X new_file->nlink = 1;
X MOD_INC_USE_COUNT;
X return 0;
+cleanup_filename_dlci:
+ remove_proc_entry(FILENAME_DLCI, ch->procdir);
+cleanup_LINE_privdata:
+ kfree(fr);
+ return -EIO;
X }
X
X static int dlci_open(struct net_device *dev)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/wan/comx-proto-ppp.c linux/drivers/net/wan/comx-proto-ppp.c
--- v2.4.0-test8/linux/drivers/net/wan/comx-proto-ppp.c Mon Mar 13 13:55:09 2000
+++ linux/drivers/net/wan/comx-proto-ppp.c Mon Sep 18 15:02:03 2000
@@ -200,6 +200,8 @@
X struct ppp_device *pppdev = (struct ppp_device *)ch->if_ptr;
X
X ch->LINE_privdata = kmalloc(sizeof(struct syncppp_data), GFP_KERNEL);
+ if (!ch->LINE_privdata)
+ return -ENOMEM;
X
X pppdev->dev = dev;
X sppp_attach(pppdev);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/wan/comx.c linux/drivers/net/wan/comx.c
--- v2.4.0-test8/linux/drivers/net/wan/comx.c Wed Jun 21 10:10:02 2000
+++ linux/drivers/net/wan/comx.c Mon Sep 18 15:02:03 2000
@@ -10,6 +10,9 @@
X *
X * Copyright (C) 1995-1999 ITConsult-Pro Co.
X *
+ * Contributors:
+ * Arnaldo Carvalho de Melo <ac...@conectiva.com.br> (0.85)
+ *


X * This program is free software; you can redistribute it and/or

X * modify it under the terms of the GNU General Public License
X * as published by the Free Software Foundation; either version
@@ -39,9 +42,13 @@
X * Version 0.84 (99/12/01):
X * - comx_status should not check for IFF_UP (to report
X * line status from dev->open())
+ *
+ * Version 0.85 (00/08/15):
+ * - resource release on failure in comx_mkdir
+ * - fix return value on failure at comx_write_proc
X */
X
-#define VERSION "0.84"
+#define VERSION "0.85"
X
X #include <linux/config.h>
X #include <linux/module.h>
@@ -506,6 +513,7 @@
X ch->loadavg_size = ch->loadavg[2] / ch->loadavg[0] + 1;
X if ((ch->avg_bytes = kmalloc(ch->loadavg_size *
X sizeof(unsigned long) * 2, GFP_KERNEL)) == NULL) {
+ kfree(ch);


X return -ENOMEM;
X }
X

@@ -629,7 +637,7 @@
X ch->debug_start = ch->debug_end = 0;
X restore_flags(flags);
X free_page((unsigned long)page);
- return count;
+ return ret ? ret : count;
X }
X
X if (*page != '+' && *page != '-') {
@@ -762,10 +770,16 @@
X struct proc_dir_entry *new_dir, *debug_file;
X struct net_device *dev;
X struct comx_channel *ch;


+ int ret = -EIO;

+
+ if ((dev = kmalloc(sizeof(struct net_device), GFP_KERNEL)) == NULL) {
+ return -ENOMEM;
+ }
+ memset(dev, 0, sizeof(struct net_device));
X
X if ((new_dir = create_proc_entry(dentry->d_name.name, mode | S_IFDIR,
X comx_root_dir)) == NULL) {
- return -EIO;
+ goto cleanup_dev;
X }
X
X new_dir->nlink = 2;
@@ -774,42 +788,38 @@
X /* Ezek kellenek */
X if (!create_comx_proc_entry(FILENAME_HARDWARE, 0644,
X strlen(HWNAME_NONE) + 1, new_dir)) {
- return -ENOMEM;
+ goto cleanup_new_dir;
X }
X if (!create_comx_proc_entry(FILENAME_PROTOCOL, 0644,
X strlen(PROTONAME_NONE) + 1, new_dir)) {
- return -ENOMEM;
+ goto cleanup_filename_hardware;
X }
X if (!create_comx_proc_entry(FILENAME_STATUS, 0444, 0, new_dir)) {
- return -ENOMEM;
+ goto cleanup_filename_protocol;
X }
X if (!create_comx_proc_entry(FILENAME_LINEUPDELAY, 0644, 2, new_dir)) {
- return -ENOMEM;
+ goto cleanup_filename_status;
X }
X
X if ((debug_file = create_proc_entry(FILENAME_DEBUG,
X S_IFREG | 0644, new_dir)) == NULL) {
- return -ENOMEM;
+ goto cleanup_filename_lineupdelay;
X }
X debug_file->data = (void *)debug_file;
X debug_file->read_proc = NULL; // see below
X debug_file->write_proc = &comx_write_proc;
X debug_file->nlink = 1;
X
- if ((dev = kmalloc(sizeof(struct net_device), GFP_KERNEL)) == NULL) {
- return -ENOMEM;
- }
- memset(dev, 0, sizeof(struct net_device));
X strcpy(dev->name, (char *)new_dir->name);
X dev->init = comx_init_dev;
X
X if (register_netdevice(dev)) {
- return -EIO;
+ goto cleanup_filename_debug;
X }
X ch=dev->priv;
X if((ch->if_ptr = (void *)kmalloc(sizeof(struct ppp_device),
X GFP_KERNEL)) == NULL) {
- return -ENOMEM;
+ goto cleanup_register;
X }
X memset(ch->if_ptr, 0, sizeof(struct ppp_device));
X ch->debug_file = debug_file;
@@ -819,13 +829,33 @@
X ch->debug_start = ch->debug_end = 0;
X if ((ch->debug_area = kmalloc(ch->debug_size = DEFAULT_DEBUG_SIZE,
X GFP_KERNEL)) == NULL) {
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto cleanup_if_ptr;
X }
X
X ch->lineup_delay = DEFAULT_LINEUP_DELAY;
X
X MOD_INC_USE_COUNT;
X return 0;
+cleanup_if_ptr:
+ kfree(ch->if_ptr);
+cleanup_register:
+ unregister_netdevice(dev);
+cleanup_filename_debug:
+ remove_proc_entry(FILENAME_DEBUG, new_dir);
+cleanup_filename_lineupdelay:
+ remove_proc_entry(FILENAME_LINEUPDELAY, new_dir);
+cleanup_filename_status:
+ remove_proc_entry(FILENAME_STATUS, new_dir);
+cleanup_filename_protocol:
+ remove_proc_entry(FILENAME_PROTOCOL, new_dir);
+cleanup_filename_hardware:
+ remove_proc_entry(FILENAME_HARDWARE, new_dir);
+cleanup_new_dir:
+ remove_proc_entry(dentry->d_name.name, &comx_root_dir);
+cleanup_dev:
+ kfree(dev);


+ return ret;
X }
X

X static int comx_rmdir(struct inode *dir, struct dentry *dentry)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/wan/cosa.c linux/drivers/net/wan/cosa.c
--- v2.4.0-test8/linux/drivers/net/wan/cosa.c Tue Aug 29 14:09:15 2000
+++ linux/drivers/net/wan/cosa.c Mon Oct 2 12:00:16 2000
@@ -303,8 +303,7 @@
X static char *chrdev_setup_rx(struct channel_data *channel, int size);
X static int chrdev_rx_done(struct channel_data *channel);
X static int chrdev_tx_done(struct channel_data *channel, int size);
-static long long cosa_lseek(struct file *file,
- long long offset, int origin);
+static loff_t cosa_lseek(struct file *file, loff_t offset, int origin);
X static ssize_t cosa_read(struct file *file,
X char *buf, size_t count, loff_t *ppos);
X static ssize_t cosa_write(struct file *file,
@@ -783,8 +782,7 @@
X init_MUTEX(&chan->wsem);
X }
X
-static long long cosa_lseek(struct file * file,
- long long offset, int origin)
+static loff_t cosa_lseek(struct file * file, loff_t offset, int origin)
X {
X return -ESPIPE;
X }
@@ -1212,7 +1210,7 @@
X {
X int rv;
X struct channel_data *chan = (struct channel_data *)dev->priv;
- rv = cosa_ioctl_common(chan->cosa, chan, cmd, (int)ifr->ifr_data);
+ rv = cosa_ioctl_common(chan->cosa, chan, cmd, (unsigned long)ifr->ifr_data);
X if (rv == -ENOIOCTLCMD) {
X return sppp_do_ioctl(dev, ifr, cmd);
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/wan/sdla.c linux/drivers/net/wan/sdla.c
--- v2.4.0-test8/linux/drivers/net/wan/sdla.c Mon Mar 13 09:50:16 2000
+++ linux/drivers/net/wan/sdla.c Tue Sep 19 08:01:34 2000
@@ -1203,7 +1203,10 @@
X return(-ENOMEM);
X sdla_read(dev, mem.addr, temp, mem.len);
X if(copy_to_user(mem.data, temp, mem.len))
+ {
+ kfree(temp);
X return -EFAULT;
+ }
X kfree(temp);
X }
X else
@@ -1212,7 +1215,10 @@
X if (!temp)
X return(-ENOMEM);
X if(copy_from_user(temp, mem.data, mem.len))
+ {
+ kfree(temp);
X return -EFAULT;
+ }
X sdla_write(dev, mem.addr, temp, mem.len);
X kfree(temp);
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/net/winbond-840.c linux/drivers/net/winbond-840.c
--- v2.4.0-test8/linux/drivers/net/winbond-840.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/winbond-840.c Sun Sep 24 12:12:33 2000
@@ -0,0 +1,1352 @@
+/* winbond-840.c: A Linux PCI network adapter skeleton device driver. */
+/*
+ Written 1998-2000 by Donald Becker.


+
+ This software may be used and distributed according to the terms of
+ the GNU General Public License (GPL), incorporated herein by reference.
+ Drivers based on or derived from this code fall under the GPL and must
+ retain the authorship, copyright and license notice. This file is not
+ a complete program and may only be used when the entire operating
+ system is licensed under the GPL.
+
+ The author may be reached as bec...@scyld.com, or C/O
+ Scyld Computing Corporation
+ 410 Severn Ave., Suite 210
+ Annapolis MD 21403
+
+ Support and updates available at

+ http://www.scyld.com/network/drivers.html
+
+ Do not remove the copyright infomation.
+ Do not change the version information unless an improvement has been made.
+ Merely removing my name, as Compex has done in the past, does not count
+ as an improvement.


+*/
+
+/* These identify the driver base version and may not be removed. */
+static const char version1[] =

+"winbond-840.c:v1.01 5/15/2000 Donald Becker <bec...@scyld.com>\n";


+static const char version2[] =

+" http://www.scyld.com/network/drivers.html\n";
+
+/* Automatically extracted configuration info:
+probe-func: winbond840_probe
+config-in: tristate 'Winbond W89c840 Ethernet support' CONFIG_WINBOND_840
+
+c-help-name: Winbond W89c840 PCI Ethernet support
+c-help-symbol: CONFIG_WINBOND_840
+c-help: This driver is for the Winbond W89c840 chip. It also works with
+c-help: the TX9882 chip on the Compex RL100-ATX board.
+c-help: More specific information and updates are available from
+c-help: http://www.scyld.com/network/drivers.html
+*/


+
+/* The user-configurable values.
+ These may be modified when a driver module is loaded.*/
+
+static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */

+static int max_interrupt_work = 20;

+/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
+ The '840 uses a 64 element hash table based on the Ethernet CRC. */


+static int multicast_filter_limit = 32;
+
+/* Set the copy breakpoint for the copy-only-tiny-frames scheme.

+ Setting to > 1518 effectively disables this feature. */


+static int rx_copybreak = 0;
+
+/* Used to pass the media type, etc.
+ Both 'options[]' and 'full_duplex[]' should exist for driver
+ interoperability.
+ The media type is usually passed in 'options[]'.
+*/
+#define MAX_UNITS 8 /* More are supported, limit only on options */
+static int options[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
+static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
+
+/* Operational parameters that are set at compile time. */
+
+/* Keep the ring sizes a power of two for compile efficiency.
+ The compiler will convert <unsigned>'%'<2^N> into a bit mask.
+ Making the Tx ring too large decreases the effectiveness of channel

+ bonding and packet priority.

+ There are no ill effects from too-large receive rings. */


+#define TX_RING_SIZE 16
+#define TX_QUEUE_LEN 10 /* Limit ring entries actually used. */
+#define RX_RING_SIZE 32
+

+/* The presumed FIFO size for working around the Tx-FIFO-overflow bug.
+ To avoid overflowing we don't queue again until we have room for a
+ full-size packet.
+ */
+#define TX_FIFO_SIZE (2048)
+#define TX_BUG_FIFO_LIMIT (TX_FIFO_SIZE-1514-16)

+/* Condensed operations for readability.

+ The compatibility defines are in kern_compat.h */
+


+#define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr))
+#define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr))
+

+MODULE_AUTHOR("Donald Becker <bec...@scyld.com>");

+MODULE_DESCRIPTION("Winbond W89c840 Ethernet driver");
+MODULE_PARM(max_interrupt_work, "i");


+MODULE_PARM(debug, "i");
+MODULE_PARM(rx_copybreak, "i");

+MODULE_PARM(multicast_filter_limit, "i");


+MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+
+/*
+ Theory of Operation
+
+I. Board Compatibility
+

+This driver is for the Winbond w89c840 chip.


+
+II. Board-specific settings
+

+None.


+
+III. Driver operation
+

+This chip is very similar to the Digital 21*4* "Tulip" family. The first
+twelve registers and the descriptor format are nearly identical. Read a
+Tulip manual for operational details.
+
+A significant difference is that the multicast filter and station address are
+stored in registers rather than loaded through a pseudo-transmit packet.
+
+Unlike the Tulip, transmit buffers are limited to 1KB. To transmit a
+full-sized packet we must use both data buffers in a descriptor. Thus the
+driver uses ring mode where descriptors are implicitly sequential in memory,
+rather than using the second descriptor address as a chain pointer to
+subsequent descriptors.
+
+IV. Notes
+
+If you are going to almost clone a Tulip, why not go all the way and avoid
+the need for a new driver?
+
+IVb. References
+
+http://www.scyld.com/expert/100mbps.html
+http://www.scyld.com/expert/NWay.html
+http://www.winbond.com.tw/
+
+IVc. Errata
+
+A horrible bug exists in the transmit FIFO. Apparently the chip doesn't
+correctly detect a full FIFO, and queuing more than 2048 bytes may result in
+silent data corruption.


+
+*/
+
+
+

+/*
+ PCI probe table.
+*/


+enum pci_id_flags_bits {
+ /* Set PCI command register bits before calling probe1(). */
+ PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
+ /* Read and map the single following PCI BAR. */
+ PCI_ADDR0=0<<4, PCI_ADDR1=1<<4, PCI_ADDR2=2<<4, PCI_ADDR3=3<<4,
+ PCI_ADDR_64BITS=0x100, PCI_NO_ACPI_WAKE=0x200, PCI_NO_MIN_LATENCY=0x400,
+};

+enum chip_capability_flags {CanHaveMII=1, HasBrokenTx=2};
+#ifdef USE_IO_OPS
+#define W840_FLAGS (PCI_USES_IO | PCI_ADDR0 | PCI_USES_MASTER)
+#else
+#define W840_FLAGS (PCI_USES_MEM | PCI_ADDR1 | PCI_USES_MASTER)
+#endif
+
+static struct pci_device_id w840_pci_tbl[] __devinitdata = {
+ { 0x1050, 0x0840, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ { 0x11f6, 0x2011, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },
+ { 0, }
+};
+MODULE_DEVICE_TABLE(pci, w840_pci_tbl);


+
+struct pci_id_info {
+ const char *name;
+ struct match_info {
+ int pci, pci_mask, subsystem, subsystem_mask;
+ int revision, revision_mask; /* Only 8 bits. */
+ } id;
+ enum pci_id_flags_bits pci_flags;
+ int io_size; /* Needed for I/O region check or ioremap(). */
+ int drv_flags; /* Driver use, intended as capability flags. */
+};
+static struct pci_id_info pci_id_tbl[] = {

+ {"Winbond W89c840", { 0x08401050, 0xffffffff, },
+ W840_FLAGS, 128, CanHaveMII | HasBrokenTx},
+ {"Compex RL100-ATX", { 0x201111F6, 0xffffffff,},
+ W840_FLAGS, 128, CanHaveMII | HasBrokenTx},


+ {0,}, /* 0 terminated list. */
+};
+

+/* This driver was written to use PCI memory space, however some x86 systems
+ work only with I/O space accesses. Pass -DUSE_IO_OPS to use PCI I/O space
+ accesses instead of memory space. */
+


+#ifdef USE_IO_OPS
+#undef readb
+#undef readw
+#undef readl
+#undef writeb
+#undef writew
+#undef writel
+#define readb inb
+#define readw inw
+#define readl inl
+#define writeb outb
+#define writew outw
+#define writel outl
+#endif
+

+/* Offsets to the Command and Status Registers, "CSRs".
+ While similar to the Tulip, these registers are longword aligned.
+ Note: It's not useful to define symbolic names for every register bit in
+ the device. The name can only partially document the semantics and make


+ the driver longer and more difficult to read.

+*/
+enum w840_offsets {
+ PCIBusCfg=0x00, TxStartDemand=0x04, RxStartDemand=0x08,
+ RxRingPtr=0x0C, TxRingPtr=0x10,
+ IntrStatus=0x14, NetworkConfig=0x18, IntrEnable=0x1C,
+ RxMissed=0x20, EECtrl=0x24, MIICtrl=0x24, BootRom=0x28, GPTimer=0x2C,
+ CurRxDescAddr=0x30, CurRxBufAddr=0x34, /* Debug use */
+ MulticastFilter0=0x38, MulticastFilter1=0x3C, StationAddr=0x40,
+ CurTxDescAddr=0x4C, CurTxBufAddr=0x50,
+};
+
+/* Bits in the interrupt status/enable registers. */
+/* The bits in the Intr Status/Enable registers, mostly interrupt sources. */
+enum intr_status_bits {
+ NormalIntr=0x10000, AbnormalIntr=0x8000,
+ IntrPCIErr=0x2000, TimerInt=0x800,
+ IntrRxDied=0x100, RxNoBuf=0x80, IntrRxDone=0x40,
+ TxFIFOUnderflow=0x20, RxErrIntr=0x10,
+ TxIdle=0x04, IntrTxStopped=0x02, IntrTxDone=0x01,
+};
+
+/* Bits in the NetworkConfig register. */
+enum rx_mode_bits {
+ AcceptErr=0x80, AcceptRunt=0x40,
+ AcceptBroadcast=0x20, AcceptMulticast=0x10,
+ AcceptAllPhys=0x08, AcceptMyPhys=0x02,
+};
+
+enum mii_reg_bits {
+ MDIO_ShiftClk=0x10000, MDIO_DataIn=0x80000, MDIO_DataOut=0x20000,
+ MDIO_EnbOutput=0x40000, MDIO_EnbIn = 0x00000,
+};
+
+/* The Tulip Rx and Tx buffer descriptors. */
+struct w840_rx_desc {
+ s32 status;
+ s32 length;
+ u32 buffer1;
+ u32 next_desc;
+};
+
+struct w840_tx_desc {
+ s32 status;
+ s32 length;
+ u32 buffer1, buffer2; /* We use only buffer 1. */
+};
+
+/* Bits in network_desc.status */
+enum desc_status_bits {
+ DescOwn=0x80000000, DescEndRing=0x02000000, DescUseLink=0x01000000,
+ DescWholePkt=0x60000000, DescStartPkt=0x20000000, DescEndPkt=0x40000000,
+ DescIntr=0x80000000,


+};
+
+#define PRIV_ALIGN 15 /* Required alignment mask */

+struct netdev_private {
+ /* Descriptor rings first for alignment. */

+ struct w840_rx_desc rx_ring[RX_RING_SIZE];
+ struct w840_tx_desc tx_ring[TX_RING_SIZE];


+ /* The addresses of receive-in-place skbuffs. */
+ struct sk_buff* rx_skbuff[RX_RING_SIZE];
+ /* The saved address of a sent-in-place packet/buffer, for later free(). */
+ struct sk_buff* tx_skbuff[TX_RING_SIZE];
+ struct net_device_stats stats;
+ struct timer_list timer; /* Media monitoring timer. */
+ /* Frequently used values: keep some adjacent for cache effect. */
+ spinlock_t lock;
+ int chip_id, drv_flags;

+ int csr6;
+ struct w840_rx_desc *rx_head_desc;


+ unsigned int cur_rx, dirty_rx; /* Producer/consumer ring indices */
+ unsigned int rx_buf_sz; /* Based on MTU+slack. */

SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 069'
echo 'File patch-2.4.0-test9 is continued in part 070'
echo "070" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part070

#!/bin/sh -x
# this is part 070 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 070; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ unsigned int cur_tx, dirty_tx;

+ int tx_q_bytes;


+ unsigned int tx_full:1; /* The Tx queue is full. */
+ /* These values are keep track of the transceiver/media in use. */
+ unsigned int full_duplex:1; /* Full-duplex operation requested. */
+ unsigned int duplex_lock:1;
+ unsigned int medialock:1; /* Do not sense media. */
+ unsigned int default_port:4; /* Last dev->if_port value. */

+ /* MII transceiver section. */
+ int mii_cnt; /* MII device addresses. */
+ u16 advertising; /* NWay media advertisement */
+ unsigned char phys[2]; /* MII device addresses. */
+};
+

+static int eeprom_read(long ioaddr, int location);

+static int mdio_read(struct net_device *dev, int phy_id, int location);
+static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
+static int netdev_open(struct net_device *dev);
+static void check_duplex(struct net_device *dev);
+static void netdev_timer(unsigned long data);
+static void tx_timeout(struct net_device *dev);
+static void init_ring(struct net_device *dev);
+static int start_tx(struct sk_buff *skb, struct net_device *dev);
+static void intr_handler(int irq, void *dev_instance, struct pt_regs *regs);
+static void netdev_error(struct net_device *dev, int intr_status);
+static int netdev_rx(struct net_device *dev);
+static void netdev_error(struct net_device *dev, int intr_status);
+static inline unsigned ether_crc(int length, unsigned char *data);
+static void set_rx_mode(struct net_device *dev);
+static struct net_device_stats *get_stats(struct net_device *dev);
+static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);


+static int netdev_close(struct net_device *dev);
+
+

+
+static int __devinit w840_probe1 (struct pci_dev *pdev,


+ const struct pci_device_id *ent)

+{
+ struct net_device *dev;
+ struct netdev_private *np;
+ static int find_cnt;


+ int chip_idx = ent->driver_data;
+ int irq = pdev->irq;

+ int i, option = find_cnt < MAX_UNITS ? options[find_cnt] : 0;

+ /* Warning: broken for big-endian machines. */


+ for (i = 0; i < 3; i++)

+ ((u16 *)dev->dev_addr)[i] = le16_to_cpu(eeprom_read(ioaddr, i));
+


+ for (i = 0; i < 5; i++)
+ printk("%2.2x:", dev->dev_addr[i]);
+ printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq);
+

+ /* Reset the chip to erase previous misconfiguration.

+ No hold time required! */
+ writel(0x00000001, ioaddr + PCIBusCfg);


+
+ dev->base_addr = ioaddr;
+ dev->irq = irq;
+
+ np = dev->priv;
+ np->chip_id = chip_idx;
+ np->drv_flags = pci_id_tbl[chip_idx].drv_flags;
+ spin_lock_init(&np->lock);

+
+ pdev->driver_data = dev;


+
+ if (dev->mem_start)
+ option = dev->mem_start;
+
+ /* The lower four bits are the media type. */
+ if (option > 0) {
+ if (option & 0x200)
+ np->full_duplex = 1;
+ np->default_port = option & 15;
+ if (np->default_port)
+ np->medialock = 1;
+ }

+ if (find_cnt < MAX_UNITS && full_duplex[find_cnt] > 0)


+ np->full_duplex = 1;
+
+ if (np->full_duplex)
+ np->duplex_lock = 1;
+
+ /* The chip-specific entries in the device structure. */
+ dev->open = &netdev_open;
+ dev->hard_start_xmit = &start_tx;
+ dev->stop = &netdev_close;
+ dev->get_stats = &get_stats;
+ dev->set_multicast_list = &set_rx_mode;
+ dev->do_ioctl = &mii_ioctl;
+ dev->tx_timeout = &tx_timeout;
+ dev->watchdog_timeo = TX_TIMEOUT;
+

+ if (np->drv_flags & CanHaveMII) {


+ int phy, phy_idx = 0;

+ for (phy = 1; phy < 32 && phy_idx < 4; phy++) {


+ int mii_status = mdio_read(dev, phy, 1);
+ if (mii_status != 0xffff && mii_status != 0x0000) {
+ np->phys[phy_idx++] = phy;
+ np->advertising = mdio_read(dev, phy, 4);
+ printk(KERN_INFO "%s: MII PHY found at address %d, status "
+ "0x%4.4x advertising %4.4x.\n",
+ dev->name, phy, mii_status, np->advertising);
+ }
+ }
+ np->mii_cnt = phy_idx;
+ if (phy_idx == 0) {

+ printk(KERN_WARNING "%s: MII PHY not found -- this device may "
+ "not operate correctly.\n", dev->name);
+ }
+ }
+
+ find_cnt++;


+ return 0;
+
+#ifndef USE_IO_OPS
+err_out_iomem:

+ release_mem_region(pci_resource_start(pdev, 1),


+ pci_id_tbl[chip_idx].io_size);
+#endif
+err_out_netdev:
+ unregister_netdev (dev);
+ kfree (dev);
+ return -ENODEV;
+}
+
+

+/* Read the EEPROM and MII Management Data I/O (MDIO) interfaces. These are
+ often serial bit streams generated by the host processor.
+ The example below is for the common 93c46 EEPROM, 64 16 bit words. */


+
+/* Delay between EEPROM clock transitions.

+ No extra delay is needed with 33Mhz PCI, but future 66Mhz access may need
+ a delay. Note that pre-2.0.34 kernels had a cache-alignment bug that
+ made udelay() unreliable.
+ The old method of using an ISA access as a delay, __SLOW_DOWN_IO__, is
+ depricated.
+*/
+#define eeprom_delay(ee_addr) readl(ee_addr)
+
+enum EEPROM_Ctrl_Bits {
+ EE_ShiftClk=0x02, EE_Write0=0x801, EE_Write1=0x805,
+ EE_ChipSelect=0x801, EE_DataIn=0x08,
+};
+
+/* The EEPROM commands include the alway-set leading bit. */
+enum EEPROM_Cmds {
+ EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),
+};
+
+static int eeprom_read(long addr, int location)
+{
+ int i;
+ int retval = 0;
+ int ee_addr = addr + EECtrl;
+ int read_cmd = location | EE_ReadCmd;
+ writel(EE_ChipSelect, ee_addr);


+
+ /* Shift the read command bits out. */

+ for (i = 10; i >= 0; i--) {
+ short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
+ writel(dataval, ee_addr);
+ eeprom_delay(ee_addr);
+ writel(dataval | EE_ShiftClk, ee_addr);
+ eeprom_delay(ee_addr);
+ }
+ writel(EE_ChipSelect, ee_addr);
+
+ for (i = 16; i > 0; i--) {
+ writel(EE_ChipSelect | EE_ShiftClk, ee_addr);
+ eeprom_delay(ee_addr);
+ retval = (retval << 1) | ((readl(ee_addr) & EE_DataIn) ? 1 : 0);
+ writel(EE_ChipSelect, ee_addr);
+ eeprom_delay(ee_addr);
+ }
+
+ /* Terminate the EEPROM access. */
+ writel(0, ee_addr);
+ return retval;


+}
+
+/* MII transceiver control section.
+ Read and write the MII registers using software-generated serial
+ MDIO protocol. See the MII specifications or DP83840A data sheet
+ for details.
+
+ The maximum data clock rate is 2.5 Mhz. The minimum timing is usually
+ met by back-to-back 33Mhz PCI cycles. */

+#define mdio_delay(mdio_addr) readl(mdio_addr)


+
+/* Set iff a MII transceiver on any interface requires mdio preamble.
+ This only set with older tranceivers, so the extra
+ code size of a per-interface flag is not worthwhile. */

+static char mii_preamble_required = 1;
+
+#define MDIO_WRITE0 (MDIO_EnbOutput)
+#define MDIO_WRITE1 (MDIO_DataOut | MDIO_EnbOutput)


+
+/* Generate the preamble required for initial synchronization and
+ a few older transceivers. */
+static void mdio_sync(long mdio_addr)
+{
+ int bits = 32;
+
+ /* Establish sync by sending at least 32 logic ones. */
+ while (--bits >= 0) {

+ writel(MDIO_WRITE1, mdio_addr);
+ mdio_delay(mdio_addr);
+ writel(MDIO_WRITE1 | MDIO_ShiftClk, mdio_addr);
+ mdio_delay(mdio_addr);


+ }
+}
+
+static int mdio_read(struct net_device *dev, int phy_id, int location)
+{
+ long mdio_addr = dev->base_addr + MIICtrl;
+ int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
+ int i, retval = 0;
+
+ if (mii_preamble_required)
+ mdio_sync(mdio_addr);
+
+ /* Shift the read command bits out. */
+ for (i = 15; i >= 0; i--) {
+ int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
+

+ writel(dataval, mdio_addr);
+ mdio_delay(mdio_addr);
+ writel(dataval | MDIO_ShiftClk, mdio_addr);
+ mdio_delay(mdio_addr);


+ }
+ /* Read the two transition, 16 data, and wire-idle bits. */

+ for (i = 20; i > 0; i--) {
+ writel(MDIO_EnbIn, mdio_addr);
+ mdio_delay(mdio_addr);
+ retval = (retval << 1) | ((readl(mdio_addr) & MDIO_DataIn) ? 1 : 0);
+ writel(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
+ mdio_delay(mdio_addr);


+ }
+ return (retval>>1) & 0xffff;
+}
+
+static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
+{

+ struct netdev_private *np = (struct netdev_private *)dev->priv;

+ long mdio_addr = dev->base_addr + MIICtrl;
+ int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
+ int i;
+

+ if (location == 4 && phy_id == np->phys[0])
+ np->advertising = value;


+
+ if (mii_preamble_required)
+ mdio_sync(mdio_addr);
+
+ /* Shift the command bits out. */
+ for (i = 31; i >= 0; i--) {
+ int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
+

+ writel(dataval, mdio_addr);
+ mdio_delay(mdio_addr);
+ writel(dataval | MDIO_ShiftClk, mdio_addr);
+ mdio_delay(mdio_addr);


+ }
+ /* Clear out extra bits. */
+ for (i = 2; i > 0; i--) {

+ writel(MDIO_EnbIn, mdio_addr);
+ mdio_delay(mdio_addr);
+ writel(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
+ mdio_delay(mdio_addr);


+ }
+ return;
+}
+
+
+static int netdev_open(struct net_device *dev)
+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ long ioaddr = dev->base_addr;
+ int i;
+

+ writel(0x00000001, ioaddr + PCIBusCfg); /* Reset */


+
+ MOD_INC_USE_COUNT;
+
+ if (request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev)) {
+ MOD_DEC_USE_COUNT;
+ return -EAGAIN;
+ }
+
+ if (debug > 1)

+ printk(KERN_DEBUG "%s: w89c840_open() irq %d.\n",


+ dev->name, dev->irq);
+
+ init_ring(dev);
+

+ writel(virt_to_bus(np->rx_ring), ioaddr + RxRingPtr);
+ writel(virt_to_bus(np->tx_ring), ioaddr + TxRingPtr);


+
+ for (i = 0; i < 6; i++)
+ writeb(dev->dev_addr[i], ioaddr + StationAddr + i);
+
+ /* Initialize other registers. */
+ /* Configure the PCI bus bursts and FIFO thresholds.

+ 486: Set 8 longword cache alignment, 8 longword burst.
+ 586: Set 16 longword cache alignment, no burst limit.
+ Cache alignment bits 15:14 Burst length 13:8
+ 0000 <not allowed> 0000 align to cache 0800 8 longwords
+ 4000 8 longwords 0100 1 longword 1000 16 longwords
+ 8000 16 longwords 0200 2 longwords 2000 32 longwords
+ C000 32 longwords 0400 4 longwords
+ Wait the specified 50 PCI cycles after a reset by initializing
+ Tx and Rx queues and the address filter list. */
+#if defined(__powerpc__) /* Big-endian */
+ writel(0x00100080 | 0xE010, ioaddr + PCIBusCfg);
+#elif defined(__alpha__)
+ writel(0xE010, ioaddr + PCIBusCfg);
+#elif defined(__i386__)
+#if defined(MODULE)
+ writel(0xE010, ioaddr + PCIBusCfg);
+#else
+ /* When not a module we can work around broken '486 PCI boards. */
+#define x86 boot_cpu_data.x86
+ writel((x86 <= 4 ? 0x4810 : 0xE010), ioaddr + PCIBusCfg);
+ if (x86 <= 4)
+ printk(KERN_INFO "%s: This is a 386/486 PCI system, setting cache "
+ "alignment to %x.\n", dev->name,
+ (x86 <= 4 ? 0x4810 : 0x8010));
+#endif
+#else
+ writel(0xE010, ioaddr + PCIBusCfg);
+#warning Processor architecture undefined!
+#endif


+
+ if (dev->if_port == 0)
+ dev->if_port = np->default_port;
+

+ writel(0, ioaddr + RxStartDemand);
+ np->csr6 = 0x20022002;
+ check_duplex(dev);
+ set_rx_mode(dev);
+
+ netif_start_queue(dev);
+
+ /* Clear and Enable interrupts by setting the interrupt mask. */
+ writel(0x1A0F5, ioaddr + IntrStatus);
+ writel(0x1A0F5, ioaddr + IntrEnable);
+
+ if (debug > 2)
+ printk(KERN_DEBUG "%s: Done netdev_open().\n", dev->name);
+


+ /* Set the timer to check for link beat. */
+ init_timer(&np->timer);
+ np->timer.expires = jiffies + 3*HZ;
+ np->timer.data = (unsigned long)dev;
+ np->timer.function = &netdev_timer; /* timer handler */
+ add_timer(&np->timer);
+
+ return 0;
+}
+
+static void check_duplex(struct net_device *dev)
+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;

+ int mii_reg5 = mdio_read(dev, np->phys[0], 5);
+ int negotiated = mii_reg5 & np->advertising;
+ int duplex;
+
+ if (np->duplex_lock || mii_reg5 == 0xffff)
+ return;
+ duplex = (negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040;
+ if (np->full_duplex != duplex) {
+ np->full_duplex = duplex;
+ if (debug)
+ printk(KERN_INFO "%s: Setting %s-duplex based on MII #%d "
+ "negotiated capability %4.4x.\n", dev->name,
+ duplex ? "full" : "half", np->phys[0], negotiated);

+ np->csr6 &= ~0x200;
+ np->csr6 |= duplex ? 0x200 : 0;


+ }
+}
+
+static void netdev_timer(unsigned long data)
+{
+ struct net_device *dev = (struct net_device *)data;
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ long ioaddr = dev->base_addr;
+ int next_tick = 10*HZ;

+ int old_csr6 = np->csr6;


+
+ if (debug > 2)

+ printk(KERN_DEBUG "%s: Media selection timer tick, status %8.8x "
+ "config %8.8x.\n",
+ dev->name, (int)readl(ioaddr + IntrStatus),
+ (int)readl(ioaddr + NetworkConfig));
+ check_duplex(dev);
+ if (np->csr6 != old_csr6) {
+ writel(np->csr6 & ~0x0002, ioaddr + NetworkConfig);
+ writel(np->csr6 | 0x2002, ioaddr + NetworkConfig);
+ }


+ np->timer.expires = jiffies + next_tick;
+ add_timer(&np->timer);
+}
+
+static void tx_timeout(struct net_device *dev)
+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ long ioaddr = dev->base_addr;
+

+ printk(KERN_WARNING "%s: Transmit timed out, status %8.8x,"
+ " resetting...\n", dev->name, (int)readl(ioaddr + IntrStatus));


+
+#ifndef __alpha__
+ {
+ int i;
+ printk(KERN_DEBUG " Rx ring %8.8x: ", (int)np->rx_ring);
+ for (i = 0; i < RX_RING_SIZE; i++)
+ printk(" %8.8x", (unsigned int)np->rx_ring[i].status);
+ printk("\n"KERN_DEBUG" Tx ring %8.8x: ", (int)np->tx_ring);
+ for (i = 0; i < TX_RING_SIZE; i++)
+ printk(" %4.4x", np->tx_ring[i].status);
+ printk("\n");
+ }
+#endif
+

+ /* Perhaps we should reinitialize the hardware here. Just trigger a
+ Tx demand for now. */
+ writel(0, ioaddr + TxStartDemand);


+ dev->if_port = 0;
+ /* Stop and restart the chip's Tx processes . */
+

+ dev->trans_start = jiffies;
+ np->stats.tx_errors++;
+ return;
+}
+
+
+/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
+static void init_ring(struct net_device *dev)
+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ int i;
+
+ np->tx_full = 0;

+ np->tx_q_bytes = np->cur_rx = np->cur_tx = 0;


+ np->dirty_rx = np->dirty_tx = 0;
+
+ np->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32);
+ np->rx_head_desc = &np->rx_ring[0];
+

+ /* Initial all Rx descriptors. */


+ for (i = 0; i < RX_RING_SIZE; i++) {

+ np->rx_ring[i].length = cpu_to_le32(np->rx_buf_sz);


+ np->rx_ring[i].status = 0;
+ np->rx_ring[i].next_desc = virt_to_le32desc(&np->rx_ring[i+1]);

+ np->rx_skbuff[i] = 0;
+ }

+ /* Mark the last entry as wrapping the ring. */
+ np->rx_ring[i-1].length |= cpu_to_le32(DescEndRing);


+ np->rx_ring[i-1].next_desc = virt_to_le32desc(&np->rx_ring[0]);
+
+ /* Fill in the Rx buffers. Handle allocation failure gracefully. */
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz);
+ np->rx_skbuff[i] = skb;
+ if (skb == NULL)
+ break;
+ skb->dev = dev; /* Mark as being used by this device. */

+ np->rx_ring[i].buffer1 = virt_to_le32desc(skb->tail);
+ np->rx_ring[i].status = cpu_to_le32(DescOwn | DescIntr);


+ }
+ np->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
+
+ for (i = 0; i < TX_RING_SIZE; i++) {
+ np->tx_skbuff[i] = 0;
+ np->tx_ring[i].status = 0;
+ }
+ return;
+}
+
+static int start_tx(struct sk_buff *skb, struct net_device *dev)
+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;

+ unsigned entry;
+


+ /* Caution: the write order is important here, set the field

+ with the "ownership" bits last. */


+
+ /* Calculate the next Tx descriptor entry. */
+ entry = np->cur_tx % TX_RING_SIZE;
+
+ np->tx_skbuff[entry] = skb;

+ np->tx_ring[entry].buffer1 = virt_to_le32desc(skb->data);
+
+#define one_buffer
+#define BPT 1022
+#if defined(one_buffer)
+ np->tx_ring[entry].length = cpu_to_le32(DescWholePkt | skb->len);


+ if (entry >= TX_RING_SIZE-1) /* Wrap ring */

+ np->tx_ring[entry].length |= cpu_to_le32(DescIntr | DescEndRing);
+ np->tx_ring[entry].status = cpu_to_le32(DescOwn);
+ np->cur_tx++;
+#elif defined(two_buffer)
+ if (skb->len > BPT) {
+ unsigned int entry1 = ++np->cur_tx % TX_RING_SIZE;
+ np->tx_ring[entry].length = cpu_to_le32(DescStartPkt | BPT);
+ np->tx_ring[entry1].length = cpu_to_le32(DescEndPkt | (skb->len - BPT));
+ np->tx_ring[entry1].buffer1 = virt_to_le32desc((skb->data) + BPT);
+ np->tx_ring[entry1].status = cpu_to_le32(DescOwn);
+ np->tx_ring[entry].status = cpu_to_le32(DescOwn);


+ if (entry >= TX_RING_SIZE-1)

+ np->tx_ring[entry].length |= cpu_to_le32(DescIntr|DescEndRing);
+ else if (entry1 >= TX_RING_SIZE-1)
+ np->tx_ring[entry1].length |= cpu_to_le32(DescIntr|DescEndRing);
+ np->cur_tx++;
+ } else {
+ np->tx_ring[entry].length = cpu_to_le32(DescWholePkt | skb->len);


+ if (entry >= TX_RING_SIZE-1) /* Wrap ring */

+ np->tx_ring[entry].length |= cpu_to_le32(DescIntr | DescEndRing);
+ np->tx_ring[entry].status = cpu_to_le32(DescOwn);
+ np->cur_tx++;
+ }
+#elif defined(split_buffer)
+ {
+ /* Work around the Tx-FIFO-full bug by splitting our transmit packet
+ into two pieces, the first which may be loaded without overflowing
+ the FIFO, and the second which contains the remainder of the
+ packet. When we get a Tx-done interrupt that frees enough room
+ in the FIFO we mark the remainder of the packet as loadable.
+
+ This has the problem that the Tx descriptors are written both
+ here and in the interrupt handler.
+ */
+
+ int buf1size = TX_FIFO_SIZE - np->tx_q_bytes;
+ int buf2size = skb->len - buf1size;
+
+ if (buf2size <= 0) { /* We fit into one descriptor. */
+ np->tx_ring[entry].length = cpu_to_le32(DescWholePkt | skb->len);
+ } else { /* We must use two descriptors. */
+ unsigned int entry2;
+ np->tx_ring[entry].length =
+ cpu_to_le32(DescIntr | DescStartPkt | buf1size);


+ if (entry >= TX_RING_SIZE-1) { /* Wrap ring */

+ np->tx_ring[entry].length |= cpu_to_le32(DescEndRing);
+ entry2 = 0;
+ } else
+ entry2 = entry + 1;
+ np->cur_tx++;
+ np->tx_ring[entry2].buffer1 =
+ virt_to_le32desc(skb->data + buf1size);
+ np->tx_ring[entry2].length = cpu_to_le32(DescEndPkt | buf2size);
+ if (entry2 >= TX_RING_SIZE-1) /* Wrap ring */
+ np->tx_ring[entry2].length |= cpu_to_le32(DescEndRing);
+ }
+ np->tx_ring[entry].status = cpu_to_le32(DescOwn);
+ np->cur_tx++;
+ }
+#endif
+ np->tx_q_bytes += skb->len;
+ writel(0, dev->base_addr + TxStartDemand);
+
+ /* Work around horrible bug in the chip by marking the queue as full
+ when we do not have FIFO room for a maximum sized packet. */
+ if (np->cur_tx - np->dirty_tx > TX_QUEUE_LEN)


+ np->tx_full = 1;

+ else if ((np->drv_flags & HasBrokenTx)
+ && np->tx_q_bytes > TX_BUG_FIFO_LIMIT)


+ np->tx_full = 1;

+ if (np->tx_full)
+ netif_stop_queue(dev);


+
+ dev->trans_start = jiffies;
+
+ if (debug > 4) {
+ printk(KERN_DEBUG "%s: Transmit frame #%d queued in slot %d.\n",
+ dev->name, np->cur_tx, entry);
+ }
+ return 0;
+}
+
+/* The interrupt handler does all of the Rx thread work and cleans up
+ after the Tx thread. */
+static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
+{
+ struct net_device *dev = (struct net_device *)dev_instance;

+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ long ioaddr = dev->base_addr;

+ int work_limit = max_interrupt_work;
+


+ spin_lock(&np->lock);
+
+ do {

+ u32 intr_status = readl(ioaddr + IntrStatus);
+
+ /* Acknowledge all of the current interrupt sources ASAP. */
+ writel(intr_status & 0x001ffff, ioaddr + IntrStatus);


+
+ if (debug > 4)
+ printk(KERN_DEBUG "%s: Interrupt, status %4.4x.\n",
+ dev->name, intr_status);
+

+ if ((intr_status & (NormalIntr|AbnormalIntr)) == 0)
+ break;
+
+ if (intr_status & (IntrRxDone | RxNoBuf))
+ netdev_rx(dev);


+
+ for (; np->cur_tx - np->dirty_tx > 0; np->dirty_tx++) {
+ int entry = np->dirty_tx % TX_RING_SIZE;

+ int tx_status = le32_to_cpu(np->tx_ring[entry].status);
+
+ if (tx_status < 0)
+ break;
+ if (tx_status & 0x8000) { /* There was an error, log it. */
+#ifndef final_version
+ if (debug > 1)
+ printk(KERN_DEBUG "%s: Transmit error, Tx status %8.8x.\n",
+ dev->name, tx_status);
+#endif
+ np->stats.tx_errors++;
+ if (tx_status & 0x0104) np->stats.tx_aborted_errors++;
+ if (tx_status & 0x0C80) np->stats.tx_carrier_errors++;
+ if (tx_status & 0x0200) np->stats.tx_window_errors++;
+ if (tx_status & 0x0002) np->stats.tx_fifo_errors++;
+ if ((tx_status & 0x0080) && np->full_duplex == 0)
+ np->stats.tx_heartbeat_errors++;
+#ifdef ETHER_STATS
+ if (tx_status & 0x0100) np->stats.collisions16++;
+#endif
+ } else {
+#ifdef ETHER_STATS
+ if (tx_status & 0x0001) np->stats.tx_deferred++;
+#endif
+ np->stats.tx_bytes += np->tx_skbuff[entry]->len;
+ np->stats.collisions += (tx_status >> 3) & 15;
+ np->stats.tx_packets++;
+ }


+ /* Free the original skb. */

+ np->tx_q_bytes -= np->tx_skbuff[entry]->len;


+ dev_kfree_skb_irq(np->tx_skbuff[entry]);
+ np->tx_skbuff[entry] = 0;
+ }

+ if (np->tx_full &&
+ np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 4
+ && np->tx_q_bytes < TX_BUG_FIFO_LIMIT) {


+ /* The ring is no longer full, clear tbusy. */
+ np->tx_full = 0;
+ netif_wake_queue(dev);
+ }
+
+ /* Abnormal error summary/uncommon events handlers. */

+ if (intr_status & (AbnormalIntr | TxFIFOUnderflow | IntrPCIErr |
+ TimerInt | IntrTxStopped))
+ netdev_error(dev, intr_status);
+
+ if (--work_limit < 0) {


+ printk(KERN_WARNING "%s: Too much work at interrupt, "

+ "status=0x%4.4x.\n", dev->name, intr_status);
+ /* Set the timer to re-enable the other interrupts after
+ 10*82usec ticks. */
+ writel(AbnormalIntr | TimerInt, ioaddr + IntrEnable);
+ writel(10, ioaddr + GPTimer);


+ break;
+ }
+ } while (1);
+
+ if (debug > 3)
+ printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",

+ dev->name, (int)readl(ioaddr + IntrStatus));


+
+ spin_unlock(&np->lock);
+}
+
+/* This routine is logically part of the interrupt handler, but separated
+ for clarity and better register allocation. */
+static int netdev_rx(struct net_device *dev)
+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ int entry = np->cur_rx % RX_RING_SIZE;

+ int work_limit = np->dirty_rx + RX_RING_SIZE - np->cur_rx;


+
+ if (debug > 4) {
+ printk(KERN_DEBUG " In netdev_rx(), entry %d status %4.4x.\n",
+ entry, np->rx_ring[entry].status);
+ }
+
+ /* If EOP is set on the next entry, it's a new packet. Send it up. */

+ while (--work_limit >= 0) {
+ struct w840_rx_desc *desc = np->rx_head_desc;
+ s32 status = le32_to_cpu(desc->status);


+
+ if (debug > 4)
+ printk(KERN_DEBUG " netdev_rx() status was %8.8x.\n",

+ status);
+ if (status < 0)
+ break;
+ if ((status & 0x38008300) != 0x0300) {
+ if ((status & 0x38000300) != 0x0300) {
+ /* Ingore earlier buffers. */
+ if ((status & 0xffff) != 0x7fff) {


+ printk(KERN_WARNING "%s: Oversized Ethernet frame spanned "

+ "multiple buffers, entry %#x status %4.4x!\n",
+ dev->name, np->cur_rx, status);
+ np->stats.rx_length_errors++;
+ }
+ } else if (status & 0x8000) {
+ /* There was a fatal error. */
+ if (debug > 2)
+ printk(KERN_DEBUG "%s: Receive error, Rx status %8.8x.\n",
+ dev->name, status);
+ np->stats.rx_errors++; /* end of a packet.*/
+ if (status & 0x0890) np->stats.rx_length_errors++;
+ if (status & 0x004C) np->stats.rx_frame_errors++;
+ if (status & 0x0002) np->stats.rx_crc_errors++;


+ }
+ } else {
+ struct sk_buff *skb;

+ /* Omit the four octet CRC from the length. */
+ int pkt_len = ((status >> 16) & 0x7ff) - 4;


+
+#ifndef final_version
+ if (debug > 4)
+ printk(KERN_DEBUG " netdev_rx() normal Rx pkt length %d"

+ " status %x.\n", pkt_len, status);


+#endif
+ /* Check if the packet is long enough to accept without copying
+ to a minimally-sized skbuff. */
+ if (pkt_len < rx_copybreak
+ && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+ skb->dev = dev;
+ skb_reserve(skb, 2); /* 16 byte align the IP header */

+ /* Call copy + cksum if available. */

+#if HAS_IP_COPYSUM


+ eth_copy_and_sum(skb, np->rx_skbuff[entry]->tail, pkt_len, 0);
+ skb_put(skb, pkt_len);

+#else
+ memcpy(skb_put(skb, pkt_len), np->rx_skbuff[entry]->tail,
+ pkt_len);
+#endif
+ } else {
+ char *temp = skb_put(skb = np->rx_skbuff[entry], pkt_len);


+ np->rx_skbuff[entry] = NULL;

+#ifndef final_version /* Remove after testing. */

+ if (le32desc_to_virt(desc->buffer1) != temp)


+ printk(KERN_ERR "%s: Internal fault: The skbuff addresses "

+ "do not match in netdev_rx: %p vs. %p / %p.\n",
+ dev->name, le32desc_to_virt(desc->buffer1),
+ skb->head, temp);
+#endif
+ }


+#ifndef final_version /* Remove after testing. */

+ /* You will want this info for the initial debug. */
+ if (debug > 5)
+ printk(KERN_DEBUG " Rx data %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:"
+ "%2.2x %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x %2.2x%2.2x "
+ "%d.%d.%d.%d.\n",
+ skb->data[0], skb->data[1], skb->data[2], skb->data[3],
+ skb->data[4], skb->data[5], skb->data[6], skb->data[7],
+ skb->data[8], skb->data[9], skb->data[10],
+ skb->data[11], skb->data[12], skb->data[13],
+ skb->data[14], skb->data[15], skb->data[16],
+ skb->data[17]);
+#endif


+ skb->protocol = eth_type_trans(skb, dev);

+ netif_rx(skb);
+ dev->last_rx = jiffies;

+ np->stats.rx_packets++;
+ np->stats.rx_bytes += pkt_len;


+ }
+ entry = (++np->cur_rx) % RX_RING_SIZE;
+ np->rx_head_desc = &np->rx_ring[entry];
+ }
+
+ /* Refill the Rx ring buffers. */
+ for (; np->cur_rx - np->dirty_rx > 0; np->dirty_rx++) {
+ struct sk_buff *skb;
+ entry = np->dirty_rx % RX_RING_SIZE;
+ if (np->rx_skbuff[entry] == NULL) {
+ skb = dev_alloc_skb(np->rx_buf_sz);
+ np->rx_skbuff[entry] = skb;
+ if (skb == NULL)
+ break; /* Better luck next round. */
+ skb->dev = dev; /* Mark as being used by this device. */

+ np->rx_ring[entry].buffer1 = virt_to_le32desc(skb->tail);
+ }
+ np->rx_ring[entry].status = cpu_to_le32(DescOwn);
+ }


+
+ return 0;
+}
+

+static void netdev_error(struct net_device *dev, int intr_status)
+{
+ long ioaddr = dev->base_addr;
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+

+ if (debug > 2)
+ printk(KERN_DEBUG "%s: Abnormal event, %8.8x.\n",
+ dev->name, intr_status);
+ if (intr_status == 0xffffffff)
+ return;
+ if (intr_status & TxFIFOUnderflow) {
+ np->csr6 += 0x4000; /* Bump up the Tx threshold */
+ printk(KERN_DEBUG "%s: Tx underflow, increasing threshold to %8.8x.\n",
+ dev->name, np->csr6);
+ writel(np->csr6, ioaddr + NetworkConfig);
+ }
+ if (intr_status & IntrRxDied) { /* Missed a Rx frame. */
+ np->stats.rx_errors++;
+ }
+ if (intr_status & TimerInt) {
+ /* Re-enable other interrupts. */
+ writel(0x1A0F5, ioaddr + IntrEnable);
+ }
+ np->stats.rx_missed_errors += readl(ioaddr + RxMissed) & 0xffff;
+ writel(0, ioaddr + RxStartDemand);


+}
+
+static struct net_device_stats *get_stats(struct net_device *dev)
+{
+ long ioaddr = dev->base_addr;
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+

+ /* The chip only need report frame silently dropped. */

+ if (netif_running(dev))
+ np->stats.rx_missed_errors += readl(ioaddr + RxMissed) & 0xffff;


+
+ return &np->stats;
+}
+

+static unsigned const ethernet_polynomial = 0x04c11db7U;
+static inline u32 ether_crc(int length, unsigned char *data)
+{
+ int crc = -1;
+


+ while(--length >= 0) {
+ unsigned char current_octet = *data++;
+ int bit;

+ for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
+ crc = (crc << 1) ^
+ ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);


+ }
+ }
+ return crc;
+}
+
+static void set_rx_mode(struct net_device *dev)
+{

+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ long ioaddr = dev->base_addr;

+ u32 mc_filter[2]; /* Multicast hash filter */
+ u32 rx_mode;
+


+ if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
+ /* Unconditionally log net taps. */
+ printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
+ memset(mc_filter, 0xff, sizeof(mc_filter));

+ rx_mode = AcceptBroadcast | AcceptMulticast | AcceptAllPhys
+ | AcceptMyPhys;


+ } else if ((dev->mc_count > multicast_filter_limit)
+ || (dev->flags & IFF_ALLMULTI)) {
+ /* Too many to match, or accept all multicasts. */
+ memset(mc_filter, 0xff, sizeof(mc_filter));
+ rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;

+ } else {
+ struct dev_mc_list *mclist;
+ int i;


+ memset(mc_filter, 0, sizeof(mc_filter));
+ for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
+ i++, mclist = mclist->next) {

+ set_bit((ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26) ^ 0x3F,
+ mc_filter);
+ }
+ rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
+ }
+ writel(mc_filter[0], ioaddr + MulticastFilter0);
+ writel(mc_filter[1], ioaddr + MulticastFilter1);
+ np->csr6 &= ~0x00F8;
+ np->csr6 |= rx_mode;
+ writel(np->csr6, ioaddr + NetworkConfig);

+ printk(KERN_DEBUG "%s: Shutting down ethercard, status was %8.8x "
+ "Config %8.8x.\n", dev->name, (int)readl(ioaddr + IntrStatus),
+ (int)readl(ioaddr + NetworkConfig));


+ printk(KERN_DEBUG "%s: Queue pointers were Tx %d / %d, Rx %d / %d.\n",
+ dev->name, np->cur_tx, np->dirty_tx, np->cur_rx, np->dirty_rx);
+ }
+
+ /* Disable interrupts by clearing the interrupt mask. */

+ writel(0x0000, ioaddr + IntrEnable);


+
+ /* Stop the chip's Tx and Rx processes. */

+ writel(np->csr6 &= ~0x20FA, ioaddr + NetworkConfig);
+
+ if (readl(ioaddr + NetworkConfig) != 0xffffffff)
+ np->stats.rx_missed_errors += readl(ioaddr + RxMissed) & 0xffff;


+
+#ifdef __i386__
+ if (debug > 2) {
+ printk("\n"KERN_DEBUG" Tx ring at %8.8x:\n",

+ (int)virt_to_le32desc(np->tx_ring));


+ for (i = 0; i < TX_RING_SIZE; i++)

+ printk(" #%d desc. %4.4x %4.4x %8.8x.\n",
+ i, np->tx_ring[i].length,
+ np->tx_ring[i].status, np->tx_ring[i].buffer1);


+ printk("\n"KERN_DEBUG " Rx ring %8.8x:\n",

+ (int)virt_to_le32desc(np->rx_ring));
+ for (i = 0; i < RX_RING_SIZE; i++) {


+ printk(KERN_DEBUG " #%d desc. %4.4x %4.4x %8.8x\n",

+ i, np->rx_ring[i].length,
+ np->rx_ring[i].status, np->rx_ring[i].buffer1);


+ }
+ }
+#endif /* __i386__ debugging only */
+
+ free_irq(dev->irq, dev);
+
+ del_timer_sync(&np->timer);
+
+ /* Free all the skbuffs in the Rx queue. */
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ np->rx_ring[i].status = 0;

+ if (np->rx_skbuff[i]) {
+ dev_kfree_skb(np->rx_skbuff[i]);
+ }
+ np->rx_skbuff[i] = 0;
+ }
+ for (i = 0; i < TX_RING_SIZE; i++) {
+ if (np->tx_skbuff[i])
+ dev_kfree_skb(np->tx_skbuff[i]);
+ np->tx_skbuff[i] = 0;
+ }
+
+ MOD_DEC_USE_COUNT;
+
+ return 0;
+}
+

+static void __devexit w840_remove1 (struct pci_dev *pdev)


+{
+ struct net_device *dev = pdev->driver_data;
+
+ /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
+ while (dev) {
+ struct netdev_private *np = (void *)(dev->priv);
+ unregister_netdev(dev);
+#ifdef USE_IO_OPS
+ release_region(dev->base_addr, pci_id_tbl[np->chip_id].io_size);
+#else
+ release_mem_region(pci_resource_start(pdev, 1),
+ pci_id_tbl[np->chip_id].io_size);
+ iounmap((char *)(dev->base_addr));
+#endif
+ kfree(dev);
+ }
+
+ pdev->driver_data = NULL;
+}
+

+static struct pci_driver w840_driver = {
+ name: "winbond-840",
+ id_table: w840_pci_tbl,
+ probe: w840_probe1,
+ remove: w840_remove1,
+};
+
+static int __init w840_init(void)
+{
+ return pci_module_init(&w840_driver);
+}
+
+static void __exit w840_exit(void)
+{
+ pci_unregister_driver(&w840_driver);
+}
+
+module_init(w840_init);
+module_exit(w840_exit);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/parport/ChangeLog linux/drivers/parport/ChangeLog
--- v2.4.0-test8/linux/drivers/parport/ChangeLog Mon Jul 24 18:59:27 2000
+++ linux/drivers/parport/ChangeLog Sun Sep 17 09:45:07 2000
@@ -1,3 +1,8 @@
+2000-09-16 Cesar Eduardo Barros <ces...@nitnet.com.br>
+
+ * parport_pc.c (sio_via_686a_probe): Handle case
+ where hardware returns 255 for IRQ or DMA.
+
X 2000-07-20 Eddie C. Dost <e...@skynet.be>
X
X * share.c (attach_driver_chain): attach[i](port) needs to be
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/parport/parport_pc.c linux/drivers/parport/parport_pc.c
--- v2.4.0-test8/linux/drivers/parport/parport_pc.c Sun Aug 6 11:24:58 2000
+++ linux/drivers/parport/parport_pc.c Sun Sep 17 09:45:07 2000
@@ -2239,11 +2239,13 @@
X irq = ((irq >> 4) & 0x0F);
X
X /* filter bogus IRQs */
+ /* 255 means NONE, and is bogus as well */
X switch (irq) {
X case 0:
X case 2:
X case 8:
X case 13:
+ case 255:
X irq = PARPORT_IRQ_NONE;
X break;
X
@@ -2252,7 +2254,9 @@
X }
X
X /* if ECP not enabled, DMA is not enabled, assumed bogus 'dma' value */
- if (!have_eppecp)
+ /* 255 means NONE. Looks like some BIOS don't set the DMA correctly
+ * even on ECP mode */
+ if (!have_eppecp || dma == 255)
X dma = PARPORT_DMA_NONE;
X
X /* finally, do the probe with values obtained */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/pci/names.c linux/drivers/pci/names.c
--- v2.4.0-test8/linux/drivers/pci/names.c Mon Jan 3 11:15:05 2000
+++ linux/drivers/pci/names.c Mon Oct 2 12:00:16 2000
@@ -131,4 +131,5 @@


X return NULL;
X }
X

-#endif
+#endif /* CONFIG_PCI_NAMES */
+
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/pci/pci.c linux/drivers/pci/pci.c
--- v2.4.0-test8/linux/drivers/pci/pci.c Mon Jun 19 13:42:38 2000
+++ linux/drivers/pci/pci.c Wed Sep 20 13:34:06 2000
@@ -657,134 +657,89 @@
X return child;
X }
X
-/*
- * A CardBus bridge is basically the same as a regular PCI bridge,
- * except we don't scan behind it because it will be changing.
- */
-static int __init pci_scan_cardbus(struct pci_bus *bus, struct pci_dev *dev, int busnr)
-{
- int i;
- unsigned short cr;
- unsigned int buses;
- struct pci_bus *child;
-
- /*
- * Insert it into the tree of buses.
- */
- DBG("Scanning CardBus bridge %s\n", dev->slot_name);
- child = pci_add_new_bus(bus, dev, ++busnr);
-
- for (i = 0; i < 4; i++)
- child->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i];
-
- /*
- * Maybe we'll have another bus behind this one?
- */
- child->subordinate = ++busnr;
- sprintf(child->name, "PCI CardBus #%02x", child->number);
-
- /*
- * Clear all status bits and turn off memory,
- * I/O and master enables.
- */
- pci_read_config_word(dev, PCI_COMMAND, &cr);
- pci_write_config_word(dev, PCI_COMMAND, 0x0000);
- pci_write_config_word(dev, PCI_STATUS, 0xffff);
-
- /*
- * Read the existing primary/secondary/subordinate bus
- * number configuration to determine if the bridge
- * has already been configured by the system. If so,
- * do not modify the configuration, merely note it.
- */
- pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses);
- if ((buses & 0xFFFFFF) != 0 && ! pcibios_assign_all_busses()) {
- child->primary = buses & 0xFF;
- child->secondary = (buses >> 8) & 0xFF;
- child->subordinate = (buses >> 16) & 0xFF;
- child->number = child->secondary;
- if (child->subordinate > busnr)
- busnr = child->subordinate;
- } else {
- /*
- * Configure the bus numbers for this bridge:
- */
- buses &= 0xff000000;
- buses |=
- (((unsigned int)(child->primary) << 0) |
- ((unsigned int)(child->secondary) << 8) |
- ((unsigned int)(child->subordinate) << 16));
- pci_write_config_dword(dev, PCI_PRIMARY_BUS, buses);
- }
- pci_write_config_word(dev, PCI_COMMAND, cr);
- return busnr;
-}
-
X static unsigned int __init pci_do_scan_bus(struct pci_bus *bus);
X
X /*
- * If it's a bridge, scan the bus behind it.
+ * If it's a bridge, configure it and scan the bus behind it.
+ * For CardBus bridges, we don't scan behind as the devices will
+ * be handled by the bridge driver itself.
+ *
+ * We need to process bridges in two passes -- first we scan those
+ * already configured by the BIOS and after we are done with all of
+ * them, we proceed to assigning numbers to the remaining buses in
+ * order to avoid overlaps between old and new bus numbers.
X */
-static int __init pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max)
+static int __init pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass)
X {
X unsigned int buses;
X unsigned short cr;
X struct pci_bus *child;
+ int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS);
X
- /*
- * Insert it into the tree of buses.
- */
- DBG("Scanning behind PCI bridge %s\n", dev->slot_name);
- child = pci_add_new_bus(bus, dev, ++max);
- sprintf(child->name, "PCI Bus #%02x", child->number);
-
- /*
- * Clear all status bits and turn off memory,
- * I/O and master enables.
- */
- pci_read_config_word(dev, PCI_COMMAND, &cr);
- pci_write_config_word(dev, PCI_COMMAND, 0x0000);
- pci_write_config_word(dev, PCI_STATUS, 0xffff);
-
- /*
- * Read the existing primary/secondary/subordinate bus
- * number configuration to determine if the PCI bridge
- * has already been configured by the system. If so,
- * do not modify the configuration, merely note it.
- */
X pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses);
- if ((buses & 0xFFFFFF) != 0 && ! pcibios_assign_all_busses()) {
- unsigned int cmax;
+ DBG("Scanning behind PCI bridge %s, config %06x, pass %d\n", dev->slot_name, buses & 0xffffff, pass);
+ if ((buses & 0xffffff) && !pcibios_assign_all_busses()) {
+ /*
+ * Bus already configured by firmware, process it in the first
+ * pass and just note the configuration.
+ */
+ if (pass)
+ return max;
+ child = pci_add_new_bus(bus, dev, 0);
X child->primary = buses & 0xFF;
X child->secondary = (buses >> 8) & 0xFF;
X child->subordinate = (buses >> 16) & 0xFF;
X child->number = child->secondary;
- cmax = pci_do_scan_bus(child);
- if (cmax > max) max = cmax;
+ if (!is_cardbus) {
+ unsigned int cmax = pci_do_scan_bus(child);
+ if (cmax > max) max = cmax;
+ } else {
+ int i;


+ for (i = 0; i < 4; i++)

+ child->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i];
+ }
X } else {
X /*
- * Configure the bus numbers for this bridge:
+ * We need to assign a number to this bus which we always
+ * do in the second pass. We also keep all address decoders
+ * on the bridge disabled during scanning. FIXME: Why?
X */
- buses &= 0xff000000;
- buses |=
- (((unsigned int)(child->primary) << 0) |
- ((unsigned int)(child->secondary) << 8) |
- ((unsigned int)(child->subordinate) << 16));
- pci_write_config_dword(dev, PCI_PRIMARY_BUS, buses);
+ if (!pass)
+ return max;
+ pci_read_config_word(dev, PCI_COMMAND, &cr);
+ pci_write_config_word(dev, PCI_COMMAND, 0x0000);
+ pci_write_config_word(dev, PCI_STATUS, 0xffff);
+ child = pci_add_new_bus(bus, dev, ++max);
+ buses = (buses & 0xff000000)
+ | ((unsigned int)(child->primary) << 0)
+ | ((unsigned int)(child->secondary) << 8)
+ | ((unsigned int)(child->subordinate) << 16);
X /*
- * Now we can scan all subordinate buses:
+ * We need to blast all three values with a single write.
X */
- max = pci_do_scan_bus(child);
+ pci_write_config_dword(dev, PCI_PRIMARY_BUS, buses);
+ if (!is_cardbus) {
+ /* Now we can scan all subordinate buses... */
+ max = pci_do_scan_bus(child);
+ } else {
+ int i;
+ /*
+ * For CardBus bridges, we leave 4 bus numbers
+ * as cards with a PCI-to-PCI bridge can be
+ * inserted later.
+ */
+ max += 3;


+ for (i = 0; i < 4; i++)

+ child->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i];
+ }
X /*
- * Set the subordinate bus number to its real
- * value:
+ * Set the subordinate bus number to its real value.
X */
X child->subordinate = max;
- buses = (buses & 0xff00ffff)
- | ((unsigned int)(child->subordinate) << 16);
- pci_write_config_dword(dev, PCI_PRIMARY_BUS, buses);
+ pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max);
+ pci_write_config_word(dev, PCI_COMMAND, cr);
X }
- pci_write_config_word(dev, PCI_COMMAND, cr);
+ sprintf(child->name, (is_cardbus ? "PCI CardBus #%02x" : "PCI Bus #%02x"), child->number);
X return max;
X }
X
@@ -933,7 +888,7 @@
X
X static unsigned int __init pci_do_scan_bus(struct pci_bus *bus)
X {
- unsigned int devfn, max;
+ unsigned int devfn, max, pass;
X struct list_head *ln;
X struct pci_dev *dev, dev0;
X
@@ -957,17 +912,12 @@
X */
X DBG("Fixups for bus %02x\n", bus->number);
X pcibios_fixup_bus(bus);
- for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
- dev = pci_dev_b(ln);
- switch (dev->class >> 8) {
- case PCI_CLASS_BRIDGE_PCI:
- max = pci_scan_bridge(bus, dev, max);
- break;
- case PCI_CLASS_BRIDGE_CARDBUS:
- max = pci_scan_cardbus(bus, dev, max);
- break;
+ for (pass=0; pass < 2; pass++)
+ for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
+ dev = pci_dev_b(ln);
+ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
+ max = pci_scan_bridge(bus, dev, max, pass);
X }
- }
X
X /*
X * We've scanned the bus and so we know all about what's on
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/pci/pci.ids linux/drivers/pci/pci.ids
--- v2.4.0-test8/linux/drivers/pci/pci.ids Sun Aug 13 19:37:15 2000
+++ linux/drivers/pci/pci.ids Thu Sep 21 15:55:32 2000
@@ -1471,9 +1471,9 @@
X 6055 3c556 Laptop Hurricane
X 5057 3c575 [Megahertz] 10/100 LAN CardBus
X 10b7 5a57 3C575 Megahertz 10/100 LAN Cardbus PC Card
- 5157 3c575 [Megahertz] 10/100 LAN CardBus
+ 5157 3CCFE575BT Cyclone CardBus
X 10b7 5b57 3C575 Megahertz 10/100 LAN Cardbus PC Card
- 5257 3CCFE575CT Cyclone CardBus
+ 5257 3CCFE575CT Tornado CardBus
X 5900 3c590 10BaseT [Vortex]
X 5920 3c592 EISA 10mbps Demon/Vortex
X 5950 3c595 100BaseTX [Vortex]
@@ -1483,8 +1483,8 @@
X 5b57 3c595 [Megahertz] 10/100 LAN CardBus
X 10b7 5b57 3C575 Megahertz 10/100 LAN Cardbus PC Card
X 6560 3CCFE656 Cyclone CardBus
- 6562 3CCFEM656 [id 6562] Cyclone CardBus
- 6564 3CCFEM656 [id 6564] Cyclone CardBus
+ 6562 3CCFEM656B Cyclone CardBus
+ 6564 3CXFEM656C Tornado CardBus
X 7646 3cSOHO100-TX Hurricane
X 8811 Token ring
X 9000 3c900 10BaseT [Boomerang]
@@ -2694,6 +2694,10 @@
X 0105 Cyclom_8Y above first megabyte
X 0200 Cyclom_Z below first megabyte
X 0201 Cyclom_Z above first megabyte
+ 0300 PC300 RX 2
+ 0301 PC300 RX 1
+ 0310 PC300 TE 2
+ 0311 PC300 TE 1
X 120f Essential Communications
X 0001 Roadrunner serial HIPPI
X 1210 Hyperparallel Technologies
@@ -2752,6 +2756,7 @@
X 121a 0060 Voodoo3 3500 TV (NTSC)
X 121a 0061 Voodoo3 3500 TV (PAL)
X 121a 0062 Voodoo3 3500 TV (SECAM)
+ 0009 Voodoo 4
X 121b Advanced Telecommunications Modules
X 121c Nippon Texaco., Ltd
X 121d Lippert Automationstechnik GmbH
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/pci/proc.c linux/drivers/pci/proc.c
--- v2.4.0-test8/linux/drivers/pci/proc.c Mon Aug 21 09:07:15 2000
+++ linux/drivers/pci/proc.c Mon Sep 18 17:36:14 2000
@@ -46,8 +46,8 @@
X const struct inode *ino = file->f_dentry->d_inode;
X const struct proc_dir_entry *dp = ino->u.generic_ip;
X struct pci_dev *dev = dp->data;
- int pos = *ppos;
- int cnt, size;
+ unsigned int pos = *ppos;
+ unsigned int cnt, size;
X
X /*
X * Normal users can read only the standardized portion of the
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/pci/quirks.c linux/drivers/pci/quirks.c
--- v2.4.0-test8/linux/drivers/pci/quirks.c Fri Aug 4 11:23:37 2000
+++ linux/drivers/pci/quirks.c Sun Oct 1 20:35:16 2000
@@ -46,7 +46,7 @@
X chipset level fix */
X
X
-int isa_dma_bridge_buggy = 0; /* Exported */
+int isa_dma_bridge_buggy; /* Exported */
X
X static void __init quirk_isa_dma_hangs(struct pci_dev *dev)
X {
@@ -56,7 +56,7 @@
X }
X }
X
-int pci_pci_problems = 0;
+int pci_pci_problems;
X
X /*
X * Chipsets where PCI->PCI transfers vanish or hang
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/pcmcia/cardbus.c linux/drivers/pcmcia/cardbus.c
--- v2.4.0-test8/linux/drivers/pcmcia/cardbus.c Tue Sep 5 12:56:51 2000
+++ linux/drivers/pcmcia/cardbus.c Mon Sep 18 15:11:51 2000
@@ -58,11 +58,6 @@
X #include <asm/irq.h>
X #include <asm/io.h>
X
-#ifndef PCMCIA_DEBUG
-#define PCMCIA_DEBUG 1
-#endif
-static int pc_debug = PCMCIA_DEBUG;
-
X #define IN_CARD_SERVICES
X #include <pcmcia/version.h>
X #include <pcmcia/cs_types.h>
@@ -73,6 +68,10 @@
X #include "cs_internal.h"
X #include "rsrc_mgr.h"
X
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+#endif
+
X /*====================================================================*/
X
X #define FIND_FIRST_BIT(n) ((n) - ((n) & ((n)-1)))
@@ -372,9 +371,9 @@
X void cb_enable(socket_info_t * s)
X {
X struct pci_dev *dev;
- u_char i, bus = s->cap.cb_dev->subordinate->number;
+ u_char i;
X
- DEBUG(0, "cs: cb_enable(bus %d)\n", bus);
+ DEBUG(0, "cs: cb_enable(bus %d)\n", s->cap.cb_dev->subordinate->number);
X
X /* Configure bridge */
X cb_release_cis_mem(s);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/pcmcia/cs.c linux/drivers/pcmcia/cs.c
--- v2.4.0-test8/linux/drivers/pcmcia/cs.c Thu Sep 7 09:13:00 2000
+++ linux/drivers/pcmcia/cs.c Mon Sep 18 15:11:51 2000
@@ -103,13 +103,13 @@
X
X #define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
X
-INT_MODULE_PARM(setup_delay, HZ/20); /* ticks */
-INT_MODULE_PARM(resume_delay, HZ/5); /* ticks */
-INT_MODULE_PARM(shutdown_delay, HZ/40); /* ticks */
-INT_MODULE_PARM(vcc_settle, 400); /* msecs */
+INT_MODULE_PARM(setup_delay, 10); /* centiseconds */
+INT_MODULE_PARM(resume_delay, 20); /* centiseconds */
+INT_MODULE_PARM(shutdown_delay, 3); /* centiseconds */
+INT_MODULE_PARM(vcc_settle, 40); /* centiseconds */
X INT_MODULE_PARM(reset_time, 10); /* usecs */
-INT_MODULE_PARM(unreset_delay, 100); /* msecs */
-INT_MODULE_PARM(unreset_check, 100); /* msecs */
+INT_MODULE_PARM(unreset_delay, 10); /* centiseconds */
+INT_MODULE_PARM(unreset_check, 10); /* centiseconds */
X INT_MODULE_PARM(unreset_limit, 30); /* unreset_check's */
X
X /* Access speed for attribute memory windows */
@@ -446,10 +446,13 @@
X
X static int send_event(socket_info_t *s, event_t event, int priority);
X
-static void msleep(unsigned int msec)
+/*
+ * Sleep for n_cs centiseconds (1 cs = 1/100th of a second)
+ */
+static void cs_sleep(unsigned int n_cs)
X {


X current->state = TASK_INTERRUPTIBLE;

- schedule_timeout( (msec * HZ + 999) / 1000);
+ schedule_timeout( (n_cs * HZ + 99) / 100);
X }
X
X static void shutdown_socket(socket_info_t *s)
@@ -504,7 +507,7 @@
X if (!(val & SS_PENDING))
X break;
X if (--setup_timeout) {
- msleep(100);
+ cs_sleep(10);
X continue;
X }
X printk(KERN_NOTICE "cs: socket %p voltage interrogation"
@@ -516,7 +519,7 @@
X if (val & SS_DETECT) {
X DEBUG(1, "cs: setup_socket(%p): applying power\n", s);
X s->state |= SOCKET_PRESENT;
- s->socket.flags = 0;
+ s->socket.flags &= SS_DEBOUNCED;
X if (val & SS_3VCARD)
X s->socket.Vcc = s->socket.Vpp = 33;
X else if (!(val & SS_XVCARD))
@@ -533,7 +536,7 @@
X #endif
X }
X set_socket(s, &s->socket);
- msleep(vcc_settle);
+ cs_sleep(vcc_settle);
X reset_socket(s);
X ret = 1;
X } else {
@@ -561,7 +564,7 @@
X udelay((long)reset_time);
X s->socket.flags &= ~SS_RESET;
X set_socket(s, &s->socket);
- msleep(unreset_delay);
+ cs_sleep(unreset_delay);
X unreset_socket(s);
X } /* reset_socket */
X
@@ -580,11 +583,11 @@
X break;
X DEBUG(2, "cs: socket %d not ready yet\n", s->sock);
X if (--setup_timeout) {
- msleep(unreset_check);
+ cs_sleep(unreset_check);
X continue;
X }
X printk(KERN_NOTICE "cs: socket %p timed out during"
- " reset\n", s);
+ " reset. Try increasing setup_delay.\n", s);
X s->state &= ~EVENT_MASK;
X return;
X }
@@ -656,7 +659,7 @@
X DEBUG(0, "cs: flushing pending setup\n");
X s->state &= ~EVENT_MASK;
X }
- msleep(shutdown_delay);
+ cs_sleep(shutdown_delay);
X s->state &= ~SOCKET_PRESENT;
X shutdown_socket(s);
X }
@@ -679,11 +682,13 @@
X }
X s->state |= SOCKET_SETUP_PENDING;
X if (s->state & SOCKET_SUSPEND)
- msleep(resume_delay);
+ cs_sleep(resume_delay);
X else
- msleep(setup_delay);
+ cs_sleep(setup_delay);
+ s->socket.flags |= SS_DEBOUNCED;
X if (setup_socket(s) == 0)
X s->state &= ~SOCKET_SETUP_PENDING;
+ s->socket.flags &= ~SS_DEBOUNCED;
X }
X }
X if (events & SS_BATDEAD)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/pcmcia/yenta.c linux/drivers/pcmcia/yenta.c
--- v2.4.0-test8/linux/drivers/pcmcia/yenta.c Wed Sep 6 11:48:58 2000
+++ linux/drivers/pcmcia/yenta.c Fri Sep 15 16:31:09 2000
@@ -233,6 +233,11 @@
X {
X u16 bridge;
X
+ if (state->flags & SS_DEBOUNCED) {
+ /* The insertion debounce period has ended. Clear any pending insertion events */
+ socket->events &= ~SS_DETECT;
+ state->flags &= ~SS_DEBOUNCED; /* SS_DEBOUNCED is oneshot */
+ }
X yenta_set_power(socket, state);
X socket->io_irq = state->io_irq;
X bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~(CB_BRIDGE_CRST | CB_BRIDGE_INTR);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/pnp/isapnp.c linux/drivers/pnp/isapnp.c
--- v2.4.0-test8/linux/drivers/pnp/isapnp.c Mon Aug 28 22:13:12 2000
+++ linux/drivers/pnp/isapnp.c Sun Oct 1 20:35:16 2000
@@ -48,14 +48,14 @@
X #define ISAPNP_DEBUG
X #endif
X
-struct resource *pidxr_res = NULL;
-struct resource *pnpwrp_res = NULL;
-struct resource *isapnp_rdp_res = NULL;
+struct resource *pidxr_res;
+struct resource *pnpwrp_res;
+struct resource *isapnp_rdp_res;
X
-int isapnp_disable = 0; /* Disable ISA PnP */
-int isapnp_rdp = 0; /* Read Data Port */
+int isapnp_disable; /* Disable ISA PnP */
+int isapnp_rdp; /* Read Data Port */
X int isapnp_reset = 1; /* reset all PnP cards (deactivate) */
-int isapnp_skip_pci_scan = 0; /* skip PCI resource scanning */
+int isapnp_skip_pci_scan; /* skip PCI resource scanning */
X int isapnp_verbose = 1; /* verbose mode */
X int isapnp_reserve_irq[16] = { [0 ... 15] = -1 }; /* reserve (don't use) some IRQ */
X int isapnp_reserve_dma[8] = { [0 ... 7] = -1 }; /* reserve (don't use) some DMA */


@@ -108,7 +108,7 @@
X

X static unsigned char isapnp_checksum_value;
X static DECLARE_MUTEX(isapnp_cfg_mutex);
-static int isapnp_detected = 0;
+static int isapnp_detected;
X
X /* some prototypes */
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/s390/Config.in linux/drivers/s390/Config.in
--- v2.4.0-test8/linux/drivers/s390/Config.in Fri May 12 11:41:44 2000
+++ linux/drivers/s390/Config.in Tue Sep 19 10:58:38 2000
@@ -5,16 +5,7 @@
X if [ "$CONFIG_NET" = "y" ]; then
X tristate 'Network block device support' CONFIG_BLK_DEV_NBD
X fi
-bool 'Multiple devices driver support' CONFIG_BLK_DEV_MD
-if [ "$CONFIG_BLK_DEV_MD" = "y" ]; then
- tristate ' Linear (append) mode' CONFIG_MD_LINEAR
- tristate ' RAID-0 (striping) mode' CONFIG_MD_STRIPED
- tristate ' RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING
- tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5
-fi
-if [ "$CONFIG_MD_LINEAR" = "y" -o "$CONFIG_MD_STRIPED" = "y" ]; then
- bool ' Boot support (linear, striped)' CONFIG_MD_BOOT
-fi
+include drivers/md/Config.in
X tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
X if [ "$CONFIG_BLK_DEV_RAM" = "y" ]; then
X bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/3w-xxxx.c linux/drivers/scsi/3w-xxxx.c
--- v2.4.0-test8/linux/drivers/scsi/3w-xxxx.c Fri Aug 4 17:56:25 2000
+++ linux/drivers/scsi/3w-xxxx.c Mon Sep 18 14:57:01 2000
@@ -3,6 +3,7 @@
X
X Written By: Adam Radford <li...@3ware.com>
X Modifications By: Joel Jacobson <li...@3ware.com>
+ Arnaldo Carvalho de Melo <ac...@conectiva.com.br>
X
X Copyright (C) 1999-2000 3ware Inc.
X
@@ -64,6 +65,8 @@
X Bug fix so hot spare drives don't show up.
X 1.02.00.002 - Fix bug with tw_setfeature() call that caused oops on some
X systems.
+ 08/21/00 - release previously allocated resources on failure at
+ tw_allocate_memory (acme)


X */
X
X #include <linux/module.h>

@@ -410,35 +413,26 @@
X /* This function will allocate memory and check if it is 16 d-word aligned */
X int tw_allocate_memory(TW_Device_Extension *tw_dev, int request_id, int size, int which)
X {
- u32 *virt_addr;
+ u32 *virt_addr = kmalloc(size, GFP_ATOMIC);
X
X dprintk(KERN_NOTICE "3w-xxxx: tw_allocate_memory()\n");
X
+ if (!virt_addr) {
+ printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): kmalloc() failed.\n");


+ return 1;
+ }
+

+ if ((u32)virt_addr % TW_ALIGNMENT) {
+ kfree(virt_addr);
+ printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): Found unaligned address.\n");


+ return 1;
+ }
+

X if (which == 0) {
- /* Allocate command packet memory */
- virt_addr = kmalloc(size, GFP_ATOMIC);
- if (virt_addr == NULL) {
- printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): kmalloc() failed.\n");
- return 1;
- }
- if ((u32)virt_addr % TW_ALIGNMENT) {
- printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): Found unaligned address.\n");
- return 1;
- }
X tw_dev->command_packet_virtual_address[request_id] = virt_addr;
X tw_dev->command_packet_physical_address[request_id] =
X virt_to_bus(virt_addr);
X } else {
- /* Allocate generic buffer */
- virt_addr = kmalloc(size, GFP_ATOMIC);
- if (virt_addr == NULL) {
- printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): kmalloc() failed.\n");
- return 1;
- }
- if ((u32)virt_addr % TW_ALIGNMENT) {
- printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): Found unaligned address.\n");
- return 1;
- }
X tw_dev->alignment_virtual_address[request_id] = virt_addr;
X tw_dev->alignment_physical_address[request_id] = virt_to_bus(virt_addr);
X }
@@ -2390,7 +2384,6 @@
X
X /* Now get things going */
X
-#ifdef MODULE
-Scsi_Host_Template driver_template = TWXXXX;
+static Scsi_Host_Template driver_template = TWXXXX;
X #include "scsi_module.c"
-#endif
+
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/3w-xxxx.h linux/drivers/scsi/3w-xxxx.h
--- v2.4.0-test8/linux/drivers/scsi/3w-xxxx.h Fri Sep 8 12:54:35 2000
+++ linux/drivers/scsi/3w-xxxx.h Mon Sep 18 14:09:49 2000
@@ -338,7 +338,6 @@
X int tw_state_request_start(TW_Device_Extension *tw_dev, int *request_id);
X void tw_unmask_command_interrupt(TW_Device_Extension *tw_dev);
X
-#if defined(HOSTS_C) || defined(MODULE)
X /* Scsi_Host_Template Initializer */
X #define TWXXXX { \
X next : NULL, \
@@ -371,5 +370,4 @@
X use_new_eh_code : 1, \
X emulated : 1 \
X }
-#endif /* HOSTS_C */
X #endif /* _3W_XXXX_H */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/53c7,8xx.c linux/drivers/scsi/53c7,8xx.c
--- v2.4.0-test8/linux/drivers/scsi/53c7,8xx.c Tue Aug 8 09:19:25 2000
+++ linux/drivers/scsi/53c7,8xx.c Mon Sep 18 13:36:24 2000
@@ -6425,6 +6425,7 @@
X vfree ((void *)hostdata->events);
X return 1;
X }
-Scsi_Host_Template driver_template = NCR53c7xx;
-#include "scsi_module.c"
X #endif /* def MODULE */
+
+static Scsi_Host_Template driver_template = NCR53c7xx;
+#include "scsi_module.c"
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/53c7,8xx.h linux/drivers/scsi/53c7,8xx.h
--- v2.4.0-test8/linux/drivers/scsi/53c7,8xx.h Fri Sep 8 12:54:35 2000
+++ linux/drivers/scsi/53c7,8xx.h Mon Sep 18 14:09:49 2000
@@ -46,7 +46,6 @@
X * array.
X */
X
-#if defined(HOSTS_C) || defined(MODULE)
X #include <scsi/scsicam.h>
X
X extern int NCR53c7xx_abort(Scsi_Cmnd *);
@@ -71,8 +70,6 @@
X sg_tablesize: 127, \
X cmd_per_lun: 3, \
X use_clustering: DISABLE_CLUSTERING}
-
-#endif /* defined(HOSTS_C) || defined(MODULE) */
X
X #ifndef HOSTS_C
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/53c7xx.c linux/drivers/scsi/53c7xx.c
--- v2.4.0-test8/linux/drivers/scsi/53c7xx.c Tue Aug 8 09:19:25 2000
+++ linux/drivers/scsi/53c7xx.c Mon Sep 18 13:36:24 2000
@@ -6102,6 +6102,7 @@
X free_pages ((u32)hostdata, 1);
X return 1;
X }
-Scsi_Host_Template driver_template = NCR53c7xx;
-#include "scsi_module.c"
X #endif /* def MODULE */
+
+static Scsi_Host_Template driver_template = NCR53c7xx;
+#include "scsi_module.c"
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/53c7xx.h linux/drivers/scsi/53c7xx.h
--- v2.4.0-test8/linux/drivers/scsi/53c7xx.h Tue Nov 23 10:29:15 1999
+++ linux/drivers/scsi/53c7xx.h Mon Sep 18 14:09:49 2000


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 070'
echo 'File patch-2.4.0-test9 is continued in part 071'
echo "071" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part071

#!/bin/sh -x
# this is part 071 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 071; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

@@ -59,7 +59,6 @@


X * array.
X */
X
-#if defined(HOSTS_C) || defined(MODULE)
X #include <scsi/scsicam.h>
X
X extern int NCR53c7xx_abort(Scsi_Cmnd *);

@@ -79,8 +78,6 @@
X NULL /* slave attach */, scsicam_bios_param, /* can queue */ 24, \
X /* id */ 7, 127 /* old SG_ALL */, /* cmd per lun */ 3, \
X /* present */ 0, /* unchecked isa dma */ 0, DISABLE_CLUSTERING}

-
-#endif /* defined(HOSTS_C) || defined(MODULE) */
X
X #ifndef HOSTS_C
X

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/AM53C974.c linux/drivers/scsi/AM53C974.c
--- v2.4.0-test8/linux/drivers/scsi/AM53C974.c Mon Jun 19 17:59:41 2000
+++ linux/drivers/scsi/AM53C974.c Mon Sep 18 13:36:24 2000
@@ -2456,11 +2456,10 @@
X
X
X #ifdef MODULE
-static Scsi_Host_Template driver_template = AM53C974;
-
X /* You can specify overrides=a,b,c,d in the same format at AM53C974=a,b,c,d
X on boot up */
-
X MODULE_PARM(overrides, "1-32i");
-#include "scsi_module.c"
X #endif
+
+static Scsi_Host_Template driver_template = AM53C974;
+#include "scsi_module.c"
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/BusLogic.c linux/drivers/scsi/BusLogic.c
--- v2.4.0-test8/linux/drivers/scsi/BusLogic.c Mon Jul 10 13:06:35 2000
+++ linux/drivers/scsi/BusLogic.c Mon Sep 18 13:36:24 2000
@@ -61,7 +61,7 @@
X */
X
X static int
- BusLogic_DriverOptionsCount = 0;
+ BusLogic_DriverOptionsCount;
X
X
X /*
@@ -79,7 +79,7 @@
X */
X
X #ifdef MODULE
-static char *BusLogic = NULL;
+static char *BusLogic;
X MODULE_PARM(BusLogic, "s");
X #endif
X
@@ -90,7 +90,7 @@
X */
X
X static BusLogic_ProbeOptions_T
- BusLogic_ProbeOptions = { 0 };
+ BusLogic_ProbeOptions;
X
X
X /*
@@ -99,7 +99,7 @@
X */
X
X static BusLogic_GlobalOptions_T
- BusLogic_GlobalOptions = { 0 };
+ BusLogic_GlobalOptions;
X
X
X /*
@@ -108,8 +108,8 @@
X */
X
X static BusLogic_HostAdapter_T
- *BusLogic_FirstRegisteredHostAdapter = NULL,
- *BusLogic_LastRegisteredHostAdapter = NULL;
+ *BusLogic_FirstRegisteredHostAdapter,
+ *BusLogic_LastRegisteredHostAdapter;
X
X
X /*
@@ -117,7 +117,7 @@
X */
X
X static int
- BusLogic_ProbeInfoCount = 0;
+ BusLogic_ProbeInfoCount;
X
X
X /*
@@ -128,7 +128,7 @@
X */
X
X static BusLogic_ProbeInfo_T
- *BusLogic_ProbeInfoList = NULL;
+ *BusLogic_ProbeInfoList;
X
X
X /*
@@ -4982,13 +4982,9 @@
X __setup("BusLogic=", BusLogic_Setup);
X
X /*
- Include Module support if requested.
+ Get it all started
X */
X
-#ifdef MODULE
-
-SCSI_Host_Template_T driver_template = BUSLOGIC;
+static SCSI_Host_Template_T driver_template = BUSLOGIC;
X
X #include "scsi_module.c"
-
-#endif
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/ChangeLog.ips linux/drivers/scsi/ChangeLog.ips
--- v2.4.0-test8/linux/drivers/scsi/ChangeLog.ips Tue Jun 20 14:14:51 2000
+++ linux/drivers/scsi/ChangeLog.ips Tue Sep 19 08:01:34 2000
@@ -1,7 +1,22 @@
X IBM ServeRAID driver Change Log
X ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ 4.20.14 - Update patch files for kernel 2.4.0-test5
+
+ 4.20.13 - Fix some failure cases / reset code
+ - Hook into the reboot_notifier to flush the controller
+ cache
+
+ 4.20.03 - Rename version to coincide with new release schedules
+ - Performance fixes
+ - Fix truncation of /proc files with cat
+ - Merge in changes through kernel 2.4.0test1ac21
+
+ 4.10.13 - Fix for dynamic unload and proc file system
+
+ 4.10.00 - Add support for ServeRAID 4M/4L
+
X 4.00.06 - Fix timeout with initial FFDC command
-
+
X 4.00.05 - Remove wish_block from init routine
X - Use linux/spinlock.h instead of asm/spinlock.h for kernels
X 2.3.18 and later
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/Config.in linux/drivers/scsi/Config.in
--- v2.4.0-test8/linux/drivers/scsi/Config.in Mon Mar 27 09:45:33 2000
+++ linux/drivers/scsi/Config.in Tue Sep 19 08:01:34 2000
@@ -55,9 +55,6 @@
X bool ' Collect statistics to report in /proc' CONFIG_AIC7XXX_PROC_STATS
X int ' Delay in seconds after SCSI bus reset' CONFIG_AIC7XXX_RESET_DELAY 5
X fi
-if [ "$CONFIG_X86" = "y" ]; then
- dep_tristate 'IBM ServeRAID support' CONFIG_SCSI_IPS $CONFIG_SCSI
-fi
X dep_tristate 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS $CONFIG_SCSI
X dep_tristate 'Always IN2000 SCSI support' CONFIG_SCSI_IN2000 $CONFIG_SCSI
X dep_tristate 'AM53/79C974 PCI SCSI support' CONFIG_SCSI_AM53C974 $CONFIG_SCSI
@@ -67,6 +64,9 @@
X if [ "$CONFIG_SCSI_BUSLOGIC" != "n" ]; then
X bool ' Omit FlashPoint support' CONFIG_SCSI_OMIT_FLASHPOINT
X fi
+if [ "$CONFIG_PCI" = "y" ]; then
+ dep_tristate 'Compaq Fibre Channel 64-bit/66Mhz HBA support' CONFIG_SCSI_CPQFCTS $CONFIG_SCSI
+fi
X dep_tristate 'DMX3191D SCSI support' CONFIG_SCSI_DMX3191D $CONFIG_SCSI $CONFIG_PCI
X dep_tristate 'DTC3180/3280 SCSI support' CONFIG_SCSI_DTC3280 $CONFIG_SCSI
X dep_tristate 'EATA ISA/EISA/PCI (DPT and generic EATA/DMA-compliant boards) support' CONFIG_SCSI_EATA $CONFIG_SCSI
@@ -89,6 +89,16 @@
X "Port CONFIG_SCSI_G_NCR5380_PORT \
X Memory CONFIG_SCSI_G_NCR5380_MEM" Port
X fi
+if [ "$CONFIG_MCA" = "y" ]; then
+ dep_tristate 'IBMMCA SCSI support' CONFIG_SCSI_IBMMCA $CONFIG_SCSI
+ if [ "$CONFIG_SCSI_IBMMCA" != "n" ]; then
+ bool ' Standard SCSI-order' CONFIG_IBMMCA_SCSI_ORDER_STANDARD
+ bool ' Reset SCSI-devices at boottime' CONFIG_IBMMCA_SCSI_DEV_RESET
+ fi
+fi
+if [ "$CONFIG_X86" = "y" ]; then
+ dep_tristate 'IBM ServeRAID support' CONFIG_SCSI_IPS $CONFIG_SCSI
+fi
X dep_tristate 'Initio 9100U(W) support' CONFIG_SCSI_INITIO $CONFIG_SCSI $CONFIG_PCI
X dep_tristate 'Initio INI-A100U2W support' CONFIG_SCSI_INIA100 $CONFIG_SCSI $CONFIG_PCI
X if [ "$CONFIG_PARPORT" != "n" ]; then
@@ -100,8 +110,6 @@
X fi
X fi
X dep_tristate 'NCR53c406a SCSI support' CONFIG_SCSI_NCR53C406A $CONFIG_SCSI
-dep_tristate 'symbios 53c416 SCSI support' CONFIG_SCSI_SYM53C416 $CONFIG_SCSI
-dep_tristate 'Simple 53c710 SCSI support (Compaq, NCR machines)' CONFIG_SCSI_SIM710 $CONFIG_SCSI
X dep_tristate 'NCR53c7,8xx SCSI support' CONFIG_SCSI_NCR53C7xx $CONFIG_SCSI $CONFIG_PCI
X if [ "$CONFIG_SCSI_NCR53C7xx" != "n" ]; then
X bool ' always negotiate synchronous transfers' CONFIG_SCSI_NCR53C7xx_sync
@@ -129,13 +137,6 @@
X fi
X fi
X if [ "$CONFIG_MCA" = "y" ]; then
- dep_tristate 'IBMMCA SCSI support' CONFIG_SCSI_IBMMCA $CONFIG_SCSI
- if [ "$CONFIG_SCSI_IBMMCA" != "n" ]; then
- bool ' Standard SCSI-order' CONFIG_IBMMCA_SCSI_ORDER_STANDARD
- bool ' Reset SCSI-devices at boottime' CONFIG_IBMMCA_SCSI_DEV_RESET
- fi
-fi
-if [ "$CONFIG_MCA" = "y" ]; then
X dep_tristate 'NCR MCA 53C9x SCSI support' CONFIG_SCSI_MCA_53C9X $CONFIG_SCSI
X fi
X dep_tristate 'PAS16 SCSI support' CONFIG_SCSI_PAS16 $CONFIG_SCSI
@@ -151,6 +152,8 @@
X if [ "$CONFIG_X86" = "y" ]; then
X dep_tristate 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE $CONFIG_SCSI
X fi
+dep_tristate 'Simple 53c710 SCSI support (Compaq, NCR machines)' CONFIG_SCSI_SIM710 $CONFIG_SCSI
+dep_tristate 'Symbios 53c416 SCSI support' CONFIG_SCSI_SYM53C416 $CONFIG_SCSI
X if [ "$CONFIG_PCI" = "y" ]; then
X dep_tristate 'Tekram DC390(T) and Am53/79C974 SCSI support' CONFIG_SCSI_DC390T $CONFIG_SCSI
X if [ "$CONFIG_SCSI_DC390T" != "n" ]; then
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/Makefile linux/drivers/scsi/Makefile
--- v2.4.0-test8/linux/drivers/scsi/Makefile Tue Sep 19 16:37:04 2000
+++ linux/drivers/scsi/Makefile Wed Sep 20 13:12:13 2000
@@ -4,6 +4,8 @@
X # 30 May 2000, Christoph Hellwig <chhe...@gmx.net>
X # Rewritten to use lists instead of if-statements.
X #
+# 20 Sep 2000, Torben Mathiasen <t...@image.dk>
+# Changed link order to reflect new scsi initialization.
X
X O_TARGET := scsidrv.o
X
@@ -22,25 +24,14 @@
X endif
X
X export-objs := scsi_syms.o
-list-multi := scsi_mod.o sr_mod.o initio.o a100u2w.o
+list-multi := scsi_mod.o initio.o a100u2w.o
X
X CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF
X CFLAGS_gdth.o = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ -DGDTH_STATISTICS
X CFLAGS_seagate.o = -DARBITRATE -DPARITY -DSEAGATE_USE_ASM
X
-obj-$(CONFIG_SCSI) += scsi_mod.o
-obj-$(CONFIG_CHR_DEV_ST) += st.o
-obj-$(CONFIG_BLK_DEV_SD) += sd.o
-obj-$(CONFIG_BLK_DEV_SR) += sr_mod.o
-obj-$(CONFIG_CHR_DEV_SG) += sg.o
+obj-$(CONFIG_SCSI) += scsi_mod.o scsi_syms.o
X
-obj-$(CONFIG_SCSI_ADVANSYS) += advansys.o
-obj-$(CONFIG_SCSI_PCI2000) += pci2000.o
-obj-$(CONFIG_SCSI_PCI2220I) += pci2220i.o
-obj-$(CONFIG_SCSI_PSI240I) += psi240i.o
-obj-$(CONFIG_MVME16x_SCSI) += mvme16x.o 53c7xx.o
-obj-$(CONFIG_BVME6000_SCSI) += bvme6000.o 53c7xx.o
-obj-$(CONFIG_SCSI_SIM710) += sim710.o
X obj-$(CONFIG_A4000T_SCSI) += amiga7xx.o 53c7xx.o
X obj-$(CONFIG_A4091_SCSI) += amiga7xx.o 53c7xx.o
X obj-$(CONFIG_BLZ603EPLUS_SCSI) += amiga7xx.o 53c7xx.o
@@ -48,8 +39,6 @@
X obj-$(CONFIG_A3000_SCSI) += a3000.o wd33c93.o
X obj-$(CONFIG_A2091_SCSI) += a2091.o wd33c93.o
X obj-$(CONFIG_GVP11_SCSI) += gvp11.o wd33c93.o
-obj-$(CONFIG_SCSI_SGIWD93) += sgiwd93.o wd33c93.o
-obj-$(CONFIG_SCSI_MCA_53C9X) += NCR53C9x.o mca_53c9x.o
X obj-$(CONFIG_CYBERSTORM_SCSI) += NCR53C9x.o cyberstorm.o
X obj-$(CONFIG_CYBERSTORMII_SCSI) += NCR53C9x.o cyberstormII.o
X obj-$(CONFIG_BLZ2060_SCSI) += NCR53C9x.o blz2060.o
@@ -58,69 +47,82 @@
X obj-$(CONFIG_OKTAGON_SCSI) += NCR53C9x.o oktagon_esp.o oktagon_io.o
X obj-$(CONFIG_ATARI_SCSI) += atari_scsi.o
X obj-$(CONFIG_MAC_SCSI) += mac_scsi.o
-obj-$(CONFIG_SUN3_SCSI) += sun3_scsi.o
X obj-$(CONFIG_SCSI_MAC_ESP) += mac_esp.o NCR53C9x.o
-obj-$(CONFIG_SCSI_PPA) += ppa.o
-obj-$(CONFIG_SCSI_IMM) += imm.o
-obj-$(CONFIG_SCSI_QLOGIC_FAS) += qlogicfas.o
-obj-$(CONFIG_SCSI_QLOGIC_ISP) += qlogicisp.o
-obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o
-obj-$(CONFIG_SCSI_ACARD) += atp870u.o
-obj-$(CONFIG_SCSI_INITIO) += initio.o
-obj-$(CONFIG_SCSI_INIA100) += a100u2w.o
-obj-$(CONFIG_SCSI_QLOGIC_FC) += qlogicfc.o
+obj-$(CONFIG_SUN3_SCSI) += sun3_scsi.o
+obj-$(CONFIG_MVME16x_SCSI) += mvme16x.o 53c7xx.o
+obj-$(CONFIG_BVME6000_SCSI) += bvme6000.o 53c7xx.o
+obj-$(CONFIG_SCSI_SIM710) += sim710.o
+obj-$(CONFIG_SCSI_ADVANSYS) += advansys.o
+obj-$(CONFIG_SCSI_PCI2000) += pci2000.o
+obj-$(CONFIG_SCSI_PCI2220I) += pci2220i.o
+obj-$(CONFIG_SCSI_PSI240I) += psi240i.o
+obj-$(CONFIG_SCSI_BUSLOGIC) += BusLogic.o
+obj-$(CONFIG_SCSI_U14_34F) += u14-34f.o
+obj-$(CONFIG_SCSI_ULTRASTOR) += ultrastor.o
X obj-$(CONFIG_SCSI_AHA152X) += aha152x.o
X obj-$(CONFIG_SCSI_AHA1542) += aha1542.o
X obj-$(CONFIG_SCSI_AHA1740) += aha1740.o
X obj-$(CONFIG_SCSI_AIC7XXX) += aic7xxx.o
X obj-$(CONFIG_SCSI_IPS) += ips.o
-obj-$(CONFIG_SCSI_DC390T) += tmscsim.o
-obj-$(CONFIG_SCSI_AM53C974) += AM53C974.o
-obj-$(CONFIG_SCSI_BUSLOGIC) += BusLogic.o
-obj-$(CONFIG_SCSI_EATA_DMA) += eata_dma.o
-obj-$(CONFIG_SCSI_EATA_PIO) += eata_pio.o
-obj-$(CONFIG_SCSI_U14_34F) += u14-34f.o
-obj-$(CONFIG_SCSI_SUNESP) += esp.o
-obj-$(CONFIG_SCSI_QLOGICPTI) += qlogicpti.o
-obj-$(CONFIG_SCSI_MESH) += mesh.o
-obj-$(CONFIG_SCSI_MAC53C94) += mac53c94.o
-obj-$(CONFIG_SCSI_GDTH) += gdth.o
-
-obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o
-
+obj-$(CONFIG_SCSI_FD_MCS) += fd_mcs.o
X obj-$(CONFIG_SCSI_FUTURE_DOMAIN)+= fdomain.o
X obj-$(CONFIG_SCSI_IN2000) += in2000.o
X obj-$(CONFIG_SCSI_GENERIC_NCR5380) += g_NCR5380.o
-obj-$(CONFIG_SCSI_NCR53C7xx) += 53c7,8xx.o
-obj-$(CONFIG_SCSI_NCR53C8XX) += ncr53c8xx.o
-obj-$(CONFIG_SCSI_SYM53C8XX) += sym53c8xx.o
+obj-$(CONFIG_SCSI_NCR53C406A) += NCR53c406a.o
+obj-$(CONFIG_SCSI_SYM53C416) += sym53c416.o
+obj-$(CONFIG_SCSI_QLOGIC_FAS) += qlogicfas.o
+obj-$(CONFIG_SCSI_QLOGIC_ISP) += qlogicisp.o
+obj-$(CONFIG_SCSI_QLOGIC_FC) += qlogicfc.o
+obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o
X obj-$(CONFIG_SCSI_PAS16) += pas16.o
X obj-$(CONFIG_SCSI_SEAGATE) += seagate.o
X obj-$(CONFIG_SCSI_FD_8xx) += seagate.o
-obj-$(CONFIG_SCSI_7000FASST) += wd7000.o
-obj-$(CONFIG_SCSI_IBMMCA) += ibmmca.o
-obj-$(CONFIG_SCSI_FD_MCS) += fd_mcs.o
X obj-$(CONFIG_SCSI_T128) += t128.o
X obj-$(CONFIG_SCSI_DMX3191D) += dmx3191d.o
X obj-$(CONFIG_SCSI_DTC3280) += dtc.o
-obj-$(CONFIG_SCSI_ULTRASTOR) += ultrastor.o
-obj-$(CONFIG_SCSI_PLUTO) += pluto.o
-obj-$(CONFIG_SCSI_FCAL) += fcal.o
+obj-$(CONFIG_SCSI_NCR53C7xx) += 53c7,8xx.o
+obj-$(CONFIG_SCSI_SYM53C8XX) += sym53c8xx.o
+obj-$(CONFIG_SCSI_NCR53C8XX) += ncr53c8xx.o
+obj-$(CONFIG_SCSI_EATA_DMA) += eata_dma.o
+obj-$(CONFIG_SCSI_EATA_PIO) += eata_pio.o
+obj-$(CONFIG_SCSI_7000FASST) += wd7000.o
+obj-$(CONFIG_SCSI_MCA_53C9X) += NCR53C9x.o mca_53c9x.o
+obj-$(CONFIG_SCSI_IBMMCA) += ibmmca.o
X obj-$(CONFIG_SCSI_EATA) += eata.o
-obj-$(CONFIG_SCSI_NCR53C406A) += NCR53c406a.o
+obj-$(CONFIG_SCSI_DC390T) += tmscsim.o
+obj-$(CONFIG_SCSI_AM53C974) += AM53C974.o
X obj-$(CONFIG_SCSI_MEGARAID) += megaraid.o
-obj-$(CONFIG_SCSI_SYM53C416) += sym53c416.o
+obj-$(CONFIG_SCSI_ACARD) += atp870u.o
+obj-$(CONFIG_SCSI_SUNESP) += esp.o
+obj-$(CONFIG_SCSI_GDTH) += gdth.o
+obj-$(CONFIG_SCSI_INITIO) += initio.o
+obj-$(CONFIG_SCSI_INIA100) += a100u2w.o
+obj-$(CONFIG_SCSI_QLOGICPTI) += qlogicpti.o
X obj-$(CONFIG_BLK_DEV_IDESCSI) += ide-scsi.o
-obj-$(CONFIG_JAZZ_ESP) += NCR53C9x.o jazz_esp.o
+obj-$(CONFIG_SCSI_MESH) += mesh.o
+obj-$(CONFIG_SCSI_MAC53C94) += mac53c94.o
+obj-$(CONFIG_SCSI_PLUTO) += pluto.o
X obj-$(CONFIG_SCSI_DECNCR) += NCR53C9x.o dec_esp.o
-obj-$(CONFIG_SUN3X_ESP) += NCR53C9x.o sun3x_esp.o
X obj-$(CONFIG_BLK_DEV_3W_XXXX_RAID) += 3w-xxxx.o
+obj-$(CONFIG_SCSI_PPA) += ppa.o
+obj-$(CONFIG_SCSI_IMM) += imm.o
+obj-$(CONFIG_JAZZ_ESP) += NCR53C9x.o jazz_esp.o
+obj-$(CONFIG_SUN3X_ESP) += NCR53C9x.o sun3x_esp.o
+obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o
+obj-$(CONFIG_SCSI_FCAL) += fcal.o
+
+obj-$(CONFIG_CHR_DEV_ST) += st.o
+obj-$(CONFIG_BLK_DEV_SD) += sd_mod.o
+obj-$(CONFIG_BLK_DEV_SR) += sr_mod.o
+obj-$(CONFIG_CHR_DEV_SG) += sg.o
+
X
-scsi_mod-objs := hosts.o scsi.o scsi_ioctl.o constants.o \
+
+scsi_mod-objs := scsi.o hosts.o scsi_ioctl.o constants.o \
X scsicam.o scsi_proc.o scsi_error.o \
X scsi_obsolete.o scsi_queue.o scsi_lib.o \
X scsi_merge.o scsi_dma.o scsi_scan.o \
- scsi_syms.o
+
X sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o
X initio-objs := ini9100u.o i91uscsi.o
X a100u2w-objs := inia100.o i60uscsi.o
@@ -136,9 +138,6 @@
X obj-m := $(filter-out $(obj-y), $(obj-m))
X int-m := $(filter-out $(int-y), $(int-m))
X
-# Take multi-part drivers out of obj-y and put components in.
-obj-y := $(filter-out $(list-multi), $(obj-y)) $(int-y)
-
X O_OBJS := $(filter-out $(export-objs), $(obj-y))
X OX_OBJS := $(filter $(export-objs), $(obj-y))


X M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m)))

@@ -151,6 +150,9 @@
X
X scsi_mod.o: $(scsi_mod-objs)
X $(LD) -r -o $@ $(scsi_mod-objs)
+
+sd_mod.o: sd.o
+ $(LD) -r -o $@ sd.o
X
X sr_mod.o: $(sr_mod-objs)
X $(LD) -r -o $@ $(sr_mod-objs)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/NCR53c406a.c linux/drivers/scsi/NCR53c406a.c
--- v2.4.0-test8/linux/drivers/scsi/NCR53c406a.c Thu Nov 11 16:57:30 1999
+++ linux/drivers/scsi/NCR53c406a.c Mon Sep 18 13:36:24 2000
@@ -1059,12 +1059,10 @@
X /* CONFIG6 = (port_base+0x0F);*/
X }
X
-#ifdef MODULE
X /* Eventually this will go into an include file, but this will be later */
-Scsi_Host_Template driver_template = NCR53c406a;
+static Scsi_Host_Template driver_template = NCR53c406a;
X
X #include "scsi_module.c"
-#endif
X
X /*
X * Overrides for Emacs so that we get a uniform tabbing style.
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/a2091.c linux/drivers/scsi/a2091.c
--- v2.4.0-test8/linux/drivers/scsi/a2091.c Wed Jan 26 12:45:20 2000
+++ linux/drivers/scsi/a2091.c Mon Sep 18 13:36:24 2000
@@ -226,17 +226,13 @@
X return num_a2091;


X }
X
-#ifdef MODULE
-

X #define HOSTS_C
X
X #include "a2091.h"
X
-Scsi_Host_Template driver_template = A2091_SCSI;
+static Scsi_Host_Template driver_template = A2091_SCSI;
X
X #include "scsi_module.c"
-
-#endif
X
X int a2091_release(struct Scsi_Host *instance)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/a2091.h linux/drivers/scsi/a2091.h
--- v2.4.0-test8/linux/drivers/scsi/a2091.h Fri Sep 8 12:54:34 2000
+++ linux/drivers/scsi/a2091.h Mon Sep 18 14:12:01 2000
@@ -29,8 +29,6 @@
X #define CAN_QUEUE 16
X #endif
X
-#ifdef HOSTS_C
-
X #define A2091_SCSI { proc_name: "A2901", \
X name: "Commodore A2091/A590 SCSI", \
X detect: a2091_detect, \
@@ -43,7 +41,6 @@
X sg_tablesize: SG_ALL, \
X cmd_per_lun: CMD_PER_LUN, \
X use_clustering: DISABLE_CLUSTERING }
-#else
X
X /*
X * if the transfer address ANDed with this results in a non-zero
@@ -91,7 +88,5 @@
X #define ISTR_OE_INT (1<<2)
X #define ISTR_FF_FLG (1<<1)
X #define ISTR_FE_FLG (1<<0)
-
-#endif /* else def HOSTS_C */
X
X #endif /* A2091_H */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/a3000.c linux/drivers/scsi/a3000.c
--- v2.4.0-test8/linux/drivers/scsi/a3000.c Wed Jan 26 12:45:20 2000
+++ linux/drivers/scsi/a3000.c Mon Sep 18 13:36:24 2000
@@ -188,17 +188,13 @@


X return 1;
X }
X

-#ifdef MODULE
-
X #define HOSTS_C
X
X #include "a3000.h"
X
-Scsi_Host_Template driver_template = A3000_SCSI;
+static Scsi_Host_Template driver_template = A3000_SCSI;
X
X #include "scsi_module.c"
-
-#endif
X
X int a3000_release(struct Scsi_Host *instance)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/a3000.h linux/drivers/scsi/a3000.h
--- v2.4.0-test8/linux/drivers/scsi/a3000.h Fri Sep 8 12:54:34 2000
+++ linux/drivers/scsi/a3000.h Mon Sep 18 14:12:01 2000
@@ -29,8 +29,6 @@
X #define CAN_QUEUE 16
X #endif
X
-#ifdef HOSTS_C
-
X #define A3000_SCSI { proc_name: "A3000", \
X proc_info: NULL, \
X name: "Amiga 3000 built-in SCSI", \
@@ -44,7 +42,6 @@
X sg_tablesize: SG_ALL, \
X cmd_per_lun: CMD_PER_LUN, \
X use_clustering: ENABLE_CLUSTERING }
-#else
X
X /*
X * if the transfer address ANDed with this results in a non-zero
@@ -95,7 +92,5 @@
X #define ISTR_OE_INT (1<<2)
X #define ISTR_FF_FLG (1<<1)
X #define ISTR_FE_FLG (1<<0)
-
-#endif /* else def HOSTS_C */
X
X #endif /* A3000_H */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/advansys.c linux/drivers/scsi/advansys.c
--- v2.4.0-test8/linux/drivers/scsi/advansys.c Mon Jun 19 13:42:40 2000
+++ linux/drivers/scsi/advansys.c Mon Sep 18 13:36:25 2000
@@ -6785,10 +6785,8 @@
X * --- Loadable Driver Support
X */
X
-#ifdef MODULE
-Scsi_Host_Template driver_template = ADVANSYS;
+static Scsi_Host_Template driver_template = ADVANSYS;
X # include "scsi_module.c"
-#endif /* MODULE */
X
X
X /*
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/aha152x.c linux/drivers/scsi/aha152x.c
--- v2.4.0-test8/linux/drivers/scsi/aha152x.c Mon Jun 19 13:42:40 2000
+++ linux/drivers/scsi/aha152x.c Mon Sep 18 13:36:25 2000
@@ -3813,9 +3813,7 @@
X return thislength < length ? thislength : length;
X }
X
-#if defined(MODULE)
X /* Eventually this will go into an include file, but this will be later */
-Scsi_Host_Template driver_template = AHA152X;
+static Scsi_Host_Template driver_template = AHA152X;
X
X #include "scsi_module.c"
-#endif
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/aha1542.c linux/drivers/scsi/aha1542.c
--- v2.4.0-test8/linux/drivers/scsi/aha1542.c Fri Jan 28 08:04:58 2000
+++ linux/drivers/scsi/aha1542.c Mon Sep 18 13:36:25 2000
@@ -1764,9 +1764,7 @@
X }
X
X
-#ifdef MODULE
X /* Eventually this will go into an include file, but this will be later */
-Scsi_Host_Template driver_template = AHA1542;
+static Scsi_Host_Template driver_template = AHA1542;
X
X #include "scsi_module.c"
-#endif
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/aha1740.c linux/drivers/scsi/aha1740.c
--- v2.4.0-test8/linux/drivers/scsi/aha1740.c Thu Nov 11 16:57:30 1999
+++ linux/drivers/scsi/aha1740.c Mon Sep 18 13:36:25 2000
@@ -601,12 +601,10 @@


X return 0;
X }
X

-#ifdef MODULE
X /* Eventually this will go into an include file, but this will be later */
-Scsi_Host_Template driver_template = AHA1740;
+static Scsi_Host_Template driver_template = AHA1740;
X
X #include "scsi_module.c"
-#endif
X
X /* Okay, you made it all the way through. As of this writing, 3/31/93, I'm
X br...@saturn.gaylord.com or br...@bradpc.gaylord.com. I'll try to help as time
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/aic7xxx.c linux/drivers/scsi/aic7xxx.c
--- v2.4.0-test8/linux/drivers/scsi/aic7xxx.c Thu Aug 10 13:14:40 2000
+++ linux/drivers/scsi/aic7xxx.c Mon Sep 18 13:36:25 2000
@@ -12217,12 +12217,10 @@
X
X #include "aic7xxx_proc.c"
X
-#ifdef MODULE
X /* Eventually this will go into an include file, but this will be later */
-Scsi_Host_Template driver_template = AIC7XXX;
+static Scsi_Host_Template driver_template = AIC7XXX;
X
X #include "scsi_module.c"
-#endif
X
X /*
X * Overrides for Emacs so that we almost follow Linus's tabbing style.
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/amiga7xx.h linux/drivers/scsi/amiga7xx.h
--- v2.4.0-test8/linux/drivers/scsi/amiga7xx.h Fri Sep 8 12:54:34 2000
+++ linux/drivers/scsi/amiga7xx.h Mon Sep 18 14:09:49 2000
@@ -22,7 +22,6 @@
X #define CAN_QUEUE 24
X #endif


X
-#if defined(HOSTS_C) || defined(MODULE)
X #include <scsi/scsicam.h>
X

X #define AMIGA7XX_SCSI {name: "Amiga NCR53c710 SCSI", \
@@ -36,5 +35,5 @@
X sg_tablesize: 63, \


X cmd_per_lun: 3, \
X use_clustering: DISABLE_CLUSTERING }

-#endif
+
X #endif /* AMIGA7XX_H */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/atari_scsi.c linux/drivers/scsi/atari_scsi.c
--- v2.4.0-test8/linux/drivers/scsi/atari_scsi.c Thu Nov 11 16:57:30 1999
+++ linux/drivers/scsi/atari_scsi.c Mon Sep 18 13:36:25 2000
@@ -1126,8 +1126,5 @@
X
X #include "atari_NCR5380.c"
X
-#ifdef MODULE
-Scsi_Host_Template driver_template = ATARI_SCSI;
-
+static Scsi_Host_Template driver_template = ATARI_SCSI;
X #include "scsi_module.c"
-#endif
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/atari_scsi.h linux/drivers/scsi/atari_scsi.h
--- v2.4.0-test8/linux/drivers/scsi/atari_scsi.h Sun Dec 21 17:04:48 1997
+++ linux/drivers/scsi/atari_scsi.h Mon Sep 18 14:12:01 2000
@@ -51,8 +51,6 @@
X #define DEFAULT_USE_TAGGED_QUEUING 0
X
X
-#if defined (HOSTS_C) || defined (MODULE)
-
X #define ATARI_SCSI { proc_info: atari_scsi_proc_info, \
X name: "Atari native SCSI", \
X detect: atari_scsi_detect, \
@@ -67,10 +65,6 @@
X cmd_per_lun: 0, /* initialized at run-time */ \
X use_clustering: DISABLE_CLUSTERING }
X
-#endif
-
-#ifndef HOSTS_C
-
X #define NCR5380_implementation_fields /* none */
X
X #define NCR5380_read(reg) atari_scsi_reg_read( reg )
@@ -267,7 +261,6 @@
X #define NDEBUG_ANY 0xffffffff
X
X
-#endif /* else def HOSTS_C */
X #endif /* ndef ASM */
X #endif /* ATARI_SCSI_H */
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/atp870u.c linux/drivers/scsi/atp870u.c
--- v2.4.0-test8/linux/drivers/scsi/atp870u.c Fri Jul 7 15:55:24 2000
+++ linux/drivers/scsi/atp870u.c Mon Sep 18 13:36:25 2000
@@ -1971,8 +1971,5 @@
X
X }
X
-#ifdef MODULE
-Scsi_Host_Template driver_template = ATP870U;
-
+static Scsi_Host_Template driver_template = ATP870U;
X #include "scsi_module.c"
-#endif
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/blz1230.c linux/drivers/scsi/blz1230.c
--- v2.4.0-test8/linux/drivers/scsi/blz1230.c Fri Jan 28 08:04:58 2000
+++ linux/drivers/scsi/blz1230.c Mon Sep 18 13:36:25 2000
@@ -274,17 +274,13 @@
X }


X }
X
-#ifdef MODULE
-

X #define HOSTS_C
X
X #include "blz1230.h"
X
-Scsi_Host_Template driver_template = SCSI_BLZ1230;
+static Scsi_Host_Template driver_template = SCSI_BLZ1230;
X
X #include "scsi_module.c"
-
-#endif
X
X int blz1230_esp_release(struct Scsi_Host *instance)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/blz2060.c linux/drivers/scsi/blz2060.c
--- v2.4.0-test8/linux/drivers/scsi/blz2060.c Fri Jan 28 08:04:58 2000
+++ linux/drivers/scsi/blz2060.c Mon Sep 18 13:36:25 2000


@@ -236,17 +236,13 @@
X }

X }
X
-#ifdef MODULE
-

X #define HOSTS_C
X
X #include "blz2060.h"
X
-Scsi_Host_Template driver_template = SCSI_BLZ2060;
+static Scsi_Host_Template driver_template = SCSI_BLZ2060;
X
X #include "scsi_module.c"
-
-#endif
X
X int blz2060_esp_release(struct Scsi_Host *instance)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/bvme6000.h linux/drivers/scsi/bvme6000.h
--- v2.4.0-test8/linux/drivers/scsi/bvme6000.h Fri Sep 8 12:54:34 2000
+++ linux/drivers/scsi/bvme6000.h Mon Sep 18 14:09:49 2000
@@ -23,7 +23,6 @@
X #define CAN_QUEUE 24
X #endif


X
-#if defined(HOSTS_C) || defined(MODULE)
X #include <scsi/scsicam.h>
X

X #define BVME6000_SCSI {name: "BVME6000 NCR53c710 SCSI", \
@@ -37,5 +36,5 @@
X sg_tablesize: 63, \


X cmd_per_lun: 3, \
X use_clustering: DISABLE_CLUSTERING }

-#endif
+
X #endif /* BVME6000_SCSI_H */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/cpqfc.Readme linux/drivers/scsi/cpqfc.Readme
--- v2.4.0-test8/linux/drivers/scsi/cpqfc.Readme Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/cpqfc.Readme Tue Sep 19 08:01:34 2000
@@ -0,0 +1,216 @@
+Notes for CPQFCTS driver for Compaq Tachyon TS
+Fibre Channel Host Bus Adapter, PCI 64-bit, 66MHz
+for Linux (RH 6.1, 6.2 kernel 2.2.12-32, 2.2.14-5)
+SMP tested
+Tested in single and dual HBA configuration, 32 and 64bit busses,
+33 and 66MHz. Only supports FC-AL.
+SEST size 512 Exchanges (simultaneous I/Os) limited by module kmalloc()
+ max of 128k bytes contiguous.
+Ver 1.3.4 Sep 7, 2000
+ Added Modinfo information
+ Fixed problem with statically linking the driver
+
+Ver 1.3.3, Aug 23, 2000
+ Fixed device/function number in ioctl
+
+Ver 1.3.2, July 27, 2000
+ Add include for Alpha compile on 2.2.14 kernel (cpq*i2c.c)
+ Change logic for different FCP-RSP sense_buffer location for HSG80 target
+ And search for Agilent Tachyon XL2 HBAs (not finished! - in test)
+
+Tested with
+(storage):
+ Compaq RA-4x000, RAID firmware ver 2.40 - 2.54
+ Seagate FC drives model ST39102FC, rev 0006
+ Hitachi DK31CJ-72FC rev J8A8
+ IBM DDYF-T18350R rev F60K
+ Compaq FC-SCSI bridge w/ DLT 35/70 Gb DLT (tape)
+(servers):
+ Compaq PL-1850R
+ Compaq PL-6500 Xeon (400MHz)
+ Compaq PL-8500 (500MHz, 66MHz, 64bit PCI)
+ Compaq Alpha DS20 (RH 6.1)
+(hubs):
+ Vixel Rapport 1000 (7-port "dumb")
+ Gadzoox Gibralter (12-port "dumb")
+ Gadzoox Capellix 2000, 3000
+(switches):
+ Brocade 2010, 2400, 2800, rev 2.0.3a (& later)
+ Gadzoox 3210 (Fabric blade beta)
+ Vixel 7100 (Fabric beta firmare - known hot plug issues)
+using "qa_test" (esp. io_test script) suite modified from Unix tests.
+
+Installation:
+copy file cpqfcTS.patch to /usr/src/linux
+patch -p1 < cpqfcTS.patch
+make menuconfig
+ (select SCSI low-level, Compaq FC HBA)
+make dep
+make modules
+make modules_install
+
+e.g. insmod -f cpqfc
+
+Due to Fabric/switch delays, driver requires 4 seconds
+to initialize. If adapters are found, there will be a entries at
+/proc/scsi/cpqfcTS/*
+
+sample contents of startup messages
+
+*************************
+ scsi_register allocating 3596 bytes for CPQFCHBA
+ ioremap'd Membase: c887e600
+ HBA Tachyon RevId 1.2
+Allocating 119808 for 576 Exchanges @ c0dc0000
+Allocating 112904 for LinkQ @ c0c20000 (576 elements)
+Allocating 110600 for TachSEST for 512 Exchanges
+ cpqfcTS: writing IMQ BASE 7C0000h PI 7C4000h
+ cpqfcTS: SEST c0e40000(virt): Wrote base E40000h @ c887e740
+cpqfcTS: New FC port 0000E8h WWN: 500507650642499D SCSI Chan/Trgt 0/0
+cpqfcTS: New FC port 0000EFh WWN: 50000E100000D5A6 SCSI Chan/Trgt 0/1
+cpqfcTS: New FC port 0000E4h WWN: 21000020370097BB SCSI Chan/Trgt 0/2
+cpqfcTS: New FC port 0000E2h WWN: 2100002037009946 SCSI Chan/Trgt 0/3
+cpqfcTS: New FC port 0000E1h WWN: 21000020370098FE SCSI Chan/Trgt 0/4
+cpqfcTS: New FC port 0000E0h WWN: 21000020370097B2 SCSI Chan/Trgt 0/5
+cpqfcTS: New FC port 0000DCh WWN: 2100002037006CC1 SCSI Chan/Trgt 0/6
+cpqfcTS: New FC port 0000DAh WWN: 21000020370059F6 SCSI Chan/Trgt 0/7
+cpqfcTS: New FC port 00000Fh WWN: 500805F1FADB0E20 SCSI Chan/Trgt 0/8
+cpqfcTS: New FC port 000008h WWN: 500805F1FADB0EBA SCSI Chan/Trgt 0/9
+cpqfcTS: New FC port 000004h WWN: 500805F1FADB1EB9 SCSI Chan/Trgt 0/10
+cpqfcTS: New FC port 000002h WWN: 500805F1FADB1ADE SCSI Chan/Trgt 0/11
+cpqfcTS: New FC port 000001h WWN: 500805F1FADBA2CA SCSI Chan/Trgt 0/12
+scsi4 : Compaq FibreChannel HBA Tachyon TS HPFC-5166A/1.2: WWN 500508B200193F50
+ on PCI bus 0 device 0xa0fc irq 5 IObaseL 0x3400, MEMBASE 0xc6ef8600
+PCI bus width 32 bits, bus speed 33 MHz
+FCP-SCSI Driver v1.3.0
+GBIC detected: Short-wave. LPSM 0h Monitor
+scsi : 5 hosts.
+ Vendor: IBM Model: DDYF-T18350R Rev: F60K
+ Type: Direct-Access ANSI SCSI revision: 03
+Detected scsi disk sdb at scsi4, channel 0, id 0, lun 0
+ Vendor: HITACHI Model: DK31CJ-72FC Rev: J8A8
+ Type: Direct-Access ANSI SCSI revision: 02
+Detected scsi disk sdc at scsi4, channel 0, id 1, lun 0
+ Vendor: SEAGATE Model: ST39102FC Rev: 0006
+ Type: Direct-Access ANSI SCSI revision: 02
+Detected scsi disk sdd at scsi4, channel 0, id 2, lun 0
+ Vendor: SEAGATE Model: ST39102FC Rev: 0006
+ Type: Direct-Access ANSI SCSI revision: 02
+Detected scsi disk sde at scsi4, channel 0, id 3, lun 0
+ Vendor: SEAGATE Model: ST39102FC Rev: 0006
+ Type: Direct-Access ANSI SCSI revision: 02
+Detected scsi disk sdf at scsi4, channel 0, id 4, lun 0
+ Vendor: SEAGATE Model: ST39102FC Rev: 0006
+ Type: Direct-Access ANSI SCSI revision: 02
+Detected scsi disk sdg at scsi4, channel 0, id 5, lun 0
+ Vendor: SEAGATE Model: ST39102FC Rev: 0006
+ Type: Direct-Access ANSI SCSI revision: 02
+Detected scsi disk sdh at scsi4, channel 0, id 6, lun 0
+ Vendor: SEAGATE Model: ST39102FC Rev: 0006
+ Type: Direct-Access ANSI SCSI revision: 02
+Detected scsi disk sdi at scsi4, channel 0, id 7, lun 0
+ Vendor: COMPAQ Model: LOGICAL VOLUME Rev: 2.48
+ Type: Direct-Access ANSI SCSI revision: 02
+Detected scsi disk sdj at scsi4, channel 0, id 8, lun 0
+ Vendor: COMPAQ Model: LOGICAL VOLUME Rev: 2.48
+ Type: Direct-Access ANSI SCSI revision: 02
+Detected scsi disk sdk at scsi4, channel 0, id 8, lun 1
+ Vendor: COMPAQ Model: LOGICAL VOLUME Rev: 2.40
+ Type: Direct-Access ANSI SCSI revision: 02
+Detected scsi disk sdl at scsi4, channel 0, id 9, lun 0
+ Vendor: COMPAQ Model: LOGICAL VOLUME Rev: 2.40
+ Type: Direct-Access ANSI SCSI revision: 02
+Detected scsi disk sdm at scsi4, channel 0, id 9, lun 1
+ Vendor: COMPAQ Model: LOGICAL VOLUME Rev: 2.54
+ Type: Direct-Access ANSI SCSI revision: 02
+Detected scsi disk sdn at scsi4, channel 0, id 10, lun 0
+ Vendor: COMPAQ Model: LOGICAL VOLUME Rev: 2.54
+ Type: Direct-Access ANSI SCSI revision: 02
+Detected scsi disk sdo at scsi4, channel 0, id 11, lun 0
+ Vendor: COMPAQ Model: LOGICAL VOLUME Rev: 2.54
+ Type: Direct-Access ANSI SCSI revision: 02
+Detected scsi disk sdp at scsi4, channel 0, id 11, lun 1
+ Vendor: COMPAQ Model: LOGICAL VOLUME Rev: 2.54
+ Type: Direct-Access ANSI SCSI revision: 02
+Detected scsi disk sdq at scsi4, channel 0, id 12, lun 0
+ Vendor: COMPAQ Model: LOGICAL VOLUME Rev: 2.54
+ Type: Direct-Access ANSI SCSI revision: 02
+Detected scsi disk sdr at scsi4, channel 0, id 12, lun 1
+resize_dma_pool: unknown device type 12
+resize_dma_pool: unknown device type 12
+SCSI device sdb: hdwr sector= 512 bytes. Sectors= 35843670 [17501 MB] [17.5 GB]
+ sdb: sdb1
+SCSI device sdc: hdwr sector= 512 bytes. Sectors= 144410880 [70513 MB] [70.5 GB]
+ sdc: sdc1
+SCSI device sdd: hdwr sector= 512 bytes. Sectors= 17783240 [8683 MB] [8.7 GB]
+ sdd: sdd1
+SCSI device sde: hdwr sector= 512 bytes. Sectors= 17783240 [8683 MB] [8.7 GB]
+ sde: sde1
+SCSI device sdf: hdwr sector= 512 bytes. Sectors= 17783240 [8683 MB] [8.7 GB]
+ sdf: sdf1
+SCSI device sdg: hdwr sector= 512 bytes. Sectors= 17783240 [8683 MB] [8.7 GB]
+ sdg: sdg1
+SCSI device sdh: hdwr sector= 512 bytes. Sectors= 17783240 [8683 MB] [8.7 GB]
+ sdh: sdh1
+SCSI device sdi: hdwr sector= 512 bytes. Sectors= 17783240 [8683 MB] [8.7 GB]
+ sdi: sdi1
+SCSI device sdj: hdwr sector= 512 bytes. Sectors= 2056160 [1003 MB] [1.0 GB]
+ sdj: sdj1
+SCSI device sdk: hdwr sector= 512 bytes. Sectors= 2052736 [1002 MB] [1.0 GB]
+ sdk: sdk1
+SCSI device sdl: hdwr sector= 512 bytes. Sectors= 17764320 [8673 MB] [8.7 GB]
+ sdl: sdl1
+SCSI device sdm: hdwr sector= 512 bytes. Sectors= 8380320 [4091 MB] [4.1 GB]
+ sdm: sdm1
+SCSI device sdn: hdwr sector= 512 bytes. Sectors= 17764320 [8673 MB] [8.7 GB]
+ sdn: sdn1
+SCSI device sdo: hdwr sector= 512 bytes. Sectors= 17764320 [8673 MB] [8.7 GB]
+ sdo: sdo1
+SCSI device sdp: hdwr sector= 512 bytes. Sectors= 17764320 [8673 MB] [8.7 GB]
+ sdp: sdp1
+SCSI device sdq: hdwr sector= 512 bytes. Sectors= 2056160 [1003 MB] [1.0 GB]
+ sdq: sdq1
+SCSI device sdr: hdwr sector= 512 bytes. Sectors= 2052736 [1002 MB] [1.0 GB]
+ sdr: sdr1
+
+*************************
+
+If a GBIC of type Short-wave, Long-wave, or Copper is detected, it will
+print out; otherwise, "none" is displayed. If the cabling is correct
+and a loop circuit is completed, you should see "Monitor"; otherwise,
+"LoopFail" (on open circuit) or some LPSM number/state with bit 3 set.
+
+
+ERRATA:
+1. Normally, Linux Scsi queries FC devices with INQUIRY strings. All LUNs
+found according to INQUIRY should get READ commands at sector 0 to find
+partition table, etc. Older kernels only query the first 4 devices. Some
+Linux kernels only look for one LUN per target (i.e. FC device).
+
+2. Physically removing a device, or a malfunctioning system which hides a
+device, leads to a 30-second timeout and subsequent _abort call.
+In some process contexts, this will hang the kernel (crashing the system).
+Single bit errors in frames and virtually all hot plugging events are
+gracefully handled with internal driver timer and Abort processing.
+
+3. Some SCSI drives with error conditions will not handle the 7 second timeout
+in this software driver, leading to infinite retries on timed out SCSI commands.
+The 7 secs balances the need to quickly recover from lost frames (esp. on sequence
+initiatives) and time needed by older/slower/error-state drives in responding.
+This can be easily changed in "Exchanges[].timeOut".
+
+4. Due to the nature of FC soft addressing, there is no assurance that the
+same LUNs (drives) will have the same path (e.g. /dev/sdb1) from one boot to
+next. Dynamic soft address changes (i.e. 24-bit FC port_id) are
+supported during run time (e.g. due to hot plug event) by the use of WWN to
+SCSI Nexus (channel/target/LUN) mapping.
+
+5. Compaq RA4x00 firmware version 2.54 and later supports SSP (Selective
+Storage Presentation), which maps LUNs to a WWN. If RA4x00 firmware prior
+2.54 (e.g. older controller) is used, or the FC HBA is replaced (another WWN
+is used), logical volumes on the RA4x00 will no longer be visible.
+
+
+Send questions/comments to:
+donald.z...@compaq.com
+dszim...@yahoo.com
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/cpqfcTS.h linux/drivers/scsi/cpqfcTS.h
--- v2.4.0-test8/linux/drivers/scsi/cpqfcTS.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/cpqfcTS.h Tue Sep 19 08:01:34 2000
@@ -0,0 +1,39 @@
+#ifndef CPQFCTS_H
+#define CPQFCTS_H
+#include "cpqfcTSstructs.h"
+
+// These functions are required by the Linux SCSI layers
+extern int cpqfcTS_detect(Scsi_Host_Template *);
+extern int cpqfcTS_release(struct Scsi_Host *);
+const char * cpqfcTS_info(struct Scsi_Host *);
+extern int cpqfcTS_proc_info(char *, char **, off_t, int, int, int);
+extern int cpqfcTS_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
+extern int cpqfcTS_abort(Scsi_Cmnd *);
+extern int cpqfcTS_reset(Scsi_Cmnd *, unsigned int);
+extern int cpqfcTS_biosparam(Disk *, kdev_t, int[]);
+extern int cpqfcTS_ioctl( Scsi_Device *ScsiDev, int Cmnd, void *arg);
+
+// note: since Tachyon TS supports an extended scatter/gather
+// linked list of infinite length (with linked Ext S/G pages,
+// limited only by available physical memory) we use SG_ALL.
+
+#define CPQFCTS { \
+ detect: cpqfcTS_detect, \
+ release: cpqfcTS_release, \
+ info: cpqfcTS_info, \
+ proc_info: cpqfcTS_proc_info, \
+ ioctl: cpqfcTS_ioctl, \
+ queuecommand: cpqfcTS_queuecommand, \
+ eh_abort_handler: cpqfcTS_abort, \
+ reset: cpqfcTS_reset, \
+ bios_param: cpqfcTS_biosparam, \
+ can_queue: CPQFCTS_REQ_QUEUE_LEN, \
+ this_id: -1, \
+ sg_tablesize: SG_ALL, \
+ cmd_per_lun: CPQFCTS_CMD_PER_LUN, \
+ present: 0, \
+ unchecked_isa_dma: 0, \
+ use_clustering: ENABLE_CLUSTERING \
+}
+
+#endif /* CPQFCTS_H */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/cpqfcTSchip.h linux/drivers/scsi/cpqfcTSchip.h
--- v2.4.0-test8/linux/drivers/scsi/cpqfcTSchip.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/cpqfcTSchip.h Tue Sep 19 08:01:34 2000
@@ -0,0 +1,238 @@
+/* Copyright(c) 2000, Compaq Computer Corporation
+ * Fibre Channel Host Bus Adapter
+ * 64-bit, 66MHz PCI
+ * Originally developed and tested on:
+ * (front): [chip] Tachyon TS HPFC-5166A/1.2 L2C1090 ...
+ * SP# P225CXCBFIEL6T, Rev XC
+ * SP# 161290-001, Rev XD
+ * (back): Board No. 010008-001 A/W Rev X5, FAB REV X5


+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the

+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ * Written by Don Zimmerman
+*/
+#ifndef CPQFCTSCHIP_H
+#define CPQFCTSCHIP_H
+#ifndef TACHYON_CHIP_INC
+
+// FC-PH (Physical) specification levels for Login payloads
+// NOTE: These are NOT strictly complied with by any FC vendors
+
+#define FC_PH42 0x08
+#define FC_PH43 0x09
+#define FC_PH3 0x20
+
+#define TACHLITE_TS_RX_SIZE 1024 // max inbound frame size
+// "I" prefix is for Include
+
+#define IVENDID 0x00 // word
+#define IDEVID 0x02
+#define ITLCFGCMD 0x04
+#define IMEMBASE 0x18 // Tachyon
+#define ITLMEMBASE 0x1C // Tachlite
+#define IIOBASEL 0x10 // Tachyon I/O base address, lower 256 bytes
+#define IIOBASEU 0x14 // Tachyon I/O base address, upper 256 bytes
+#define ITLIOBASEL 0x14 // TachLite I/O base address, lower 256 bytes
+#define ITLIOBASEU 0x18 // TachLite I/O base address, upper 256 bytes
+#define ITLRAMBASE 0x20 // TL on-board RAM start
+#define ISROMBASE 0x24
+#define IROMBASE 0x30
+
+#define ICFGCMD 0x04 // PCI config - PCI config access (word)
+#define ICFGSTAT 0x06 // PCI status (R - word)
+#define IRCTR_WCTR 0x1F2 // ROM control / pre-fetch wait counter
+#define IPCIMCTR 0x1F3 // PCI master control register
+#define IINTPEND 0x1FD // Interrupt pending (I/O Upper - Tachyon & TL)
+#define IINTEN 0x1FE // Interrupt enable (I/O Upper - Tachyon & TL)
+#define IINTSTAT 0x1FF // Interrupt status (I/O Upper - Tachyon & TL)
+
+#define IMQ_BASE 0x80
+#define IMQ_LENGTH 0x84
+#define IMQ_CONSUMER_INDEX 0x88
+#define IMQ_PRODUCER_INDEX 0x8C // Tach copies its INDX to bits 0-7 of value
+
+/*
+// IOBASE UPPER
+#define SFSBQ_BASE 0x00 // single-frame sequences
+#define SFSBQ_LENGTH 0x04
+#define SFSBQ_PRODUCER_INDEX 0x08
+#define SFSBQ_CONSUMER_INDEX 0x0C // (R)
+#define SFS_BUFFER_LENGTH 0X10
+ // SCSI-FCP hardware assists
+#define SEST_BASE 0x40 // SSCI Exchange State Table
+#define SEST_LENGTH 0x44
+#define SCSI_BUFFER_LENGTH 0x48
+#define SEST_LINKED_LIST 0x4C
+
+#define TACHYON_My_ID 0x6C
+#define TACHYON_CONFIGURATION 0x84 // (R/W) reset val 2
+#define TACHYON_CONTROL 0x88
+#define TACHYON_STATUS 0x8C // (R)
+#define TACHYON_FLUSH_SEST 0x90 // (R/W)
+#define TACHYON_EE_CREDIT_TMR 0x94 // (R)
+#define TACHYON_BB_CREDIT_TMR 0x98 // (R)
+#define TACHYON_RCV_FRAME_ERR 0x9C // (R)
+#define FRAME_MANAGER_CONFIG 0xC0 // (R/W)
+#define FRAME_MANAGER_CONTROL 0xC4
+#define FRAME_MANAGER_STATUS 0xC8 // (R)
+#define FRAME_MANAGER_ED_TOV 0xCC
+#define FRAME_MANAGER_LINK_ERR1 0xD0 // (R)
+#define FRAME_MANAGER_LINK_ERR2 0xD4 // (R)
+#define FRAME_MANAGER_TIMEOUT2 0xD8 // (W)
+#define FRAME_MANAGER_BB_CREDIT 0xDC // (R)
+#define FRAME_MANAGER_WWN_HI 0xE0 // (R/W)
+#define FRAME_MANAGER_WWN_LO 0xE4 // (R/W)
+#define FRAME_MANAGER_RCV_AL_PA 0xE8 // (R)
+#define FRAME_MANAGER_PRIMITIVE 0xEC // {K28.5} byte1 byte2 byte3
+*/
+
+#define TL_MEM_ERQ_BASE 0x0 //ERQ Base
+#define TL_IO_ERQ_BASE 0x0 //ERQ base
+
+#define TL_MEM_ERQ_LENGTH 0x4 //ERQ Length
+#define TL_IO_ERQ_LENGTH 0x4 //ERQ Length
+
+#define TL_MEM_ERQ_PRODUCER_INDEX 0x8 //ERQ Producer Index register
+#define TL_IO_ERQ_PRODUCER_INDEX 0x8 //ERQ Producer Index register
+
+#define TL_MEM_ERQ_CONSUMER_INDEX_ADR 0xC //ERQ Consumer Index address register
+#define TL_IO_ERQ_CONSUMER_INDEX_ADR 0xC //ERQ Consumer Index address register
+
+#define TL_MEM_ERQ_CONSUMER_INDEX 0xC //ERQ Consumer Index
+#define TL_IO_ERQ_CONSUMER_INDEX 0xC //ERQ Consumer Index
+
+#define TL_MEM_SFQ_BASE 0x50 //SFQ Base
+#define TL_IO_SFQ_BASE 0x50 //SFQ base
+
+#define TL_MEM_SFQ_LENGTH 0x54 //SFQ Length
+#define TL_IO_SFQ_LENGTH 0x54 //SFQ Length
+
+#define TL_MEM_SFQ_CONSUMER_INDEX 0x58 //SFQ Consumer Index
+#define TL_IO_SFQ_CONSUMER_INDEX 0x58 //SFQ Consumer Index
+
+#define TL_MEM_IMQ_BASE 0x80 //IMQ Base
+#define TL_IO_IMQ_BASE 0x80 //IMQ base
+
+#define TL_MEM_IMQ_LENGTH 0x84 //IMQ Length
+#define TL_IO_IMQ_LENGTH 0x84 //IMQ Length
+
+#define TL_MEM_IMQ_CONSUMER_INDEX 0x88 //IMQ Consumer Index
+#define TL_IO_IMQ_CONSUMER_INDEX 0x88 //IMQ Consumer Index
+
+#define TL_MEM_IMQ_PRODUCER_INDEX_ADR 0x8C //IMQ Producer Index address register
+#define TL_IO_IMQ_PRODUCER_INDEX_ADR 0x8C //IMQ Producer Index address register
+
+#define TL_MEM_SEST_BASE 0x140 //SFQ Base
+#define TL_IO_SEST_BASE 0x40 //SFQ base
+
+#define TL_MEM_SEST_LENGTH 0x144 //SFQ Length
+#define TL_IO_SEST_LENGTH 0x44 //SFQ Length
+
+#define TL_MEM_SEST_LINKED_LIST 0x14C
+
+#define TL_MEM_SEST_SG_PAGE 0x168 // Extended Scatter/Gather page size
+
+#define TL_MEM_TACH_My_ID 0x16C
+#define TL_IO_TACH_My_ID 0x6C //My AL_PA ID
+
+#define TL_MEM_TACH_CONFIG 0x184 //Tachlite Configuration register
+#define TL_IO_CONFIG 0x84 //Tachlite Configuration register
+
+#define TL_MEM_TACH_CONTROL 0x188 //Tachlite Control register
+#define TL_IO_CTR 0x88 //Tachlite Control register
+
+#define TL_MEM_TACH_STATUS 0x18C //Tachlite Status register
+#define TL_IO_STAT 0x8C //Tachlite Status register
+
+#define TL_MEM_FM_CONFIG 0x1C0 //Frame Manager Configuration register
+#define TL_IO_FM_CONFIG 0xC0 //Frame Manager Configuration register
+
+#define TL_MEM_FM_CONTROL 0x1C4 //Frame Manager Control
+#define TL_IO_FM_CTL 0xC4 //Frame Manager Control
+
+#define TL_MEM_FM_STATUS 0x1C8 //Frame Manager Status
+#define TL_IO_FM_STAT 0xC8 //Frame Manager Status
+
+#define TL_MEM_FM_LINK_STAT1 0x1D0 //Frame Manager Link Status 1
+#define TL_IO_FM_LINK_STAT1 0xD0 //Frame Manager Link Status 1
+
+#define TL_MEM_FM_LINK_STAT2 0x1D4 //Frame Manager Link Status 2
+#define TL_IO_FM_LINK_STAT2 0xD4 //Frame Manager Link Status 2
+
+#define TL_MEM_FM_TIMEOUT2 0x1D8 // (W)
+
+#define TL_MEM_FM_BB_CREDIT0 0x1DC
+
+#define TL_MEM_FM_WWN_HI 0x1E0 //Frame Manager World Wide Name High
+#define TL_IO_FM_WWN_HI 0xE0 //Frame Manager World Wide Name High
+
+#define TL_MEM_FM_WWN_LO 0x1E4 //Frame Manager World Wide Name LOW
+#define TL_IO_FM_WWN_LO 0xE4 //Frame Manager World Wide Name Low
+
+#define TL_MEM_FM_RCV_AL_PA 0x1E8 //Frame Manager AL_PA Received register
+#define TL_IO_FM_ALPA 0xE8 //Frame Manager AL_PA Received register
+
+#define TL_MEM_FM_ED_TOV 0x1CC
+
+#define TL_IO_ROMCTR 0xFA //TL PCI ROM Control Register
+#define TL_IO_PCIMCTR 0xFB //TL PCI Master Control Register
+#define TL_IO_SOFTRST 0xFC //Tachlite Configuration register
+#define TL_MEM_SOFTRST 0x1FC //Tachlite Configuration register
+
+// completion message types (bit 8 set means Interrupt generated)
+// CM_Type
+#define OUTBOUND_COMPLETION 0
+#define ERROR_IDLE_COMPLETION 0x01
+#define OUT_HI_PRI_COMPLETION 0x01
+#define INBOUND_MFS_COMPLETION 0x02
+#define INBOUND_000_COMPLETION 0x03
+#define INBOUND_SFS_COMPLETION 0x04 // Tachyon & TachLite
+#define ERQ_FROZEN_COMPLETION 0x06 // TachLite
+#define INBOUND_C1_TIMEOUT 0x05
+#define INBOUND_BUSIED_FRAME 0x06
+#define SFS_BUF_WARN 0x07
+#define FCP_FROZEN_COMPLETION 0x07 // TachLite
+#define MFS_BUF_WARN 0x08
+#define IMQ_BUF_WARN 0x09
+#define FRAME_MGR_INTERRUPT 0x0A
+#define READ_STATUS 0x0B
+#define INBOUND_SCSI_DATA_COMPLETION 0x0C
+#define INBOUND_FCP_XCHG_COMPLETION 0x0C // TachLite
+#define INBOUND_SCSI_DATA_COMMAND 0x0D
+#define BAD_SCSI_FRAME 0x0E
+#define INB_SCSI_STATUS_COMPLETION 0x0F
+#define BUFFER_PROCESSED_COMPLETION 0x11
+
+// FC-AL (Tachyon) Loop Port State Machine defs
+// (loop "Up" states)
+#define MONITORING 0x0
+#define ARBITRATING 0x1
+#define ARBITRAT_WON 0x2
+#define OPEN 0x3
+#define OPENED 0x4
+#define XMITTD_CLOSE 0x5
+#define RCVD_CLOSE 0x6
+#define TRANSFER 0x7
+
+// (loop "Down" states)
+#define INITIALIZING 0x8
+#define O_I_INIT 0x9
+#define O_I_PROTOCOL 0xa
+#define O_I_LIP_RCVD 0xb
+#define HOST_CONTROL 0xc
+#define LOOP_FAIL 0xd
+// (no 0xe)
+#define OLD_PORT 0xf
+
+
+
+#define TACHYON_CHIP_INC
+#endif
+#endif /* CPQFCTSCHIP_H */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/cpqfcTScontrol.c linux/drivers/scsi/cpqfcTScontrol.c
--- v2.4.0-test8/linux/drivers/scsi/cpqfcTScontrol.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/cpqfcTScontrol.c Tue Sep 19 08:01:34 2000
@@ -0,0 +1,2200 @@
+/* Copyright 2000, Compaq Computer Corporation
+ * Fibre Channel Host Bus Adapter
+ * 64-bit, 66MHz PCI
+ * Originally developed and tested on:
+ * (front): [chip] Tachyon TS HPFC-5166A/1.2 L2C1090 ...
+ * SP# P225CXCBFIEL6T, Rev XC
+ * SP# 161290-001, Rev XD
+ * (back): Board No. 010008-001 A/W Rev X5, FAB REV X5


+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the

+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ * Written by Don Zimmerman
+*/
+/* These functions control the host bus adapter (HBA) hardware. The main chip
+ control takes place in the interrupt handler where we process the IMQ
+ (Inbound Message Queue). The IMQ is Tachyon's way of communicating FC link
+ events and state information to the driver. The Single Frame Queue (SFQ)
+ buffers incoming FC frames for processing by the driver. References to
+ "TL/TS UG" are for:
+ "HP HPFC-5100/5166 Tachyon TL/TS ICs User Guide", August 16, 1999, 1st Ed.
+ Hewlitt Packard Manual Part Number 5968-1083E.
+*/
+
+#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
+
+#include <linux/blk.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/ioport.h> // request_region() prototype
+#include <linux/sched.h>
+#include <linux/malloc.h> // need "kfree" for ext. S/G pages
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/unistd.h>
+#include <asm/io.h> // struct pt_regs for IRQ handler & Port I/O
+#include <asm/irq.h>
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,18)
+#include <asm/spinlock.h>
+#else
+#include <linux/spinlock.h>
+#endif
+
+#include "sd.h"
+#include "hosts.h" // Scsi_Host definition for INT handler
+#include "cpqfcTSchip.h"
+#include "cpqfcTSstructs.h"
+
+//#define IMQ_DEBUG 1
+
+static void fcParseLinkStatusCounters(TACHYON * fcChip);
+static void CpqTsGetSFQEntry(TACHYON * fcChip,
+ USHORT pi, ULONG * buffr, BOOLEAN UpdateChip);
+
+
+// Note special requirements for Q alignment! (TL/TS UG pg. 190)
+// We place critical index pointers at end of QUE elements to assist
+// in non-symbolic (i.e. memory dump) debugging
+// opcode defines placement of Queues (e.g. local/external RAM)
+
+int CpqTsCreateTachLiteQues( void* pHBA, int opcode)
+{
+ CPQFCHBA *cpqfcHBAdata = (CPQFCHBA*)pHBA;
+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;
+
+ int iStatus=0;
+ unsigned long ulAddr;
+
+
+ // NOTE! fcMemManager() will return system virtual addresses.
+ // System (kernel) virtual addresses, though non-paged, still
+ // aren't physical addresses. Convert to PHYSICAL_ADDRESS for Tachyon's
+ // DMA use.
+ ENTER("CreateTachLiteQues");
+
+
+ // Allocate primary EXCHANGES array...
+
+ printk("Allocating %u for %u Exchanges ",
+ (ULONG)sizeof(FC_EXCHANGES), TACH_MAX_XID);
+ fcChip->Exchanges = kmalloc( sizeof( FC_EXCHANGES), GFP_KERNEL );
+ printk("@ %p\n", fcChip->Exchanges);
+
+ if( fcChip->Exchanges == NULL ) // fatal error!!
+ {
+ printk("kmalloc failure on Exchanges: fatal error\n");
+ return -1;
+ }
+ // zero out the entire EXCHANGE space
+ memset( fcChip->Exchanges, 0, sizeof( FC_EXCHANGES));
+
+
+ printk("Allocating %u for LinkQ ", (ULONG)sizeof(FC_LINK_QUE));
+ cpqfcHBAdata->fcLQ = kmalloc( sizeof( FC_LINK_QUE), GFP_KERNEL );
+ printk("@ %p (%u elements)\n", cpqfcHBAdata->fcLQ, FC_LINKQ_DEPTH);
+ memset( cpqfcHBAdata->fcLQ, 0, sizeof( FC_LINK_QUE));
+
+ if( cpqfcHBAdata->fcLQ == NULL ) // fatal error!!
+ {
+ printk("kmalloc failure on fc Link Que: fatal error\n");
+ return -1;
+ }
+ // zero out the entire EXCHANGE space
+ memset( cpqfcHBAdata->fcLQ, 0, sizeof( FC_LINK_QUE));
+
+
+
+
+ // Verify that basic Tach I/O registers are not NULL
+
+ if( !fcChip->Registers.ReMapMemBase )
+ {
+ printk("HBA base address NULL: fatal error\n");


+ return -1;
+ }
+
+

+ // Initialize the fcMemManager memory pairs (stores allocated/aligned
+ // pairs for future freeing)
+ memset( cpqfcHBAdata->dynamic_mem, 0, sizeof(cpqfcHBAdata->dynamic_mem));
+
+
+ // Allocate Tach's Exchange Request Queue (each ERQ entry 32 bytes)
+
+ fcChip->ERQ = fcMemManager( &cpqfcHBAdata->dynamic_mem[0],
+ sizeof( TachLiteERQ ), 32*(ERQ_LEN), 0L );
+ if( !fcChip->ERQ )
+ {
+ printk("kmalloc/alignment failure on ERQ: fatal error\n");
+ return -1;
+ }
+ fcChip->ERQ->length = ERQ_LEN-1;
+ ulAddr = virt_to_bus( fcChip->ERQ);
+#if BITS_PER_LONG > 32
+ if( (ulAddr >> 32) )
+ {
+ printk(" FATAL! ERQ ptr %p exceeds Tachyon's 32-bit register size\n",
+ (void*)ulAddr);
+ return -1; // failed
+ }
+#endif
+ fcChip->ERQ->base = (ULONG)ulAddr; // copy for quick reference
+
+
+ // Allocate Tach's Inbound Message Queue (32 bytes per entry)
+
+ fcChip->IMQ = fcMemManager( &cpqfcHBAdata->dynamic_mem[0],
+ sizeof( TachyonIMQ ), 32*(IMQ_LEN), 0L );
+ if( !fcChip->IMQ )
+ {
+ printk("kmalloc/alignment failure on IMQ: fatal error\n");
+ return -1;
+ }
+ fcChip->IMQ->length = IMQ_LEN-1;
+
+ ulAddr = virt_to_bus( fcChip->IMQ);
+#if BITS_PER_LONG > 32
+ if( (ulAddr >> 32) )
+ {
+ printk(" FATAL! IMQ ptr %p exceeds Tachyon's 32-bit register size\n",
+ (void*)ulAddr);
+ return -1; // failed
+ }
+#endif
+ fcChip->IMQ->base = (ULONG)ulAddr; // copy for quick reference
+
+
+ // Allocate Tach's Single Frame Queue (64 bytes per entry)
+ fcChip->SFQ = fcMemManager( &cpqfcHBAdata->dynamic_mem[0],
+ sizeof( TachLiteSFQ ), 64*(SFQ_LEN),0L );
+ if( !fcChip->SFQ )
+ {
+ printk("kmalloc/alignment failure on SFQ: fatal error\n");
+ return -1;
+ }
+ fcChip->SFQ->length = SFQ_LEN-1; // i.e. Que length [# entries -
+ // min. 32; max. 4096 (0xffff)]
+
+ ulAddr = virt_to_bus( fcChip->SFQ);
+#if BITS_PER_LONG > 32
+ if( (ulAddr >> 32) )
+ {
+ printk(" FATAL! SFQ ptr %p exceeds Tachyon's 32-bit register size\n",
+ (void*)ulAddr);
+ return -1; // failed
+ }
+#endif
+ fcChip->SFQ->base = (ULONG)ulAddr; // copy for quick reference
+
+
+ // Allocate SCSI Exchange State Table; aligned nearest @sizeof
+ // power-of-2 boundary
+ // LIVE DANGEROUSLY! Assume the boundary for SEST mem will
+ // be on physical page (e.g. 4k) boundary.
+ printk("Allocating %u for TachSEST for %u Exchanges\n",
+ (ULONG)sizeof(TachSEST), TACH_SEST_LEN);
+ fcChip->SEST = fcMemManager( &cpqfcHBAdata->dynamic_mem[0],
+ sizeof(TachSEST), 4, 0L );
+// sizeof(TachSEST), 64*TACH_SEST_LEN, 0L );
+ if( !fcChip->SEST )
+ {
+ printk("kmalloc/alignment failure on SEST: fatal error\n");


+ return -1;
+ }
+

+ fcChip->SEST->length = TACH_SEST_LEN; // e.g. DON'T subtract one
+ // (TL/TS UG, pg 153)
+
+ ulAddr = virt_to_bus( fcChip->SEST);
+#if BITS_PER_LONG > 32
+ if( (ulAddr >> 32) )
+ {
+ printk(" FATAL! SFQ ptr %p exceeds Tachyon's 32-bit register size\n",
+ (void*)ulAddr);
+ return -1; // failed
+ }
+#endif
+ fcChip->SEST->base = (ULONG)ulAddr; // copy for quick reference
+
+
+ // Now that structures are defined,
+ // fill in Tachyon chip registers...
+
+ // EEEEEEEE EXCHANGE REQUEST QUEUE
+
+ writel( fcChip->ERQ->base,
+ (fcChip->Registers.ReMapMemBase + TL_MEM_ERQ_BASE));
+
+ writel( fcChip->ERQ->length,
+ (fcChip->Registers.ReMapMemBase + TL_MEM_ERQ_LENGTH));
+
+
+ fcChip->ERQ->producerIndex = 0L;
+ writel( fcChip->ERQ->producerIndex,
+ (fcChip->Registers.ReMapMemBase + TL_MEM_ERQ_PRODUCER_INDEX));
+
+
+ // NOTE! write consumer index last, since the write
+ // causes Tachyon to process the other registers
+
+ ulAddr = virt_to_bus( &fcChip->ERQ->consumerIndex);
+
+ // NOTE! Tachyon DMAs to the ERQ consumer Index host
+ // address; must be correctly aligned
+ writel( (ULONG)ulAddr,
+ (fcChip->Registers.ReMapMemBase + TL_MEM_ERQ_CONSUMER_INDEX_ADR));
+
+
+
+ // IIIIIIIIIIIII INBOUND MESSAGE QUEUE
+ // Tell Tachyon where the Que starts
+
+ // set the Host's pointer for Tachyon to access
+
+ printk(" cpqfcTS: writing IMQ BASE %Xh ", fcChip->IMQ->base );
+ writel( fcChip->IMQ->base,
+ (fcChip->Registers.ReMapMemBase + IMQ_BASE));
+
+ writel( fcChip->IMQ->length,
+ (fcChip->Registers.ReMapMemBase + IMQ_LENGTH));
+
+ writel( fcChip->IMQ->consumerIndex,
+ (fcChip->Registers.ReMapMemBase + IMQ_CONSUMER_INDEX));
+
+
+ // NOTE: TachLite DMAs to the producerIndex host address
+ // must be correctly aligned with address bits 1-0 cleared
+ // Writing the BASE register clears the PI register, so write it last
+ ulAddr = virt_to_bus( &fcChip->IMQ->producerIndex);
+#if BITS_PER_LONG > 32
+ if( (ulAddr >> 32) )
+ {
+ printk(" FATAL! IMQ ptr %p exceeds Tachyon's 32-bit register size\n",
+ (void*)ulAddr);
+ return -1; // failed
+ }
+#endif
+//#if DBG
+ printk(" PI %Xh\n", (ULONG)ulAddr );
+//#endif
+ writel( (ULONG)ulAddr,
+ (fcChip->Registers.ReMapMemBase + IMQ_PRODUCER_INDEX));
+
+
+
+ // SSSSSSSSSSSSSSS SINGLE FRAME SEQUENCE
+ // Tell TachLite where the Que starts
+
+ writel( fcChip->SFQ->base,
+ (fcChip->Registers.ReMapMemBase + TL_MEM_SFQ_BASE));
+
+ writel( fcChip->SFQ->length,
+ (fcChip->Registers.ReMapMemBase + TL_MEM_SFQ_LENGTH));
+
+
+ // tell TachLite where SEST table is & how long
+ writel( fcChip->SEST->base,
+ (fcChip->Registers.ReMapMemBase + TL_MEM_SEST_BASE));
+
+ printk(" cpqfcTS: SEST %p(virt): Wrote base %Xh @ %p\n",
+ fcChip->SEST, fcChip->SEST->base,
+ fcChip->Registers.ReMapMemBase + TL_MEM_SEST_BASE);
+
+ writel( fcChip->SEST->length,
+ (fcChip->Registers.ReMapMemBase + TL_MEM_SEST_LENGTH));
+
+ writel( (TL_EXT_SG_PAGE_COUNT-1),
+ (fcChip->Registers.ReMapMemBase + TL_MEM_SEST_SG_PAGE));


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 071'
echo 'File patch-2.4.0-test9 is continued in part 072'
echo "072" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part072

#!/bin/sh -x
# this is part 072 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 072; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+
+
+ LEAVE("CreateTachLiteQues");
+
+ return iStatus;
+}
+
+
+
+// function to return TachLite to Power On state
+// 1st - reset tachyon ('SOFT' reset)
+// others - future
+
+int CpqTsResetTachLite(void *pHBA, int type)


+{
+ CPQFCHBA *cpqfcHBAdata = (CPQFCHBA*)pHBA;
+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;

+ ULONG ulBuff, i;
+ int ret_status=0; // def. success
+
+ ENTER("ResetTach");
+
+ switch(type)
+ {
+
+ case CLEAR_FCPORTS:
+
+ // in case he was running previously, mask Tach's interrupt
+ writeb( 0, (fcChip->Registers.ReMapMemBase + IINTEN));
+
+ // de-allocate mem for any Logged in ports
+ // (e.g., our module is unloading)
+ // search the forward linked list, de-allocating
+ // the memory we allocated when the port was initially logged in
+ {
+ PFC_LOGGEDIN_PORT pLoggedInPort = fcChip->fcPorts.pNextPort;
+ PFC_LOGGEDIN_PORT ptr;
+// printk("checking for allocated LoggedInPorts...\n");
+
+ while( pLoggedInPort )
+ {
+ ptr = pLoggedInPort;
+ pLoggedInPort = ptr->pNextPort;
+// printk("kfree(%p) on FC LoggedInPort port_id 0x%06lX\n",
+// ptr, ptr->port_id);
+ kfree( ptr );
+ }
+ }
+ // (continue resetting hardware...)
+
+ case 1: // RESTART Tachyon (power-up state)
+
+ // in case he was running previously, mask Tach's interrupt
+ writeb( 0, (fcChip->Registers.ReMapMemBase + IINTEN));
+ // turn OFF laser (NOTE: laser is turned
+ // off during reset, because GPIO4 is cleared
+ // to 0 by reset action - see TLUM, sec 7.22)
+ // However, CPQ 64-bit HBAs have a "health
+ // circuit" which keeps laser ON for a brief
+ // period after it is turned off ( < 1s)
+
+ fcChip->LaserControl( fcChip->Registers.ReMapMemBase, 0);
+
+
+
+ // soft reset timing constraints require:
+ // 1. set RST to 1
+ // 2. read SOFTRST register
+ // (128 times per R. Callison code)
+ // 3. clear PCI ints
+ // 4. clear RST to 0
+ writel( 0xff000001L,
+ (fcChip->Registers.ReMapMemBase + TL_MEM_SOFTRST));
+
+ for( i=0; i<128; i++)
+ ulBuff = readl( fcChip->Registers.ReMapMemBase + TL_MEM_SOFTRST);
+
+ // clear the soft reset
+ for( i=0; i<8; i++)
+ writel( 0, (fcChip->Registers.ReMapMemBase + TL_MEM_SOFTRST));
+
+
+
+ // clear out our copy of Tach regs,
+ // because they must be invalid now,
+ // since TachLite reset all his regs.
+ CpqTsDestroyTachLiteQues(cpqfcHBAdata,0); // remove Host-based Que structs
+ cpqfcTSClearLinkStatusCounters(fcChip); // clear our s/w accumulators
+ // lower bits give GBIC info
+ fcChip->Registers.TYstatus.value =
+ readl( fcChip->Registers.TYstatus.address );
+ break;
+
+/*
+ case 2: // freeze SCSI
+ case 3: // reset Outbound command que (ERQ)
+ case 4: // unfreeze OSM (Outbound Seq. Man.) 'er'
+ case 5: // report status
+
+ break;
+*/
+ default:
+ ret_status = -1; // invalid option passed to RESET function
+ break;
+ }
+ LEAVE("ResetTach");
+ return ret_status;


+}
+
+
+
+

+
+
+// 'addrBase' is IOBaseU for both TachLite and (older) Tachyon
+int CpqTsLaserControl( void* addrBase, int opcode )
+{
+ ULONG dwBuff;
+
+ dwBuff = readl((addrBase + TL_MEM_TACH_CONTROL) ); // read TL Control reg
+ // (change only bit 4)
+ if( opcode == 1)
+ dwBuff |= ~0xffffffefL; // set - ON
+ else
+ dwBuff &= 0xffffffefL; // clear - OFF
+ writel( dwBuff, (addrBase + TL_MEM_TACH_CONTROL)); // write TL Control reg
+ return 0;


+}
+
+
+
+

+
+// Use controller's "Options" field to determine loopback mode (if any)
+// internal loopback (silicon - no GBIC)
+// external loopback (GBIC - no FC loop)
+// no loopback: L_PORT, external cable from GBIC required
+
+int CpqTsInitializeFrameManager( void *pChip, int opcode)
+{
+ PTACHYON fcChip;
+ int iStatus;
+ ULONG wwnLo, wwnHi; // for readback verification
+
+ ENTER("InitializeFrameManager");
+ fcChip = (PTACHYON)pChip;
+ if( !fcChip->Registers.ReMapMemBase ) // undefined controller?
+ return -1;
+
+ // TL/TS UG, pg. 184
+ // 0x0065 = 100ms for RT_TOV
+ // 0x01f5 = 500ms for ED_TOV
+ // 0x07D1 = 2000ms
+ fcChip->Registers.ed_tov.value = 0x006507D1;
+ writel( fcChip->Registers.ed_tov.value,
+ (fcChip->Registers.ed_tov.address));
+
+
+ // Set LP_TOV to the FC-AL2 specified 2 secs.
+ // TL/TS UG, pg. 185
+ writel( 0x07d00010, fcChip->Registers.ReMapMemBase +TL_MEM_FM_TIMEOUT2);
+
+
+ // Now try to read the WWN from the adapter's NVRAM
+ iStatus = CpqTsReadWriteWWN( fcChip, 1); // '1' for READ
+
+ if( iStatus ) // NVRAM read failed?
+ {
+ printk(" WARNING! HBA NVRAM WWN read failed - make alias\n");
+ // make up a WWN. If NULL or duplicated on loop, FC loop may hang!
+
+
+ fcChip->Registers.wwn_hi = (__u32)jiffies;
+ fcChip->Registers.wwn_hi |= 0x50000000L;
+ fcChip->Registers.wwn_lo = 0x44556677L;
+ }
+
+
+ writel( fcChip->Registers.wwn_hi,
+ fcChip->Registers.ReMapMemBase + TL_MEM_FM_WWN_HI);
+
+ writel( fcChip->Registers.wwn_lo,
+ fcChip->Registers.ReMapMemBase + TL_MEM_FM_WWN_LO);
+
+
+ // readback for verification:
+ wwnHi = readl( fcChip->Registers.ReMapMemBase + TL_MEM_FM_WWN_HI );
+
+ wwnLo = readl( fcChip->Registers.ReMapMemBase + TL_MEM_FM_WWN_LO);
+ // test for correct chip register WRITE/READ
+ DEBUG_PCI( printk(" WWN %08X%08X\n",
+ fcChip->Registers.wwn_hi, fcChip->Registers.wwn_lo ) );
+
+ if( wwnHi != fcChip->Registers.wwn_hi ||
+ wwnLo != fcChip->Registers.wwn_lo )
+ {
+ printk( "cpqfcTS: WorldWideName register load failed\n");
+ return -1; // FAILED!
+ }
+
+
+
+ // set Frame Manager Initialize command
+ fcChip->Registers.FMcontrol.value = 0x06;
+
+ // Note: for test/debug purposes, we may use "Hard" address,
+ // but we completely support "soft" addressing, including
+ // dynamically changing our address.
+ if( fcChip->Options.intLoopback == 1 ) // internal loopback
+ fcChip->Registers.FMconfig.value = 0x0f002080L;
+ else if( fcChip->Options.extLoopback == 1 ) // internal loopback
+ fcChip->Registers.FMconfig.value = 0x0f004080L;
+ else // L_Port
+ fcChip->Registers.FMconfig.value = 0x55000100L; // hard address (55h start)
+// fcChip->Registers.FMconfig.value = 0x01000080L; // soft address (can't pick)
+// fcChip->Registers.FMconfig.value = 0x55000100L; // hard address (55h start)
+
+ // write config to FM
+
+ if( !fcChip->Options.intLoopback && !fcChip->Options.extLoopback )
+ // (also need LASER for real LOOP)
+ fcChip->LaserControl( fcChip->Registers.ReMapMemBase, 1); // turn on LASER
+
+ writel( fcChip->Registers.FMconfig.value,
+ fcChip->Registers.FMconfig.address);
+
+
+ // issue INITIALIZE command to FM - ACTION!
+ writel( fcChip->Registers.FMcontrol.value,
+ fcChip->Registers.FMcontrol.address);
+
+ LEAVE("InitializeFrameManager");
+
+ return 0;


+}
+
+
+
+

+
+// This "look ahead" function examines the IMQ for occurence of
+// "type". Returns 1 if found, 0 if not.
+static int PeekIMQEntry( PTACHYON fcChip, ULONG type)
+{
+ ULONG CI = fcChip->IMQ->consumerIndex;
+ ULONG PI = fcChip->IMQ->producerIndex; // snapshot of IMQ indexes
+
+ while( CI != PI )
+ { // proceed with search
+ if( (++CI) >= IMQ_LEN ) CI = 0; // rollover check
+
+ switch( type )
+ {
+ case ELS_LILP_FRAME:
+ {
+ // first, we need to find an Inbound Completion message,
+ // If we find it, check the incoming frame payload (1st word)
+ // for LILP frame
+ if( (fcChip->IMQ->QEntry[CI].type & 0x1FF) == 0x104 )
+ {
+ TachFCHDR_GCMND* fchs;
+ ULONG ulFibreFrame[2048/4]; // max DWORDS in incoming FC Frame
+ USHORT SFQpi = (USHORT)(fcChip->IMQ->QEntry[CI].word[0] & 0x0fffL);
+
+ CpqTsGetSFQEntry( fcChip,
+ SFQpi, // SFQ producer ndx
+ ulFibreFrame, // contiguous dest. buffer
+ FALSE); // DON'T update chip--this is a "lookahead"
+
+ fchs = (TachFCHDR_GCMND*)&ulFibreFrame;
+ if( fchs->pl[0] == ELS_LILP_FRAME)
+ {
+ return 1; // found the LILP frame!
+ }
+ else
+ {
+ // keep looking...
+ }
+ }
+ }
+ break;
+
+ case OUTBOUND_COMPLETION:
+ if( (fcChip->IMQ->QEntry[CI].type & 0x1FF) == 0x00 )
+ {
+
+ // any OCM errors?
+ if( fcChip->IMQ->QEntry[CI].word[2] & 0x7a000000L )
+ return 1; // found OCM error
+ }


+ break;
+
+
+

+ default:
+ break;
+ }
+ }
+ return 0; // failed to find "type"
+}
+
+
+static void SetTachTOV( CPQFCHBA* cpqfcHBAdata)
+{


+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;
+

+ // TL/TS UG, pg. 184
+ // 0x0065 = 100ms for RT_TOV
+ // 0x01f5 = 500ms for ED_TOV
+ // 0x07d1 = 2000ms for ED_TOV
+
+ // SANMark Level 1 requires an "initialization backoff"
+ // (See "SANMark Test Suite Level 1":
+ // initialization_timeout.fcal.SANMark-1.fc)
+ // We have to use 2sec, 24sec, then 128sec when login/
+ // port discovery processes fail to complete.
+
+ // when port discovery completes (logins done), we set
+ // ED_TOV to 500ms -- this is the normal operational case
+ // On the first Link Down, we'll move to 2 secs (7D1 ms)
+ if( (fcChip->Registers.ed_tov.value &0xFFFF) <= 0x1f5)
+ fcChip->Registers.ed_tov.value = 0x006507D1;
+
+ // If we get another LST after we moved TOV to 2 sec,
+ // increase to 24 seconds (5DC1 ms) per SANMark!
+ else if( (fcChip->Registers.ed_tov.value &0xFFFF) <= 0x7D1)
+ fcChip->Registers.ed_tov.value = 0x00655DC1;
+
+ // If we get still another LST, set the max TOV (Tachyon
+ // has only 16 bits for ms timer, so the max is 65.5 sec)
+ else if( (fcChip->Registers.ed_tov.value &0xFFFF) <= 0x5DC1)
+ fcChip->Registers.ed_tov.value = 0x0065FFFF;
+
+ writel( fcChip->Registers.ed_tov.value,
+ (fcChip->Registers.ed_tov.address));
+ // keep the same 2sec LP_TOV
+ writel( 0x07D00010, fcChip->Registers.ReMapMemBase +TL_MEM_FM_TIMEOUT2);
+}
+
+
+// The IMQ is an array with IMQ_LEN length, each element (QEntry)
+// with eight 32-bit words. Tachyon PRODUCES a QEntry with each
+// message it wants to send to the host. The host CONSUMES IMQ entries
+
+// This function copies the current
+// (or oldest not-yet-processed) QEntry to
+// the caller, clears/ re-enables the interrupt, and updates the
+// (Host) Consumer Index.
+// Return value:
+// 0 message processed, none remain (producer and consumer
+// indexes match)
+// 1 message processed, more messages remain
+// -1 no message processed - none were available to process
+// Remarks:
+// TL/TS UG specifices that the following actions for
+// INTA_L handling:
+// 1. read PCI Interrupt Status register (0xff)
+// 2. all IMQ messages should be processed before writing the
+// IMQ consumer index.
+
+
+int CpqTsProcessIMQEntry(void *host)
+{
+ struct Scsi_Host *HostAdapter = (struct Scsi_Host *)host;
+ CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;


+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;

+ FC_EXCHANGES *Exchanges = fcChip->Exchanges;
+ int iStatus;
+ USHORT i, RPCset, DPCset;
+ ULONG x_ID;
+ ULONG ulBuff, dwStatus;
+ TachFCHDR_GCMND* fchs;
+ ULONG ulFibreFrame[2048/4]; // max number of DWORDS in incoming Fibre Frame
+ UCHAR ucInboundMessageType; // Inbound CM, dword 3 "type" field
+
+ ENTER("ProcessIMQEntry");
+
+
+ // check TachLite's IMQ producer index -
+ // is a new message waiting for us?
+ // equal indexes means empty que
+
+ if( fcChip->IMQ->producerIndex != fcChip->IMQ->consumerIndex )
+ { // need to process message
+
+
+#ifdef IMQ_DEBUG
+ printk("PI %X, CI %X type: %X\n",
+ fcChip->IMQ->producerIndex,fcChip->IMQ->consumerIndex,
+ fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].type);
+#endif
+ // Examine Completion Messages in IMQ
+ // what CM_Type?
+ switch( (UCHAR)(fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].type
+ & 0xffL) )
+ {
+ case OUTBOUND_COMPLETION:
+
+ // Remarks:
+ // x_IDs (OX_ID, RX_ID) are partitioned by SEST entries
+ // (starting at 0), and SFS entries (starting at
+ // SEST_LEN -- outside the SEST space).
+ // Psuedo code:
+ // x_ID (OX_ID or RX_ID) from message is Trans_ID or SEST index
+ // range check - x_ID
+ // if x_ID outside 'Transactions' length, error - exit
+ // if any OCM error, copy error status to Exchange slot
+ // if FCP ASSIST transaction (x_ID within SEST),
+ // call fcComplete (to App)
+ // ...
+
+
+ ulBuff = fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[1];
+ x_ID = ulBuff & 0x7fffL; // lower 14 bits SEST_Index/Trans_ID
+ // Range check CM OX/RX_ID value...
+ if( x_ID < TACH_MAX_XID ) // don't go beyond array space
+ {
+
+
+ if( ulBuff & 0x20000000L ) // RPC -Response Phase Complete?
+ RPCset = 1; // (SEST transactions only)
+ else
+ RPCset = 0;
+
+ if( ulBuff & 0x40000000L ) // DPC -Data Phase Complete?
+ DPCset = 1; // (SEST transactions only)
+ else
+ DPCset = 0;
+ // set the status for this Outbound transaction's ID
+ dwStatus = 0L;
+ if( ulBuff & 0x10000000L ) // SPE? (SEST Programming Error)
+ dwStatus |= SESTPROG_ERR;
+
+ ulBuff = fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[2];
+ if( ulBuff & 0x7a000000L ) // any other errs?
+ {
+ if( ulBuff & 0x40000000L )
+ dwStatus |= INV_ENTRY;
+ if( ulBuff & 0x20000000L )
+ dwStatus |= FRAME_TO; // FTO
+ if( ulBuff & 0x10000000L )
+ dwStatus |= HOSTPROG_ERR;
+ if( ulBuff & 0x08000000L )
+ dwStatus |= LINKFAIL_TX;
+ if( ulBuff & 0x02000000L )
+ dwStatus |= ABORTSEQ_NOTIFY; // ASN
+ }
+
+
+ if( dwStatus ) // any errors?
+ {
+ // set the Outbound Completion status
+ Exchanges->fcExchange[ x_ID ].status |= dwStatus;
+
+ // if this Outbound frame was for a SEST entry, automatically
+ // reque it in the case of LINKFAIL (it will restart on PDISC)
+ if( x_ID < TACH_SEST_LEN )
+ {
+
+ printk(" #OCM error %Xh x_ID %X# ",
+ dwStatus, x_ID);
+
+ Exchanges->fcExchange[x_ID].timeOut = 30000; // seconds default
+
+
+ // We Q ABTS for each exchange.
+ // NOTE: We can get FRAME_TO on bad alpa (device gone). Since
+ // bad alpa is reported before FRAME_TO, examine the status
+ // flags to see if the device is removed. If so, DON'T
+ // post an ABTS, since it will be terminated by the bad alpa
+ // message.
+ if( dwStatus & FRAME_TO ) // check for device removed...
+ {
+ if( !(Exchanges->fcExchange[x_ID].status & DEVICE_REMOVED) )
+ {
+ // presumes device is still there: send ABTS.
+
+ cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &x_ID);
+ }
+ }
+ else // Abort all other errors
+ {
+ cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &x_ID);
+ }
+
+ // if the HPE bit is set, we have to CLose the LOOP
+ // (see TL/TS UG, pg. 239)
+
+ if( dwStatus &= HOSTPROG_ERR )
+ // set CL bit (see TL/TS UG, pg. 172)
+ writel( 4, fcChip->Registers.FMcontrol.address);
+ }
+ }
+ // NOTE: we don't necessarily care about ALL completion messages...
+ // SCSI resp. complete OR
+ if( ((x_ID < TACH_SEST_LEN) && RPCset)||
+ (x_ID >= TACH_SEST_LEN) ) // non-SCSI command
+ {
+ // exchange done; complete to upper levels with status
+ // (if necessary) and free the exchange slot
+
+
+ if( x_ID >= TACH_SEST_LEN ) // Link Service Outbound frame?
+ // A Request or Reply has been sent
+ { // signal waiting WorkerThread
+
+ up( cpqfcHBAdata->TYOBcomplete); // frame is OUT of Tach
+
+ // WorkerThread will complete Xchng
+ }
+ else // X_ID is for FCP assist (SEST)
+ {
+ // TBD (target mode)
+// fcCompleteExchange( fcChip, x_ID); // TRE completed
+ }
+ }
+ }
+ else // ERROR CONDITION! bogus x_ID in completion message
+ {
+
+ printk(" ProcessIMQ (OBCM) x_id out of range %Xh\n", x_ID);


+
+ }
+
+
+

+ // Load the Frame Manager's error counters. We check them here
+ // because presumably the link is up and healthy enough for the
+ // counters to be meaningful (i.e., don't check them while loop
+ // is initializing).
+ fcChip->Registers.FMLinkStatus1.value = // get TL's counter
+ readl(fcChip->Registers.FMLinkStatus1.address);
+
+ fcChip->Registers.FMLinkStatus2.value = // get TL's counter
+ readl(fcChip->Registers.FMLinkStatus2.address);
+
+
+ fcParseLinkStatusCounters( fcChip); // load into 6 s/w accumulators


+ break;
+
+
+

+ case ERROR_IDLE_COMPLETION: // TachLite Error Idle...
+
+ // We usually get this when the link goes down during heavy traffic.
+ // For now, presume that if SEST Exchanges are open, we will
+ // get this as our cue to INVALIDATE all SEST entries
+ // (and we OWN all the SEST entries).
+ // See TL/TS UG, pg. 53
+
+ for( x_ID = 0; x_ID < TACH_SEST_LEN; x_ID++)
+ {
+
+ // Does this VALid SEST entry need to be invalidated for Abort?
+ fcChip->SEST->u[ x_ID].IWE.Hdr_Len &= 0x7FFFFFFF;
+ }
+
+ CpqTsUnFreezeTachlite( fcChip, 2); // unfreeze Tachyon, if Link OK
+
+ break;
+
+
+ case INBOUND_SFS_COMPLETION: //0x04
+ // NOTE! we must process this SFQ message to avoid SFQ filling
+ // up and stopping TachLite. Incoming commands are placed here,
+ // as well as 'unknown' frames (e.g. LIP loop position data)
+ // write this CM's producer index to global...
+ // TL/TS UG, pg 234:
+ // Type: 0 - reserved
+ // 1 - Unassisted FCP
+ // 2 - BAD FCP
+ // 3 - Unkown Frame
+ // 4-F reserved
+
+
+ fcChip->SFQ->producerIndex = (USHORT)
+ (fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[0] & 0x0fffL);
+
+
+ ucInboundMessageType = 0; // default to useless frame
+
+ // we can only process two Types: 1, Unassisted FCP, and 3, Unknown
+ // Also, we aren't interested in processing frame fragments
+ // so don't Que anything with 'LKF' bit set
+ if( !(fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[2]
+ & 0x40000000) ) // 'LKF' link failure bit clear?
+ {
+ ucInboundMessageType = (UCHAR) // ICM DWord3, "Type"
+ (fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[2] & 0x0fL);
+ }
+ else
+ {
+ fcChip->fcStats.linkFailRX++;
+// printk("LKF (link failure) bit set on inbound message\n");
+ }
+
+ // clears SFQ entry from Tachyon buffer; copies to contiguous ulBuff
+ CpqTsGetSFQEntry(
+ fcChip, // i.e. this Device Object
+ (USHORT)fcChip->SFQ->producerIndex, // SFQ producer ndx
+ ulFibreFrame, TRUE); // contiguous destination buffer, update chip
+
+ // analyze the incoming frame outside the INT handler...
+ // (i.e., Worker)
+
+ if( ucInboundMessageType == 1 )
+ {
+ fchs = (TachFCHDR_GCMND*)ulFibreFrame; // cast to examine IB frame
+ // don't fill up our Q with garbage - only accept FCP-CMND
+ // or XRDY frames
+ if( (fchs->d_id & 0xFF000000) == 0x06000000 ) // CMND
+ {
+ // someone sent us a SCSI command
+
+// fcPutScsiQue( cpqfcHBAdata,
+// SFQ_UNASSISTED_FCP, ulFibreFrame);
+ }
+ else if( ((fchs->d_id & 0xFF000000) == 0x07000000) || // RSP (status)
+ (fchs->d_id & 0xFF000000) == 0x05000000 ) // XRDY
+ {
+ ULONG x_ID;
+ // Unfortunately, ABTS requires a Freeze on the chip so
+ // we can modify the shared memory SEST. When frozen,
+ // any received Exchange frames cannot be processed by
+ // Tachyon, so they will be dumped in here. It is too
+ // complex to attempt the reconstruct these frames in
+ // the correct Exchange context, so we simply seek to
+ // find status or transfer ready frames, and cause the
+ // exchange to complete with errors before the timeout
+ // expires. We use a Linux Scsi Cmnd result code that
+ // causes immediate retry.
+
+
+ // Do we have an open exchange that matches this s_id
+ // and ox_id?
+ for( x_ID = 0; x_ID < TACH_SEST_LEN; x_ID++)
+ {
+ if( (fchs->s_id & 0xFFFFFF) ==
+ (Exchanges->fcExchange[x_ID].fchs.d_id & 0xFFFFFF)
+ &&
+ (fchs->ox_rx_id & 0xFFFF0000) ==
+ (Exchanges->fcExchange[x_ID].fchs.ox_rx_id & 0xFFFF0000) )
+ {
+ // printk(" #R/X frame x_ID %08X# ", fchs->ox_rx_id );
+ // simulate the anticipated error - since the
+ // SEST was frozen, frames were lost...
+ Exchanges->fcExchange[ x_ID ].status |= SFQ_FRAME;
+
+ // presumes device is still there: send ABTS.
+ cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &x_ID);
+ break; // done


+ }
+ }
+ }
+
+ }

+
+ else if( ucInboundMessageType == 3)
+ {
+ // FC Link Service frames (e.g. PLOGI, ACC) come in here.
+ cpqfcTSPutLinkQue( cpqfcHBAdata, SFQ_UNKNOWN, ulFibreFrame);
+
+ }
+
+ else if( ucInboundMessageType == 2 ) // "bad FCP"?
+ {
+#ifdef IMQ_DEBUG
+ printk("Bad FCP incoming frame discarded\n");
+#endif
+ }
+
+ else // don't know this type
+ {
+#ifdef IMQ_DEBUG
+ printk("Incoming frame discarded, type: %Xh\n", ucInboundMessageType);
+#endif
+ }
+
+ // Check the Frame Manager's error counters. We check them here
+ // because presumably the link is up and healthy enough for the
+ // counters to be meaningful (i.e., don't check them while loop
+ // is initializing).
+ fcChip->Registers.FMLinkStatus1.value = // get TL's counter
+ readl(fcChip->Registers.FMLinkStatus1.address);
+
+
+ fcChip->Registers.FMLinkStatus2.value = // get TL's counter
+ readl(fcChip->Registers.FMLinkStatus2.address);
+
+
+ break;
+
+
+
+
+ // We get this CM because we issued a freeze
+ // command to stop outbound frames. We issue the
+ // freeze command at Link Up time; when this message
+ // is received, the ERQ base can be switched and PDISC
+ // frames can be sent.
+
+
+ case ERQ_FROZEN_COMPLETION: // note: expect ERQ followed immediately
+ // by FCP when freezing TL
+ fcChip->Registers.TYstatus.value = // read what's frozen
+ readl(fcChip->Registers.TYstatus.address);
+ // (do nothing; wait for FCP frozen message)
+ break;
+ case FCP_FROZEN_COMPLETION:
+
+ fcChip->Registers.TYstatus.value = // read what's frozen
+ readl(fcChip->Registers.TYstatus.address);
+
+ // Signal the kernel thread to proceed with SEST modification
+ up( cpqfcHBAdata->TachFrozen);
+


+ break;
+
+
+

+ case INBOUND_C1_TIMEOUT:
+ case MFS_BUF_WARN:
+ case IMQ_BUF_WARN:
+ break;


+
+
+
+
+

+ // In older Tachyons, we 'clear' the internal 'core' interrupt state
+ // by reading the FMstatus register. In newer TachLite (Tachyon),
+ // we must WRITE the register
+ // to clear the condition (TL/TS UG, pg 179)
+ case FRAME_MGR_INTERRUPT:
+ {
+ PFC_LOGGEDIN_PORT pLoggedInPort;
+
+ fcChip->Registers.FMstatus.value =
+ readl( fcChip->Registers.FMstatus.address );
+
+ // PROBLEM: It is possible, especially with "dumb" hubs that
+ // don't automatically LIP on by-pass of ports that are going
+ // away, for the hub by-pass process to destroy critical
+ // ordered sets of a frame. The result of this is a hung LPSM
+ // (Loop Port State Machine), which on Tachyon results in a
+ // (default 2 sec) Loop State Timeout (LST) FM message. We
+ // want to avoid this relatively huge timeout by detecting
+ // likely scenarios which will result in LST.
+ // To do this, we could examine FMstatus for Loss of Synchronization
+ // and/or Elastic Store (ES) errors. Of these, Elastic Store is better
+ // because we get this indication more quickly than the LOS.
+ // Not all ES errors are harmfull, so we don't want to LIP on every
+ // ES. Instead, on every ES, detect whether our LPSM in in one
+ // of the LST states: ARBITRATING, OPEN, OPENED, XMITTED CLOSE,
+ // or RECEIVED CLOSE. (See TL/TS UG, pg. 181)
+ // If any of these LPSM states are detected
+ // in combination with the LIP while LDn is not set,
+ // send an FM init (LIP F7,F7 for loops)!
+ // It is critical to the physical link stability NOT to reset (LIP)
+ // more than absolutely necessary; this is a basic premise of the
+ // SANMark level 1 spec.
+ {
+ ULONG Lpsm = (fcChip->Registers.FMstatus.value & 0xF0) >>4;
+
+ if( (fcChip->Registers.FMstatus.value & 0x400) // ElasticStore?
+ &&
+ !(fcChip->Registers.FMstatus.value & 0x100) // NOT LDn
+ &&
+ !(fcChip->Registers.FMstatus.value & 0x1000)) // NOT LF
+ {
+ if( (Lpsm != 0) || // not MONITORING? or
+ !(Lpsm & 0x8) )// not already offline?
+ {
+ // now check the particular LST states...
+ if( (Lpsm == ARBITRATING) || (Lpsm == OPEN) ||
+ (Lpsm == OPENED) || (Lpsm == XMITTD_CLOSE) ||
+ (Lpsm == RCVD_CLOSE) )
+ {
+ // re-init the loop before it hangs itself!
+ printk(" #req FMinit on E-S: LPSM %Xh# ",Lpsm);
+
+
+ fcChip->fcStats.FMinits++;
+ writel( 6, fcChip->Registers.FMcontrol.address); // LIP
+ }
+ }
+ }
+ else if( fcChip->Registers.FMstatus.value & 0x40000 ) // LST?
+ {
+ printk(" #req FMinit on LST, LPSM %Xh# ",Lpsm);
+
+ fcChip->fcStats.FMinits++;
+ writel( 6, fcChip->Registers.FMcontrol.address); // LIP
+ }
+ }
+
+
+ // clear only the 'interrupting' type bits for this REG read
+ writel( (fcChip->Registers.FMstatus.value & 0xff3fff00L),
+ fcChip->Registers.FMstatus.address);
+
+
+ // copy frame manager status to unused ULONG slot
+ fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[0] =
+ fcChip->Registers.FMstatus.value; // (for debugging)
+
+
+ // Load the Frame Manager's error counters. We check them here
+ // because presumably the link is up and healthy enough for the
+ // counters to be meaningful (i.e., don't check them while loop
+ // is initializing).
+ fcChip->Registers.FMLinkStatus1.value = // get TL's counter
+ readl(fcChip->Registers.FMLinkStatus1.address);
+
+ fcChip->Registers.FMLinkStatus2.value = // get TL's counter
+ readl(fcChip->Registers.FMLinkStatus2.address);
+
+ // Get FM BB_Credit Zero Reg - does not clear on READ
+ fcChip->Registers.FMBB_CreditZero.value = // get TL's counter
+ readl(fcChip->Registers.FMBB_CreditZero.address);
+
+
+
+ fcParseLinkStatusCounters( fcChip); // load into 6 s/w accumulators
+
+
+ // LINK DOWN
+
+ if( fcChip->Registers.FMstatus.value & 0x100L ) // Link DOWN bit
+ {
+
+#ifdef IMQ_DEBUG
+ printk("LinkDn\n");
+#endif
+ printk(" #LDn# ");
+
+ fcChip->fcStats.linkDown++;
+
+ SetTachTOV( cpqfcHBAdata); // must set according to SANMark
+
+ // Check the ERQ - force it to be "empty" to prevent Tach
+ // from sending out frames before we do logins.
+
+
+ if( fcChip->ERQ->producerIndex != fcChip->ERQ->consumerIndex)
+ {
+// printk("#ERQ PI != CI#");
+ CpqTsFreezeTachlite( fcChip, 1); // freeze ERQ only
+ fcChip->ERQ->producerIndex = fcChip->ERQ->consumerIndex = 0;


+ writel( fcChip->ERQ->base,
+ (fcChip->Registers.ReMapMemBase + TL_MEM_ERQ_BASE));

+ // re-writing base forces ERQ PI to equal CI
+
+ }
+
+ // link down transition occurred -- port_ids can change
+ // on next LinkUp, so we must invalidate current logins
+ // (and any I/O in progress) until PDISC or PLOGI/PRLI
+ // completes
+ {
+ pLoggedInPort = &fcChip->fcPorts;
+ while( pLoggedInPort ) // for all ports which are expecting
+ // PDISC after the next LIP, set the
+ // logoutTimer
+ {
+
+ if( pLoggedInPort->pdisc) // expecting PDISC within 2 sec?
+ {
+ pLoggedInPort->LOGO_timer = 3; // we want 2 seconds
+ // but Timer granularity
+ // is 1 second
+ }
+ // suspend any I/O in progress until
+ // PDISC received...
+ pLoggedInPort->prli = FALSE; // block FCP-SCSI commands
+
+ pLoggedInPort = pLoggedInPort->pNextPort;
+ } // ... all Previously known ports checked
+ }
+
+ // since any hot plugging device may NOT support LILP frames
+ // (such as early Tachyon chips), clear this flag indicating
+ // we shouldn't use (our copy of) a LILP map.
+ // If we receive an LILP frame, we'll set it again.
+ fcChip->Options.LILPin = 0; // our LILPmap is invalid
+ cpqfcHBAdata->PortDiscDone = 0; // must re-validate FC ports!
+
+ // also, we want to invalidate (i.e. INITIATOR_ABORT) any
+ // open Login exchanges, in case the LinkDown happened in the
+ // middle of logins. It's possible that some ports already
+ // ACCepted login commands which we have not processed before
+ // another LinkDown occured. Any accepted Login exhanges are
+ // invalidated by LinkDown, even before they are acknowledged.
+ // It's also possible for a port to have a Queued Reply or Request
+ // for login which was interrupted by LinkDown; it may come later,
+ // but it will be unacceptable to us.
+
+ // we must scan the entire exchange space, find every Login type
+ // originated by us, and abort it. This is NOT an abort due to
+ // timeout, so we don't actually send abort to the other port -
+ // we just complete it to free up the fcExchange slot.
+
+ for( i=TACH_SEST_LEN; i< TACH_MAX_XID; i++)
+ { // looking for Extended Link Serv.Exchanges
+ if( Exchanges->fcExchange[i].type == ELS_PDISC ||
+ Exchanges->fcExchange[i].type == ELS_PLOGI ||
+ Exchanges->fcExchange[i].type == ELS_PRLI )
+ {
+ // ABORT the exchange!
+#ifdef IMQ_DEBUG
+ printk("Originator ABORT x_id %Xh, type %Xh, port_id %Xh on LDn\n",
+ i, Exchanges->fcExchange[i].type,
+ Exchanges->fcExchange[i].fchs.d_id);
+#endif
+
+ Exchanges->fcExchange[i].status |= INITIATOR_ABORT;
+ cpqfcTSCompleteExchange( fcChip, i); // abort on LDn


+ }
+ }
+
+ }
+

+ // ################ LINK UP ##################
+ if( fcChip->Registers.FMstatus.value & 0x200L ) // Link Up bit
+ { // AL_PA could have changed
+
+ // We need the following code, duplicated from LinkDn condition,
+ // because it's possible for the Tachyon to re-initialize (hard
+ // reset) without ever getting a LinkDn indication.
+ pLoggedInPort = &fcChip->fcPorts;
+ while( pLoggedInPort ) // for all ports which are expecting
+ // PDISC after the next LIP, set the
+ // logoutTimer
+ {
+ if( pLoggedInPort->pdisc) // expecting PDISC within 2 sec?
+ {
+ pLoggedInPort->LOGO_timer = 3; // we want 2 seconds
+ // but Timer granularity
+ // is 1 second
+
+ // suspend any I/O in progress until
+ // PDISC received...
+
+ }
+ pLoggedInPort = pLoggedInPort->pNextPort;
+ } // ... all Previously known ports checked
+
+ // CpqTs acquired AL_PA in register AL_PA (ACQ_ALPA)
+ fcChip->Registers.rcv_al_pa.value =
+ readl(fcChip->Registers.rcv_al_pa.address);
+
+ // Now, if our acquired address is DIFFERENT from our
+ // previous one, we are not allow to do PDISC - we
+ // must go back to PLOGI, which will terminate I/O in
+ // progress for ALL logged in FC devices...
+ // (This is highly unlikely).
+
+ if( (fcChip->Registers.my_al_pa & 0xFF) !=
+ ((fcChip->Registers.rcv_al_pa.value >> 16) &0xFF) )
+ {
+
+// printk(" #our HBA port_id changed!# "); // FC port_id changed!!
+
+ pLoggedInPort = &fcChip->fcPorts;
+ while( pLoggedInPort ) // for all ports which are expecting
+ // PDISC after the next LIP, set the
+ // logoutTimer
+ {
+ pLoggedInPort->pdisc = FALSE;
+ pLoggedInPort->prli = FALSE;
+ pLoggedInPort = pLoggedInPort->pNextPort;
+ } // ... all Previously known ports checked
+
+ // when the port_id changes, we must terminate
+ // all open exchanges.
+ cpqfcTSTerminateExchange( cpqfcHBAdata, NULL, PORTID_CHANGED);
+
+ }
+
+ // Replace the entire 24-bit port_id. We only know the
+ // lower 8 bits (alpa) from Tachyon; if a FLOGI is done,
+ // we'll get the upper 16-bits from the FLOGI ACC frame.
+ // If someone plugs into Fabric switch, we'll do FLOGI and
+ // get full 24-bit port_id; someone could then remove and
+ // hot-plug us into a dumb hub. If we send a 24-bit PLOGI
+ // to a "private" loop device, it might blow up.
+ // Consequently, we force the upper 16-bits of port_id to
+ // be re-set on every LinkUp transition
+ fcChip->Registers.my_al_pa =
+ (fcChip->Registers.rcv_al_pa.value >> 16) & 0xFF;
+
+
+ // copy frame manager status to unused ULONG slot
+ fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[1] =
+ fcChip->Registers.my_al_pa; // (for debugging)
+
+ // for TachLite, we need to write the acquired al_pa
+ // back into the FMconfig register, because after
+ // first initialization, the AQ (prev. acq.) bit gets
+ // set, causing TL FM to use the AL_PA field in FMconfig.
+ // (In Tachyon, FM writes the acquired AL_PA for us.)
+ ulBuff = readl( fcChip->Registers.FMconfig.address);
+ ulBuff &= 0x00ffffffL; // mask out current al_pa
+ ulBuff |= ( fcChip->Registers.my_al_pa << 24 ); // or in acq. al_pa
+ fcChip->Registers.FMconfig.value = ulBuff; // copy it back
+ writel( fcChip->Registers.FMconfig.value, // put in TachLite
+ fcChip->Registers.FMconfig.address);
+
+
+#ifdef IMQ_DEBUG
+ printk("#LUp %Xh, FMstat 0x%08X#",
+ fcChip->Registers.my_al_pa, fcChip->Registers.FMstatus.value);
+#endif
+
+ // also set the WRITE-ONLY My_ID Register (for Fabric
+ // initialization)
+ writel( fcChip->Registers.my_al_pa,
+ fcChip->Registers.ReMapMemBase +TL_MEM_TACH_My_ID);
+
+
+ fcChip->fcStats.linkUp++;
+
+ // reset TL statistics counters
+ // (we ignore these error counters
+ // while link is down)
+ ulBuff = // just reset TL's counter
+ readl( fcChip->Registers.FMLinkStatus1.address);
+
+ ulBuff = // just reset TL's counter
+ readl( fcChip->Registers.FMLinkStatus2.address);
+
+ // for initiator, need to start verifying ports (e.g. PDISC)


+
+
+
+
+

+
+ CpqTsUnFreezeTachlite( fcChip, 2); // unfreeze Tachlite, if Link OK
+
+ // Tachyon creates an interesting problem for us on LILP frames.
+ // Instead of writing the incoming LILP frame into the SFQ before
+ // indicating LINK UP (the actual order of events), Tachyon tells
+ // us LINK UP, and later us the LILP. So we delay, then examine the
+ // IMQ for an Inbound CM (x04); if found, we can set
+ // LINKACTIVE after processing the LILP. Otherwise, just proceed.
+ // Since Tachyon imposes this time delay (and doesn't tell us
+ // what it is), we have to impose a delay before "Peeking" the IMQ
+ // for Tach hardware (DMA) delivery.
+ // Processing LILP is required by SANMark
+ udelay( 1000); // microsec delay waiting for LILP (if it comes)
+ if( PeekIMQEntry( fcChip, ELS_LILP_FRAME) )
+ { // found SFQ LILP, which will post LINKACTIVE
+// printk("skipping LINKACTIVE post\n");
+
+ }
+ else
+ cpqfcTSPutLinkQue( cpqfcHBAdata, LINKACTIVE, ulFibreFrame);
+ }
+
+
+
+ // ******* Set Fabric Login indication ********
+ if( fcChip->Registers.FMstatus.value & 0x2000 )
+ {
+ printk(" #Fabric# ");
+ fcChip->Options.fabric = 1;
+ }
+ else
+ fcChip->Options.fabric = 0;
+
+
+
+ // ******* LIP(F8,x) or BAD AL_PA? ********
+ if( fcChip->Registers.FMstatus.value & 0x30000L )
+ {
+ // copy the error AL_PAs
+ fcChip->Registers.rcv_al_pa.value =
+ readl(fcChip->Registers.rcv_al_pa.address);
+
+ // Bad AL_PA?
+ if( fcChip->Registers.FMstatus.value & 0x10000L )
+ {
+ PFC_LOGGEDIN_PORT pLoggedInPort;
+
+ // copy "BAD" al_pa field
+ fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[1] =
+ (fcChip->Registers.rcv_al_pa.value & 0xff00L) >> 8;
+
+ pLoggedInPort = fcFindLoggedInPort( fcChip,
+ NULL, // DON'T search Scsi Nexus
+ fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[1], // port id
+ NULL, // DON'T search linked list for FC WWN
+ NULL); // DON'T care about end of list
+
+ if( pLoggedInPort )
+ {
+ // Just in case we got this BAD_ALPA because a device
+ // quietly disappeared (can happen on non-managed hubs such
+ // as the Vixel Rapport 1000),
+ // do an Implicit Logout. We never expect this on a Logged
+ // in port (but do expect it on port discovery).
+ // (As a reasonable alternative, this could be changed to
+ // simply start the implicit logout timer, giving the device
+ // several seconds to "come back".)
+ //
+ printk(" #BAD alpa %Xh# ",
+ fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[1]);
+ cpqfcTSImplicitLogout( cpqfcHBAdata, pLoggedInPort);
+ }
+ }
+ // LIP(f8,x)?
+ if( fcChip->Registers.FMstatus.value & 0x20000L )
+ {
+ // for debugging, copy al_pa field
+ fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[2] =
+ (fcChip->Registers.rcv_al_pa.value & 0xffL);
+ // get the other port's al_pa
+ // (one that sent LIP(F8,?) )
+ }
+ }
+
+ // Elastic store err
+ if( fcChip->Registers.FMstatus.value & 0x400L )
+ {
+ // don't count e-s if loop is down!
+ if( !(USHORT)(fcChip->Registers.FMstatus.value & 0x80) )
+ fcChip->fcStats.e_stores++;
+
+ }
+ }
+ break;
+
+
+ case INBOUND_FCP_XCHG_COMPLETION: // 0x0C
+
+ // Remarks:
+ // On Tachlite TL/TS, we get this message when the data phase
+ // of a SEST inbound transfer is complete. For example, if a WRITE command
+ // was received with OX_ID 0, we might respond with XFER_RDY with
+ // RX_ID 8001. This would start the SEST controlled data phases. When
+ // all data frames are received, we get this inbound completion. This means
+ // we should send a status frame to complete the status phase of the
+ // FCP-SCSI exchange, using the same OX_ID,RX_ID that we used for data
+ // frames.
+ // See Outbound CM discussion of x_IDs
+ // Psuedo Code
+ // Get SEST index (x_ID)
+ // x_ID out of range, return (err condition)
+ // set status bits from 2nd dword
+ // free transactionID & SEST entry
+ // call fcComplete with transactionID & status
+
+ ulBuff = fcChip->IMQ->QEntry[fcChip->IMQ->consumerIndex].word[0];
+ x_ID = ulBuff & 0x7fffL; // lower 14 bits SEST_Index/Trans_ID
+ // (mask out MSB "direction" bit)
+ // Range check CM OX/RX_ID value...
+ if( x_ID < TACH_SEST_LEN ) // don't go beyond SEST array space
+ {
+
+//#define FCP_COMPLETION_DBG 1
+#ifdef FCP_COMPLETION_DBG
+ printk(" FCP_CM x_ID %Xh, status %Xh, Cmnd %p\n",
+ x_ID, ulBuff, Exchanges->fcExchange[x_ID].Cmnd);
+#endif
+ if( ulBuff & 0x08000000L ) // RPC -Response Phase Complete - or -
+ // time to send response frame?
+ RPCset = 1; // (SEST transaction)
+ else
+ RPCset = 0;
+ // set the status for this Inbound SCSI transaction's ID
+ dwStatus = 0L;
+ if( ulBuff & 0x70000000L ) // any errs?
+ {
+
+ if( ulBuff & 0x40000000L )
+ dwStatus |= LINKFAIL_RX;
+
+ if( ulBuff & 0x20000000L )
+ dwStatus |= COUNT_ERROR;
+
+ if( ulBuff & 0x10000000L )
+ dwStatus |= OVERFLOW;
+ }
+
+
+ // FCP transaction done - copy status
+ Exchanges->fcExchange[ x_ID ].status = dwStatus;
+
+
+ // Did the exchange get an FCP-RSP response frame?
+ // (Note the little endian/big endian FC payload difference)
+
+ if( RPCset ) // SEST transaction Response frame rec'd
+ {
+ // complete the command in our driver...
+ cpqfcTSCompleteExchange( fcChip, x_ID);
+
+ } // end "RPCset"
+
+ else // ("target" logic)
+ {
+ // Tachlite says all data frames have been received - now it's time
+ // to analyze data transfer (successful?), then send a response
+ // frame for this exchange
+
+ ulFibreFrame[0] = x_ID; // copy for later reference
+
+ // if this was a TWE, we have to send satus response
+ if( Exchanges->fcExchange[ x_ID].type == SCSI_TWE )
+ {
+// fcPutScsiQue( cpqfcHBAdata,
+// NEED_FCP_RSP, ulFibreFrame); // (ulFibreFrame not used here)
+ }
+ }
+ }
+ else // ERROR CONDITION! bogus x_ID in completion message
+ {
+ printk("IN FCP_XCHG: bad x_ID: %Xh\n", x_ID);
+ }
+
+ break;
+
+
+
+
+ case INBOUND_SCSI_DATA_COMMAND:
+ case BAD_SCSI_FRAME:
+ case INB_SCSI_STATUS_COMPLETION:
+ case BUFFER_PROCESSED_COMPLETION:
+ break;
+ }
+
+ // Tachyon is producing;
+ // we are consuming
+ fcChip->IMQ->consumerIndex++; // increment OUR consumerIndex
+ if( fcChip->IMQ->consumerIndex >= IMQ_LEN)// check for rollover
+ fcChip->IMQ->consumerIndex = 0L; // reset it
+
+
+ if( fcChip->IMQ->producerIndex == fcChip->IMQ->consumerIndex )
+ { // all Messages are processed -
+ iStatus = 0; // no more messages to process
+
+ }
+ else
+ iStatus = 1; // more messages to process
+
+ // update TachLite's ConsumerIndex... (clears INTA_L)
+ // NOTE: according to TL/TS UG, the
+ // "host must return completion messages in sequential order".
+ // Does this mean one at a time, in the order received? We
+ // presume so.


+
+ writel( fcChip->IMQ->consumerIndex,
+ (fcChip->Registers.ReMapMemBase + IMQ_CONSUMER_INDEX));
+

+#if IMQ_DEBUG
+ printk("Process IMQ: writing consumer ndx %d\n ",
+ fcChip->IMQ->consumerIndex);
+ printk("PI %X, CI %X\n",
+ fcChip->IMQ->producerIndex,fcChip->IMQ->consumerIndex );
+#endif
+
+
+
+ }
+ else
+ {
+ // hmmm... why did we get interrupted/called with no message?
+ iStatus = -1; // nothing to process
+#if IMQ_DEBUG
+ printk("Process IMQ: no message PI %Xh CI %Xh",
+ fcChip->IMQ->producerIndex,
+ fcChip->IMQ->consumerIndex);
+#endif
+ }
+
+ LEAVE("ProcessIMQEntry");
+
+ return iStatus;


+}
+
+
+
+

+
+// This routine initializes Tachyon according to the following
+// options (opcode1):
+// 1 - RESTART Tachyon, simulate power on condition by shutting
+// down laser, resetting the hardware, de-allocating all buffers;
+// continue
+// 2 - Config Tachyon / PCI registers;
+// continue
+// 3 - Allocating memory and setting Tachyon queues (write Tachyon regs);
+// continue
+// 4 - Config frame manager registers, initialize, turn on laser
+//
+// Returns:
+// -1 on fatal error
+// 0 on success
+
+int CpqTsInitializeTachLite( void *pHBA, int opcode1, int opcode2)


+{
+ CPQFCHBA *cpqfcHBAdata = (CPQFCHBA*)pHBA;
+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;

+ ULONG ulBuff;
+ UCHAR bBuff;
+ int iStatus=-1; // assume failure
+
+ ENTER("InitializeTachLite");
+
+ // verify board's base address (sanity check)
+
+ if( !fcChip->Registers.ReMapMemBase) // NULL address for card?
+ return -1; // FATAL error!
+
+
+
+ switch( opcode1 )
+ {
+ case 1: // restore hardware to power-on (hard) restart
+
+
+ iStatus = fcChip->ResetTachyon(
+ cpqfcHBAdata, opcode2); // laser off, reset hardware
+ // de-allocate aligned buffers
+
+
+/* TBD // reset FC link Q (producer and consumer = 0)
+ fcLinkQReset(cpqfcHBAdata);
+
+*/
+
+ if( iStatus )
+ break;
+
+ case 2: // Config PCI/Tachyon registers
+ // NOTE: For Tach TL/TS, bit 31 must be set to 1. For TS chips, a read
+ // of bit 31 indicates state of M66EN signal; if 1, chip may run at
+ // 33-66MHz (see TL/TS UG, pg 159)
+
+ ulBuff = 0x80000000; // TachLite Configuration Register
+
+ writel( ulBuff, fcChip->Registers.TYconfig.address);
+// ulBuff = 0x0147L; // CpqTs PCI CFGCMD register
+// WritePCIConfiguration( fcChip->Backplane.bus,
+// fcChip->Backplane.slot, TLCFGCMD, ulBuff, 4);
+// ulBuff = 0x0L; // test!
+// ReadPCIConfiguration( fcChip->Backplane.bus,
+// fcChip->Backplane.slot, TLCFGCMD, &ulBuff, 4);
+
+ // read back for reference...
+ fcChip->Registers.TYconfig.value =
+ readl( fcChip->Registers.TYconfig.address );
+
+ // what is the PCI bus width?
+ pci_read_config_byte( cpqfcHBAdata->PciDev,
+ 0x43, // PCIMCTR offset
+ &bBuff);
+
+ fcChip->Registers.PCIMCTR = bBuff;
+
+ // set string identifying the chip on the circuit board
+
+ fcChip->Registers.TYstatus.value =
+ readl( fcChip->Registers.TYstatus.address);
+
+ {
+// Now that we are supporting multiple boards, we need to change
+// this logic to check for PCI vendor/device IDs...
+// for now, quick & dirty is simply checking Chip rev
+
+ ULONG RevId = (fcChip->Registers.TYstatus.value &0x3E0)>>5;
+ UCHAR Minor = (UCHAR)(RevId & 0x3);
+ UCHAR Major = (UCHAR)((RevId & 0x1C) >>2);
+
+ printk(" HBA Tachyon RevId %d.%d\n", Major, Minor);
+ if( (Major == 1) && (Minor == 2) )
+ {
+ sprintf( cpqfcHBAdata->fcChip.Name, STACHLITE66_TS12);
+
+ }
+ else if( (Major == 1) && (Minor == 3) )
+ {
+ sprintf( cpqfcHBAdata->fcChip.Name, STACHLITE66_TS13);
+ }
+ else if( (Major == 2) && (Minor == 1) )
+ {
+ sprintf( cpqfcHBAdata->fcChip.Name, SAGILENT_XL2_21);
+ }
+ else
+ sprintf( cpqfcHBAdata->fcChip.Name, STACHLITE_UNKNOWN);
+ }
+
+
+
+ case 3: // allocate mem, set Tachyon Que registers
+ iStatus = CpqTsCreateTachLiteQues( cpqfcHBAdata, opcode2);
+
+ // now that the Queues exist, Tach can DMA to them, so
+ // we can begin processing INTs
+ // INTEN register - enable INT (TachLite interrupt)
+ writeb( 0x1F, fcChip->Registers.ReMapMemBase + IINTEN);
+
+
+ if( iStatus )
+ break;
+
+
+ case 4: // Config Fame Manager, Init Loop Command, laser on
+
+ // L_PORT or loopback
+ // depending on Options
+ iStatus = CpqTsInitializeFrameManager( fcChip,0 );
+ if( iStatus )
+ {
+ // failed to initialize Frame Manager
+ break;
+ }
+
+ default:
+ break;
+ }
+ LEAVE("InitializeTachLite");
+
+ return iStatus;


+}
+
+
+
+

+// Depending on the type of platform memory allocation (e.g. dynamic),
+// it's probably best to free memory in opposite order as it was allocated.
+// Order of allocation: see other function
+
+
+int CpqTsDestroyTachLiteQues( void *pHBA, int opcode)


+{
+ CPQFCHBA *cpqfcHBAdata = (CPQFCHBA*)pHBA;
+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;

+ USHORT i, j, iStatus=0;
+ void* vPtr; // mem Align manager sets this to the freed address on success
+ unsigned long ulPtr; // for 64-bit pointer cast (e.g. Alpa machine)
+
+ ENTER("DestroyTachLiteQues");
+
+ if( fcChip->SEST )
+ {
+ // search out and free Pool for Extended S/G list pages
+
+ for( i=0, j=0; i < TACH_SEST_LEN; i++, j=0) // for each exchange
+ {
+ // It's possible that extended S/G pages were allocated and
+ // not cleared due to error conditions or O/S driver termination.
+ // Make sure they're all gone.
+ while( fcChip->SEST->sgPages[i].PoolPage[j] &&
+ (j < TL_MAX_SGPAGES))
+ kfree( fcChip->SEST->sgPages[i].PoolPage[j++]);
+
+ }
+ ulPtr = (unsigned long)fcChip->SEST;
+ vPtr = fcMemManager( &cpqfcHBAdata->dynamic_mem[0],
+ 0,0, (ULONG)ulPtr ); // 'free' mem
+ fcChip->SEST = 0L; // null invalid ptr
+ if( !vPtr )
+ {
+ printk("SEST mem not freed\n");
+ iStatus = -1;
+ }
+ }
+
+ if( fcChip->SFQ )
+ {
+
+ ulPtr = (unsigned long)fcChip->SFQ;
+ vPtr = fcMemManager( &cpqfcHBAdata->dynamic_mem[0],
+ 0,0, (ULONG)ulPtr ); // 'free' mem
+ fcChip->SFQ = 0L; // null invalid ptr
+ if( !vPtr )
+ {
+ printk("SFQ mem not freed\n");
+ iStatus = -2;
+ }
+ }
+
+
+ if( fcChip->IMQ )
+ {
+ // clear Indexes to show empty Queue
+ fcChip->IMQ->producerIndex = 0;
+ fcChip->IMQ->consumerIndex = 0;
+
+ ulPtr = (unsigned long)fcChip->IMQ;
+ vPtr = fcMemManager( &cpqfcHBAdata->dynamic_mem[0],
+ 0,0, (ULONG)ulPtr ); // 'free' mem
+ fcChip->IMQ = 0L; // null invalid ptr
+ if( !vPtr )
+ {
+ printk("IMQ mem not freed\n");
+ iStatus = -3;
+ }
+ }
+
+ if( fcChip->ERQ ) // release memory blocks used by the queues
+ {
+ ulPtr = (unsigned long)fcChip->ERQ;
+ vPtr = fcMemManager( &cpqfcHBAdata->dynamic_mem[0],
+ 0,0, (ULONG)ulPtr ); // 'free' mem
+ fcChip->ERQ = 0L; // null invalid ptr
+ if( !vPtr )
+ {
+ printk("ERQ mem not freed\n");
+ iStatus = -4;
+ }
+ }
+
+ // free up the primary EXCHANGES struct
+ if( fcChip->Exchanges != NULL)
+ {
+// printk("kfree() on Exchanges @%p\n", fcChip->Exchanges);
+ kfree( fcChip->Exchanges);
+ }
+
+ // free up Link Q
+ if( cpqfcHBAdata->fcLQ != NULL )
+ {
+// printk("kfree() on LinkQ @%p\n", fcChip->fcLQ);
+ kfree( cpqfcHBAdata->fcLQ);
+ }
+
+ LEAVE("DestroyTachLiteQues");
+
+ return iStatus; // non-zero (failed) if any memory not freed


+}
+
+
+
+

+
+// The SFQ is an array with SFQ_LEN length, each element (QEntry)
+// with eight 32-bit words. TachLite places incoming FC frames (i.e.
+// a valid FC frame with our AL_PA ) in contiguous SFQ entries
+// and sends a completion message telling the host where the frame is
+// in the que.
+// This function copies the current (or oldest not-yet-processed) QEntry to
+// a caller's contiguous buffer and updates the Tachyon chip's consumer index
+//
+// NOTE:
+// An FC frame may consume one or many SFQ entries. We know the total
+// length from the completion message. The caller passes a buffer large
+// enough for the complete message (max 2k).
+
+static void CpqTsGetSFQEntry(
+ PTACHYON fcChip,
+ USHORT producerNdx,
+ ULONG *ulDestPtr, // contiguous destination buffer
+ BOOLEAN UpdateChip)
+{
+ ULONG total_bytes=0;
+ ULONG consumerIndex = fcChip->SFQ->consumerIndex;
+
+ // check passed copy of SFQ producer index -
+ // is a new message waiting for us?
+ // equal indexes means SFS is copied
+
+ while( producerNdx != consumerIndex )
+ { // need to process message
+ total_bytes += 64; // maintain count to prevent writing past buffer
+ // don't allow copies over Fibre Channel defined length!
+ if( total_bytes <= 2048 )
+ {
+ memcpy( ulDestPtr,
+ &fcChip->SFQ->QEntry[consumerIndex],
+ 64 ); // each SFQ entry is 64 bytes
+ ulDestPtr += 16; // advance pointer to next 64 byte block
+ }
+ // Tachyon is producing,
+ // and we are consuming
+
+ if( ++consumerIndex >= SFQ_LEN)// check for rollover
+ consumerIndex = 0L; // reset it
+ }
+
+ // if specified, update the Tachlite chip ConsumerIndex...
+ if( UpdateChip )
+ {
+ fcChip->SFQ->consumerIndex = consumerIndex;
+ writel( fcChip->SFQ->consumerIndex,
+ fcChip->Registers.SFQconsumerIndex.address);


+ }
+}
+
+
+

+// TachLite routinely freezes it's core ques - Outbound FIFO, Inbound FIFO,
+// and Exchange Request Queue (ERQ) on error recover -
+// (e.g. whenever a LIP occurs). Here
+// we routinely RESUME by clearing these bits, but only if the loop is up
+// to avoid ERROR IDLE messages forever.
+
+void CpqTsUnFreezeTachlite( void *pChip, int type )
+{
+ PTACHYON fcChip = (PTACHYON)pChip;
+ fcChip->Registers.TYcontrol.value =
+ readl(fcChip->Registers.TYcontrol.address);
+
+ // (bit 4 of value is GBIC LASER)
+ // if we 'unfreeze' the core machines before the loop is healthy
+ // (i.e. FLT, OS, LS failure bits set in FMstatus)
+ // we can get 'error idle' messages forever. Verify that
+ // FMstatus (Link Status) is OK before unfreezing.
+
+ if( !(fcChip->Registers.FMstatus.value & 0x07000000L) && // bits clear?
+ !(fcChip->Registers.FMstatus.value & 0x80 )) // Active LPSM?
+ {
+ fcChip->Registers.TYcontrol.value &= ~0x300L; // clear FEQ, FFA
+ if( type == 1 ) // unfreeze ERQ only
+ {
+// printk("Unfreezing ERQ\n");
+ fcChip->Registers.TYcontrol.value |= 0x10000L; // set REQ
+ }
+ else // unfreeze both ERQ and FCP-ASSIST (SEST)
+ {
+// printk("Unfreezing ERQ & FCP-ASSIST\n");
+
+ // set ROF, RIF, REQ - resume Outbound FCP, Inbnd FCP, ERQ
+ fcChip->Registers.TYcontrol.value |= 0x70000L; // set ROF, RIF, REQ
+ }
+
+ writel( fcChip->Registers.TYcontrol.value,
+ fcChip->Registers.TYcontrol.address);
+
+ }
+ // readback for verify (TachLite still frozen?)
+ fcChip->Registers.TYstatus.value =
+ readl(fcChip->Registers.TYstatus.address);
+}
+
+
+// Whenever an FC Exchange Abort is required, we must manipulate the
+// Host/Tachyon shared memory SEST table. Before doing this, we
+// must freeze Tachyon, which flushes certain buffers and ensure we
+// can manipulate the SEST without contention.
+// This freeze function will result in FCP & ERQ FROZEN completion
+// messages (per argument "type").
+
+void CpqTsFreezeTachlite( void *pChip, int type )
+{
+ PTACHYON fcChip = (PTACHYON)pChip;
+ fcChip->Registers.TYcontrol.value =
+ readl(fcChip->Registers.TYcontrol.address);
+
+ //set FFA, FEQ - freezes SCSI assist and ERQ
+ if( type == 1) // freeze ERQ only


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 072'
echo 'File patch-2.4.0-test9 is continued in part 073'
echo "073" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part073

#!/bin/sh -x
# this is part 073 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 073; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ fcChip->Registers.TYcontrol.value |= 0x100L; // (bit 4 is laser)
+ else // freeze both FCP assists (SEST) and ERQ
+ fcChip->Registers.TYcontrol.value |= 0x300L; // (bit 4 is laser)


+
+ writel( fcChip->Registers.TYcontrol.value,
+ fcChip->Registers.TYcontrol.address);
+
+}
+

+
+
+
+// TL has two Frame Manager Link Status Registers, with three 8-bit
+// fields each. These eight bit counters are cleared after each read,
+// so we define six 32-bit accumulators for these TL counters. This
+// function breaks out each 8-bit field and adds the value to the existing
+// sum. (s/w counters cleared independently)
+
+void fcParseLinkStatusCounters(PTACHYON fcChip)
+{
+ UCHAR bBuff;
+ ULONG ulBuff;
+
+
+// The BB0 timer usually increments when TL is initialized, resulting
+// in an initially bogus count. If our own counter is ZERO, it means we
+// are reading this thing for the first time, so we ignore the first count.
+// Also, reading the register does not clear it, so we have to keep an
+// additional static counter to detect rollover (yuk).
+
+ if( fcChip->fcStats.lastBB0timer == 0L) // TL was reset? (ignore 1st values)
+ {
+ // get TL's register counter - the "last" count
+ fcChip->fcStats.lastBB0timer =
+ fcChip->Registers.FMBB_CreditZero.value & 0x00ffffffL;
+ }
+ else // subsequent pass - check for rollover
+ {
+ // "this" count
+ ulBuff = fcChip->Registers.FMBB_CreditZero.value & 0x00ffffffL;
+ if( fcChip->fcStats.lastBB0timer > ulBuff ) // rollover happened
+ {
+ // counter advanced to max...
+ fcChip->fcStats.BB0_Timer += (0x00FFFFFFL - fcChip->fcStats.lastBB0timer);
+ fcChip->fcStats.BB0_Timer += ulBuff; // plus some more
+
+
+ }
+ else // no rollover -- more counts or no change
+ {
+ fcChip->fcStats.BB0_Timer += (ulBuff - fcChip->fcStats.lastBB0timer);
+
+ }
+
+ fcChip->fcStats.lastBB0timer = ulBuff;
+ }
+
+
+
+ bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus1.value >> 24);
+ fcChip->fcStats.LossofSignal += bBuff;
+
+ bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus1.value >> 16);
+ fcChip->fcStats.BadRXChar += bBuff;
+
+ bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus1.value >> 8);
+ fcChip->fcStats.LossofSync += bBuff;
+
+
+ bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus2.value >> 24);
+ fcChip->fcStats.Rx_EOFa += bBuff;
+
+ bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus2.value >> 16);
+ fcChip->fcStats.Dis_Frm += bBuff;
+
+ bBuff = (UCHAR)(fcChip->Registers.FMLinkStatus2.value >> 8);
+ fcChip->fcStats.Bad_CRC += bBuff;
+}
+
+
+void cpqfcTSClearLinkStatusCounters(PTACHYON fcChip)
+{
+ ENTER("ClearLinkStatusCounters");
+ memset( &fcChip->fcStats, 0, sizeof( FCSTATS));
+ LEAVE("ClearLinkStatusCounters");
+
+}
+
+
+
+
+// The following function reads the I2C hardware to get the adapter's
+// World Wide Name (WWN).
+// If the WWN is "500805f1fadb43e8" (as printed on the card), the
+// Tachyon WWN_hi (32-bit) register is 500805f1, and WWN_lo register
+// is fadb43e8.
+// In the NVRAM, the bytes appear as:
+// [2d] ..
+// [2e] ..
+// [2f] 50
+// [30] 08
+// [31] 05
+// [32] f1
+// [33] fa
+// [34] db
+// [35] 43
+// [36] e8
+//
+// In the Fibre Channel (Big Endian) format, the FC-AL LISM frame will
+// be correctly loaded by Tachyon silicon. In the login payload, bytes
+// must be correctly swapped for Big Endian format.
+
+int CpqTsReadWriteWWN( PVOID pChip, int Read)


+{
+ PTACHYON fcChip = (PTACHYON)pChip;

+#define NVRAM_SIZE 512
+ unsigned short i, count = NVRAM_SIZE;
+ UCHAR nvRam[NVRAM_SIZE], WWNbuf[8];
+ ULONG ulBuff;


+ int iStatus=-1; // assume failure

+ int WWNoffset;
+
+ ENTER("ReadWriteWWN");


+ // Now try to read the WWN from the adapter's NVRAM
+

+ if( Read ) // READing NVRAM WWN?
+ {
+ ulBuff = cpqfcTS_ReadNVRAM( fcChip->Registers.TYstatus.address,
+ fcChip->Registers.TYcontrol.address,
+ count, &nvRam[0] );
+
+ if( ulBuff ) // NVRAM read successful?
+ {
+ iStatus = 0; // success!
+
+ // for engineering/ prototype boards, the data may be
+ // invalid (GIGO, usually all "FF"); this prevents the
+ // parse routine from working correctly, which means
+ // nothing will be written to our passed buffer.
+
+ WWNoffset = cpqfcTS_GetNVRAM_data( WWNbuf, nvRam );
+
+ if( !WWNoffset ) // uninitialized NVRAM -- copy bytes directly
+ {
+ printk( "CAUTION: Copying NVRAM data on fcChip\n");
+ for( i= 0; i < 8; i++)
+ WWNbuf[i] = nvRam[i +0x2f]; // dangerous! some formats won't work
+ }
+
+ fcChip->Registers.wwn_hi = 0L;
+ fcChip->Registers.wwn_lo = 0L;
+ for( i=0; i<4; i++) // WWN bytes are big endian in NVRAM
+ {
+ ulBuff = 0L;
+ ulBuff = (ULONG)(WWNbuf[i]) << (8 * (3-i));
+ fcChip->Registers.wwn_hi |= ulBuff;
+ }
+ for( i=0; i<4; i++) // WWN bytes are big endian in NVRAM
+ {
+ ulBuff = 0L;
+ ulBuff = (ULONG)(WWNbuf[i+4]) << (8 * (3-i));
+ fcChip->Registers.wwn_lo |= ulBuff;
+ }
+ } // done reading
+ else
+ {
+
+ printk( "cpqfcTS: NVRAM read failed\n");
+
+ }
+ }
+
+ else // WRITE
+ {
+
+ // NOTE: WRITE not supported & not used in released driver.
+
+
+ printk("ReadWriteNRAM: can't write NVRAM; aborting write\n");
+ }
+
+ LEAVE("ReadWriteWWN");


+ return iStatus;
+}
+
+
+
+
+

+// The following function reads or writes the entire "NVRAM" contents of
+// the I2C hardware (i.e. the NM24C03). Note that HP's 5121A (TS 66Mhz)
+// adapter does not use the NM24C03 chip, so this function only works on
+// Compaq's adapters.
+
+int CpqTsReadWriteNVRAM( PVOID pChip, PVOID buf, int Read)


+{
+ PTACHYON fcChip = (PTACHYON)pChip;

+#define NVRAM_SIZE 512
+ ULONG ulBuff;
+ UCHAR *ucPtr = buf; // cast caller's void ptr to UCHAR array


+ int iStatus=-1; // assume failure
+
+

+ if( Read ) // READing NVRAM?
+ {
+ ulBuff = cpqfcTS_ReadNVRAM( // TRUE on success
+ fcChip->Registers.TYstatus.address,
+ fcChip->Registers.TYcontrol.address,
+ 256, // bytes to write
+ ucPtr ); // source ptr
+
+
+ if( ulBuff )
+ iStatus = 0; // success
+ else
+ {
+#ifdef DBG
+ printk( "CAUTION: NVRAM read failed\n");
+#endif
+ }
+ } // done reading
+
+ else // WRITING NVRAM
+ {
+
+ printk("cpqfcTS: WRITE of FC Controller's NVRAM disabled\n");
+ }
+
+ return iStatus;
+}
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/cpqfcTSi2c.c linux/drivers/scsi/cpqfcTSi2c.c
--- v2.4.0-test8/linux/drivers/scsi/cpqfcTSi2c.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/cpqfcTSi2c.c Thu Sep 21 13:22:05 2000
@@ -0,0 +1,493 @@


+/* Copyright(c) 2000, Compaq Computer Corporation
+ * Fibre Channel Host Bus Adapter
+ * 64-bit, 66MHz PCI
+ * Originally developed and tested on:
+ * (front): [chip] Tachyon TS HPFC-5166A/1.2 L2C1090 ...
+ * SP# P225CXCBFIEL6T, Rev XC
+ * SP# 161290-001, Rev XD
+ * (back): Board No. 010008-001 A/W Rev X5, FAB REV X5
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ * Written by Don Zimmerman
+*/

+// These functions control the NVRAM I2C hardware on
+// non-intelligent Fibre Host Adapters.
+// The primary purpose is to read the HBA's NVRAM to get adapter's
+// manufactured WWN to copy into Tachyon chip registers
+// Orignal source author unknown
+
+#include <linux/types.h>
+enum boolean { FALSE, TRUE } ;
+
+
+#ifndef UCHAR
+typedef __u8 UCHAR;
+#endif
+#ifndef BOOLEAN
+typedef __u8 BOOLEAN;
+#endif
+#ifndef USHORT
+typedef __u16 USHORT;
+#endif
+#ifndef ULONG
+typedef __u32 ULONG;
+#endif
+
+
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/sched.h>


+#include <asm/io.h> // struct pt_regs for IRQ handler & Port I/O
+

+#include "cpqfcTSchip.h"
+
+static void tl_i2c_tx_byte( void* GPIOout, UCHAR data );
+/*static BOOLEAN tl_write_i2c_page_portion( void* GPIOin, void* GPIOout,
+ USHORT startOffset, // e.g. 0x2f for WWN start
+ USHORT count,
+ UCHAR *buf );
+*/
+
+//
+// Tachlite GPIO2, GPIO3 (I2C) DEFINES
+// The NVRAM chip NM24C03 defines SCL (serial clock) and SDA (serial data)
+// GPIO2 drives SDA, and GPIO3 drives SCL
+//
+// Since Tachlite inverts the state of the GPIO 0-3 outputs, SET writes 0
+// and clear writes 1. The input lines (read in TL status) is NOT inverted
+// This really helps confuse the code and debugging.
+
+#define SET_DATA_HI 0x0
+#define SET_DATA_LO 0x8
+#define SET_CLOCK_HI 0x0
+#define SET_CLOCK_LO 0x4
+
+#define SENSE_DATA_HI 0x8
+#define SENSE_DATA_LO 0x0
+#define SENSE_CLOCK_HI 0x4
+#define SENSE_CLOCK_LO 0x0
+
+#define SLAVE_READ_ADDRESS 0xA1
+#define SLAVE_WRITE_ADDRESS 0xA0
+
+
+static void i2c_delay(ULONG mstime);
+static void tl_i2c_clock_pulse( UCHAR , void* GPIOout);
+static UCHAR tl_read_i2c_data( void* );
+
+
+//-----------------------------------------------------------------------------
+//
+// Name: I2C_RX_ACK
+//
+// This routine receives an acknowledge over the I2C bus.
+//
+//-----------------------------------------------------------------------------
+static unsigned short tl_i2c_rx_ack( void* GPIOin, void* GPIOout )
+{
+ unsigned long value;
+
+ // do clock pulse, let data line float high
+ tl_i2c_clock_pulse( SET_DATA_HI, GPIOout );
+
+ // slave must drive data low for acknowledge
+ value = tl_read_i2c_data( GPIOin);
+ if (value & SENSE_DATA_HI )
+ return( FALSE );
+
+ return( TRUE );
+}
+//-----------------------------------------------------------------------------
+//
+// Name: READ_I2C_REG
+//
+// This routine reads the I2C control register using the global
+// IO address stored in gpioreg.
+//
+//-----------------------------------------------------------------------------
+static UCHAR tl_read_i2c_data( void* gpioreg )
+{
+ return( (UCHAR)(readl( gpioreg ) & 0x08L) ); // GPIO3
+}
+//-----------------------------------------------------------------------------
+//
+// Name: WRITE_I2C_REG
+//
+// This routine writes the I2C control register using the global
+// IO address stored in gpioreg.
+// In Tachlite, we don't want to modify other bits in TL Control reg.
+//
+//-----------------------------------------------------------------------------
+static void tl_write_i2c_reg( void* gpioregOUT, UCHAR value )
+{
+ ULONG temp;
+
+ // First read the register and clear out the old bits
+ temp = readl( gpioregOUT ) & 0xfffffff3L;
+
+ // Now or in the new data and send it back out
+ writel( temp | value, gpioregOUT);
+}
+//-----------------------------------------------------------------------------
+//
+// Name: I2C_TX_START
+//
+// This routine transmits a start condition over the I2C bus.
+// 1. Set SCL (clock, GPIO2) HIGH, set SDA (data, GPIO3) HIGH,
+// wait 5us to stabilize.
+// 2. With SCL still HIGH, drive SDA low. The low transition marks
+// the start condition to NM24Cxx (the chip)
+// NOTE! In TL control reg., output 1 means chip sees LOW
+//
+//-----------------------------------------------------------------------------
+static unsigned short tl_i2c_tx_start( void* GPIOin, void* GPIOout )
+{
+ unsigned short i;
+ ULONG value;
+
+ if ( !(tl_read_i2c_data(GPIOin) & SENSE_DATA_HI))
+ {
+ // start with clock high, let data float high
+ tl_write_i2c_reg( GPIOout, SET_DATA_HI | SET_CLOCK_HI );
+
+ // keep sending clock pulses if slave is driving data line
+ for (i = 0; i < 10; i++)
+ {
+ tl_i2c_clock_pulse( SET_DATA_HI, GPIOout );
+
+ if ( tl_read_i2c_data(GPIOin) & SENSE_DATA_HI )
+ break;
+ }
+
+ // if he's still driving data low after 10 clocks, abort
+ value = tl_read_i2c_data( GPIOin ); // read status
+ if (!(value & 0x08) )
+ return( FALSE );
+ }
+
+
+ // To START, bring data low while clock high
+ tl_write_i2c_reg( GPIOout, SET_CLOCK_HI | SET_DATA_LO );
+
+ i2c_delay(0);
+
+ return( TRUE ); // TX start successful
+}
+//-----------------------------------------------------------------------------
+//
+// Name: I2C_TX_STOP
+//
+// This routine transmits a stop condition over the I2C bus.
+//
+//-----------------------------------------------------------------------------
+
+static unsigned short tl_i2c_tx_stop( void* GPIOin, void* GPIOout )


+{
+ int i;
+

+ for (i = 0; i < 10; i++)
+ {
+ // Send clock pulse, drive data line low
+ tl_i2c_clock_pulse( SET_DATA_LO, GPIOout );
+
+ // To STOP, bring data high while clock high
+ tl_write_i2c_reg( GPIOout, SET_DATA_HI | SET_CLOCK_HI );
+
+ // Give the data line time to float high
+ i2c_delay(0);
+
+ // If slave is driving data line low, there's a problem; retry
+ if ( tl_read_i2c_data(GPIOin) & SENSE_DATA_HI )
+ return( TRUE ); // TX STOP successful!
+ }
+
+ return( FALSE ); // error
+}
+//-----------------------------------------------------------------------------
+//
+// Name: I2C_TX_uchar
+//
+// This routine transmits a byte across the I2C bus.
+//
+//-----------------------------------------------------------------------------
+static void tl_i2c_tx_byte( void* GPIOout, UCHAR data )
+{
+ UCHAR bit;
+
+ for (bit = 0x80; bit; bit >>= 1)
+ {
+ if( data & bit )
+ tl_i2c_clock_pulse( (UCHAR)SET_DATA_HI, GPIOout);
+ else
+ tl_i2c_clock_pulse( (UCHAR)SET_DATA_LO, GPIOout);
+ }
+}
+//-----------------------------------------------------------------------------
+//
+// Name: I2C_RX_uchar
+//
+// This routine receives a byte across the I2C bus.
+//
+//-----------------------------------------------------------------------------
+static UCHAR tl_i2c_rx_byte( void* GPIOin, void* GPIOout )
+{
+ UCHAR bit;
+ UCHAR data = 0;
+
+
+ for (bit = 0x80; bit; bit >>= 1) {
+ // do clock pulse, let data line float high
+ tl_i2c_clock_pulse( SET_DATA_HI, GPIOout );
+
+ // read data line
+ if ( tl_read_i2c_data( GPIOin) & 0x08 )
+ data |= bit;
+ }
+
+ return (data);
+}
+//*****************************************************************************
+//*****************************************************************************
+// Function: read_i2c_nvram
+// Arguments: UCHAR count number of bytes to read
+// UCHAR *buf area to store the bytes read
+// Returns: 0 - failed
+// 1 - success
+//*****************************************************************************
+//*****************************************************************************
+unsigned long cpqfcTS_ReadNVRAM( void* GPIOin, void* GPIOout , USHORT count,
+ UCHAR *buf )
+{
+ unsigned short i;
+
+ if( !( tl_i2c_tx_start(GPIOin, GPIOout) ))
+ return FALSE;
+
+ // Select the NVRAM for "dummy" write, to set the address
+ tl_i2c_tx_byte( GPIOout , SLAVE_WRITE_ADDRESS );
+ if ( !tl_i2c_rx_ack(GPIOin, GPIOout ) )
+ return( FALSE );
+
+ // Now send the address where we want to start reading
+ tl_i2c_tx_byte( GPIOout , 0 );
+ if ( !tl_i2c_rx_ack(GPIOin, GPIOout ) )
+ return( FALSE );
+
+ // Send a repeated start condition and select the
+ // slave for reading now.
+ if( tl_i2c_tx_start(GPIOin, GPIOout) )
+ tl_i2c_tx_byte( GPIOout, SLAVE_READ_ADDRESS );
+
+ if ( !tl_i2c_rx_ack(GPIOin, GPIOout) )
+ return( FALSE );
+
+ // this loop will now read out the data and store it
+ // in the buffer pointed to by buf
+ for ( i=0; i<count; i++)
+ {
+ *buf++ = tl_i2c_rx_byte(GPIOin, GPIOout);
+
+ // Send ACK by holding data line low for 1 clock
+ if ( i < (count-1) )
+ tl_i2c_clock_pulse( 0x08, GPIOout );
+ else {
+ // Don't send ack for final byte
+ tl_i2c_clock_pulse( SET_DATA_HI, GPIOout );
+ }
+ }
+
+ tl_i2c_tx_stop(GPIOin, GPIOout);
+
+ return( TRUE );
+}
+
+//****************************************************************
+//
+//
+//
+// routines to set and clear the data and clock bits
+//
+//
+//
+//****************************************************************
+
+static void tl_set_clock(void* gpioreg)
+{
+ ULONG ret_val;
+
+ ret_val = readl( gpioreg );
+ ret_val &= 0xffffffFBL; // clear GPIO2 (SCL)
+ writel( ret_val, gpioreg);
+}
+
+static void tl_clr_clock(void* gpioreg)
+{
+ ULONG ret_val;
+
+ ret_val = readl( gpioreg );
+ ret_val |= SET_CLOCK_LO;
+ writel( ret_val, gpioreg);
+}
+
+//*****************************************************************
+//
+//
+// This routine will advance the clock by one period
+//
+//
+//*****************************************************************
+static void tl_i2c_clock_pulse( UCHAR value, void* GPIOout )
+{
+ ULONG ret_val;
+
+ // clear the clock bit
+ tl_clr_clock( GPIOout );
+
+ i2c_delay(0);
+
+
+ // read the port to preserve non-I2C bits
+ ret_val = readl( GPIOout );
+
+ // clear the data & clock bits
+ ret_val &= 0xFFFFFFf3;
+
+ // write the value passed in...
+ // data can only change while clock is LOW!
+ ret_val |= value; // the data
+ ret_val |= SET_CLOCK_LO; // the clock
+ writel( ret_val, GPIOout );
+
+ i2c_delay(0);
+
+
+ //set clock bit
+ tl_set_clock( GPIOout);


+}
+
+
+
+

+//*****************************************************************
+//
+//
+// This routine returns the 64-bit WWN
+//
+//
+//*****************************************************************
+int cpqfcTS_GetNVRAM_data( UCHAR *wwnbuf, UCHAR *buf )
+{
+ ULONG len;
+ ULONG sub_len;
+ ULONG ptr_inc;
+ ULONG i;
+ ULONG j;
+ UCHAR *data_ptr;
+ UCHAR z;
+ UCHAR name;
+ UCHAR sub_name;
+ UCHAR done;
+ int iReturn=0; // def. 0 offset is failure to find WWN field
+
+
+
+ data_ptr = (UCHAR *)buf;
+
+ done = FALSE;
+ i = 0;
+
+ while ( (i < 128) && (!done) )
+ {
+ z = data_ptr[i];\
+ if ( !(z & 0x80) )
+ {
+ len = 1 + (z & 0x07);
+
+ name = (z & 0x78) >> 3;
+ if (name == 0x0F)
+ done = TRUE;
+ }
+ else
+ {
+ name = z & 0x7F;
+ len = 3 + data_ptr[i+1] + (data_ptr[i+2] << 8);
+
+ switch (name)
+ {
+ case 0x0D:
+ //
+ j = i + 3;
+ //
+ if ( data_ptr[j] == 0x3b ) {
+ len = 6;
+ break;
+ }
+
+ while ( j<(i+len) ) {
+ sub_name = (data_ptr[j] & 0x3f);
+ sub_len = data_ptr[j+1] +
+ (data_ptr[j+2] << 8);
+ ptr_inc = sub_len + 3;
+ switch (sub_name)
+ {
+ case 0x3C:
+ memcpy( wwnbuf, &data_ptr[j+3], 8);
+ iReturn = j+3;
+ break;


+ default:
+ break;
+ }

+ j += ptr_inc;
+ }
+ break;


+ default:
+ break;
+ }
+ }

+ //
+ i += len;
+ } // end while
+ return iReturn;


+}
+
+
+
+
+

+// define a short 5 micro sec delay, and longer (ms) delay
+
+static void i2c_delay(ULONG mstime)
+{
+ ULONG i;
+
+// NOTE: we only expect to use these delays when reading
+// our adapter's NVRAM, which happens only during adapter reset.
+// Delay technique from "Linux Device Drivers", A. Rubini
+// (1st Ed.) pg 137.
+
+// printk(" delay %lx ", mstime);
+ if( mstime ) // ms delay?
+ {
+ // delay technique
+ for( i=0; i < mstime; i++)
+ udelay(1000); // 1ms per loop
+
+ }
+ else // 5 micro sec delay
+
+ udelay( 5 ); // micro secs
+
+// printk("done\n");
+}
+
+
+
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/cpqfcTSinit.c linux/drivers/scsi/cpqfcTSinit.c
--- v2.4.0-test8/linux/drivers/scsi/cpqfcTSinit.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/cpqfcTSinit.c Tue Sep 19 08:01:34 2000
@@ -0,0 +1,1815 @@


+/* Copyright(c) 2000, Compaq Computer Corporation
+ * Fibre Channel Host Bus Adapter
+ * 64-bit, 66MHz PCI
+ * Originally developed and tested on:
+ * (front): [chip] Tachyon TS HPFC-5166A/1.2 L2C1090 ...
+ * SP# P225CXCBFIEL6T, Rev XC
+ * SP# 161290-001, Rev XD
+ * (back): Board No. 010008-001 A/W Rev X5, FAB REV X5
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ * Written by Don Zimmerman

+ * IOCTL and procfs added by Jouke Numan
+ * SMP testing by Chel Van Gennip
+ *
+ * portions copied from:
+ * QLogic CPQFCTS SCSI-FCP
+ * Written by Erik H. Moe, e...@cris.com
+ * Copyright 1995, Erik H. Moe
+ * Renamed and updated to 1.3.x by Michael Griffith <gr...@cs.ucr.edu>
+ * Chris Loveland <c...@iol.unh.edu> to support the isp2100 and isp2200
+*/
+


+
+#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
+
+#include <linux/blk.h>
+#include <linux/kernel.h>
+#include <linux/string.h>

+#include <linux/sched.h>


+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/delay.h>

+#include <linux/timer.h>


+#include <linux/ioport.h> // request_region() prototype

+#include <linux/vmalloc.h> // ioremap()
+#ifdef __alpha__
+#define __KERNEL_SYSCALLS__
+#endif
+#include <asm/unistd.h>
+#include <asm/io.h>
+#include <asm/uaccess.h> // ioctl related


+#include <asm/irq.h>
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,18)
+#include <asm/spinlock.h>
+#else
+#include <linux/spinlock.h>
+#endif

+#include "sd.h"
+#include <scsi/scsi_ioctl.h>
+#include "hosts.h"


+#include "cpqfcTSchip.h"
+#include "cpqfcTSstructs.h"
+

+#include "cpqfcTS.h"
+
+#include <linux/module.h>
+/* Embedded module documentation macros - see module.h */
+MODULE_AUTHOR("Compaq Computer Corporation");
+MODULE_DESCRIPTION("Driver for Compaq 64-bit/66Mhz PCI Fibre Channel HBA");
+
+// This struct was originally defined in
+// /usr/src/linux/include/linux/proc_fs.h
+// since it's only partially implemented, we only use first
+// few fields...
+// NOTE: proc_fs changes in 2.4 kernel
+
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27)
+static struct proc_dir_entry proc_scsi_cpqfcTS =
+{
+ PROC_SCSI_CPQFCTS, // ushort low_ino (enumerated list)
+ 7, // ushort namelen
+ DEV_NAME, // const char* name
+ S_IFDIR | S_IRUGO | S_IXUGO, // mode_t mode
+ 2 // nlink_t nlink
+ // etc. ...
+};


+
+
+#endif
+
+

+
+/* local function to load our per-HBA (local) data for chip
+ registers, FC link state, all FC exchanges, etc.
+
+ We allocate space and compute address offsets for the
+ most frequently accessed addresses; others (like World Wide
+ Name) are not necessary.
+
+*/
+static void Cpqfc_initHBAdata( CPQFCHBA *cpqfcHBAdata, struct pci_dev *PciDev )
+{
+
+ cpqfcHBAdata->PciDev = PciDev; // copy PCI info ptr
+
+ // since x86 port space is 64k, we only need the lower 16 bits
+ cpqfcHBAdata->fcChip.Registers.IOBaseL =
+ PciDev->base_address[1] & PCI_BASE_ADDRESS_IO_MASK;
+
+ cpqfcHBAdata->fcChip.Registers.IOBaseU =
+ PciDev->base_address[2] & PCI_BASE_ADDRESS_IO_MASK;
+
+ // 32-bit memory addresses
+ cpqfcHBAdata->fcChip.Registers.MemBase =
+ PciDev->base_address[3] & PCI_BASE_ADDRESS_MEM_MASK;
+
+ cpqfcHBAdata->fcChip.Registers.ReMapMemBase =
+ ioremap( PciDev->base_address[3] & PCI_BASE_ADDRESS_MEM_MASK,
+ 0x200);
+
+ cpqfcHBAdata->fcChip.Registers.RAMBase =
+ PciDev->base_address[4];
+
+ cpqfcHBAdata->fcChip.Registers.SROMBase = // NULL for HP TS adapter
+ PciDev->base_address[5];
+
+ // now the Tachlite chip registers
+ // the REGISTER struct holds both the physical address & last
+ // written value (some TL registers are WRITE ONLY)
+
+ cpqfcHBAdata->fcChip.Registers.SFQconsumerIndex.address =
+ cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_SFQ_CONSUMER_INDEX;
+
+ cpqfcHBAdata->fcChip.Registers.ERQproducerIndex.address =
+ cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_ERQ_PRODUCER_INDEX;
+
+ // TL Frame Manager
+ cpqfcHBAdata->fcChip.Registers.FMconfig.address =
+ cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_FM_CONFIG;
+ cpqfcHBAdata->fcChip.Registers.FMcontrol.address =
+ cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_FM_CONTROL;
+ cpqfcHBAdata->fcChip.Registers.FMstatus.address =
+ cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_FM_STATUS;
+ cpqfcHBAdata->fcChip.Registers.FMLinkStatus1.address =
+ cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_FM_LINK_STAT1;
+ cpqfcHBAdata->fcChip.Registers.FMLinkStatus2.address =
+ cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_FM_LINK_STAT2;
+ cpqfcHBAdata->fcChip.Registers.FMBB_CreditZero.address =
+ cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_FM_BB_CREDIT0;
+
+ // TL Control Regs
+ cpqfcHBAdata->fcChip.Registers.TYconfig.address =
+ cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_TACH_CONFIG;
+ cpqfcHBAdata->fcChip.Registers.TYcontrol.address =
+ cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_TACH_CONTROL;
+ cpqfcHBAdata->fcChip.Registers.TYstatus.address =
+ cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_TACH_STATUS;
+ cpqfcHBAdata->fcChip.Registers.rcv_al_pa.address =
+ cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_FM_RCV_AL_PA;
+ cpqfcHBAdata->fcChip.Registers.ed_tov.address =
+ cpqfcHBAdata->fcChip.Registers.ReMapMemBase + TL_MEM_FM_ED_TOV;
+
+
+ cpqfcHBAdata->fcChip.Registers.INTEN.address =
+ cpqfcHBAdata->fcChip.Registers.ReMapMemBase + IINTEN;
+ cpqfcHBAdata->fcChip.Registers.INTPEND.address =
+ cpqfcHBAdata->fcChip.Registers.ReMapMemBase + IINTPEND;
+ cpqfcHBAdata->fcChip.Registers.INTSTAT.address =
+ cpqfcHBAdata->fcChip.Registers.ReMapMemBase + IINTSTAT;
+
+ DEBUG_PCI(printk(" cpqfcHBAdata->fcChip.Registers. :\n"));
+ DEBUG_PCI(printk(" IOBaseL = %x\n",
+ cpqfcHBAdata->fcChip.Registers.IOBaseL));
+ DEBUG_PCI(printk(" IOBaseU = %x\n",
+ cpqfcHBAdata->fcChip.Registers.IOBaseU));
+
+ printk(" ioremap'd Membase: %p\n", cpqfcHBAdata->fcChip.Registers.ReMapMemBase);
+
+ DEBUG_PCI(printk(" SFQconsumerIndex.address = %p\n",
+ cpqfcHBAdata->fcChip.Registers.SFQconsumerIndex.address));
+ DEBUG_PCI(printk(" ERQproducerIndex.address = %p\n",
+ cpqfcHBAdata->fcChip.Registers.ERQproducerIndex.address));
+ DEBUG_PCI(printk(" TYconfig.address = %p\n",
+ cpqfcHBAdata->fcChip.Registers.TYconfig.address));
+ DEBUG_PCI(printk(" FMconfig.address = %p\n",
+ cpqfcHBAdata->fcChip.Registers.FMconfig.address));
+ DEBUG_PCI(printk(" FMcontrol.address = %p\n",
+ cpqfcHBAdata->fcChip.Registers.FMcontrol.address));
+
+ // set default options for FC controller (chip)
+ cpqfcHBAdata->fcChip.Options.initiator = 1; // default: SCSI initiator
+ cpqfcHBAdata->fcChip.Options.target = 0; // default: SCSI target
+ cpqfcHBAdata->fcChip.Options.extLoopback = 0;// default: no loopback @GBIC
+ cpqfcHBAdata->fcChip.Options.intLoopback = 0;// default: no loopback inside chip
+
+ // set highest and lowest FC-PH version the adapter/driver supports
+ // (NOT strict compliance)
+ cpqfcHBAdata->fcChip.highest_FCPH_ver = FC_PH3;
+ cpqfcHBAdata->fcChip.lowest_FCPH_ver = FC_PH43;
+
+ // set function points for this controller / adapter
+ cpqfcHBAdata->fcChip.ResetTachyon = CpqTsResetTachLite;
+ cpqfcHBAdata->fcChip.FreezeTachyon = CpqTsFreezeTachlite;
+ cpqfcHBAdata->fcChip.UnFreezeTachyon = CpqTsUnFreezeTachlite;
+ cpqfcHBAdata->fcChip.CreateTachyonQues = CpqTsCreateTachLiteQues;
+ cpqfcHBAdata->fcChip.DestroyTachyonQues = CpqTsDestroyTachLiteQues;
+ cpqfcHBAdata->fcChip.InitializeTachyon = CpqTsInitializeTachLite;
+ cpqfcHBAdata->fcChip.LaserControl = CpqTsLaserControl;
+ cpqfcHBAdata->fcChip.ProcessIMQEntry = CpqTsProcessIMQEntry;
+ cpqfcHBAdata->fcChip.InitializeFrameManager = CpqTsInitializeFrameManager;;
+ cpqfcHBAdata->fcChip.ReadWriteWWN = CpqTsReadWriteWWN;
+ cpqfcHBAdata->fcChip.ReadWriteNVRAM = CpqTsReadWriteNVRAM;


+
+
+
+}
+
+

+/* (borrowed from linux/drivers/scsi/hosts.c) */
+static void launch_FCworker_thread(struct Scsi_Host *HostAdapter)
+{
+ DECLARE_MUTEX_LOCKED(sem);
+
+ CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
+
+ ENTER("launch_FC_worker_thread");
+
+ cpqfcHBAdata->notify_wt = &sem;
+
+ kernel_thread((int (*)(void *))cpqfcTSWorkerThread,
+ (void *) HostAdapter, 0);
+ /*
+ * Now wait for the kernel error thread to initialize itself
+
+ */
+ down (&sem);
+ cpqfcHBAdata->notify_wt = NULL;
+
+ LEAVE("launch_FC_worker_thread");
+
+}
+
+
+/* "Entry" point to discover if any supported PCI
+ bus adapter can be found
+*/
+// We're supporting:
+// Compaq 64-bit, 66MHz HBA with Tachyon TS
+// Agilent XL2
+#define HBA_TYPES 2
+
+
+int cpqfcTS_detect(Scsi_Host_Template *ScsiHostTemplate)
+{
+ int NumberOfAdapters=0; // how many of our PCI adapters are found?
+ struct pci_dev *PciDev = NULL;
+ struct Scsi_Host *HostAdapter = NULL;
+ CPQFCHBA *cpqfcHBAdata = NULL;
+ struct timer_list *cpqfcTStimer = NULL;
+ SupportedPCIcards PCIids[HBA_TYPES];
+ int i;
+
+ ENTER("cpqfcTS_detect");
+
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27)
+ ScsiHostTemplate->proc_dir = &proc_scsi_cpqfcTS;
+#else
+ ScsiHostTemplate->proc_name = "cpqfcTS";
+#endif
+
+ if( pci_present() == 0) // no PCI busses?
+ {
+ printk( " no PCI bus?@#!\n");
+ return NumberOfAdapters;
+ }
+
+ // what HBA adapters are we supporting?
+ PCIids[0].vendor_id = PCI_VENDOR_ID_COMPAQ;
+ PCIids[0].device_id = CPQ_DEVICE_ID;
+ PCIids[1].vendor_id = PCI_VENDOR_ID_HP; // i.e. 103Ch (Agilent == HP for now)
+ PCIids[1].device_id = AGILENT_XL2_ID; // i.e. 1029h
+
+ for( i=0; i < HBA_TYPES; i++)
+ {
+ // look for all HBAs of each type
+
+ while( (PciDev =
+ pci_find_device( PCIids[i].vendor_id, PCIids[i].device_id, PciDev) ))
+ {
+ // NOTE: (kernel 2.2.12-32) limits allocation to 128k bytes...
+ printk(" scsi_register allocating %d bytes for FC HBA\n",
+ (ULONG)sizeof(CPQFCHBA));
+
+ HostAdapter = scsi_register( ScsiHostTemplate, sizeof( CPQFCHBA ) );
+ DEBUG_PCI( printk(" HBA found!\n"));
+ DEBUG_PCI( printk(" HostAdapter->PciDev->irq = %u\n", PciDev->irq) );
+ DEBUG_PCI(printk(" PciDev->baseaddress[]= %lx\n", PciDev->base_address[0]));
+ DEBUG_PCI(printk(" PciDev->baseaddress[]= %lx\n", PciDev->base_address[1]));
+ DEBUG_PCI(printk(" PciDev->baseaddress[]= %lx\n", PciDev->base_address[2]));
+ DEBUG_PCI(printk(" PciDev->baseaddress[]= %lx\n", PciDev->base_address[3]));
+
+
+ HostAdapter->irq = PciDev->irq; // copy for Scsi layers
+
+ // HP Tachlite uses two (255-byte) ranges of Port I/O (lower & upper),
+ // for a total I/O port address space of 512 bytes.
+ // mask out the I/O port address (lower) & record
+ HostAdapter->io_port = (unsigned int)
+ PciDev->base_address[1] & PCI_BASE_ADDRESS_IO_MASK;
+ HostAdapter->n_io_port = 0xff;
+
+ // i.e., expect 128 targets (arbitrary number), while the
+ // RA-4000 supports 32 LUNs
+ HostAdapter->max_id = 0; // incremented as devices log in
+ HostAdapter->max_lun = CPQFCTS_MAX_LUN; // LUNs per FC device
+ HostAdapter->max_channel = CPQFCTS_MAX_CHANNEL; // multiple busses?
+ HostAdapter->hostt->use_new_eh_code = 1; // new error handling
+
+ // get the pointer to our HBA specific data... (one for
+ // each HBA on the PCI bus(ses)).
+ cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
+
+ // make certain our data struct is clear
+ memset( cpqfcHBAdata, 0, sizeof( CPQFCHBA ) );
+
+
+ // initialize our HBA info
+ cpqfcHBAdata->HBAnum = NumberOfAdapters;
+
+ cpqfcHBAdata->HostAdapter = HostAdapter; // back ptr
+ Cpqfc_initHBAdata( cpqfcHBAdata, PciDev ); // fill MOST fields
+
+ cpqfcHBAdata->HBAnum = NumberOfAdapters;
+
+
+ // request necessary resources and check for conflicts
+ if( request_irq( HostAdapter->irq,
+ cpqfcTS_intr_handler,
+ SA_INTERRUPT | SA_SHIRQ,
+ DEV_NAME,
+ HostAdapter) )
+ {
+ printk(" IRQ %u already used\n", HostAdapter->irq);
+ scsi_unregister( HostAdapter);
+ continue;
+ }
+
+ // Since we have two 256-byte I/O port ranges (upper
+ // and lower), check them both
+ if( check_region( cpqfcHBAdata->fcChip.Registers.IOBaseU, 0xff) )
+ {
+ printk(" cpqfcTS address in use: %x\n",
+ cpqfcHBAdata->fcChip.Registers.IOBaseU);
+ free_irq( HostAdapter->irq, HostAdapter);
+ scsi_unregister( HostAdapter);
+ continue;
+ }
+
+ if( check_region( cpqfcHBAdata->fcChip.Registers.IOBaseL, 0xff) )
+ {
+ printk(" cpqfcTS address in use: %x\n",
+ cpqfcHBAdata->fcChip.Registers.IOBaseL);
+ free_irq( HostAdapter->irq, HostAdapter);
+ scsi_unregister( HostAdapter);
+ continue;
+ }
+
+ // OK, we should be able to grab everything we need now.
+ request_region( cpqfcHBAdata->fcChip.Registers.IOBaseL, 0xff, DEV_NAME);
+ request_region( cpqfcHBAdata->fcChip.Registers.IOBaseU, 0xff, DEV_NAME);
+ DEBUG_PCI(printk(" Requesting 255 I/O addresses @ %x\n",
+ cpqfcHBAdata->fcChip.Registers.IOBaseL ));
+ DEBUG_PCI(printk(" Requesting 255 I/O addresses @ %x\n",
+ cpqfcHBAdata->fcChip.Registers.IOBaseU ));
+
+
+ // start our kernel worker thread
+
+ launch_FCworker_thread(HostAdapter);
+
+
+ // start our TimerTask...
+
+ cpqfcTStimer = &cpqfcHBAdata->cpqfcTStimer;
+
+ init_timer( cpqfcTStimer); // Linux clears next/prev values
+ cpqfcTStimer->expires = jiffies + HZ; // one second
+ cpqfcTStimer->data = (unsigned long)cpqfcHBAdata; // this adapter
+ cpqfcTStimer->function = cpqfcTSheartbeat; // handles timeouts, housekeeping
+
+ add_timer( cpqfcTStimer); // give it to Linux
+
+
+ // now initialize our hardware...
+
+ cpqfcHBAdata->fcChip.InitializeTachyon( cpqfcHBAdata, 1,1);
+
+ cpqfcHBAdata->fcStatsTime = jiffies; // (for FC Statistics delta)
+
+ // give our HBA time to initialize and login current devices...
+ {
+ // The Brocade switch (e.g. 2400, 2010, etc.) as of March 2000,
+ // has the following algorithm for FL_Port startup:
+ // Time(sec) Action
+ // 0: Device Plugin and LIP(F7,F7) transmission
+ // 1.0 LIP incoming
+ // 1.027 LISA incoming, no CLS! (link not up)
+ // 1.028 NOS incoming (switch test for N_Port)
+ // 1.577 ED_TOV expired, transmit LIPs again
+ // 3.0 LIP(F8,F7) incoming (switch passes Tach Prim.Sig)
+ // 3.028 LILP received, link up, FLOGI starts
+ // slowest(worst) case, measured on 1Gb Finisar GT analyzer
+
+ int wait_time;
+ for( wait_time = jiffies + 4*HZ; wait_time > jiffies; )
+ schedule(); // (our worker task needs to run)
+
+ }
+
+ NumberOfAdapters++;
+ } // end of while()
+ }
+
+ LEAVE("cpqfcTS_detect");
+
+ return NumberOfAdapters;
+}
+
+
+static void my_ioctl_done (Scsi_Cmnd * SCpnt)
+{
+ struct request * req;
+
+ req = &SCpnt->request;
+ req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */
+
+ if (req->sem != NULL) {
+ up(req->sem);


+ }
+}
+
+
+

+int cpqfcTS_ioctl( Scsi_Device *ScsiDev, int Cmnd, void *arg)
+{
+ int result = 0;
+ struct Scsi_Host *HostAdapter = ScsiDev->host;


+ CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;

+ PFC_LOGGEDIN_PORT pLoggedInPort;
+ Scsi_Cmnd DumCmnd;
+ int i, j;
+ VENDOR_IOCTL_REQ ioc;
+ cpqfc_passthru_t *vendor_cmd;
+ Scsi_Device *SDpnt;
+ Scsi_Cmnd *ScsiPassThruCmnd;


+ unsigned long flags;
+

+ ENTER("cpqfcTS_ioctl");
+
+ // can we find an FC device mapping to this SCSI target?
+ DumCmnd.channel = ScsiDev->channel; // For searching
+ DumCmnd.target = ScsiDev->id;


+ pLoggedInPort = fcFindLoggedInPort( fcChip,

+ &DumCmnd, // search Scsi Nexus
+ 0, // DON'T search linked list for FC port id


+ NULL, // DON'T search linked list for FC WWN
+ NULL); // DON'T care about end of list
+

+ if( pLoggedInPort == NULL ) // not found!
+ {
+ result = -ENXIO;
+ }
+
+ else // we know what FC device to operate on...
+ {
+ switch (Cmnd)
+ {
+ // Passthrough provides a mechanism to bypass the RAID
+ // or other controller and talk directly to the devices
+ // (e.g. physical disk drive)
+ // Passthrough commands, unfortunately, tend to be vendor
+ // specific; this is tailored to COMPAQ's RAID (RA4x00)
+ case CPQFCTS_SCSI_PASSTHRU:
+ {
+ void *buf = NULL; // for kernel space buffer for user data
+
+ if( !arg)
+ return -EINVAL;
+
+ // must be super user to send stuff directly to the
+ // controller and/or physical drives...
+ if( !suser() )
+ return -EPERM;
+
+ // copy the caller's struct to our space.
+ copy_from_user_ret( &ioc, arg,
+ sizeof( VENDOR_IOCTL_REQ), -EFAULT);
+
+ vendor_cmd = ioc.argp; // i.e., CPQ specific command struct
+
+ // If necessary, grab a kernel/DMA buffer
+ if( vendor_cmd->len)
+ {
+ buf = kmalloc( vendor_cmd->len, GFP_KERNEL);
+ if( !buf)
+ return -ENOMEM;
+ }
+
+ // Now build a SCSI_CMND to pass down...
+ // This function allocates and sets Scsi_Cmnd ptrs such as
+ // ->channel, ->target, ->host
+ ScsiPassThruCmnd = scsi_allocate_device(NULL, ScsiDev, 1);
+
+ // Need data from user?
+ // make sure caller's buffer is in kernel space.
+ if( (vendor_cmd->rw_flag == VENDOR_WRITE_OPCODE) &&
+ vendor_cmd->len)
+ copy_from_user_ret( buf, vendor_cmd->bufp, vendor_cmd->len, -EFAULT);
+
+ // copy the CDB (if/when MAX_COMMAND_SIZE is 16, remove copy below)
+ memcpy( &ScsiPassThruCmnd->cmnd[0],
+ &vendor_cmd->cdb[0],
+ MAX_COMMAND_SIZE);
+ // we want to copy all 16 bytes into the FCP-SCSI CDB,
+ // although the actual passthru only uses up to the
+ // first 12.
+
+ ScsiPassThruCmnd->cmd_len = 16; // sizeof FCP-SCSI CDB
+
+ // Unfortunately, the SCSI command cmnd[] field has only
+ // 12 bytes. Ideally the MAX_COMMAND_SIZE should be increased
+ // to 16 for newer Fibre Channel and SCSI-3 larger CDBs.
+ // However, to avoid a mandatory kernel rebuild, we use the SCp
+ // spare field to store the extra 4 bytes ( ugly :-(
+
+ if( MAX_COMMAND_SIZE < 16)
+ {
+ memcpy( &ScsiPassThruCmnd->SCp.buffers_residual,
+ &vendor_cmd->cdb[12], 4);
+ }
+
+
+ ScsiPassThruCmnd->SCp.sent_command = 1; // PASSTHRU!
+ // suppress LUN masking
+ // and VSA logic
+
+ // Use spare fields to copy FCP-SCSI LUN address info...
+ ScsiPassThruCmnd->SCp.phase = vendor_cmd->bus;
+ ScsiPassThruCmnd->SCp.have_data_in = vendor_cmd->pdrive;
+
+
+
+ // We copy the scheme used by scsi.c to submit commands
+ // to our own HBA. We do this in order to stall the
+ // thread calling the IOCTL until it completes, and use
+ // the same "_quecommand" function for synchronizing
+ // FC Link events with our "worker thread".
+
+ spin_lock_irqsave(&io_request_lock, flags);
+ {
+ DECLARE_MUTEX_LOCKED(sem);
+ ScsiPassThruCmnd->request.sem = &sem;
+ // eventually gets us to our own _quecommand routine
+ scsi_do_cmd( ScsiPassThruCmnd, &vendor_cmd->cdb[0],
+ buf,
+ vendor_cmd->len,
+ my_ioctl_done,
+ 10*HZ, 1);// timeout,retries
+ spin_unlock_irqrestore(&io_request_lock, flags);
+ // Other I/Os can now resume; we wait for our ioctl
+ // command to complete
+ down(&sem);
+ spin_lock_irqsave(&io_request_lock, flags);
+ ScsiPassThruCmnd->request.sem = NULL;
+ }
+
+ result = ScsiPassThruCmnd->result;
+
+ // copy any sense data back to caller
+ if( result != 0 )
+ {
+ memcpy( vendor_cmd->sense_data, // see struct def - size=40
+ ScsiPassThruCmnd->sense_buffer,
+ sizeof(ScsiPassThruCmnd->sense_buffer));
+ }
+ SDpnt = ScsiPassThruCmnd->device;
+ scsi_release_command(ScsiPassThruCmnd); // "de-allocate"
+ ScsiPassThruCmnd = NULL;
+
+ if (!SDpnt->was_reset && SDpnt->scsi_request_fn)
+ (*SDpnt->scsi_request_fn)();
+
+ wake_up(&SDpnt->device_wait);
+ spin_unlock_irqrestore(&io_request_lock, flags);
+
+ // need to pass data back to user (space)?
+ if( (vendor_cmd->rw_flag == VENDOR_READ_OPCODE) &&
+ vendor_cmd->len )
+ copy_to_user_ret( vendor_cmd->bufp, buf, vendor_cmd->len, -EFAULT);
+
+ if( buf)
+ kfree( buf);
+
+ return result;
+ }
+
+ case CPQFCTS_GETPCIINFO:
+ {
+ cpqfc_pci_info_struct pciinfo;
+
+ if( !arg)


+ return -EINVAL;
+
+

+
+ pciinfo.bus = cpqfcHBAdata->PciDev->bus->number;
+ pciinfo.dev_fn = cpqfcHBAdata->PciDev->devfn;
+ pciinfo.board_id = cpqfcHBAdata->PciDev->device |
+ (cpqfcHBAdata->PciDev->vendor <<16);
+
+ copy_to_user_ret( arg, &pciinfo,
+ sizeof(cpqfc_pci_info_struct), -EFAULT);


+ return 0;
+ }
+

+ case CPQFCTS_GETDRIVVER:
+ {
+ DriverVer_type DriverVer =
+ CPQFCTS_DRIVER_VER( VER_MAJOR,VER_MINOR,VER_SUBMINOR);
+
+ if( !arg)
+ return -EINVAL;
+
+ copy_to_user_ret( arg, &DriverVer,
+ sizeof(DriverVer), -EFAULT);


+ return 0;
+ }
+
+
+

+ case SCSI_IOCTL_FC_TARGET_ADDRESS:
+ result =
+ verify_area(VERIFY_WRITE, arg, sizeof(Scsi_FCTargAddress));
+ if (result)
+ break;
+
+ put_user(pLoggedInPort->port_id,
+ &((Scsi_FCTargAddress *) arg)->host_port_id);
+
+ for( i=3,j=0; i>=0; i--) // copy the LOGIN port's WWN
+ put_user(pLoggedInPort->u.ucWWN[i],
+ &((Scsi_FCTargAddress *) arg)->host_wwn[j++]);
+ for( i=7; i>3; i--) // copy the LOGIN port's WWN
+ put_user(pLoggedInPort->u.ucWWN[i],
+ &((Scsi_FCTargAddress *) arg)->host_wwn[j++]);
+ break;
+ default:
+ result = -EINVAL;


+ break;
+ }
+ }
+

+ LEAVE("cpqfcTS_ioctl");
+ return result;
+}
+
+
+/* "Release" the Host Bus Adapter...
+ disable interrupts, stop the HBA, release the interrupt,
+ and free all resources */
+
+int cpqfcTS_release(struct Scsi_Host *HostAdapter)
+{
+ CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
+
+
+ ENTER("cpqfcTS_release");
+
+ DEBUG_PCI( printk(" cpqfcTS: delete timer...\n"));
+ del_timer( &cpqfcHBAdata->cpqfcTStimer);
+
+ // disable the hardware...
+ DEBUG_PCI( printk(" disable hardware, destroy queues, free mem\n"));
+ cpqfcHBAdata->fcChip.ResetTachyon( cpqfcHBAdata, CLEAR_FCPORTS);
+
+ // kill kernel thread
+ if( cpqfcHBAdata->worker_thread ) // (only if exists)
+ {
+ DECLARE_MUTEX_LOCKED(sem); // synchronize thread kill
+
+ cpqfcHBAdata->notify_wt = &sem;
+ DEBUG_PCI( printk(" killing kernel thread\n"));
+ send_sig( SIGKILL, cpqfcHBAdata->worker_thread, 1);
+ down( &sem);
+ cpqfcHBAdata->notify_wt = NULL;
+
+ }
+
+ // free Linux resources
+ DEBUG_PCI( printk(" cpqfcTS: freeing resources...\n"));
+ free_irq( HostAdapter->irq, HostAdapter);
+ scsi_unregister( HostAdapter);
+ release_region( cpqfcHBAdata->fcChip.Registers.IOBaseL, 0xff);
+ release_region( cpqfcHBAdata->fcChip.Registers.IOBaseU, 0xff);
+ /* we get "vfree: bad address" executing this - need to investigate...
+ if( (void*)((unsigned long)cpqfcHBAdata->fcChip.Registers.MemBase) !=
+ cpqfcHBAdata->fcChip.Registers.ReMapMemBase)
+ vfree( cpqfcHBAdata->fcChip.Registers.ReMapMemBase);
+*/
+
+ LEAVE("cpqfcTS_release");


+ return 0;
+}
+
+

+const char * cpqfcTS_info(struct Scsi_Host *HostAdapter)
+{
+ static char buf[300];
+ CPQFCHBA *cpqfcHBA;
+ int BusSpeed, BusWidth;
+
+ // get the pointer to our Scsi layer HBA buffer
+ cpqfcHBA = (CPQFCHBA *)HostAdapter->hostdata;
+
+ BusWidth = (cpqfcHBA->fcChip.Registers.PCIMCTR &0x4) > 0 ?
+ 64 : 32;
+
+ if( cpqfcHBA->fcChip.Registers.TYconfig.value & 0x80000000)
+ BusSpeed = 66;
+ else
+ BusSpeed = 33;
+
+ sprintf(buf,
+"%s: WWN %08X%08X\n on PCI bus %d device 0x%02x irq %d IObaseL 0x%x, MEMBASE 0x%x\nPCI bus width %d bits, bus speed %d MHz\nFCP-SCSI Driver v%d.%d.%d",
+ cpqfcHBA->fcChip.Name,
+ cpqfcHBA->fcChip.Registers.wwn_hi,
+ cpqfcHBA->fcChip.Registers.wwn_lo,
+ cpqfcHBA->PciDev->bus->number,
+ cpqfcHBA->PciDev->device,
+ HostAdapter->irq,
+ cpqfcHBA->fcChip.Registers.IOBaseL,
+ cpqfcHBA->fcChip.Registers.MemBase,
+ BusWidth,
+ BusSpeed,
+ VER_MAJOR, VER_MINOR, VER_SUBMINOR
+);
+
+
+ cpqfcTSDecodeGBICtype( &cpqfcHBA->fcChip, &buf[ strlen(buf)]);
+ cpqfcTSGetLPSM( &cpqfcHBA->fcChip, &buf[ strlen(buf)]);
+ return buf;
+}
+
+//
+// /proc/scsi support. The following routines allow us to do 'normal'
+// sprintf like calls to return the currently requested piece (buflenght
+// chars, starting at bufoffset) of the file. Although procfs allows for
+// a 1 Kb bytes overflow after te supplied buffer, I consider it bad
+// programming to use it to make programming a little simpler. This piece
+// of coding is borrowed from ncr53c8xx.c with some modifications
+//
+struct info_str
+{
+ char *buffer; // Pointer to output buffer
+ int buflength; // It's length
+ int bufoffset; // File offset corresponding with buf[0]
+ int buffillen; // Current filled length
+ int filpos; // Current file offset
+};
+
+static void copy_mem_info(struct info_str *info, char *data, int datalen)
+{
+
+ if (info->filpos < info->bufoffset) { // Current offset before buffer offset
+ if (info->filpos + datalen <= info->bufoffset) {
+ info->filpos += datalen; // Discard if completely before buffer
+ return;
+ } else { // Partial copy, set to begin
+ data += (info->bufoffset - info->filpos);
+ datalen -= (info->bufoffset - info->filpos);
+ info->filpos = info->bufoffset;
+ }
+ }
+
+ info->filpos += datalen; // Update current offset
+
+ if (info->buffillen == info->buflength) // Buffer full, discard
+ return;
+
+ if (info->buflength - info->buffillen < datalen) // Overflows buffer ?
+ datalen = info->buflength - info->buffillen;
+
+ memcpy(info->buffer + info->buffillen, data, datalen);
+ info->buffillen += datalen;
+}
+
+static int copy_info(struct info_str *info, char *fmt, ...)
+{
+ va_list args;
+ char buf[400];
+ int len;
+
+ va_start(args, fmt);
+ len = vsprintf(buf, fmt, args);
+ va_end(args);
+
+ copy_mem_info(info, buf, len);
+ return len;
+}
+
+
+// Routine to get data for /proc RAM filesystem
+//
+int cpqfcTS_proc_info (char *buffer, char **start, off_t offset, int length,
+ int hostno, int inout)
+{
+ struct Scsi_Host *host;
+ Scsi_Cmnd DumCmnd;
+ int Chan, Targ, i;
+ struct info_str info;
+ CPQFCHBA *cpqfcHBA;
+ PTACHYON fcChip;
+ PFC_LOGGEDIN_PORT pLoggedInPort;
+ char buf[81];
+
+ // Search the Scsi host list for our controller
+ for (host=scsi_hostlist; host; host=host->next)
+ if (host->host_no == hostno)
+ break;
+
+ if (!host) return -ESRCH;
+
+ if (inout) return -EINVAL;
+
+ // get the pointer to our Scsi layer HBA buffer
+ cpqfcHBA = (CPQFCHBA *)host->hostdata;
+ fcChip = &cpqfcHBA->fcChip;
+
+ *start = buffer;
+
+ info.buffer = buffer;
+ info.buflength = length;
+ info.bufoffset = offset;
+ info.filpos = 0;
+ info.buffillen = 0;
+ copy_info(&info, "Driver version = %d.%d.%d", VER_MAJOR, VER_MINOR, VER_SUBMINOR);
+ cpqfcTSDecodeGBICtype( &cpqfcHBA->fcChip, &buf[0]);
+ cpqfcTSGetLPSM( &cpqfcHBA->fcChip, &buf[ strlen(buf)]);
+ copy_info(&info, "%s\n", buf);
+
+
+#define DISPLAY_WWN_INFO
+#ifdef DISPLAY_WWN_INFO
+ copy_info(&info, "WWN database: (\"port_id: 000000\" means disconnected)\n");
+ for ( Chan=0; Chan <= host->max_channel; Chan++) {
+ DumCmnd.channel = Chan;
+ for (Targ=0; Targ <= host->max_id; Targ++) {
+ DumCmnd.target = Targ;
+ if ((pLoggedInPort = fcFindLoggedInPort( fcChip,
+ &DumCmnd, // search Scsi Nexus
+ 0, // DON'T search list for FC port id
+ NULL, // DON'T search list for FC WWN
+ NULL))){ // DON'T care about end of list
+ copy_info(&info, "Host: scsi%d Channel: %02d TargetId: %02d -> WWN: ",
+ hostno, Chan, Targ);
+ for( i=3; i>=0; i--) // copy the LOGIN port's WWN
+ copy_info(&info, "%02X", pLoggedInPort->u.ucWWN[i]);
+ for( i=7; i>3; i--) // copy the LOGIN port's WWN
+ copy_info(&info, "%02X", pLoggedInPort->u.ucWWN[i]);
+ copy_info(&info, " port_id: %06X\n", pLoggedInPort->port_id);
+ }


+ }
+ }
+#endif
+
+

+// Unfortunately, the proc_info buffer isn't big enough
+// for everything we would like...
+// For FC stats, compile this and turn off WWN stuff above
+//#define DISPLAY_FC_STATS
+#ifdef DISPLAY_FC_STATS
+// get the Fibre Channel statistics
+ {
+ int DeltaSecs = (jiffies - cpqfcHBA->fcStatsTime) / HZ;
+ int days,hours,minutes,secs;
+
+ days = DeltaSecs / (3600*24); // days
+ hours = (DeltaSecs% (3600*24)) / 3600; // hours
+ minutes = (DeltaSecs%3600 /60); // minutes
+ secs = DeltaSecs%60; // secs
+copy_info( &info, "Fibre Channel Stats (time dd:hh:mm:ss %02u:%02u:%02u:%02u\n",
+ days, hours, minutes, secs);
+ }
+
+ cpqfcHBA->fcStatsTime = jiffies; // (for next delta)
+
+ copy_info( &info, " LinkUp %9u LinkDown %u\n",
+ fcChip->fcStats.linkUp, fcChip->fcStats.linkDown);
+
+ copy_info( &info, " Loss of Signal %9u Loss of Sync %u\n",
+ fcChip->fcStats.LossofSignal, fcChip->fcStats.LossofSync);
+
+ copy_info( &info, " Discarded Frames %9u Bad CRC Frame %u\n",
+ fcChip->fcStats.Dis_Frm, fcChip->fcStats.Bad_CRC);
+
+ copy_info( &info, " TACH LinkFailTX %9u TACH LinkFailRX %u\n",
+ fcChip->fcStats.linkFailTX, fcChip->fcStats.linkFailRX);
+
+ copy_info( &info, " TACH RxEOFa %9u TACH Elastic Store %u\n",
+ fcChip->fcStats.Rx_EOFa, fcChip->fcStats.e_stores);
+
+ copy_info( &info, " BufferCreditWait %9uus TACH FM Inits %u\n",
+ fcChip->fcStats.BB0_Timer*10, fcChip->fcStats.FMinits );
+
+ copy_info( &info, " FC-2 Timeouts %9u FC-2 Logouts %u\n",
+ fcChip->fcStats.timeouts, fcChip->fcStats.logouts);
+
+ copy_info( &info, " FC-2 Aborts %9u FC-4 Aborts %u\n",
+ fcChip->fcStats.FC2aborted, fcChip->fcStats.FC4aborted);
+
+ // clear the counters
+ cpqfcTSClearLinkStatusCounters( fcChip);
+#endif
+
+ return info.buffillen;
+}
+
+
+#if DEBUG_CMND
+
+UCHAR *ScsiToAscii( UCHAR ScsiCommand)
+{
+
+/*++
+
+Routine Description:
+
+ Converts a SCSI command to a text string for debugging purposes.
+
+
+Arguments:
+
+ ScsiCommand -- hex value SCSI Command
+
+
+Return Value:
+
+ An ASCII, null-terminated string if found, else returns NULL.
+
+Original code from M. McGowen, Compaq
+--*/
+
+
+ switch (ScsiCommand)
+ {
+ case 0x00:
+ return( "Test Unit Ready" );
+
+ case 0x01:
+ return( "Rezero Unit or Rewind" );
+
+ case 0x02:
+ return( "Request Block Address" );
+
+ case 0x03:
+ return( "Requese Sense" );
+
+ case 0x04:
+ return( "Format Unit" );
+
+ case 0x05:
+ return( "Read Block Limits" );
+
+ case 0x07:
+ return( "Reassign Blocks" );
+
+ case 0x08:
+ return( "Read (6)" );
+
+ case 0x0a:
+ return( "Write (6)" );
+
+ case 0x0b:
+ return( "Seek (6)" );
+
+ case 0x12:
+ return( "Inquiry" );
+
+ case 0x15:
+ return( "Mode Select (6)" );
+
+ case 0x16:
+ return( "Reserve" );
+
+ case 0x17:
+ return( "Release" );
+
+ case 0x1a:
+ return( "ModeSen(6)" );
+
+ case 0x1b:
+ return( "Start/Stop Unit" );
+
+ case 0x1c:
+ return( "Receive Diagnostic Results" );
+
+ case 0x1d:
+ return( "Send Diagnostic" );
+
+ case 0x25:
+ return( "Read Capacity" );
+
+ case 0x28:
+ return( "Read (10)" );
+
+ case 0x2a:
+ return( "Write (10)" );
+
+ case 0x2b:
+ return( "Seek (10)" );
+
+ case 0x2e:
+ return( "Write and Verify" );
+
+ case 0x2f:
+ return( "Verify" );
+
+ case 0x34:
+ return( "Pre-Fetch" );
+
+ case 0x35:
+ return( "Synchronize Cache" );
+
+ case 0x37:
+ return( "Read Defect Data (10)" );
+
+ case 0x3b:
+ return( "Write Buffer" );
+
+ case 0x3c:
+ return( "Read Buffer" );
+
+ case 0x3e:
+ return( "Read Long" );
+
+ case 0x3f:
+ return( "Write Long" );
+
+ case 0x41:
+ return( "Write Same" );
+
+ case 0x4c:
+ return( "Log Select" );
+
+ case 0x4d:
+ return( "Log Sense" );
+
+ case 0x56:
+ return( "Reserve (10)" );
+
+ case 0x57:
+ return( "Release (10)" );
+
+ case 0xa0:
+ return( "ReportLuns" );
+
+ case 0xb7:
+ return( "Read Defect Data (12)" );
+
+ case 0xca:
+ return( "Peripheral Device Addressing SCSI Passthrough" );
+
+ case 0xcb:
+ return( "Compaq Array Firmware Passthrough" );
+
+ default:
+ return( NULL );
+ }
+
+} // end ScsiToAscii()
+
+void cpqfcTS_print_scsi_cmd(Scsi_Cmnd * cmd)
+{
+
+printk("cpqfcTS: (%s) chnl 0x%02x, trgt = 0x%02x, lun = 0x%02x, cmd_len = 0x%02x\n",
+ ScsiToAscii( cmd->cmnd[0]), cmd->channel, cmd->target, cmd->lun, cmd->cmd_len);
+
+if( cmd->cmnd[0] == 0) // Test Unit Ready?


+{
+ int i;
+

+ printk("Cmnd->request_bufflen = 0x%X, ->use_sg = %d, ->bufflen = %d\n",
+ cmd->request_bufflen, cmd->use_sg, cmd->bufflen);
+ printk("Cmnd->request_buffer = %p, ->sglist_len = %d, ->buffer = %p\n",
+ cmd->request_buffer, cmd->sglist_len, cmd->buffer);
+ for (i = 0; i < cmd->cmd_len; i++)
+ printk("0x%02x ", cmd->cmnd[i]);
+ printk("\n");
+}
+
+}
+
+#endif /* DEBUG_CMND */
+
+
+
+
+static void QueCmndOnBoardLock( CPQFCHBA *cpqfcHBAdata, Scsi_Cmnd *Cmnd)
+{
+ int i;
+
+ for( i=0; i< CPQFCTS_REQ_QUEUE_LEN; i++)
+ { // find spare slot
+ if( cpqfcHBAdata->BoardLockCmnd[i] == NULL )
+ {
+ cpqfcHBAdata->BoardLockCmnd[i] = Cmnd;
+// printk(" BoardLockCmnd[%d] %p Queued, chnl/target/lun %d/%d/%d\n",
+// i,Cmnd, Cmnd->channel, Cmnd->target, Cmnd->lun);
+ break;
+ }
+ }
+ if( i >= CPQFCTS_REQ_QUEUE_LEN)
+ {
+ printk(" cpqfcTS WARNING: Lost Cmnd %p on BoardLock Q full!", Cmnd);


+ }
+
+}
+
+

+static void QueLinkDownCmnd( CPQFCHBA *cpqfcHBAdata, Scsi_Cmnd *Cmnd)
+{
+ int indx;
+
+ // Remember the command ptr so we can return; we'll complete when
+ // the device comes back, causing immediate retry
+ for( indx=0; indx < CPQFCTS_REQ_QUEUE_LEN; indx++)//, SCptr++)
+ {
+ if( cpqfcHBAdata->LinkDnCmnd[indx] == NULL ) // available?
+ {
+#ifdef DUMMYCMND_DBG
+ printk(" @add Cmnd %p to LnkDnCmnd[%d]@ ", Cmnd,indx);
+#endif
+ cpqfcHBAdata->LinkDnCmnd[indx] = Cmnd;


+ break;
+ }
+ }
+

+ if( indx >= CPQFCTS_REQ_QUEUE_LEN ) // no space for Cmnd??
+ {
+ // this will result in an _abort call later (with possible trouble)
+ printk("no buffer for LinkDnCmnd!! %p\n", Cmnd);


+ }
+}
+
+
+
+
+

+// The file "hosts.h" says not to call scsi_done from
+// inside _queuecommand, so we'll do it from the heartbeat timer
+
+static void QueBadTargetCmnd( CPQFCHBA *cpqfcHBAdata, Scsi_Cmnd *Cmnd)
+{
+ int i;
+ // printk(" can't find target %d\n", Cmnd->target);
+
+ for( i=0; i< CPQFCTS_MAX_TARGET_ID; i++)
+ { // find spare slot
+ if( cpqfcHBAdata->BadTargetCmnd[i] == NULL )
+ {
+ cpqfcHBAdata->BadTargetCmnd[i] = Cmnd;
+// printk(" BadTargetCmnd[%d] %p Queued, chnl/target/lun %d/%d/%d\n",
+// i,Cmnd, Cmnd->channel, Cmnd->target, Cmnd->lun);


+ break;
+ }
+ }
+}
+
+

+// This is the "main" entry point for Linux Scsi commands --
+// it all starts here.
+
+int cpqfcTS_queuecommand(Scsi_Cmnd *Cmnd, void (* done)(Scsi_Cmnd *))
+{
+ struct Scsi_Host *HostAdapter = Cmnd->host;


+ CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;

+ TachFCHDR_GCMND fchs; // only use for FC destination id field
+ PFC_LOGGEDIN_PORT pLoggedInPort;
+ ULONG ulStatus, SESTtype;
+ LONG ExchangeID;
+
+
+
+
+ ENTER("cpqfcTS_queuecommand");
+
+ PCI_TRACEO( (ULONG)Cmnd, 0x98)
+
+
+ Cmnd->scsi_done = done;
+#ifdef DEBUG_CMND
+ cpqfcTS_print_scsi_cmd( Cmnd);
+#endif
+
+ // prevent board contention with kernel thread...

SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 073'
echo 'File patch-2.4.0-test9 is continued in part 074'
echo "074" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part074

#!/bin/sh -x
# this is part 074 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 074; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&
+

+ if( cpqfcHBAdata->BoardLock )
+ {
+// printk(" @BrdLck Hld@ ");
+ QueCmndOnBoardLock( cpqfcHBAdata, Cmnd);
+ }


+
+ else
+ {
+

+ // in the current system (2.2.12), this routine is called
+ // after spin_lock_irqsave(), so INTs are disabled. However,
+ // we might have something pending in the LinkQ, which
+ // might cause the WorkerTask to run. In case that
+ // happens, make sure we lock it out.
+
+
+
+ PCI_TRACE( 0x98)
+ CPQ_SPINLOCK_HBA( cpqfcHBAdata)
+ PCI_TRACE( 0x98)

+
+ // can we find an FC device mapping to this SCSI target?

+ pLoggedInPort = fcFindLoggedInPort( fcChip,

+ Cmnd, // search Scsi Nexus


+ 0, // DON'T search linked list for FC port id
+ NULL, // DON'T search linked list for FC WWN
+ NULL); // DON'T care about end of list
+
+ if( pLoggedInPort == NULL ) // not found!
+ {

+// printk(" @Q bad targ cmnd %p@ ", Cmnd);
+ QueBadTargetCmnd( cpqfcHBAdata, Cmnd);
+ }
+
+ else // we know what FC device to send to...
+ {
+
+ // does this device support FCP target functions?
+ // (determined by PRLI field)
+
+ if( !(pLoggedInPort->fcp_info & TARGET_FUNCTION) )
+ {
+ printk(" Doesn't support TARGET functions port_id %Xh\n",
+ pLoggedInPort->port_id );
+ QueBadTargetCmnd( cpqfcHBAdata, Cmnd);
+ }
+
+ // In this case (previous login OK), the device is temporarily
+ // unavailable waiting for re-login, in which case we expect it
+ // to be back in between 25 - 500ms.
+ // If the FC port doesn't log back in within several seconds
+ // (i.e. implicit "logout"), or we get an explicit logout,
+ // we set "device_blocked" in Scsi_Device struct; in this
+ // case 30 seconds will elapse before Linux/Scsi sends another
+ // command to the device.
+ else if( pLoggedInPort->prli != TRUE )
+ {
+// printk("Device (Chnl/Target %d/%d) invalid PRLI, port_id %06lXh\n",
+// Cmnd->channel, Cmnd->target, pLoggedInPort->port_id);
+ QueLinkDownCmnd( cpqfcHBAdata, Cmnd);
+// Need to use "blocked" flag??
+// Cmnd->device->device_blocked = TRUE; // just let it timeout
+ }
+ else // device supports TARGET functions, and is logged in...
+ {
+ // (context of fchs is to "reply" to...)
+ fchs.s_id = pLoggedInPort->port_id; // destination FC address
+
+ // what is the data direction? For data TO the device,
+ // we need IWE (Intiator Write Entry). Otherwise, IRE.
+
+ if( Cmnd->cmnd[0] == WRITE_10 ||
+ Cmnd->cmnd[0] == WRITE_6 ||
+ Cmnd->cmnd[0] == WRITE_BUFFER ||
+ Cmnd->cmnd[0] == VENDOR_WRITE_OPCODE || // CPQ specific
+ Cmnd->cmnd[0] == MODE_SELECT )
+ {
+ SESTtype = SCSI_IWE; // data from HBA to Device
+ }
+ else
+ SESTtype = SCSI_IRE; // data from Device to HBA
+
+ ulStatus = cpqfcTSBuildExchange(
+ cpqfcHBAdata,
+ SESTtype, // e.g. Initiator Read Entry (IRE)
+ &fchs, // we are originator; only use d_id
+ Cmnd, // Linux SCSI command (with scatter/gather list)
+ &ExchangeID );// fcController->fcExchanges index, -1 if failed
+
+ if( !ulStatus ) // Exchange setup?
+
+ {
+ if( cpqfcHBAdata->BoardLock )
+ {
+ TriggerHBA( fcChip->Registers.ReMapMemBase, 0);
+ printk(" @bl! %d, xID %Xh@ ", current->pid, ExchangeID);
+ }
+
+ ulStatus = cpqfcTSStartExchange( cpqfcHBAdata, ExchangeID );
+ if( !ulStatus )
+ {
+ PCI_TRACEO( ExchangeID, 0xB8)
+ // submitted to Tach's Outbound Que (ERQ PI incremented)
+ // waited for completion for ELS type (Login frames issued
+ // synchronously)
+ }
+ else
+ // check reason for Exchange not being started - we might
+ // want to Queue and start later, or fail with error
+ {
+ printk("quecommand: cpqfcTSStartExchange failed: %Xh\n", ulStatus );
+ }
+ } // end good BuildExchange status
+
+ else // SEST table probably full -- why? hardware hang?
+ {
+ printk("quecommand: cpqfcTSBuildExchange faild: %Xh\n", ulStatus);
+ }
+ } // end can't do FCP-SCSI target functions
+ } // end can't find target (FC device)
+
+ CPQ_SPINUNLOCK_HBA( cpqfcHBAdata)
+ }
+
+ PCI_TRACEO( (ULONG)Cmnd, 0x9C)
+ LEAVE("cpqfcTS_queuecommand");


+ return 0;
+}
+
+

+// Entry point for upper Scsi layer intiated abort. Typically
+// this is called if the command (for hard disk) fails to complete
+// in 30 seconds. This driver intends to complete all disk commands
+// within Exchange ".timeOut" seconds (now 7) with target status, or
+// in case of ".timeOut" expiration, a DID_SOFT_ERROR which causes
+// immediate retry.
+// If any disk commands get the _abort call, except for the case that
+// the physical device was removed or unavailable due to hardware
+// errors, it should be considered a driver error and reported to
+// the author.
+
+int cpqfcTS_abort(Scsi_Cmnd *Cmnd)


+{
+ struct Scsi_Host *HostAdapter = Cmnd->host;

+ // get the pointer to our Scsi layer HBA buffer

+ CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;

+ FC_EXCHANGES *Exchanges = fcChip->Exchanges;

+ int i;
+ ENTER("cpqfcTS_abort");
+
+ Cmnd->result = DID_ABORT <<16; // assume we'll find it
+
+ printk(" @Linux _abort Scsi_Cmnd %p ", Cmnd);
+ // See if we can find a Cmnd pointer that matches...
+ // The most likely case is we accepted the command
+ // from Linux Scsi (e.g. ceated a SEST entry) and it
+ // got lost somehow. If we can't find any reference
+ // to the passed pointer, we can only presume it
+ // got completed as far as our driver is concerned.
+ // If we found it, we will try to abort it through
+ // common mechanism. If FC ABTS is successful (ACC)
+ // or is rejected (RJT) by target, we will call
+ // Scsi "done" quickly. Otherwise, the ABTS will timeout
+ // and we'll call "done" later.
+
+ // Search the SEST exchanges for a matching Cmnd ptr.
+ for( i=0; i< TACH_SEST_LEN; i++)
+ {
+ if( Exchanges->fcExchange[i].Cmnd == Cmnd )
+ {
+
+ // found it!
+ printk(" x_ID %Xh, type %Xh\n", i, Exchanges->fcExchange[i].type);
+
+ Exchanges->fcExchange[i].status = INITIATOR_ABORT; // seconds default
+ Exchanges->fcExchange[i].timeOut = 10; // seconds default (changed later)
+
+ // Since we need to immediately return the aborted Cmnd to Scsi
+ // upper layers, we can't make future reference to any of it's
+ // fields (e.g the Nexus).
+
+ cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &i);
+


+ break;
+ }
+ }
+

+ if( i >= TACH_SEST_LEN ) // didn't find Cmnd ptr in chip's SEST?
+ {
+ // now search our non-SEST buffers (i.e. Cmnd waiting to
+ // start on the HBA or waiting to complete with error for retry).
+
+ // first check BadTargetCmnd


+ for( i=0; i< CPQFCTS_MAX_TARGET_ID; i++)
+ {

+ if( cpqfcHBAdata->BadTargetCmnd[i] == Cmnd )
+ {
+ cpqfcHBAdata->BadTargetCmnd[i] = NULL;
+ printk("in BadTargetCmnd Q\n");
+ goto Done; // exit
+ }
+ }
+
+ // if not found above...


+
+ for( i=0; i < CPQFCTS_REQ_QUEUE_LEN; i++)
+ {

+ if( cpqfcHBAdata->LinkDnCmnd[i] == Cmnd )
+ {
+ cpqfcHBAdata->LinkDnCmnd[i] = NULL;
+ printk("in LinkDnCmnd Q\n");
+ goto Done;
+ }
+ }
+
+


+ for( i=0; i< CPQFCTS_REQ_QUEUE_LEN; i++)
+ { // find spare slot

+ if( cpqfcHBAdata->BoardLockCmnd[i] == Cmnd )
+ {
+ cpqfcHBAdata->BoardLockCmnd[i] = NULL;
+ printk("in BoardLockCmnd Q\n");
+ goto Done;
+ }
+ }
+
+ Cmnd->result = DID_ERROR <<16; // Hmmm...
+ printk("Not found! ");
+// panic("_abort");
+ }
+
+Done:
+
+// panic("_abort");
+ LEAVE("cpqfcTS_abort");
+ return 0; // (see scsi.h)


+}
+
+
+
+

+// To be done...
+int cpqfcTS_reset(Scsi_Cmnd *Cmnd, unsigned int reset_flags)
+{
+ int return_status = SUCCESS;
+
+ ENTER("cpqfcTS_reset");
+
+
+
+
+ LEAVE("cpqfcTS_reset");
+ return return_status;
+}
+
+
+
+/* This function determines the bios parameters for a given
+ harddisk. These tend to be numbers that are made up by the
+ host adapter. Parameters:
+ size, device number, list (heads, sectors,cylinders).
+ (from hosts.h)
+*/
+
+int cpqfcTS_biosparam(Disk *disk, kdev_t n, int ip[])
+{
+ int size = disk->capacity;
+
+ ENTER("cpqfcTS_biosparam");
+ ip[0] = 64;
+ ip[1] = 32;
+ ip[2] = size >> 11;
+
+ if( ip[2] > 1024 )
+ {
+ ip[0] = 255;
+ ip[1] = 63;
+ ip[2] = size / (ip[0] * ip[1]);
+ }
+
+ LEAVE("cpqfcTS_biosparam");


+ return 0;
+}
+
+
+

+void cpqfcTS_intr_handler( int irq,
+ void *dev_id,
+ struct pt_regs *regs)
+{
+
+ unsigned long flags, InfLoopBrk=0;
+ struct Scsi_Host *HostAdapter = dev_id;
+ CPQFCHBA *cpqfcHBA = (CPQFCHBA *)HostAdapter->hostdata;
+ int MoreMessages = 1; // assume we have something to do
+ UCHAR IntPending;
+
+ ENTER("intr_handler");
+
+ spin_lock_irqsave( &io_request_lock, flags);
+ // is this our INT?
+ IntPending = readb( cpqfcHBA->fcChip.Registers.INTPEND.address);
+
+ // broken boards can generate messages forever, so
+ // prevent the infinite loop
+#define INFINITE_IMQ_BREAK 10000
+ if( IntPending )
+ {
+
+ // mask our HBA interrupts until we handle it...
+ writeb( 0, cpqfcHBA->fcChip.Registers.INTEN.address);
+
+ if( IntPending & 0x4) // "INT" - Tach wrote to IMQ
+ {
+ while( (++InfLoopBrk < INFINITE_IMQ_BREAK) && (MoreMessages ==1) )
+ {
+ MoreMessages = CpqTsProcessIMQEntry( HostAdapter); // ret 0 when done
+ }
+ if( InfLoopBrk >= INFINITE_IMQ_BREAK )
+ {
+ printk("WARNING: Compaq FC adapter generating excessive INTs -REPLACE\n");
+ printk("or investigate alternate causes (e.g. physical FC layer)\n");
+ }
+
+ else // working normally - re-enable INTs and continue
+ writeb( 0x1F, cpqfcHBA->fcChip.Registers.INTEN.address);
+
+ } // (...ProcessIMQEntry() clears INT by writing IMQ consumer)
+ else // indications of errors or problems...
+ // these usually indicate critical system hardware problems.
+ {
+ if( IntPending & 0x10 )
+ printk(" cpqfcTS adapter external memory parity error detected\n");
+ if( IntPending & 0x8 )
+ printk(" cpqfcTS adapter PCI master address crossed 45-bit boundary\n");
+ if( IntPending & 0x2 )
+ printk(" cpqfcTS adapter DMA error detected\n");
+ if( IntPending & 0x1 )
+ printk(" cpqfcTS adapter PCI error detected\n");
+ }
+ }
+ spin_unlock_irqrestore( &io_request_lock, flags);
+ LEAVE("intr_handler");


+}
+
+
+
+

+int cpqfcTSDecodeGBICtype( PTACHYON fcChip, char cErrorString[])
+{
+ // Verify GBIC type (if any) and correct Tachyon Port State Machine
+ // (GBIC) module definition is:
+ // GPIO1, GPIO0, GPIO4 for MD2, MD1, MD0. The input states appear
+ // to be inverted -- i.e., a setting of 111 is read when there is NO
+ // GBIC present. The Module Def (MD) spec says 000 is "no GBIC"
+ // Hard code the bit states to detect Copper,
+ // Long wave (single mode), Short wave (multi-mode), and absent GBIC
+
+ ULONG ulBuff;
+
+ sprintf( cErrorString, "\nGBIC detected: ");
+
+ ulBuff = fcChip->Registers.TYstatus.value & 0x13;
+ switch( ulBuff )
+ {
+ case 0x13: // GPIO4, GPIO1, GPIO0 = 111; no GBIC!
+ sprintf( &cErrorString[ strlen( cErrorString)],
+ "NONE! ");


+ return FALSE;
+
+

+ case 0x11: // Copper GBIC detected
+ sprintf( &cErrorString[ strlen( cErrorString)],
+ "Copper. ");
+ break;
+
+ case 0x10: // Long-wave (single mode) GBIC detected
+ sprintf( &cErrorString[ strlen( cErrorString)],
+ "Long-wave. ");
+ break;
+ case 0x1: // Short-wave (multi mode) GBIC detected
+ sprintf( &cErrorString[ strlen( cErrorString)],
+ "Short-wave. ");
+ break;
+ default: // unknown GBIC - presumably it will work (?)
+ sprintf( &cErrorString[ strlen( cErrorString)],
+ "Unknown. ");
+
+ break;
+ } // end switch GBIC detection
+
+ return TRUE;


+}
+
+
+
+
+
+

+int cpqfcTSGetLPSM( PTACHYON fcChip, char cErrorString[])
+{
+ // Tachyon's Frame Manager LPSM in LinkDown state?
+ // (For non-loop port, check PSM instead.)
+ // return string with state and FALSE is Link Down
+
+ int LinkUp;
+
+ if( fcChip->Registers.FMstatus.value & 0x80 )
+ LinkUp = FALSE;
+ else
+ LinkUp = TRUE;
+
+ sprintf( &cErrorString[ strlen( cErrorString)],
+ " LPSM %Xh ",
+ (fcChip->Registers.FMstatus.value >>4) & 0xf );
+
+
+ switch( fcChip->Registers.FMstatus.value & 0xF0)
+ {
+ // bits set in LPSM
+ case 0x10:
+ sprintf( &cErrorString[ strlen( cErrorString)], "ARB");
+ break;
+ case 0x20:
+ sprintf( &cErrorString[ strlen( cErrorString)], "ARBwon");
+ break;
+ case 0x30:
+ sprintf( &cErrorString[ strlen( cErrorString)], "OPEN");
+ break;
+ case 0x40:
+ sprintf( &cErrorString[ strlen( cErrorString)], "OPENed");
+ break;
+ case 0x50:
+ sprintf( &cErrorString[ strlen( cErrorString)], "XmitCLS");
+ break;
+ case 0x60:
+ sprintf( &cErrorString[ strlen( cErrorString)], "RxCLS");
+ break;
+ case 0x70:
+ sprintf( &cErrorString[ strlen( cErrorString)], "Xfer");
+ break;
+ case 0x80:
+ sprintf( &cErrorString[ strlen( cErrorString)], "Init");
+ break;
+ case 0x90:
+ sprintf( &cErrorString[ strlen( cErrorString)], "O-IInitFin");
+ break;
+ case 0xa0:
+ sprintf( &cErrorString[ strlen( cErrorString)], "O-IProtocol");
+ break;
+ case 0xb0:
+ sprintf( &cErrorString[ strlen( cErrorString)], "O-ILipRcvd");
+ break;
+ case 0xc0:
+ sprintf( &cErrorString[ strlen( cErrorString)], "HostControl");
+ break;
+ case 0xd0:
+ sprintf( &cErrorString[ strlen( cErrorString)], "LoopFail");
+ break;
+ case 0xe0:
+ sprintf( &cErrorString[ strlen( cErrorString)], "Offline");
+ break;
+ case 0xf0:
+ sprintf( &cErrorString[ strlen( cErrorString)], "OldPort");
+ break;
+ case 0:
+ default:
+ sprintf( &cErrorString[ strlen( cErrorString)], "Monitor");


+ break;
+
+ }
+

+ return LinkUp;


+}
+
+
+
+

+#include "linux/malloc.h"
+
+// Dynamic memory allocation alignment routines
+// HP's Tachyon Fibre Channel Controller chips require
+// certain memory queues and register pointers to be aligned
+// on various boundaries, usually the size of the Queue in question.
+// Alignment might be on 2, 4, 8, ... or even 512 byte boundaries.
+// Since most O/Ss don't allow this (usually only Cache aligned -
+// 32-byte boundary), these routines provide generic alignment (after
+// O/S allocation) at any boundary, and store the original allocated
+// pointer for deletion (O/S free function). Typically, we expect
+// these functions to only be called at HBA initialization and
+// removal time (load and unload times)
+// ALGORITHM notes:
+// Memory allocation varies by compiler and platform. In the worst case,
+// we are only assured BYTE allignment, but in the best case, we can
+// request allocation on any desired boundary. Our strategy: pad the
+// allocation request size (i.e. waste memory) so that we are assured
+// of passing desired boundary near beginning of contiguous space, then
+// mask out lower address bits.
+// We define the following algorithm:
+// allocBoundary - compiler/platform specific address alignment
+// in number of bytes (default is single byte; i.e. 1)
+// n_alloc - number of bytes application wants @ aligned address
+// ab - alignment boundary, in bytes (e.g. 4, 32, ...)
+// t_alloc - total allocation needed to ensure desired boundary
+// mask - to clear least significant address bits for boundary
+// Compute:
+// t_alloc = n_alloc + (ab - allocBoundary)
+// allocate t_alloc bytes @ alloc_address
+// mask = NOT (ab - 1)
+// (e.g. if ab=32 _0001 1111 -> _1110 0000
+// aligned_address = alloc_address & mask
+// set n_alloc bytes to 0
+// return aligned_address (NULL if failed)
+//
+// If u32_AlignedAddress is non-zero, then search for BaseAddress (stored
+// from previous allocation). If found, invoke call to FREE the memory.
+// Return NULL if BaseAddress not found
+
+// we need about 8 allocations per HBA. Figuring at most 10 HBAs per server
+// size the dynamic_mem array at 80.
+
+void* fcMemManager( ALIGNED_MEM *dynamic_mem, ULONG n_alloc, ULONG ab,
+ ULONG u32_AlignedAddress)
+{
+ USHORT allocBoundary=1; // compiler specific - worst case 1
+ // best case - replace malloc() call
+ // with function that allocates exactly
+ // at desired boundary
+
+ unsigned long ulAddress;
+ ULONG t_alloc, i;
+ void *alloc_address = 0; // def. error code / address not found
+ LONG mask; // must be 32-bits wide!
+
+ ENTER("fcMemManager");
+ if( u32_AlignedAddress ) // are we freeing existing memory?
+ {
+// printk(" freeing AlignedAddress %Xh\n", u32_AlignedAddress);
+ for( i=0; i<DYNAMIC_ALLOCATIONS; i++) // look for the base address
+ {
+// printk("dynamic_mem[%u].AlignedAddress %lX\n", i, dynamic_mem[i].AlignedAddress);
+ if( dynamic_mem[i].AlignedAddress == u32_AlignedAddress )
+ {
+ alloc_address = dynamic_mem[i].BaseAllocated; // 'success' status
+ kfree( dynamic_mem[i].BaseAllocated); // return pages to kernel
+ dynamic_mem[i].BaseAllocated = 0; // clear for next use
+ dynamic_mem[i].AlignedAddress = 0;
+ break; // quit for loop; done
+ }
+ }
+ }
+ else if( n_alloc ) // want new memory?
+ {
+ t_alloc = n_alloc + (ab - allocBoundary); // pad bytes for alignment
+// printk("kmalloc() for Tach alignment: %ld bytes\n", t_alloc);
+
+ alloc_address = // total bytes (NumberOfBytes)
+ kmalloc( t_alloc, GFP_KERNEL); // allow thread block to free pages
+
+
+ // now mask off least sig. bits of address
+ if( alloc_address ) // (only if non-NULL)
+ {
+ // find place to store ptr, so we
+ // can free it later...
+ for( i=0; i<DYNAMIC_ALLOCATIONS; i++) // look for free slot
+ {
+ if( dynamic_mem[i].BaseAllocated == 0) // take 1st available
+ {
+ dynamic_mem[i].BaseAllocated = alloc_address;// address from O/S
+ break;
+ }
+ }
+ mask = (LONG)(ab - 1); // mask all low-order bits
+ mask = ~mask; // invert bits
+
+ ulAddress = (unsigned long)alloc_address;
+
+ ulAddress += (ab - allocBoundary); // add the alignment bytes-
+ // then truncate address...
+ alloc_address = (void*)(ulAddress & mask);
+
+ dynamic_mem[i].AlignedAddress =
+ (ULONG)(ulAddress & mask); // 32bit Tach address
+ memset( alloc_address, 0, n_alloc ); // clear new memory
+ }
+ else // O/S dynamic mem alloc failed!
+ alloc_address = 0; // (for debugging breakpt)
+
+ }
+
+ LEAVE("fcMemManager");
+ return alloc_address; // good (or NULL) address


+}
+
+
+
+

+#ifdef MODULE
+
+Scsi_Host_Template driver_template = CPQFCTS;
+
+#include "scsi_module.c"


+
+
+#endif
+
+

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/cpqfcTSioctl.h linux/drivers/scsi/cpqfcTSioctl.h
--- v2.4.0-test8/linux/drivers/scsi/cpqfcTSioctl.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/cpqfcTSioctl.h Tue Sep 19 08:01:34 2000
@@ -0,0 +1,84 @@
+// for user apps, make sure data size types are defined
+// with
+
+
+#define CCPQFCTS_IOC_MAGIC 'Z'
+
+typedef struct
+{
+ __u8 bus;
+ __u8 dev_fn;
+ __u32 board_id;
+} cpqfc_pci_info_struct;
+
+typedef __u32 DriverVer_type;
+/*
+typedef union
+{
+ struct // Peripheral Unit Device
+ {
+ __u8 Bus:6;
+ __u8 Mode:2; // b00
+ __u8 Dev;
+ } PeripDev;
+ struct // Volume Set Address
+ {
+ __u8 DevMSB:6;
+ __u8 Mode:2; // b01
+ __u8 DevLSB;
+ } LogDev;
+ struct // Logical Unit Device (SCSI-3, SCC-2 defined)
+ {
+ __u8 Targ:6;
+ __u8 Mode:2; // b10
+ __u8 Dev:5;
+ __u8 Bus:3;
+
+ } LogUnit;
+} SCSI3Addr_struct;
+
+
+typedef struct
+{
+ SCSI3Addr_struct FCP_Nexus;
+ __u8 cdb[16];
+} PassThru_Command_struct;
+*/
+
+/* this is nearly duplicated in idashare.h */
+typedef struct {
+ int lc; /* Controller number */
+ int node; /* Node (box) number */
+ int ld; /* Logical Drive on this box, if required */
+ __u32 nexus; /* SCSI Nexus */
+ void *argp; /* Argument pointer */
+} VENDOR_IOCTL_REQ;
+
+
+typedef struct {
+ char cdb[16]; /* SCSI CDB for the pass-through */
+ ushort bus; /* Target bus on the box */
+ ushort pdrive; /* Physical drive on the box */
+ int len; /* Length of the data area of the CDB */
+ int sense_len; /* Length of the sense data */
+ char sense_data[40]; /* Sense data */
+ void *bufp; /* Data area for the CDB */
+ char rw_flag; /* Read CDB or Write CDB */
+} cpqfc_passthru_t;


+
+
+
+
+/*

+** Defines for the IOCTLS.
+*/
+
+#define VENDOR_READ_OPCODE 0x26
+#define VENDOR_WRITE_OPCODE 0x27
+
+#define CPQFCTS_GETPCIINFO _IOR( CCPQFCTS_IOC_MAGIC, 1, cpqfc_pci_info_struct)
+#define CPQFCTS_GETDRIVVER _IOR( CCPQFCTS_IOC_MAGIC, 9, DriverVer_type)
+
+#define CPQFCTS_SCSI_PASSTHRU _IOWR( CCPQFCTS_IOC_MAGIC,11, VENDOR_IOCTL_REQ)
+
+
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/cpqfcTSstructs.h linux/drivers/scsi/cpqfcTSstructs.h
--- v2.4.0-test8/linux/drivers/scsi/cpqfcTSstructs.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/cpqfcTSstructs.h Tue Sep 19 08:01:34 2000
@@ -0,0 +1,1494 @@


+/* Copyright(c) 2000, Compaq Computer Corporation

+ * Fibre Channel Host Bus Adapter 64-bit, 66MHz PCI

+ * Originally developed and tested on:
+ * (front): [chip] Tachyon TS HPFC-5166A/1.2 L2C1090 ...
+ * SP# P225CXCBFIEL6T, Rev XC
+ * SP# 161290-001, Rev XD
+ * (back): Board No. 010008-001 A/W Rev X5, FAB REV X5
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ * Written by Don Zimmerman
+*/

+#ifndef CPQFCTSSTRUCTS_H
+#define CPQFCTSSTRUCTS_H
+
+#include <linux/timer.h> // timer declaration in our host data
+#include <linux/tqueue.h> // task queue sched
+#include <asm/atomic.h>
+#include "cpqfcTSioctl.h"
+
+#define DbgDelay(secs) { int wait_time; printk( " DbgDelay %ds ", secs); \
+ for( wait_time=jiffies + (secs*HZ); \
+ wait_time > jiffies ;) ; }
+#define CPQFCTS_DRIVER_VER(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
+#define VER_MAJOR 1
+#define VER_MINOR 3
+#define VER_SUBMINOR 4
+
+// Macros for kernel (esp. SMP) tracing using a PCI analyzer
+// (e.g. x86).
+//#define PCI_KERNEL_TRACE
+#ifdef PCI_KERNEL_TRACE
+#define PCI_TRACE(x) inl( fcChip->Registers.IOBaseL +x);
+#define PCI_TRACEO(x,y) outl( x, (fcChip->Registers.IOBaseL +y));
+#else
+
+#define PCI_TRACE(x)
+#define PCI_TRACEO(x,y)
+#endif
+
+
+//#define DEBUG_CMND 1 // debug output for Linux Scsi CDBs
+//#define DUMMYCMND_DBG 1
+
+//#define DEBUG_CPQFCTS 1
+//#undef DEBUG_CPQFCTS
+#ifdef DEBUG_CPQFCTS
+#define ENTER(x) printk("cpqfcts : entering %s()\n", x);
+#define LEAVE(x) printk("cpqfcts : leaving %s()\n", x);
+#define DEBUG(x) x
+#else
+#define ENTER(x)
+#define LEAVE(x)
+#define DEBUG(x)
+#endif /* DEBUG_CPQFCTS */
+
+//#define DEBUG_CPQFCTS_PCI 1
+//#undef DEBUG_CPQFCTS_PCI
+#if DEBUG_CPQFCTS_PCI
+#define DEBUG_PCI(x) x
+#else
+#define DEBUG_PCI(x)
+#endif /* DEBUG_CPQFCTS_PCI */
+
+#define STACHLITE66_TS12 "Compaq FibreChannel HBA Tachyon TS HPFC-5166A/1.2"
+#define STACHLITE66_TS13 "Compaq FibreChannel HBA Tachyon TS HPFC-5166A/1.3"
+#define STACHLITE_UNKNOWN "Compaq FibreChannel HBA Tachyon Chip/Board Ver??"
+#define SAGILENT_XL2_21 "Agilent FC HBA, Tachyon XL2 HPFC-5200B/2.1"
+
+// PDA is Peripheral Device Address, VSA is Volume Set Addressing
+// Linux SCSI parameters
+#define CPQFCTS_MAX_TARGET_ID 64
+#define CPQFCTS_MAX_LUN 8 // The RA-4x00 supports 32 (Linux SCSI supports 8)
+#define CPQFCTS_MAX_CHANNEL 0 // One FC port on cpqfcTS HBA
+
+#define CPQFCTS_CMD_PER_LUN 15 // power of 2 -1, must be >0
+#define CPQFCTS_REQ_QUEUE_LEN (TACH_SEST_LEN/2) // must be < TACH_SEST_LEN


+
+#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))

+#ifndef DECLARE_MUTEX_LOCKED
+#define DECLARE_MUTEX_LOCKED(sem) struct semaphore sem = MUTEX_LOCKED
+#endif
+
+#define DEV_NAME "cpqfcTS"
+
+#define CPQ_DEVICE_ID 0xA0FC
+#define AGILENT_XL2_ID 0x1029
+
+typedef struct
+{
+ __u16 vendor_id;
+ __u16 device_id;
+} SupportedPCIcards;
+
+// nn:nn denotes bit field
+ // TachyonHeader struct def.
+ // the fields shared with ODB
+ // need to have same value
+
+
+
+
+#ifndef BYTE
+//typedef UCHAR BYTE;
+typedef __u8 BYTE;
+#endif


+#ifndef UCHAR
+typedef __u8 UCHAR;
+#endif

+#ifndef LONG
+typedef __s32 LONG;


+#endif
+#ifndef ULONG
+typedef __u32 ULONG;
+#endif

+#ifndef PVOID
+typedef void * PVOID;


+#endif
+#ifndef USHORT
+typedef __u16 USHORT;
+#endif
+#ifndef BOOLEAN
+typedef __u8 BOOLEAN;
+#endif
+

+
+// macro for FC-PH reject codes
+// payload format for LS_RJT (FC payloads are big endian):
+// byte 0 1 2 3 (MSB)
+// DWORD 0 01 00 00 00
+// DWORD 1 resvd code expl. vendor
+
+#define LS_RJT_REASON( code, expl) (( code<<8) | (expl <<16))
+
+
+#define TachLiteSTATUS 0x12
+
+// Fibre Channel EXCHANGE status codes for Tachyon chips/ driver software
+// 32-bit ERROR word defines
+#define INVALID_ARGS 0x1
+#define LNKDWN_OSLS 0x2
+#define LNKDWN_LASER 0x4
+#define OUTQUE_FULL 0x8
+#define DRIVERQ_FULL 0x10
+#define SEST_FULL 0x20
+#define BAD_ALPA 0x40
+#define OVERFLOW 0x80 // inbound CM
+#define COUNT_ERROR 0x100 // inbound CM
+#define LINKFAIL_RX 0x200 // inbound CM
+#define ABORTSEQ_NOTIFY 0x400 // outbound CM
+#define LINKFAIL_TX 0x800 // outbound CM
+#define HOSTPROG_ERR 0x1000 // outbound CM
+#define FRAME_TO 0x2000 // outbound CM
+#define INV_ENTRY 0x4000 // outbound CM
+#define SESTPROG_ERR 0x8000 // outbound CM
+#define OUTBOUND_TIMEOUT 0x10000L // timeout waiting for Tachyon outbound CM
+#define INITIATOR_ABORT 0x20000L // initiator exchange timeout or O/S ABORT
+#define MEMPOOL_FAIL 0x40000L // O/S memory pool allocation failed
+#define FC2_TIMEOUT 0x80000L // driver timeout for lost frames
+#define TARGET_ABORT 0x100000L // ABTS received from FC port
+#define EXCHANGE_QUEUED 0x200000L // e.g. Link State was LDn on fcStart
+#define PORTID_CHANGED 0x400000L // fc Port address changed
+#define DEVICE_REMOVED 0x800000L // fc Port address changed
+// Several error scenarios result in SEST Exchange frames
+// unexpectedly arriving in the SFQ
+#define SFQ_FRAME 0x1000000L // SFQ frames from open Exchange
+
+// Maximum number of Host Bus Adapters (HBA) / controllers supported
+// only important for mem allocation dimensions - increase as necessary
+
+#define MAX_ADAPTERS 8
+#define MAX_RX_PAYLOAD 1024 // hardware dependent max frame payload
+// Tach header struc defines
+#define SOFi3 0x7
+#define SOFf 0x8
+#define SOFn3 0xB
+#define EOFn 0x5
+#define EOFt 0x6
+
+// FCP R_CTL defines
+#define FCP_CMND 0x6
+#define FCP_XFER_RDY 0x5
+#define FCP_RSP 0x7
+#define FCP_RESPONSE 0x777 // (arbitrary #)
+#define NEED_FCP_RSP 0x77 // (arbitrary #)
+#define FCP_DATA 0x1
+
+#define RESET_TACH 0x100 // Reset Tachyon/TachLite
+#define SCSI_IWE 0x2000 // initiator write entry (for SEST)
+#define SCSI_IRE 0x3000 // initiator read entry (for SEST)
+#define SCSI_TRE 0x400 // target read entry (for SEST)
+#define SCSI_TWE 0x500 // target write entry (for SEST)
+#define TOGGLE_LASER 0x800
+#define LIP 0x900
+#define CLEAR_FCPORTS 99 // (arbitrary #) free mem for Logged in ports
+#define FMINIT 0x707 // (arbitrary) for Frame Manager Init command
+
+// BLS == Basic Link Service
+// ELS == Extended Link Service
+#define BLS_NOP 4
+#define BLS_ABTS 0x10 // FC-PH Basic Link Service Abort Sequence
+#define BLS_ABTS_ACC 0x100 // FC-PH Basic Link Service Abort Sequence Accept
+#define BLS_ABTS_RJT 0x101 // FC-PH Basic Link Service Abort Sequence Reject
+#define ELS_PLOGI 0x03 // FC-PH Port Login (arbitrary assign)
+#define ELS_SCR 0x70 // (arb assign) State Change Registration (Fabric)
+#define FCS_NSR 0x72 // (arb assign) Name Service Request (Fabric)
+#define ELS_FLOGI 0x44 // (arb assign) Fabric Login
+#define ELS_FDISC 0x41 // (arb assign) Fabric Discovery (Login)
+#define ELS_PDISC 0x50 // FC-PH2 Port Discovery
+#define ELS_ABTX 0x06 // FC-PH Abort Exchange
+#define ELS_LOGO 0x05 // FC-PH Port Logout
+#define ELS_PRLI 0x20 // FCP-SCSI Process Login
+#define ELS_PRLO 0x21 // FCP-SCSI Process Logout
+#define ELS_LOGO_ACC 0x07 // {FC-PH} Port Logout Accept
+#define ELS_PLOGI_ACC 0x08 // {FC-PH} Port Login Accept
+#define ELS_ACC 0x18 // {FC-PH} (generic) ACCept
+#define ELS_PRLI_ACC 0x22 // {FCP-SCSI} Process Login Accept
+#define ELS_RJT 0x1000000
+#define SCSI_REPORT_LUNS 0x0A0
+#define REPORT_LUNS 0xA0 // SCSI-3 command op-code
+
+#define ELS_LILP_FRAME 0x00000711 // 1st payload word of LILP frame
+
+#define SFQ_UNASSISTED_FCP 1 // ICM, DWord3, "Type" unassisted FCP
+#define SFQ_UNKNOWN 0x31 // (arbitrary) ICM, DWord3, "Type" unknown
+
+// these "LINK" bits refer to loop or non-loop
+#define LINKACTIVE 0x2 // fcLinkQ type - LINK UP Tachyon FM 'Lup' bit set
+#define LINKDOWN 0xf2 // fcLinkQ type - LINK DOWN Tachyon FM 'Ldn' bit set
+
+//#define VOLUME_SET_ADDRESSING 1 // "channel" or "bus" 1
+
+typedef struct // 32 bytes hdr ONLY (e.g. FCP_DATA buffer for SEST)
+{
+ ULONG reserved; // dword 0 (don't use)
+ ULONG sof_eof;
+ ULONG d_id; // dword 2 - 31:24 R_CTL, 23:0 D_ID
+ ULONG s_id; // dword 3 - 31:24 CS_CTL, 23:0 S_ID
+ ULONG f_ctl; // dword 4 - 31:24 Type, 23:0 F_CTL
+ ULONG seq_cnt; // dword 5 - 31:24 SEQ_ID, 23:16 DF_CTL, 15:0 SEQ_CNT
+ ULONG ox_rx_id; // dword 6 - 31:16 OX_ID, 15:0 RX_ID
+ ULONG ro; // dword 7 - relative offset
+} TachFCHDR;
+
+ // NOTE!! the following struct MUST be 64 bytes.
+typedef struct // 32 bytes hdr + 32 bytes payload
+{
+ ULONG reserved; // dword 0 (don't use - must clear to 0)
+ ULONG sof_eof; // dword 1 - 31:24 SOF:EOF, UAM,CLS, LCr, TFV, TimeStamp
+ ULONG d_id; // dword 2 - 31:24 R_CTL, 23:0 D_ID
+ ULONG s_id; // dword 3 - 31:24 CS_CTL, 23:0 S_ID
+ ULONG f_ctl; // dword 4 - 31:24 Type, 23:0 F_CTL
+ ULONG seq_cnt; // dword 5 - 31:24 SEQ_ID, 23:16 DF_CTL, 15:0 SEQ_CNT
+ ULONG ox_rx_id; // dword 6 - 31:16 OX_ID, 15:0 RX_ID
+ ULONG ro; // dword 7 - relative offset
+//---------
+ __u32 pl[8]; // dwords 8-15 frame data payload
+} TachFCHDR_CMND;
+
+
+typedef struct // 32 bytes hdr + 120 bytes payload
+{
+ ULONG reserved; // dword 0 (don't use - must clear to 0)
+ ULONG sof_eof; // dword 1 - 31:24 SOF:EOF, UAM,CLS, LCr, TFV, TimeStamp
+ ULONG d_id; // dword 2 - 31:24 R_CTL, 23:0 D_ID
+ ULONG s_id; // dword 3 - 31:24 CS_CTL, 23:0 S_ID
+ ULONG f_ctl; // dword 4 - 31:24 Type, 23:0 F_CTL
+ ULONG seq_cnt; // dword 5 - 31:24 SEQ_ID, 23:16 DF_CTL, 15:0 SEQ_CNT
+ ULONG ox_rx_id; // dword 6 - 31:16 OX_ID, 15:0 RX_ID
+ ULONG ro; // dword 7 - relative offset
+//---------
+ __u32 pl[30]; // largest necessary payload (for LOGIN cmnds)
+} TachFCHDR_GCMND;
+
+typedef struct // 32 bytes hdr + 64 bytes payload
+{
+ ULONG reserved; // dword 0 (don't use)
+ ULONG sof_eof;
+ ULONG d_id; // dword 2 - 31:24 R_CTL, 23:0 D_ID
+ ULONG s_id; // dword 3 - 31:24 CS_CTL, 23:0 S_ID
+ ULONG f_ctl; // dword 4 - 31:24 Type, 23:0 F_CTL
+ ULONG seq_cnt; // dword 5 - 31:24 SEQ_ID, 23:16 DF_CTL, 15:0 SEQ_CNT
+ ULONG ox_rx_id; // dword 6 - 31:16 OX_ID, 15:0 RX_ID
+ ULONG ro; // dword 7 - relative offset
+//---------
+ __u32 pl[18]; // payload for FCP-RSP (response buffer) RA-4x00 is 72bytes
+} TachFCHDR_RSP;


+
+
+
+
+
+

+// Inbound Message Queue structures...
+typedef struct // each entry 8 words (32 bytes)
+{
+ ULONG type; // IMQ completion message types
+ ULONG word[7]; // remainder of structure
+ // interpreted by IMQ type
+} TachyonIMQE;
+
+
+// Queues for TachLite not in original Tachyon
+// ERQ - Exchange Request Queue (for outbound commands)
+// SFQ - Single Frame Queue (for incoming frames)
+
+ // Define Tachyon Outbound Command Que
+ // (Since many Tachyon registers are Read
+ // only, maintain copies for debugging)
+ // most Tach ques need power-of-2 sizes,
+ // where registers are loaded with po2 -1
+#define TACH_SEST_LEN 512 // TachLite SEST
+
+#define ELS_EXCHANGES 64 // e.g. PLOGI, RSCN, ...
+// define the total number of outstanding (simultaneous) exchanges
+#define TACH_MAX_XID (TACH_SEST_LEN + ELS_EXCHANGES) // ELS exchanges
+
+#define ERQ_LEN 128 // power of 2, max 4096
+
+// Inbound Message Queue structures...
+#define IMQ_LEN 512 // minimum 4 entries [(power of 2) - 1]
+typedef struct // 8 words - 32 bytes
+{
+ TachyonIMQE QEntry[IMQ_LEN];
+ ULONG producerIndex; // IMQ Producer Index register
+ // @32 byte align
+ ULONG consumerIndex; // Consumer Index register (in Tachyon)
+ ULONG length; // Length register
+ ULONG base;
+} TachyonIMQ; // @ 32 * IMQ_LEN align
+
+
+
+typedef struct // inbound completion message
+{
+ ULONG Type;
+ ULONG Index;
+ ULONG TransferLength;
+} TachyonInbCM;
+
+
+
+// arbitrary numeric tags for TL structures
+#define TL_FCHS 1 // TachLite Fibre Channel Header Structure
+#define TL_IWE 2 // initiator write entry (for SEST)
+#define TL_TWE 3 // target write entry (for SEST)
+#define TL_IRE 4 // initiator read entry (for SEST)
+#define TL_TRE 5 // target read entry (for SEST)
+#define TL_IRB 6 // I/O request block
+
+ // for INCOMING frames
+#define SFQ_LEN 32 // minimum 32 entries, max 4096
+
+typedef struct // Single Frame Que
+{
+ TachFCHDR_CMND QEntry[SFQ_LEN]; // must be 64 bytes!!
+ ULONG producerIndex; // IMQ Producer Index register
+ // @32 byte align
+ ULONG consumerIndex; // Consumer Index register (in Tachyon)
+ ULONG length; // Length register
+ ULONG base;
+} TachLiteSFQ;
+
+
+typedef struct // I/O Request Block flags
+{
+ UCHAR BRD : 1;
+ UCHAR : 1; // reserved
+ UCHAR SFA : 1;
+ UCHAR DNC : 1;
+ UCHAR DIN : 1;
+ UCHAR DCM : 1;
+ UCHAR CTS : 1;
+ UCHAR SBV : 1; // IRB entry valid - IRB'B' only
+} IRBflags;
+
+typedef struct // I/O Request Block
+{ // Request 'A'
+ ULONG Req_A_SFS_Len; // total frame len (hdr + payload), min 32
+ ULONG Req_A_SFS_Addr; // 32-bit pointer to FCHS struct (to be sent)
+ ULONG Req_A_SFS_D_ID; // 24-bit FC destination (i.e. 8 bit al_pa)
+ ULONG Req_A_Trans_ID; // X_ID (OX_ID or RX_ID) and/or Index in SEST
+ // Request 'B'
+ ULONG Req_B_SFS_Len; // total frame len (hdr + payload), min 32
+ ULONG Req_B_SFS_Addr; // 32-bit pointer to FCHS struct (to be sent)
+ ULONG Req_B_SFS_D_ID; // 24-bit FC destination (i.e. 8 bit al_pa)
+ ULONG Req_B_Trans_ID; // X_ID (OX_ID or RX_ID) and/or Index in SEST
+} TachLiteIRB;
+
+
+typedef struct // TachLite placeholder for IRBs
+{ // aligned @sizeof(ERQ) for TachLite
+ // MAX commands is sum of SEST len and ERQ
+ // we know that each SEST entry requires an
+ // IRB (ERQ) entry; in addition, we provide
+ // ERQ_LEN
+ TachLiteIRB QEntry[ERQ_LEN]; // Base register; entries 32 bytes ea.
+ ULONG consumerIndex; // Consumer Index register
+ ULONG producerIndex; // ERQ Producer Index register
+ ULONG length; // Length register
+ ULONG base; // copy of base ptr for debug
+ // struct is sized for largest expected cmnd (LOGIN)
+} TachLiteERQ;
+
+
+#define TL_MAX_SGPAGES 4 // arbitrary limit to # of TL Ext. S/G pages
+ // stores array of allocated page blocks used
+ // in extended S/G lists. Affects amount of static
+ // memory consumed by driver.
+#define TL_EXT_SG_PAGE_COUNT 256 // Number of Extended Scatter/Gather a/l PAIRS
+ // Tachyon register (IOBaseU 0x68)
+ // power-of-2 value ONLY! 4 min, 256 max
+
+ // byte len is #Pairs * 2 ULONG/Pair * 4 bytes/ULONG
+#define TL_EXT_SG_PAGE_BYTELEN (TL_EXT_SG_PAGE_COUNT *2 *4)
+
+
+
+// SEST entry types: IWE, IRE, TWE, TRE
+typedef struct
+{
+ ULONG Hdr_Len;
+ ULONG Hdr_Addr;
+ ULONG RSP_Len;
+ ULONG RSP_Addr;
+ ULONG Buff_Off;
+ ULONG Link;
+ ULONG RX_ID;
+ ULONG Data_Len;
+ ULONG Exp_RO;
+ ULONG Exp_Byte_Cnt;
+ // --- extended/local Gather Len/Address pairs
+ ULONG GLen1;
+ ULONG GAddr1;
+ ULONG GLen2;
+ ULONG GAddr2;
+ ULONG GLen3;
+ ULONG GAddr3;
+} TachLiteIWE;
+
+
+typedef struct
+{
+ ULONG Seq_Accum;
+ ULONG reserved; // must clear to 0
+ ULONG RSP_Len;
+ ULONG RSP_Addr;
+ ULONG Buff_Off;
+ ULONG Buff_Index; // ULONG 5
+ ULONG Exp_RO;
+ ULONG Byte_Count;
+ ULONG reserved_; // ULONG 8
+ ULONG Exp_Byte_Cnt;
+ // --- extended/local Scatter Len/Address pairs
+ ULONG SLen1;
+ ULONG SAddr1;
+ ULONG SLen2;
+ ULONG SAddr2;
+ ULONG SLen3;
+ ULONG SAddr3;
+} TachLiteIRE;
+
+
+typedef struct // Target Write Entry
+{
+ ULONG Seq_Accum; // dword 0
+ ULONG reserved; // dword 1 must clear to 0
+ ULONG Remote_Node_ID;
+ ULONG reserved1; // dword 3 must clear to 0
+ ULONG Buff_Off;
+ ULONG Buff_Index; // ULONG 5
+ ULONG Exp_RO;
+ ULONG Byte_Count;
+ ULONG reserved_; // ULONG 8
+ ULONG Exp_Byte_Cnt;
+ // --- extended/local Scatter Len/Address pairs
+ ULONG SLen1;
+ ULONG SAddr1;
+ ULONG SLen2;
+ ULONG SAddr2;
+ ULONG SLen3;
+ ULONG SAddr3;
+} TachLiteTWE;
+
+typedef struct
+{
+ ULONG Hdr_Len;
+ ULONG Hdr_Addr;
+ ULONG RSP_Len; // DWord 2
+ ULONG RSP_Addr;
+ ULONG Buff_Off;
+ ULONG Buff_Index; // DWord 5
+ ULONG reserved;
+ ULONG Data_Len;
+ ULONG reserved_;
+ ULONG reserved__;
+ // --- extended/local Gather Len/Address pairs
+ ULONG GLen1; // DWord A
+ ULONG GAddr1;
+ ULONG GLen2;
+ ULONG GAddr2;
+ ULONG GLen3;
+ ULONG GAddr3;
+} TachLiteTRE;
+
+typedef struct
+{
+ void *PoolPage[TL_MAX_SGPAGES];
+} SGPAGES, *PSGPAGES; // linked list of S/G pairs, by Exchange
+
+
+
+typedef struct // SCSI Exchange State Table
+{
+ union // Entry can be IWE, IRE, TWE, TRE
+ { // 64 bytes per entry
+ TachLiteIWE IWE;
+ TachLiteIRE IRE;
+ TachLiteTWE TWE;
+ TachLiteTRE TRE;
+ } u[TACH_SEST_LEN];
+
+ TachFCHDR DataHDR[TACH_SEST_LEN]; // for SEST FCP_DATA frame hdr (no pl)
+ TachFCHDR_RSP RspHDR[TACH_SEST_LEN]; // space for SEST FCP_RSP frame
+ SGPAGES sgPages[TACH_SEST_LEN]; // array of Pool-allocations
+ ULONG length; // Length register
+ ULONG base; // copy of base ptr for debug
+} TachSEST;
+
+
+
+typedef struct // each register has it's own address
+ // and value (used for write-only regs)
+{
+ void* address;
+ volatile ULONG value;
+} FCREGISTER;
+
+typedef struct // Host copy - TachLite Registers
+{
+ ULONG IOBaseL, IOBaseU; // I/O port lower and upper TL register addresses
+ ULONG MemBase; // memory mapped register addresses
+ void* ReMapMemBase; // O/S VM reference for MemBase
+ ULONG wwn_hi; // WWN is set once at startup
+ ULONG wwn_lo;
+ ULONG my_al_pa; // al_pa received after LIP()
+ ULONG ROMCTR; // flags for on-board RAM/ROM
+ ULONG RAMBase; // on-board RAM (i.e. some Tachlites)
+ ULONG SROMBase; // on-board EEPROM (some Tachlites)
+ ULONG PCIMCTR; // PCI Master Control Reg (has bus width)
+
+ FCREGISTER INTEN; // copy of interrupt enable mask
+ FCREGISTER INTPEND; // interrupt pending
+ FCREGISTER INTSTAT; // interrupt status
+ FCREGISTER SFQconsumerIndex;
+ FCREGISTER ERQproducerIndex;
+ FCREGISTER TYconfig; // TachYon (chip level)
+ FCREGISTER TYcontrol;
+ FCREGISTER TYstatus;
+ FCREGISTER FMconfig; // Frame Manager (FC loop level)
+ FCREGISTER FMcontrol;
+ FCREGISTER FMstatus;
+ FCREGISTER FMLinkStatus1;
+ FCREGISTER FMLinkStatus2;
+ FCREGISTER FMBB_CreditZero;
+ FCREGISTER status;
+ FCREGISTER ed_tov; // error detect time-out value
+ FCREGISTER rcv_al_pa; // received arb. loop physical address
+ FCREGISTER primitive; // e.g. LIP(), OPN(), ...
+} TL_REGISTERS;
+
+
+
+typedef struct
+{
+ ULONG ok;
+ ULONG invalidArgs;
+ ULONG linkDown;
+ ULONG linkUp;
+ ULONG outQueFull;
+ ULONG SESTFull;
+ ULONG hpe; // host programming err (from Tach)
+ ULONG FC4aborted; // aborts from Application or upper driver layer
+ ULONG FC2aborted; // aborts from our driver's timeouts
+ ULONG timeouts; // our driver timeout (on individual exchanges)
+ ULONG logouts; // explicit - sent LOGO; implicit - device removed
+ ULONG retries;
+ ULONG linkFailTX;
+ ULONG linkFailRX;
+ ULONG CntErrors; // byte count expected != count received (typ. SEST)
+ ULONG e_stores; // elastic store errs
+ ULONG resets; // hard or soft controller resets
+ ULONG FMinits; // TACH Frame Manager Init (e.g. LIPs)
+ ULONG lnkQueFull; // too many LOGIN, loop commands
+ ULONG ScsiQueFull; // too many FCP-SCSI inbound frames
+ ULONG LossofSignal; // FM link status 1 regs
+ ULONG BadRXChar; // FM link status 1 regs
+ ULONG LossofSync; // FM link status 1 regs
+ ULONG Rx_EOFa; // FM link status 2 regs (received EOFa)
+ ULONG Dis_Frm; // FM link status 2 regs (discarded frames)
+ ULONG Bad_CRC; // FM link status 2 regs
+ ULONG BB0_Timer; // FM BB_Credit Zero Timer Reg
+ ULONG loopBreaks; // infinite loop exits
+ ULONG lastBB0timer; // static accum. buffer needed by Tachlite
+} FCSTATS;
+
+
+typedef struct // Config Options
+{ // LS Bit first
+ USHORT : 1; // bit0:
+ USHORT flogi : 1; // bit1: We sent FLOGI - wait for Fabric logins
+ USHORT fabric: 1; // bit2: Tachyon detected Fabric (FM stat LG)
+ USHORT LILPin: 1; // bit3: We can use an FC-AL LILP frame
+ USHORT target: 1; // bit4: this Port has SCSI target capability
+ USHORT initiator: 1; // bit5: this Port has SCSI initiator capability
+ USHORT extLoopback: 1; // bit6: loopback at GBIC
+ USHORT intLoopback: 1; // bit7: loopback in HP silicon
+ USHORT : 1; // bit8:
+ USHORT : 1; // bit9:
+ USHORT : 1; // bit10:
+ USHORT : 1; // bit11:
+ USHORT : 1; // bit12:
+ USHORT : 1; // bit13:
+ USHORT : 1; // bit14:
+ USHORT : 1; // bit15:
+} FC_OPTIONS;
+
+
+
+typedef struct dyn_mem_pair
+{
+ void *BaseAllocated; // address as allocated from O/S;
+ unsigned long AlignedAddress; // aligned address (used by Tachyon DMA)
+} ALIGNED_MEM;
+
+
+
+
+// these structs contain only CRUCIAL (stuff we actually use) parameters
+// from FC-PH(n) logins. (Don't save entire LOGIN payload to save mem.)
+
+// Implicit logout happens when the loop goes down - we require PDISC
+// to restore. Explicit logout is when WE decide never to talk to someone,
+// or when a target refuses to talk to us, i.e. sends us a LOGO frame or
+// LS_RJT reject in response to our PLOGI request.
+
+#define IMPLICIT_LOGOUT 1
+#define EXPLICIT_LOGOUT 2
+
+typedef struct
+{
+ UCHAR channel; // SCSI "bus"
+ UCHAR target;
+ UCHAR InqDeviceType; // byte 0 from SCSI Inquiry response
+ UCHAR VolumeSetAddressing; // FCP-SCSI LUN coding (40h for VSA)
+ UCHAR LunMasking; // True if selective presentation supported
+ UCHAR lun[CPQFCTS_MAX_LUN];
+} SCSI_NEXUS;
+
+
+typedef struct
+{
+ union
+ {
+ UCHAR ucWWN[8]; // a FC 64-bit World Wide Name/ PortID of target
+ // addressing of single target on single loop...
+ u64 liWWN;
+ } u;
+
+ ULONG port_id; // a FC 24-bit address of port (lower 8 bits = al_pa)
+
+ Scsi_Cmnd ScsiCmnd; // command buffer for Report Luns
+#define REPORT_LUNS_PL 256
+ UCHAR ReportLunsPayload[REPORT_LUNS_PL];
+
+ SCSI_NEXUS ScsiNexus; // LUNs per FC device
+
+ ULONG LOGO_counter; // might try several times before logging out for good
+ ULONG LOGO_timer; // after LIP, ports expecting PDISC must time-out and
+ // LOGOut if successful PDISC not completed in 2 secs
+
+ ULONG concurrent_seq; // must be 1 or greater
+ ULONG rx_data_size; // e.g. 128, 256, 1024, 2048 per FC-PH spec
+ ULONG BB_credit;
+ ULONG EE_credit;
+
+ ULONG fcp_info; // from PRLI (i.e. INITIATOR/ TARGET flags)
+ // flags for login process
+ BOOLEAN Originator; // Login sequence Originated (if false, we
+ // responded to another port's login sequence)
+ BOOLEAN plogi; // PLOGI frame ACCepted (originated or responded)
+ BOOLEAN pdisc; // PDISC frame was ORIGINATED (self-login logic)
+ BOOLEAN prli; // PRLI frame ACCepted (originated or responded)
+ BOOLEAN flogi; // FLOGI frame ACCepted (originated or responded)
+ BOOLEAN logo; // port permanently logged out (invalid login param)
+ BOOLEAN flogiReq; // Fabric login required (set in LIP process)
+ UCHAR highest_ver;
+ UCHAR lowest_ver;
+
+
+ // when the "target" (actually FC Port) is waiting for login
+ // (e.g. after Link reset), set the device_blocked bit;
+ // after Port completes login, un-block target.
+ UCHAR device_blocked; // see Scsi_Device struct
+
+ // define singly-linked list of logged-in ports
+ // once a port_id is identified, it is remembered,
+ // even if the port is removed indefinitely
+ PVOID pNextPort; // actually, type PFC_LOGGEDIN_PORT; void for Compiler
+
+} FC_LOGGEDIN_PORT, *PFC_LOGGEDIN_PORT;
+
+
+
+// This serves as the ESB (Exchange Status Block),
+// and has timeout counter; used for ABORTs
+typedef struct
+{ // FC-1 X_IDs
+ ULONG type; // ELS_PLOGI, SCSI_IWE, ... (0 if free)
+ PFC_LOGGEDIN_PORT pLoggedInPort; // FC device on other end of Exchange
+ Scsi_Cmnd *Cmnd; // Linux SCSI command packet includes S/G list
+ ULONG timeOut; // units of ??, DEC by driver, Abort when 0
+ ULONG reTries; // need one or more retries?
+ ULONG status; // flags indicating errors (0 if none)
+ TachLiteIRB IRB; // I/O Request Block, gets copied to ERQ
+ TachFCHDR_GCMND fchs; // location of IRB's Req_A_SFS_Addr
+} FC_EXCHANGE, *PFC_EXCHANGE;
+
+// Unfortunately, Linux limits our kmalloc() allocations to 128k.
+// Because of this and the fact that our ScsiRegister allocation
+// is also constrained, we move this large structure out for
+// allocation after Scsi Register.
+// (In other words, this cumbersome indirection is necessary
+// because of kernel memory allocation constraints!)
+
+typedef struct // we will allocate this dynamically
+{
+ FC_EXCHANGE fcExchange[ TACH_MAX_XID ];
+} FC_EXCHANGES;


+
+
+
+
+
+
+
+

+
+
+
+typedef struct
+{
+ char Name[64]; // name of controller ("HP Tachlite TL Rev2.0, 33MHz, 64bit bus")
+ //PVOID pAdapterDevExt; // back pointer to device object/extension
+ ULONG ChipType; // local numeric key for Tachyon Type / Rev.
+ ULONG status; // our Driver - logical status
+
+ TL_REGISTERS Registers; // reg addresses & host memory copies
+ // FC-4 mapping of 'transaction' to X_IDs
+ UCHAR LILPmap[32*4]; // Loop Position Map of ALPAs (late FC-AL only)
+ FC_OPTIONS Options; // e.g. Target, Initiator, loopback...
+ UCHAR highest_FCPH_ver; // FC-PH version limits
+ UCHAR lowest_FCPH_ver; // FC-PH version limits
+
+ FC_EXCHANGES *Exchanges;
+ ULONG fcLsExchangeLRU; // Least Recently Used counter (Link Service)
+ ULONG fcSestExchangeLRU; // Least Recently Used counter (FCP-SCSI)
+ FC_LOGGEDIN_PORT fcPorts; // linked list of every FC port ever seen
+ FCSTATS fcStats; // FC comm err counters
+
+ // Host memory QUEUE pointers
+ TachLiteERQ *ERQ; // Exchange Request Que
+ TachyonIMQ *IMQ; // Inbound Message Que
+ TachLiteSFQ *SFQ; // Single Frame Queue
+ TachSEST *SEST; // SCSI Exchange State Table
+
+ // these function pointers are for "generic" functions, which are
+ // replaced with Host Bus Adapter types at
+ // runtime.
+ int (*CreateTachyonQues)( void* , int);
+ int (*DestroyTachyonQues)( void* , int);
+ int (*LaserControl)(void*, int ); // e.g. On/Off
+ int (*ResetTachyon)(void*, int );
+ void (*FreezeTachyon)(void*, int );
+ void (*UnFreezeTachyon)(void*, int );
+ int (*InitializeTachyon)(void*, int, int );
+ int (*InitializeFrameManager)(void*, int );
+ int (*ProcessIMQEntry)(void*);
+ int (*ReadWriteWWN)(void*, int ReadWrite);
+ int (*ReadWriteNVRAM)(void*, void*, int ReadWrite);
+
+} TACHYON, *PTACHYON;
+
+
+void cpqfcTSClearLinkStatusCounters(TACHYON * fcChip);
+
+int CpqTsCreateTachLiteQues( void* pHBA, int opcode);
+int CpqTsDestroyTachLiteQues( void* , int);


+int CpqTsInitializeTachLite( void *pHBA, int opcode1, int opcode2);
+

+int CpqTsProcessIMQEntry(void* pHBA);
+int CpqTsResetTachLite(void *pHBA, int type);
+void CpqTsFreezeTachlite(void *pHBA, int type);
+void CpqTsUnFreezeTachlite(void *pHBA, int type);
+int CpqTsInitializeFrameManager(void *pHBA, int);
+int CpqTsLaserControl( void* addrBase, int opcode );
+int CpqTsReadWriteWWN(void*, int ReadWrite);
+int CpqTsReadWriteNVRAM(void*, void* data, int ReadWrite);
+
+void cpqfcTS_WorkTask( struct Scsi_Host *HostAdapter);
+void cpqfcTSWorkerThread( void *host);
+
+int cpqfcTS_GetNVRAM_data( UCHAR *wwnbuf, UCHAR *buf );
+ULONG cpqfcTS_ReadNVRAM( void* GPIOin, void* GPIOout , USHORT count,


+ UCHAR *buf );
+

+BOOLEAN tl_write_i2c_nvram( void* GPIOin, void* GPIOout,


+ USHORT startOffset, // e.g. 0x2f for WWN start
+ USHORT count,
+ UCHAR *buf );
+

+
+// define misc functions
+int cpqfcTSGetLPSM( PTACHYON fcChip, char cErrorString[]);
+int cpqfcTSDecodeGBICtype( PTACHYON fcChip, char cErrorString[]);
+void* fcMemManager( ALIGNED_MEM *dyn_mem_pair, ULONG n_alloc, ULONG ab,
+ ULONG ulAlignedAddress);
+
+void BigEndianSwap( UCHAR *source, UCHAR *dest, USHORT cnt);
+
+//ULONG virt_to_phys( PVOID virtaddr );
+
+
+// Linux interrupt handler
+void cpqfcTS_intr_handler( int irq,void *dev_id,struct pt_regs *regs);
+void cpqfcTSheartbeat( unsigned long ptr );
+
+
+
+// The biggest Q element we deal with is Aborts - we
+// need 4 bytes for x_ID, and a Scsi_Cmnd (~284 bytes)
+//#define LINKQ_ITEM_SIZE ((4+sizeof(Scsi_Cmnd)+3)/4)
+#define LINKQ_ITEM_SIZE (3*16)
+typedef struct
+{
+ ULONG Type; // e.g. LINKUP, SFQENTRY, PDISC, BLS_ABTS, ...
+ ULONG ulBuff[ LINKQ_ITEM_SIZE ];
+} LINKQ_ITEM;
+
+#define FC_LINKQ_DEPTH TACH_MAX_XID
+typedef struct
+{
+ ULONG producer;
+ ULONG consumer; // when producer equals consumer, Q empty
+
+ LINKQ_ITEM Qitem[ FC_LINKQ_DEPTH ];
+
+} FC_LINK_QUE, *PFC_LINK_QUE;
+
+
+ // DPC routines post to here on Inbound SCSI frames
+ // User thread processes
+#define FC_SCSIQ_DEPTH 32
+
+typedef struct
+{
+ int Type; // e.g. SCSI
+ ULONG ulBuff[ 3*16 ];
+} SCSIQ_ITEM;
+
+typedef struct
+{
+ ULONG producer;
+ ULONG consumer; // when producer equals consumer, Q empty
+
+ SCSIQ_ITEM Qitem[ FC_SCSIQ_DEPTH ];
+
+} FC_SCSI_QUE, *PFC_SCSI_QUE;


+
+
+
+
+

+#define DYNAMIC_ALLOCATIONS 4 // Tachyon aligned allocations: ERQ,IMQ,SFQ,SEST
+
+// Linux space allocated per HBA (chip state, etc.)
+typedef struct
+{
+ struct Scsi_Host *HostAdapter; // back pointer to Linux Scsi struct
+
+ TACHYON fcChip; // All Tachyon registers, Queues, functions
+ ALIGNED_MEM dynamic_mem[DYNAMIC_ALLOCATIONS];
+
+ struct pci_dev *PciDev;
+
+ Scsi_Cmnd *LinkDnCmnd[CPQFCTS_REQ_QUEUE_LEN]; // collects Cmnds during LDn
+ // (for Acceptable targets)
+ Scsi_Cmnd *BoardLockCmnd[CPQFCTS_REQ_QUEUE_LEN]; // SEST was full
+
+ Scsi_Cmnd *BadTargetCmnd[CPQFCTS_MAX_TARGET_ID]; // missing targets
+
+ u_char HBAnum; // 0-based host number
+
+
+ struct timer_list cpqfcTStimer; // FC utility timer for implicit
+ // logouts, FC protocol timeouts, etc.
+ int fcStatsTime; // Statistics delta reporting time
+
+ struct task_struct *worker_thread; // our kernel thread
+ int PortDiscDone; // set by SendLogins(), cleared by LDn
+
+ struct semaphore *TachFrozen;
+ struct semaphore *TYOBcomplete; // handshake for Tach outbound frames
+ struct semaphore *fcQueReady; // FibreChannel work for our kernel thread
+ struct semaphore *notify_wt; // synchronizes kernel thread kill
+ struct semaphore *BoardLock;
+
+ PFC_LINK_QUE fcLQ; // the WorkerThread operates on this
+
+ spinlock_t hba_spinlock; // held/released by WorkerThread
+
+} CPQFCHBA;
+
+#define CPQ_SPINLOCK_HBA( x ) spin_lock(&x->hba_spinlock);
+#define CPQ_SPINUNLOCK_HBA(x) spin_unlock(&x->hba_spinlock);
+
+
+
+void cpqfcTSImplicitLogout( CPQFCHBA* cpqfcHBAdata,
+ PFC_LOGGEDIN_PORT pFcPort);
+
+
+void cpqfcTSTerminateExchange( CPQFCHBA*, SCSI_NEXUS *target, int );
+
+PFC_LOGGEDIN_PORT fcPortLoggedIn(
+ CPQFCHBA *cpqfcHBAdata,
+ TachFCHDR_GCMND* fchs,
+ BOOLEAN,
+ BOOLEAN);
+void fcProcessLoggedIn(
+ CPQFCHBA *cpqfcHBAdata, TachFCHDR_GCMND* fchs);
+
+
+ULONG cpqfcTSBuildExchange(
+ CPQFCHBA *cpqfcHBAdata,
+ ULONG type, // e.g. PLOGI
+ TachFCHDR_GCMND* InFCHS, // incoming FCHS
+ void *Data, // the CDB, scatter/gather, etc.
+ LONG *ExchangeID ); // allocated exchange ID
+
+ULONG cpqfcTSStartExchange(
+ CPQFCHBA *cpqfcHBAdata,
+ LONG ExchangeID );
+
+void cpqfcTSCompleteExchange(
+ PTACHYON fcChip,
+ ULONG exchange_ID);
+
+
+PFC_LOGGEDIN_PORT fcFindLoggedInPort(
+ PTACHYON fcChip,
+ Scsi_Cmnd *Cmnd, // (We want the channel/target/lun Nexus from Cmnd)
+ ULONG port_id, // search linked list for al_pa, or
+ UCHAR wwn[8], // search linked list for WWN, or...
+ PFC_LOGGEDIN_PORT *pLastLoggedInPort
+);
+
+// don't do this unless you have the right hardware!
+#define TRIGGERABLE_HBA 1
+#ifdef TRIGGERABLE_HBA
+void TriggerHBA( void*, int);
+#endif
+
+void cpqfcTSPutLinkQue(
+ CPQFCHBA *cpqfcHBAdata,
+ int Type,
+ void *QueContent);
+
+void fcPutScsiQue(
+ CPQFCHBA *cpqfcHBAdata,
+ int Type,
+ void *QueContent);
+
+void fcLinkQReset(
+ CPQFCHBA *);
+void fcScsiQReset(
+ CPQFCHBA *);
+void fcSestReset(
+ CPQFCHBA *);


+
+
+
+
+

+extern const UCHAR valid_al_pa[];
+extern const int number_of_al_pa;
+
+#define FCP_RESID_UNDER 0x80000
+#define FCP_RESID_OVER 0x40000
+#define FCP_SNS_LEN_VALID 0x20000
+#define FCP_RSP_LEN_VALID 0x10000
+
+// RSP_CODE definitions (dpANS Fibre Channel Protocol for SCSI, pg 34)
+#define FCP_DATA_LEN_NOT_BURST_LEN 0x1000000
+#define FCP_CMND_FIELD_INVALID 0x2000000
+#define FCP_DATA_RO_NOT_XRDY_RO 0x3000000
+#define FCP_TASKFUNCTION_NS 0x4000000
+#define FCP_TASKFUNCTION_FAIL 0x5000000
+
+// FCP-SCSI response status struct
+typedef struct // see "TachFCHDR_RSP" definition - 64 bytes
+{
+ __u32 reserved;
+ __u32 reserved1;
+ __u32 fcp_status; // field validity and SCSI status
+ __u32 fcp_resid;
+ __u32 fcp_sns_len; // length of FCP_SNS_INFO field
+ __u32 fcp_rsp_len; // length of FCP_RSP_INFO field (expect 8)
+ __u32 fcp_rsp_info; // 4 bytes of FCP protocol response information
+ __u32 fcp_rsp_info2; // (4 more bytes, since most implementations use 8)
+ __u8 fcp_sns_info[36]; // bytes for SCSI sense (ASC, ASCQ)


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 074'
echo 'File patch-2.4.0-test9 is continued in part 075'
echo "075" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part075

#!/bin/sh -x
# this is part 075 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 075; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&
+

+} FCP_STATUS_RESPONSE, *PFCP_STATUS_RESPONSE;
+
+
+// Fabric State Change Registration
+typedef struct scrpl
+{
+ __u32 command;
+ __u32 function;
+} SCR_PL;
+
+// Fabric Name Service Request
+typedef struct nsrpl
+{
+ __u32 CT_Rev; // (& IN_ID) WORD 0
+ __u32 FCS_Type; // WORD 1
+ __u32 Command_code; // WORD 2
+ __u32 reason_code; // WORD 3
+ __u32 FCP; // WORD 4 (lower byte)
+
+} NSR_PL;
+
+
+
+// "FC.H"
+#define MAX_RX_SIZE 0x800 // Max Receive Buffer Size is 2048
+#define MIN_RX_SIZE 0x100 // Min Size is 256, per FC-PLDA Spec
+#define MAX_TARGET_RXIDS SEST_DEPTH
+#define TARGET_RX_SIZE SEST_BUFFER_LENGTH
+
+#define CLASS_1 0x01
+#define CLASS_2 0x02
+#define CLASS_3 0x03


+
+#define FC_PH42 0x08
+#define FC_PH43 0x09
+#define FC_PH3 0x20
+

+#define RR_TOV 2 // Minimum Time for target to wait for
+ // PDISC after a LIP.
+#define E_D_TOV 2 // Minimum Time to wait for Sequence
+ // Completion.
+#define R_A_TOV 0 // Minimum Time for Target to wait
+ // before reclaiming resources.
+//
+// R_CTL Field
+//
+// Routing Bits (31-28)
+//
+#define FC4_DEVICE_DATA 0x00000000
+#define EXT_LINK_DATA 0x20000000
+#define FC4_LINK_DATA 0x30000000
+#define VIDEO_DATA 0x40000000
+#define BASIC_LINK_DATA 0x80000000
+#define LINK_CONTROL 0xC0000000
+#define ROUTING_MASK 0xF0000000
+
+//
+// Information Bits (27-24)
+//
+#define UNCAT_INFORMATION 0x00000000
+#define SOLICITED_DATA 0x01000000
+#define UNSOLICITED_CONTROL 0x02000000
+#define SOLICITED_CONTROL 0x03000000
+#define UNSOLICITED_DATA 0x04000000
+#define DATA_DESCRIPTOR 0x05000000
+#define UNSOLICITED_COMMAND 0x06000000
+#define COMMAND_STATUS 0x07000000
+#define INFO_MASK 0x0F000000
+//
+// (Link Control Codes)
+//
+#define ACK_1 0x00000000
+#define ACK_0_OR_N 0x01000000
+#define P_RJT 0x02000000
+#define F_RJT 0x03000000
+#define P_BSY 0x04000000
+#define FABRIC_BUSY_TO_DF 0x05000000 // Fabric Busy to Data Frame
+#define FABRIC_BUSY_TO_LC 0x06000000 // Fabric Busy to Link Ctl Frame
+#define LINK_CREDIT_RESET 0x07000000
+//
+// (Link Service Command Codes)
+//
+//#define LS_RJT 0x01000000 // LS Reject
+
+#define LS_ACC 0x02000000 // LS Accept
+#define LS_PLOGI 0x03000000 // N_PORT Login
+#define LS_FLOGI 0x04000000 // F_PORT Login
+#define LS_LOGO 0x05000000 // Logout
+#define LS_ABTX 0x06000000 // Abort Exchange
+#define LS_RCS 0x07000000 // Read Connection Status
+#define LS_RES 0x08000000 // Read Exchange Status
+#define LS_RSS 0x09000000 // Read Sequence Status
+#define LS_RSI 0x0A000000 // Request Seq Initiative
+#define LS_ESTS 0x0B000000 // Establish Steaming
+#define LS_ESTC 0x0C000000 // Estimate Credit
+#define LS_ADVC 0x0D000000 // Advice Credit
+#define LS_RTV 0x0E000000 // Read Timeout Value
+#define LS_RLS 0x0F000000 // Read Link Status
+#define LS_ECHO 0x10000000 // Echo
+#define LS_TEST 0x11000000 // Test
+#define LS_RRQ 0x12000000 // Reinstate Rec. Qual.
+#define LS_PRLI 0x20000000 // Process Login
+#define LS_PRLO 0x21000000 // Process Logout
+#define LS_TPRLO 0x24000000 // 3rd Party Process Logout
+#define LS_PDISC 0x50000000 // Process Discovery
+#define LS_FDISC 0x51000000 // Fabric Discovery
+#define LS_ADISC 0x52000000 // Discover Address
+#define LS_RNC 0x53000000 // Report Node Capability
+#define LS_SCR 0x62000000 // State Change Registration
+#define LS_MASK 0xFF000000
+
+//
+// TYPE Bit Masks
+//
+#define BASIC_LINK_SERVICE 0x00000000
+#define EXT_LINK_SERVICE 0x01000000
+
+#define LLC 0x04000000
+#define LLC_SNAP 0x05000000
+#define SCSI_FCP 0x08000000
+#define SCSI_GPP 0x09000000
+#define IPI3_MASTER 0x11000000
+#define IPI3_SLAVE 0x12000000
+#define IPI3_PEER 0x13000000
+#define CP_IPI3_MASTER 0x15000000
+#define CP_IPI3_SLAVE 0x16000000
+#define CP_IPI3_PEER 0x17000000
+#define SBCCS_CHANNEL 0x19000000
+#define SBCCS_CONTROL 0x1A000000
+#define FIBRE_SERVICES 0x20000000
+#define FC_FG 0x21000000
+#define FC_XS 0x22000000
+#define FC_AL 0x23000000
+#define SNMP 0x24000000
+#define HIPPI_FP 0x40000000
+#define TYPE_MASK 0xFF000000
+
+typedef struct {
+ UCHAR seq_id_valid;
+ UCHAR seq_id;
+ USHORT reserved; // 2 bytes reserved
+ ULONG ox_rx_id;
+ USHORT low_seq_cnt;
+ USHORT high_seq_cnt;
+} BA_ACC_PAYLOAD;
+
+typedef struct {
+ UCHAR reserved;
+ UCHAR reason_code;
+ UCHAR reason_explain;
+ UCHAR vendor_unique;
+} BA_RJT_PAYLOAD;
+
+
+typedef struct {
+ ULONG command_code;
+ ULONG sid;
+ USHORT ox_id;
+ USHORT rx_id;
+} RRQ_MESSAGE;
+
+typedef struct {
+ ULONG command_code;
+ UCHAR vendor;
+ UCHAR explain;
+ UCHAR reason;
+ UCHAR reserved;
+} REJECT_MESSAGE;
+
+
+#define N_OR_F_PORT 0x1000
+#define RANDOM_RELATIVE_OFFSET 0x4000
+#define CONTINUOSLY_INCREASING 0x8000
+
+#define CLASS_VALID 0x8000
+#define INTERMIX_MODE 0x4000
+#define TRANSPARENT_STACKED 0x2000
+#define LOCKDOWN_STACKED 0x1000
+#define SEQ_DELIVERY 0x800
+
+#define XID_NOT_SUPPORTED 0x00
+#define XID_SUPPORTED 0x4000
+#define XID_REQUIRED 0xC000
+
+#define ASSOCIATOR_NOT_SUPPORTED 0x00
+#define ASSOCIATOR_SUPPORTED 0x1000
+#define ASSOCIATOR_REQUIRED 0x3000
+
+#define INIT_ACK0_SUPPORT 0x800
+#define INIT_ACKN_SUPPORT 0x400
+
+#define RECIP_ACK0_SUPPORT 0x8000
+#define RECIP_ACKN_SUPPORT 0x4000
+
+#define X_ID_INTERLOCK 0x2000
+
+#define ERROR_POLICY 0x1800 // Error Policy Supported
+#define ERROR_DISCARD 0x00 // Only Discard Supported
+#define ERROR_DISC_PROCESS 0x02 // Discard and process supported
+
+#define NODE_ID 0x01
+#define IEEE_EXT 0x20
+
+//
+// Categories Supported Per Sequence
+//
+#define CATEGORIES_PER_SEQUENCE 0x300
+#define ONE_CATEGORY_SEQUENCE 0x00 // 1 Category per Sequence
+#define TWO_CATEGORY_SEQUENCE 0x01 // 2 Categories per Sequence
+#define MANY_CATEGORY_SEQUENCE 0x03 // > 2 Categories/Sequence
+
+typedef struct {
+
+ USHORT initiator_control;
+ USHORT service_options;
+
+ USHORT rx_data_size;
+ USHORT recipient_control;
+
+ USHORT ee_credit;
+ USHORT concurrent_sequences;
+
+ USHORT reserved;
+ USHORT open_sequences;
+
+} CLASS_PARAMETERS;
+
+typedef struct {
+ ULONG login_cmd;
+ //
+ // Common Service Parameters
+ //
+ struct {
+
+ USHORT bb_credit;
+ UCHAR lowest_ver;
+ UCHAR highest_ver;
+
+ USHORT bb_rx_size;
+ USHORT common_features;
+
+ USHORT rel_offset;
+ USHORT concurrent_seq;
+
+
+ ULONG e_d_tov;
+ } cmn_services;
+
+ //
+ // Port Name
+ //
+ UCHAR port_name[8];
+
+ //
+ // Node/Fabric Name
+ //
+ UCHAR node_name[8];
+
+ //
+ // Class 1, 2 and 3 Service Parameters
+ //
+ CLASS_PARAMETERS class1;
+ CLASS_PARAMETERS class2;
+ CLASS_PARAMETERS class3;
+
+ ULONG reserved[4];
+
+ //
+ // Vendor Version Level
+ //
+ UCHAR vendor_id[2];
+ UCHAR vendor_version[6];
+ ULONG buffer_size;
+ USHORT rxid_start;
+ USHORT total_rxids;
+} LOGIN_PAYLOAD;


+
+
+typedef struct
+{

+ ULONG cmd; // 4 bytes
+ UCHAR n_port_identifier[3];
+ UCHAR reserved;
+ UCHAR port_name[8];
+} LOGOUT_PAYLOAD;
+
+
+//
+// PRLI Request Service Parameter Defines
+//
+#define PRLI_ACC 0x01
+#define PRLI_REQ 0x02
+#define ORIG_PROCESS_ASSOC_VALID 0x8000
+#define RESP_PROCESS_ASSOC_VALID 0x4000
+#define ESTABLISH_PAIR 0x2000
+#define DATA_OVERLAY_ALLOWED 0x40
+#define INITIATOR_FUNCTION 0x20
+#define TARGET_FUNCTION 0x10
+#define CMD_DATA_MIXED 0x08
+#define DATA_RESP_MIXED 0x04
+#define READ_XFER_RDY 0x02
+#define WRITE_XFER_RDY 0x01
+
+#define RESPONSE_CODE_MASK 0xF00
+#define REQUEST_EXECUTED 0x100
+#define NO_RESOURCES 0x200
+#define INIT_NOT_COMPLETE 0x300
+#define IMAGE_DOES_NOT_EXIST 0x400
+#define BAD_PREDEFINED_COND 0x500
+#define REQ_EXEC_COND 0x600
+#define NO_MULTI_PAGE 0x700
+
+typedef struct {
+ USHORT payload_length;
+ UCHAR page_length;
+ UCHAR cmd;
+
+
+ ULONG valid;
+
+ ULONG orig_process_associator;
+
+ ULONG resp_process_associator;
+
+ ULONG fcp_info;
+} PRLI_REQUEST;
+
+typedef struct {
+
+ USHORT payload_length;
+ UCHAR page_length;
+ UCHAR cmd;
+
+ ULONG valid;
+ ULONG orig_process_associator;
+
+ ULONG resp_process_associator;
+ ULONG reserved;
+} PRLO_REQUEST;
+
+typedef struct {
+ ULONG cmd;
+
+ ULONG hard_address;
+
+ UCHAR port_name[8];
+
+ UCHAR node_name[8];
+
+ ULONG s_id;
+} ADISC_PAYLOAD;
+
+// J. McCarty's LINK.H
+//
+// LS_RJT Reason Codes
+//
+
+#define INVALID_COMMAND_CODE 0x01
+#define LOGICAL_ERROR 0x03
+#define LOGICAL_BUSY 0x05
+#define PROTOCOL_ERROR 0x07
+#define UNABLE_TO_PERFORM 0x09
+#define COMMAND_NOT_SUPPORTED 0x0B
+#define LS_VENDOR_UNIQUE 0xFF
+
+//
+// LS_RJT Reason Codes Explanations
+//
+#define NO_REASON 0x00
+#define OPTIONS_ERROR 0x01
+#define INITIATOR_CTL_ERROR 0x03
+#define RECIPIENT_CTL_ERROR 0x05
+#define DATA_FIELD_SIZE_ERROR 0x07
+#define CONCURRENT_SEQ_ERROR 0x09
+#define CREDIT_ERROR 0x0B
+#define INVALID_PORT_NAME 0x0D
+#define INVALID_NODE_NAME 0x0E
+#define INVALID_CSP 0x0F // Invalid Service Parameters
+#define INVALID_ASSOC_HDR 0x11 // Invalid Association Header
+#define ASSOC_HDR_REQUIRED 0x13 // Association Header Required
+#define LS_INVALID_S_ID 0x15
+#define INVALID_OX_RX_ID 0x17 // Invalid OX_ID RX_ID Combination
+#define CMD_IN_PROCESS 0x19
+#define INVALID_IDENTIFIER 0x1F // Invalid N_PORT Identifier
+#define INVALID_SEQ_ID 0x21
+#define ABT_INVALID_XCHNG 0x23 // Attempt to Abort an invalid Exchange
+#define ABT_INACTIVE_XCHNG 0x25 // Attempt to Abort an inactive Exchange
+#define NEED_REC_QUAL 0x27 // Recovery Qualifier required
+#define NO_LOGIN_RESOURCES 0x29 // No resources to support login
+#define NO_DATA 0x2A // Unable to supply requested data
+#define REQUEST_NOT_SUPPORTED 0x2C // Request Not Supported
+
+//
+// Link Control Codes
+//
+
+//
+// P_BSY Action Codes
+//
+#define SEQUENCE_TERMINATED 0x01000000
+#define SEQUENCE_ACTIVE 0x02000000
+
+//
+// P_BSY Reason Codes
+//
+#define PHYS_NPORT_BUSY 0x010000
+#define NPORT_RESOURCE_BUSY 0x020000
+
+//
+// P_RJT, F_RJT Action Codes
+//
+
+#define RETRYABLE_ERROR 0x01000000
+#define NON_RETRYABLE_ERROR 0x02000000
+
+//
+// P_RJT, F_RJT Reason Codes
+//
+#define INVALID_D_ID 0x010000
+#define INVALID_S_ID 0x020000
+#define NPORT_NOT_AVAIL_TMP 0x030000
+#define NPORT_NOT_AVAIL_PERM 0x040000
+#define CLASS_NOT_SUPPORTED 0x050000
+#define USAGE_ERROR 0x060000
+#define TYPE_NOT_SUPPORTED 0x070000
+#define INVAL_LINK_CONTROL 0x080000
+#define INVAL_R_CTL 0x090000
+#define INVAL_F_CTL 0x0A0000
+#define INVAL_OX_ID 0x0B0000
+#define INVAL_RX_ID 0x0C0000
+#define INVAL_SEQ_ID 0x0D0000
+#define INVAL_DF_CTL 0x0E0000
+#define INVAL_SEQ_CNT 0x0F0000
+#define INVAL_PARAMS 0x100000
+#define EXCHANGE_ERROR 0x110000
+#define LS_PROTOCOL_ERROR 0x120000
+#define INCORRECT_LENGTH 0x130000
+#define UNEXPECTED_ACK 0x140000
+#define LOGIN_REQ 0x160000
+#define EXCESSIVE_SEQ 0x170000
+#define NO_EXCHANGE 0x180000
+#define SEC_HDR_NOT_SUPPORTED 0x190000
+#define NO_FABRIC 0x1A0000
+#define P_VENDOR_UNIQUE 0xFF0000
+
+//
+// BA_RJT Reason Codes
+//
+#define BA_INVALID_COMMAND 0x00010000
+#define BA_LOGICAL_ERROR 0x00030000
+#define BA_LOGICAL_BUSY 0x00050000
+#define BA_PROTOCOL_ERROR 0x00070000
+#define BA_UNABLE_TO_PERFORM 0x00090000
+
+//
+// BA_RJT Reason Explanation Codes
+//
+#define BA_NO_REASON 0x00000000
+#define BA_INVALID_OX_RX 0x00000300
+#define BA_SEQUENCE_ABORTED 0x00000500
+
+
+
+#endif /* CPQFCTSSTRUCTS_H */
+
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/cpqfcTStrigger.c linux/drivers/scsi/cpqfcTStrigger.c
--- v2.4.0-test8/linux/drivers/scsi/cpqfcTStrigger.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/cpqfcTStrigger.c Tue Sep 19 08:01:34 2000
@@ -0,0 +1,30 @@
+// Routine to trigger Finisar GTA analyzer. Runs of GPIO2
+// NOTE: DEBUG ONLY! Could interfere with FCMNGR/Miniport operation
+// since it writes directly to the Tachyon board. This function
+// developed for Compaq HBA Tachyon TS v1.2 (Rev X5 PCB)
+
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+
+void TriggerHBA( void* IOBaseUpper, int Print)
+{
+ __u32 long value;
+
+ // get initial value in hopes of not modifying any other GPIO line
+ IOBaseUpper += 0x188; // TachTL/TS Control reg
+
+ value = readl( IOBaseUpper);
+ // set HIGH to trigger external analyzer (tested on Dolche Finisar 1Gb GTA)
+ // The Finisar anaylzer triggers on low-to-high TTL transition
+ value |= 0x01; // set bit 0
+
+ writel( value, IOBaseUpper);
+
+ if( Print)
+ printk( " -GPIO0 set- ");
+}
+
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/cpqfcTSworker.c linux/drivers/scsi/cpqfcTSworker.c
--- v2.4.0-test8/linux/drivers/scsi/cpqfcTSworker.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/cpqfcTSworker.c Tue Sep 19 08:01:35 2000
@@ -0,0 +1,6238 @@


+/* Copyright(c) 2000, Compaq Computer Corporation
+ * Fibre Channel Host Bus Adapter

+ * 64-bit, 66MHz PCI

+ * Originally developed and tested on:
+ * (front): [chip] Tachyon TS HPFC-5166A/1.2 L2C1090 ...
+ * SP# P225CXCBFIEL6T, Rev XC
+ * SP# 161290-001, Rev XD
+ * (back): Board No. 010008-001 A/W Rev X5, FAB REV X5
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ * Written by Don Zimmerman
+*/
+

+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/string.h>
+#include <linux/malloc.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/stat.h>
+#include <linux/blk.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/smp_lock.h>
+
+#define __KERNEL_SYSCALLS__
+
+#define SHUTDOWN_SIGS (sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM))
+
+#include <linux/unistd.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/dma.h>
+
+
+
+#include "sd.h"
+#include "hosts.h" // struct Scsi_Host definition for T handler


+#include "cpqfcTSchip.h"
+#include "cpqfcTSstructs.h"
+

+//#define LOGIN_DBG 1
+
+// REMARKS:
+// Since Tachyon chips may be permitted to wait from 500ms up to 2 sec
+// to empty an outgoing frame from its FIFO to the Fibre Channel stream,
+// we cannot do everything we need to in the interrupt handler. Specifically,
+// every time a link re-init (e.g. LIP) takes place, all SCSI I/O has to be
+// suspended until the login sequences have been completed. Login commands
+// are frames just like SCSI commands are frames; they are subject to the same
+// timeout issues and delays. Also, various specs provide up to 2 seconds for
+// devices to log back in (i.e. respond with ACC to a login frame), so I/O to
+// that device has to be suspended.
+// A serious problem here occurs on highly loaded FC-AL systems. If our FC port
+// has a low priority (e.g. high arbitrated loop physical address, alpa), and
+// some other device is hogging bandwidth (permissible under FC-AL), we might
+// time out thinking the link is hung, when it's simply busy. Many such
+// considerations complicate the design. Although Tachyon assumes control
+// (in silicon) for many link-specific issues, the Linux driver is left with the
+// rest, which turns out to be a difficult, time critical chore.
+
+// These "worker" functions will handle things like FC Logins; all
+// processes with I/O to our device must wait for the Login to complete
+// and (if successful) I/O to resume. In the event of a malfunctioning or
+// very busy loop, it may take hundreds of millisecs or even seconds to complete
+// a frame send. We don't want to hang up the entire server (and all
+// processes which don't depend on Fibre) during this wait.
+
+// The Tachyon chip can have around 30,000 I/O operations ("exchanges")
+// open at one time. However, each exchange must be initiated
+// synchronously (i.e. each of the 30k I/O had to be started one at a
+// time by sending a starting frame via Tachyon's outbound que).
+
+// To accomodate kernel "module" build, this driver limits the exchanges
+// to 256, because of the contiguous physical memory limitation of 128M.
+
+// Typical FC Exchanges are opened presuming the FC frames start without errors,
+// while Exchange completion is handled in the interrupt handler. This
+// optimizes performance for the "everything's working" case.
+// However, when we have FC related errors or hot plugging of FC ports, we pause
+// I/O and handle FC-specific tasks in the worker thread. These FC-specific
+// functions will handle things like FC Logins and Aborts. As the Login sequence
+// completes to each and every target, I/O can resume to that target.
+
+// Our kernel "worker thread" must share the HBA with threads calling
+// "queuecommand". We define a "BoardLock" semaphore which indicates
+// to "queuecommand" that the HBA is unavailable, and Cmnds are added to a
+// board lock Q. When the worker thread finishes with the board, the board
+// lock Q commands are completed with status causing immediate retry.
+// Typically, the board is locked while Logins are in progress after an
+// FC Link Down condition. When Cmnds are re-queued after board lock, the
+// particular Scsi channel/target may or may not have logged back in. When
+// the device is waiting for login, the "prli" flag is clear, in which case
+// commands are passed to a Link Down Q. Whenever the login finally completes,
+// the LinkDown Q is completed, again with status causing immediate retry.
+// When FC devices are logged in, we build and start FC commands to the
+// devices.
+
+// NOTE!! As of May 2000, kernel 2.2.14, the error recovery logic for devices
+// that never log back in (e.g. physically removed) is NOT completely
+// understood. I've still seen instances of system hangs on failed Write
+// commands (possibly from the ext2 layer?) on device removal. Such special
+// cases need to be evaluated from a system/application view - e.g., how
+// exactly does the system want me to complete commands when the device is
+// physically removed??
+
+// local functions
+
+static void SetLoginFields(
+ PFC_LOGGEDIN_PORT pLoggedInPort,
+ TachFCHDR_GCMND* fchs,
+ BOOLEAN PDisc,
+ BOOLEAN Originator);
+
+static void AnalyzeIncomingFrame(
+ CPQFCHBA *cpqfcHBAdata,
+ ULONG QNdx );
+
+static void SendLogins( CPQFCHBA *cpqfcHBAdata, __u32 *FabricPortIds );
+
+static int verify_PLOGI( PTACHYON fcChip,
+ TachFCHDR_GCMND* fchs, ULONG* reject_explain);
+static int verify_PRLI( TachFCHDR_GCMND* fchs, ULONG* reject_explain);
+
+static void LoadWWN( PTACHYON fcChip, UCHAR* dest, UCHAR type);
+static void BuildLinkServicePayload(
+ PTACHYON fcChip, ULONG type, void* payload);
+
+static void UnblockScsiDevice( struct Scsi_Host *HostAdapter,
+ PFC_LOGGEDIN_PORT pLoggedInPort);
+
+static void cpqfcTSCheckandSnoopFCP( PTACHYON fcChip, ULONG x_ID);
+
+static void CompleteBoardLockCmnd( CPQFCHBA *cpqfcHBAdata);
+
+static void RevalidateSEST( struct Scsi_Host *HostAdapter,
+ PFC_LOGGEDIN_PORT pLoggedInPort);
+
+static void IssueReportLunsCommand(
+ CPQFCHBA* cpqfcHBAdata,
+ TachFCHDR_GCMND* fchs);
+
+
+// (see scsi_error.c comments on kernel task creation)
+
+void cpqfcTSWorkerThread( void *host)
+{
+ struct Scsi_Host *HostAdapter = (struct Scsi_Host*)host;


+ CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;

+#ifdef PCI_KERNEL_TRACE


+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;

+#endif
+ struct fs_struct *fs;
+ DECLARE_MUTEX_LOCKED(fcQueReady);
+ DECLARE_MUTEX_LOCKED(fcTYOBcomplete);
+ DECLARE_MUTEX_LOCKED(TachFrozen);
+ DECLARE_MUTEX_LOCKED(BoardLock);
+
+ ENTER("WorkerThread");
+
+ lock_kernel();
+ /*
+ * If we were started as result of loading a module, close all of the
+ * user space pages. We don't need them, and if we didn't close them
+ * they would be locked into memory.
+ */
+ exit_mm(current);
+
+ current->session = 1;
+ current->pgrp = 1;
+
+ /* Become as one with the init task */
+
+ exit_fs(current); /* current->fs->count--; */
+ fs = init_task.fs;
+ // Some kernels compiled for SMP, while actually running
+ // on a uniproc machine, will return NULL for this call
+ if( !fs)
+ {
+ printk(" cpqfcTS FATAL: fs is NULL! Is this an SMP kernel on uniproc machine?\n ");
+ }
+
+ else
+ {
+ current->fs = fs;
+ atomic_inc(&fs->count);
+ }
+
+ siginitsetinv(&current->blocked, SHUTDOWN_SIGS);
+
+
+ /*
+ * Set the name of this process.
+ */
+ sprintf(current->comm, "cpqfcTS_wt_%d", HostAdapter->host_no);
+
+ cpqfcHBAdata->fcQueReady = &fcQueReady; // primary wait point
+ cpqfcHBAdata->TYOBcomplete = &fcTYOBcomplete;
+ cpqfcHBAdata->TachFrozen = &TachFrozen;
+
+
+ cpqfcHBAdata->worker_thread = current;
+
+ unlock_kernel();
+
+ if( cpqfcHBAdata->notify_wt != NULL )
+ up( cpqfcHBAdata->notify_wt); // OK to continue
+
+ while(1)
+ {


+ unsigned long flags;
+

+ down_interruptible( &fcQueReady); // wait for something to do
+
+ if (signal_pending(current) )
+ break;
+
+ PCI_TRACE( 0x90)
+ // first, take the IO lock so the SCSI upper layers can't call
+ // into our _quecommand function (this also disables INTs)
+ spin_lock_irqsave( &io_request_lock, flags); // STOP _que function
+ PCI_TRACE( 0x90)
+
+ CPQ_SPINLOCK_HBA( cpqfcHBAdata)
+ // next, set this pointer to indicate to the _quecommand function
+ // that the board is in use, so it should que the command and
+ // immediately return (we don't actually require the semaphore function
+ // in this driver rev)
+
+ cpqfcHBAdata->BoardLock = &BoardLock;
+
+ PCI_TRACE( 0x90)
+
+ // release the IO lock (and re-enable interrupts)


+ spin_unlock_irqrestore( &io_request_lock, flags);
+

+ // disable OUR HBA interrupt (keep them off as much as possible
+ // during error recovery)
+ disable_irq( cpqfcHBAdata->HostAdapter->irq);
+
+ // OK, let's process the Fibre Channel Link Q and do the work
+ cpqfcTS_WorkTask( HostAdapter);
+
+ // hopefully, no more "work" to do;
+ // re-enable our INTs for "normal" completion processing
+ enable_irq( cpqfcHBAdata->HostAdapter->irq);
+
+
+ cpqfcHBAdata->BoardLock = NULL; // allow commands to be queued


+ CPQ_SPINUNLOCK_HBA( cpqfcHBAdata)
+
+

+ // Now, complete any Cmnd we Q'd up while BoardLock was held
+
+ CompleteBoardLockCmnd( cpqfcHBAdata);
+
+
+ }
+ // hopefully, the signal was for our module exit...
+ if( cpqfcHBAdata->notify_wt != NULL )
+ up( cpqfcHBAdata->notify_wt); // yep, we're outta here
+}
+
+
+// Freeze Tachyon routine.
+// If Tachyon is already frozen, return FALSE
+// If Tachyon is not frozen, call freeze function, return TRUE
+//
+static BOOLEAN FreezeTach( CPQFCHBA *cpqfcHBAdata)
+{


+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;

+ BOOLEAN FrozeTach = FALSE;
+ // It's possible that the chip is already frozen; if so,
+ // "Freezing" again will NOT! generate another Freeze
+ // Completion Message.
+
+ if( (fcChip->Registers.TYstatus.value & 0x70000) != 0x70000)
+ { // (need to freeze...)
+ fcChip->FreezeTachyon( fcChip, 2); // both ERQ and FCP assists
+
+ // 2. Get Tach freeze confirmation
+ // (synchronize SEST manipulation with Freeze Completion Message)
+ // we need INTs on so semaphore can be set.
+ enable_irq( cpqfcHBAdata->HostAdapter->irq); // only way to get Semaphore
+ down_interruptible( cpqfcHBAdata->TachFrozen); // wait for INT handler sem.
+ // can we TIMEOUT semaphore wait?? TBD
+ disable_irq( cpqfcHBAdata->HostAdapter->irq);
+
+ FrozeTach = TRUE;
+ } // (else, already frozen)
+
+ return FrozeTach;


+}
+
+
+
+

+// This is the kernel worker thread task, which processes FC
+// tasks which were queued by the Interrupt handler or by
+// other WorkTask functions.
+
+#define DBG 1
+//#undef DBG


+void cpqfcTS_WorkTask( struct Scsi_Host *HostAdapter)

+{


+ CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;
+ FC_EXCHANGES *Exchanges = fcChip->Exchanges;

+ ULONG QconsumerNdx;
+ LONG ExchangeID;
+ ULONG ulStatus=0;
+ TachFCHDR_GCMND fchs;
+ PFC_LINK_QUE fcLQ = cpqfcHBAdata->fcLQ;
+
+ ENTER("WorkTask");
+
+ // copy current index to work on
+ QconsumerNdx = fcLQ->consumer;
+
+ PCI_TRACEO( fcLQ->Qitem[QconsumerNdx].Type, 0x90)
+
+
+ // NOTE: when this switch completes, we will "consume" the Que item
+// printk("Que type %Xh\n", fcLQ->Qitem[QconsumerNdx].Type);
+ switch( fcLQ->Qitem[QconsumerNdx].Type )
+ {
+ // incoming frame - link service (ACC, UNSOL REQ, etc.)
+ // or FCP-SCSI command
+ case SFQ_UNKNOWN:
+ AnalyzeIncomingFrame( cpqfcHBAdata, QconsumerNdx );
+
+ break;
+
+
+
+ case EXCHANGE_QUEUED: // an Exchange (i.e. FCP-SCSI) was previously
+ // Queued because the link was down. The
+ // heartbeat timer detected it and Queued it here.
+ // We attempt to start it again, and if
+ // successful we clear the EXCHANGE_Q flag.
+ // If the link doesn't come up, the Exchange
+ // will eventually time-out.
+
+ ExchangeID = (LONG) // x_ID copied from DPC timeout function
+ fcLQ->Qitem[QconsumerNdx].ulBuff[0];
+
+ // It's possible that a Q'd exchange could have already
+ // been started by other logic (e.g. ABTS process)
+ // Don't start if already started (Q'd flag clear)
+
+ if( Exchanges->fcExchange[ExchangeID].status & EXCHANGE_QUEUED )
+ {
+// printk(" *Start Q'd x_ID %Xh: type %Xh ",
+// ExchangeID, Exchanges->fcExchange[ExchangeID].type);


+
+ ulStatus = cpqfcTSStartExchange( cpqfcHBAdata, ExchangeID);
+ if( !ulStatus )
+ {

+// printk("success* ");
+ }

+ else
+ {
+#ifdef DBG
+

+ if( ulStatus == EXCHANGE_QUEUED)
+ printk("Queued* ");
+ else
+ printk("failed* ");
+
+#endif
+ }

+ }
+ break;
+
+

+ case LINKDOWN:
+ // (lots of things already done in INT handler) future here?
+ break;
+
+
+ case LINKACTIVE: // Tachyon set the Lup bit in FM status
+ // NOTE: some misbehaving FC ports (like Tach2.1)
+ // can re-LIP immediately after a LIP completes.
+
+ // if "initiator", need to verify LOGs with ports
+// printk("\n*LNKUP* ");
+
+ if( fcChip->Options.initiator )
+ SendLogins( cpqfcHBAdata, NULL ); // PLOGI or PDISC, based on fcPort data
+ // if SendLogins successfully completes, PortDiscDone
+ // will be set.
+
+
+ // If SendLogins was successful, then we expect to get incoming
+ // ACCepts or REJECTs, which are handled below.
+
+ break;
+
+ // LinkService and Fabric request/reply processing
+ case ELS_FDISC: // need to send Fabric Discovery (Login)
+ case ELS_FLOGI: // need to send Fabric Login
+ case ELS_SCR: // need to send State Change Registration
+ case FCS_NSR: // need to send Name Service Request
+ case ELS_PLOGI: // need to send PLOGI
+ case ELS_ACC: // send generic ACCept
+ case ELS_PLOGI_ACC: // need to send ELS ACCept frame to recv'd PLOGI
+ case ELS_PRLI_ACC: // need to send ELS ACCept frame to recv'd PRLI
+ case ELS_LOGO: // need to send ELS LOGO (logout)
+ case ELS_LOGO_ACC: // need to send ELS ACCept frame to recv'd PLOGI
+ case ELS_RJT: // ReJecT reply
+ case ELS_PRLI: // need to send ELS PRLI
+
+
+// printk(" *ELS %Xh* ", fcLQ->Qitem[QconsumerNdx].Type);
+ // if PortDiscDone is not set, it means the SendLogins routine
+ // failed to complete -- assume that LDn occured, so login frames
+ // are invalid
+ if( !cpqfcHBAdata->PortDiscDone) // cleared by LDn
+ {
+ printk("Discard Q'd ELS login frame\n");
+ break;
+ }
+


+ ulStatus = cpqfcTSBuildExchange(
+ cpqfcHBAdata,

+ fcLQ->Qitem[QconsumerNdx].Type, // e.g. PLOGI
+ (TachFCHDR_GCMND*)
+ fcLQ->Qitem[QconsumerNdx].ulBuff, // incoming fchs
+ NULL, // no data (no scatter/gather list)


+ &ExchangeID );// fcController->fcExchanges index, -1 if failed
+
+ if( !ulStatus ) // Exchange setup?
+ {

+ ulStatus = cpqfcTSStartExchange( cpqfcHBAdata, ExchangeID );
+ if( !ulStatus )
+ {

+ // submitted to Tach's Outbound Que (ERQ PI incremented)
+ // waited for completion for ELS type (Login frames issued
+ // synchronously)
+ }
+ else
+ // check reason for Exchange not being started - we might
+ // want to Queue and start later, or fail with error
+ {
+

+ }
+ }
+
+ else // Xchange setup failed...
+ printk(" cpqfcTSBuildExchange failed: %Xh\n", ulStatus );
+
+ break;
+
+ case SCSI_REPORT_LUNS:
+ // pass the incoming frame (actually, it's a PRLI frame)
+ // so we can send REPORT_LUNS, in order to determine VSA/PDU
+ // FCP-SCSI Lun address mode
+ IssueReportLunsCommand( cpqfcHBAdata, (TachFCHDR_GCMND*)
+ fcLQ->Qitem[QconsumerNdx].ulBuff);

+
+ break;
+
+
+
+

+ case BLS_ABTS: // need to ABORT one or more exchanges
+ {
+ LONG x_ID = fcLQ->Qitem[QconsumerNdx].ulBuff[0];
+ BOOLEAN FrozeTach = FALSE;
+
+ if( x_ID > TACH_SEST_LEN ) // (in)sanity check
+ {
+// printk( " cpqfcTS ERROR! BOGUS x_ID %Xh", x_ID);


+ break;
+ }
+
+

+ if( Exchanges->fcExchange[ x_ID].Cmnd == NULL ) // should be RARE
+ {
+// printk(" ABTS %Xh Scsi Cmnd null! ", x_ID);
+
+ break; // nothing to abort!
+ }
+
+//#define ABTS_DBG
+#ifdef ABTS_DBG
+ printk("INV SEST[%X] ", x_ID);
+ if( Exchanges->fcExchange[x_ID].status & FC2_TIMEOUT)
+ {
+ printk("FC2TO");
+ }
+ if( Exchanges->fcExchange[x_ID].status & INITIATOR_ABORT)
+ {
+ printk("IA");
+ }
+ if( Exchanges->fcExchange[x_ID].status & PORTID_CHANGED)
+ {
+ printk("PORTID");
+ }
+ if( Exchanges->fcExchange[x_ID].status & DEVICE_REMOVED)
+ {
+ printk("DEVRM");
+ }
+ if( Exchanges->fcExchange[x_ID].status & LINKFAIL_TX)
+ {
+ printk("LKF");
+ }
+ if( Exchanges->fcExchange[x_ID].status & FRAME_TO)
+ {
+ printk("FRMTO");
+ }
+ if( Exchanges->fcExchange[x_ID].status & ABORTSEQ_NOTIFY)
+ {
+ printk("ABSQ");
+ }
+ if( Exchanges->fcExchange[x_ID].status & SFQ_FRAME)
+ {
+ printk("SFQFR");
+ }
+
+ if( Exchanges->fcExchange[ x_ID].type == 0x2000)
+ printk(" WR");
+ else if( Exchanges->fcExchange[ x_ID].type == 0x3000)
+ printk(" RD");
+ else if( Exchanges->fcExchange[ x_ID].type == 0x10)
+ printk(" ABTS");
+ else
+ printk(" %Xh", Exchanges->fcExchange[ x_ID].type);
+
+ if( !(Exchanges->fcExchange[x_ID].status & INITIATOR_ABORT))
+ {
+ printk(" Cmd %p, ",
+ Exchanges->fcExchange[ x_ID].Cmnd);
+
+ printk(" brd/chn/trg/lun %d/%d/%d/%d port_id %06X\n",
+ cpqfcHBAdata->HBAnum,
+ Exchanges->fcExchange[ x_ID].Cmnd->channel,
+ Exchanges->fcExchange[ x_ID].Cmnd->target,
+ Exchanges->fcExchange[ x_ID].Cmnd->lun,
+ Exchanges->fcExchange[ x_ID].fchs.d_id & 0xFFFFFF);
+ }
+ else // assume that Cmnd ptr is invalid on _abort()
+ {
+ printk(" Cmd ptr invalid\n");


+ }
+
+#endif
+
+

+ // Steps to ABORT a SEST exchange:
+ // 1. Freeze TL SCSI assists & ERQ (everything)
+ // 2. Receive FROZEN inbound CM (must succeed!)
+ // 3. Invalidate x_ID SEST entry
+ // 4. Resume TL SCSI assists & ERQ (everything)
+ // 5. Build/start on exchange - change "type" to BLS_ABTS,
+ // timeout to X sec (RA_TOV from PLDA is actually 0)
+ // 6. Set Exchange Q'd status if ABTS cannot be started,
+ // or simply complete Exchange in "Terminate" condition
+
+ PCI_TRACEO( x_ID, 0xB4)
+
+ // 1 & 2 . Freeze Tach & get confirmation of freeze
+ FrozeTach = FreezeTach( cpqfcHBAdata);
+
+ // 3. OK, Tachyon is frozen, so we can invalidate SEST exchange.
+ // FC2_TIMEOUT means we are originating the abort, while
+ // TARGET_ABORT means we are ACCepting an abort.
+ // LINKFAIL_TX, ABORTSEQ_NOFITY, INV_ENTRY or FRAME_TO are
+ // all from Tachyon:
+ // Exchange was corrupted by LDn or other FC physical failure
+ // INITIATOR_ABORT means the upper layer driver/application
+ // requested the abort.
+
+
+
+ // clear bit 31 (VALid), to invalidate & take control from TL


+ fcChip->SEST->u[ x_ID].IWE.Hdr_Len &= 0x7FFFFFFF;
+
+

+ // examine and Tach's "Linked List" for IWEs that
+ // received (nearly) simultaneous transfer ready (XRDY)
+ // repair linked list if necessary (TBD!)
+ // (If we ignore the "Linked List", we will time out
+ // WRITE commands where we received the FCP-SCSI XFRDY
+ // frame (because Tachyon didn't processes it). Linked List
+ // management should be done as an optimization.
+
+// readl( fcChip->Registers.ReMapMemBase+TL_MEM_SEST_LINKED_LIST ));
+
+
+
+
+ // 4. Resume all Tachlite functions (for other open Exchanges)
+ // as quickly as possible to allow other exchanges to other ports
+ // to resume. Freezing Tachyon may cause cascading errors, because
+ // any received SEST frame cannot be processed by the SEST.
+ // Don't "unfreeze" unless Link is operational
+ if( FrozeTach ) // did we just freeze it (above)?
+ fcChip->UnFreezeTachyon( fcChip, 2); // both ERQ and FCP assists
+
+
+ PCI_TRACEO( x_ID, 0xB4)
+
+ // Note there is no confirmation that the chip is "unfrozen". Also,
+ // if the Link is down when unfreeze is called, it has no effect.
+ // Chip will unfreeze when the Link is back up.
+
+ // 5. Now send out Abort commands if possible
+ // Some Aborts can't be "sent" (Port_id changed or gone);
+ // if the device is gone, there is no port_id to send the ABTS to.
+
+ if( !(Exchanges->fcExchange[ x_ID].status & PORTID_CHANGED)
+ &&
+ !(Exchanges->fcExchange[ x_ID].status & DEVICE_REMOVED) )
+ {
+ Exchanges->fcExchange[ x_ID].type = BLS_ABTS;
+ fchs.s_id = Exchanges->fcExchange[ x_ID].fchs.d_id;


+ ulStatus = cpqfcTSBuildExchange(
+ cpqfcHBAdata,

+ BLS_ABTS,
+ &fchs, // (uses only s_id)
+ NULL, // (no scatter/gather list for ABTS)
+ &x_ID );// ABTS on this Exchange ID
+
+ if( !ulStatus ) // Exchange setup build OK?
+ {
+
+ // ABTS may be needed because an Exchange was corrupted
+ // by a Link disruption. If the Link is UP, we can
+ // presume that this ABTS can start immediately; otherwise,
+ // set Que'd status so the Login functions
+ // can restart it when the FC physical Link is restored
+ if( ((fcChip->Registers.FMstatus.value &0xF0) &0x80)) // loop init?
+ {
+// printk(" *set Q status x_ID %Xh on LDn* ", x_ID);
+ Exchanges->fcExchange[ x_ID].status |= EXCHANGE_QUEUED;
+ }
+
+ else // what FC device (port_id) does the Cmd belong to?


+ {
+ PFC_LOGGEDIN_PORT pLoggedInPort =

+ Exchanges->fcExchange[ x_ID].pLoggedInPort;
+
+ // if Port is logged in, we might start the abort.
+
+ if( (pLoggedInPort != NULL)
+ &&
+ (pLoggedInPort->prli == TRUE) )
+ {
+ // it's possible that an Exchange has already been Queued
+ // to start after Login completes. Check and don't
+ // start it (again) here if Q'd status set
+// printk(" ABTS xchg %Xh ", x_ID);
+ if( Exchanges->fcExchange[x_ID].status & EXCHANGE_QUEUED)
+ {
+// printk("already Q'd ");
+ }
+ else
+ {
+// printk("starting ");
+
+ fcChip->fcStats.FC2aborted++;
+ ulStatus = cpqfcTSStartExchange( cpqfcHBAdata, x_ID );


+ if( !ulStatus )
+ {

+ // OK


+ // submitted to Tach's Outbound Que (ERQ PI incremented)
+ }

+ else
+ {
+/* printk("ABTS exchange start failed -status %Xh, x_ID %Xh ",
+ ulStatus, x_ID);
+*/


+ }
+ }
+ }
+ else

+ {
+/* printk(" ABTS NOT starting xchg %Xh, %p ",
+ x_ID, pLoggedInPort);
+ if( pLoggedInPort )
+ printk("prli %d ", pLoggedInPort->prli);
+*/
+ }
+ }
+ }
+ else // what the #@!
+ { // how do we fail to build an Exchange for ABTS??
+ printk("ABTS exchange build failed -status %Xh, x_ID %Xh\n",
+ ulStatus, x_ID);
+ }
+ }
+ else // abort without ABTS -- just complete exchange/Cmnd to Linux
+ {
+// printk(" *Terminating x_ID %Xh on %Xh* ",
+// x_ID, Exchanges->fcExchange[x_ID].status);
+ cpqfcTSCompleteExchange( fcChip, x_ID);
+
+
+ }
+ } // end of ABTS case


+ break;
+
+
+

+ case BLS_ABTS_ACC: // need to ACCept one ABTS
+ // (NOTE! this code not updated for Linux yet..)
+
+
+ printk(" *ABTS_ACC* ");
+ // 1. Freeze TL
+
+ fcChip->FreezeTachyon( fcChip, 2); // both ERQ and FCP assists
+
+ memcpy( // copy the incoming ABTS frame
+ &fchs,
+ fcLQ->Qitem[QconsumerNdx].ulBuff, // incoming fchs
+ sizeof( fchs));
+
+ // 3. OK, Tachyon is frozen so we can invalidate SEST entry
+ // (if necessary)
+ // Status FC2_TIMEOUT means we are originating the abort, while
+ // TARGET_ABORT means we are ACCepting an abort
+
+ ExchangeID = fchs.ox_rx_id & 0x7FFF; // RX_ID for exchange
+// printk("ABTS ACC for Target ExchangeID %Xh\n", ExchangeID);
+
+
+ // sanity check on received ExchangeID
+ if( Exchanges->fcExchange[ ExchangeID].status == TARGET_ABORT )
+ {
+ // clear bit 31 (VALid), to invalidate & take control from TL
+// printk("Invalidating SEST exchange %Xh\n", ExchangeID);
+ fcChip->SEST->u[ ExchangeID].IWE.Hdr_Len &= 0x7FFFFFFF;
+ }
+
+
+ // 4. Resume all Tachlite functions (for other open Exchanges)
+ // as quickly as possible to allow other exchanges to other ports
+ // to resume. Freezing Tachyon for too long may royally screw
+ // up everything!
+ fcChip->UnFreezeTachyon( fcChip, 2); // both ERQ and FCP assists
+
+ // Note there is no confirmation that the chip is "unfrozen". Also,
+ // if the Link is down when unfreeze is called, it has no effect.
+ // Chip will unfreeze when the Link is back up.
+
+ // 5. Now send out Abort ACC reply for this exchange
+ Exchanges->fcExchange[ ExchangeID].type = BLS_ABTS_ACC;
+
+ fchs.s_id = Exchanges->fcExchange[ ExchangeID].fchs.d_id;


+ ulStatus = cpqfcTSBuildExchange(
+ cpqfcHBAdata,

+ BLS_ABTS_ACC,
+ &fchs,
+ NULL, // no data (no scatter/gather list)


+ &ExchangeID );// fcController->fcExchanges index, -1 if failed
+
+ if( !ulStatus ) // Exchange setup?
+ {

+ ulStatus = cpqfcTSStartExchange( cpqfcHBAdata, ExchangeID );
+ if( !ulStatus )
+ {

+ // submitted to Tach's Outbound Que (ERQ PI incremented)
+ // waited for completion for ELS type (Login frames issued
+ // synchronously)
+ }
+ else
+ // check reason for Exchange not being started - we might
+ // want to Queue and start later, or fail with error
+ {
+

+ }

+ }
+ break;
+
+

+ case BLS_ABTS_RJT: // need to ReJecT one ABTS; reject implies the
+ // exchange doesn't exist in the TARGET context.
+ // ExchangeID has to come from LinkService space.
+
+ printk(" *ABTS_RJT* ");


+ ulStatus = cpqfcTSBuildExchange(
+ cpqfcHBAdata,

+ BLS_ABTS_RJT,
+ (TachFCHDR_GCMND*)
+ fcLQ->Qitem[QconsumerNdx].ulBuff, // incoming fchs
+ NULL, // no data (no scatter/gather list)


+ &ExchangeID );// fcController->fcExchanges index, -1 if failed
+

+ if( !ulStatus ) // Exchange setup OK?


+ {
+ ulStatus = cpqfcTSStartExchange( cpqfcHBAdata, ExchangeID );

+ // If it fails, we aren't required to retry.
+ }
+ if( ulStatus )
+ {
+ printk("Failed to send BLS_RJT for ABTS, X_ID %Xh\n", ExchangeID);
+ }
+ else
+ {
+ printk("Sent BLS_RJT for ABTS, X_ID %Xh\n", ExchangeID);
+
+ }


+
+ break;
+
+
+

+ default:


+ break;
+ } // end switch

+//doNothing:
+ // done with this item - now set the NEXT index
+
+ if( QconsumerNdx+1 >= FC_LINKQ_DEPTH ) // rollover test
+ {
+ fcLQ->consumer = 0;
+ }
+ else
+ {
+ fcLQ->consumer++;
+ }
+
+ PCI_TRACEO( fcLQ->Qitem[QconsumerNdx].Type, 0x94)
+
+ LEAVE("WorkTask");
+ return;


+}
+
+
+
+

+// When Tachyon reports link down, bad al_pa, or Link Service (e.g. Login)
+// commands come in, post to the LinkQ so that action can be taken outside the
+// interrupt handler.
+// This circular Q works like Tachyon's que - the producer points to the next
+// (unused) entry. Called by Interrupt handler, WorkerThread, Timer
+// sputlinkq
+void cpqfcTSPutLinkQue( CPQFCHBA *cpqfcHBAdata,


+ int Type,
+ void *QueContent)

+{


+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;

+// FC_EXCHANGES *Exchanges = fcChip->Exchanges;
+ PFC_LINK_QUE fcLQ = cpqfcHBAdata->fcLQ;
+ ULONG ndx;
+
+ ENTER("cpqfcTSPutLinkQ");
+
+ ndx = fcLQ->producer;
+
+ ndx += 1; // test for Que full
+
+
+
+ if( ndx >= FC_LINKQ_DEPTH ) // rollover test
+ ndx = 0;
+
+ if( ndx == fcLQ->consumer ) // QUE full test
+ {
+ // QUE was full! lost LK command (fatal to logic)
+ fcChip->fcStats.lnkQueFull++;
+
+ printk("*LinkQ Full!*");
+ TriggerHBA( fcChip->Registers.ReMapMemBase, 1);
+/*
+ {
+ int i;
+ printk("LinkQ PI %d, CI %d\n", fcLQ->producer,
+ fcLQ->consumer);
+
+ for( i=0; i< FC_LINKQ_DEPTH; )
+ {
+ printk(" [%d]%Xh ", i, fcLQ->Qitem[i].Type);
+ if( (++i %8) == 0) printk("\n");
+ }
+
+ }
+*/
+ printk( "cpqfcTS: WARNING!! PutLinkQue - FULL!\n"); // we're hung
+ }
+ else // QUE next element
+ {
+ // Prevent certain multiple (back-to-back) requests.
+ // This is important in that we don't want to issue multiple
+ // ABTS for the same Exchange, or do multiple FM inits, etc.
+ // We can never be sure of the timing of events reported to
+ // us by Tach's IMQ, which can depend on system/bus speeds,
+ // FC physical link circumstances, etc.
+
+ if( (fcLQ->producer != fcLQ->consumer)
+ &&
+ (Type == FMINIT) )
+ {
+ LONG lastNdx; // compute previous producer index
+ if( fcLQ->producer)
+ lastNdx = fcLQ->producer- 1;
+ else
+ lastNdx = FC_LINKQ_DEPTH-1;
+
+
+ if( fcLQ->Qitem[lastNdx].Type == FMINIT)
+ {
+// printk(" *skip FMINIT Q post* ");
+// goto DoneWithPutQ;
+ }
+
+ }
+
+ // OK, add the Q'd item...
+
+ fcLQ->Qitem[fcLQ->producer].Type = Type;
+
+ memcpy(
+ fcLQ->Qitem[fcLQ->producer].ulBuff,
+ QueContent,
+ sizeof(fcLQ->Qitem[fcLQ->producer].ulBuff));
+
+ fcLQ->producer = ndx; // increment Que producer
+
+ // set semaphore to wake up Kernel (worker) thread
+ //
+ up( cpqfcHBAdata->fcQueReady );
+ }
+
+//DoneWithPutQ:
+
+ LEAVE("cpqfcTSPutLinkQ");


+}
+
+
+
+

+// reset device ext FC link Q
+void cpqfcTSLinkQReset( CPQFCHBA *cpqfcHBAdata)
+
+{
+ PFC_LINK_QUE fcLQ = cpqfcHBAdata->fcLQ;
+ fcLQ->producer = 0;
+ fcLQ->consumer = 0;


+
+}
+
+
+

+
+
+// When Tachyon gets an unassisted FCP-SCSI frame, post here so
+// an arbitrary context thread (e.g. IOCTL loopback test function)
+// can process it.
+
+// (NOTE: Not revised for Linux)
+// This Q works like Tachyon's que - the producer points to the next
+// (unused) entry.
+void cpqfcTSPutScsiQue( CPQFCHBA *cpqfcHBAdata,


+ int Type,
+ void *QueContent)

+{
+// CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
+// PTACHYON fcChip = &cpqfcHBAdata->fcChip;
+
+// ULONG ndx;
+
+// ULONG *pExchangeID;
+// LONG ExchangeID;
+
+/*
+ KeAcquireSpinLockAtDpcLevel( &pDevExt->fcScsiQueLock);
+ ndx = pDevExt->fcScsiQue.producer + 1; // test for Que full
+
+ if( ndx >= FC_SCSIQ_DEPTH ) // rollover test
+ ndx = 0;
+
+ if( ndx == pDevExt->fcScsiQue.consumer ) // QUE full test
+ {
+ // QUE was full! lost LK command (fatal to logic)
+ fcChip->fcStats.ScsiQueFull++;
+#ifdef DBG
+ printk( "fcPutScsiQue - FULL!\n");
+#endif
+
+ }
+ else // QUE next element
+ {
+ pDevExt->fcScsiQue.Qitem[pDevExt->fcScsiQue.producer].Type = Type;
+
+ if( Type == FCP_RSP )
+ {
+ // this TL inbound message type means that a TL SEST exchange has
+ // copied an FCP response frame into a buffer pointed to by the SEST
+ // entry. That buffer is allocated in the SEST structure at ->RspHDR.
+ // Copy the RspHDR for use by the Que handler.
+ pExchangeID = (ULONG *)QueContent;
+
+ memcpy(
+ pDevExt->fcScsiQue.Qitem[pDevExt->fcScsiQue.producer].ulBuff,
+ &fcChip->SEST->RspHDR[ *pExchangeID ],
+ sizeof(pDevExt->fcScsiQue.Qitem[0].ulBuff)); // (any element for size)


+
+ }
+ else
+ {

+ memcpy(
+ pDevExt->fcScsiQue.Qitem[pDevExt->fcScsiQue.producer].ulBuff,
+ QueContent,
+ sizeof(pDevExt->fcScsiQue.Qitem[pDevExt->fcScsiQue.producer].ulBuff));
+ }
+
+ pDevExt->fcScsiQue.producer = ndx; // increment Que
+
+
+ KeSetEvent( &pDevExt->TYIBscsi, // signal any waiting thread
+ 0, // no priority boost
+ FALSE ); // no waiting later for this event
+ }
+ KeReleaseSpinLockFromDpcLevel( &pDevExt->fcScsiQueLock);
+*/


+}
+
+
+
+
+
+
+

+static void ProcessELS_Request( CPQFCHBA*,TachFCHDR_GCMND*);
+
+static void ProcessELS_Reply( CPQFCHBA*,TachFCHDR_GCMND*);
+
+static void ProcessFCS_Reply( CPQFCHBA*,TachFCHDR_GCMND*);


+
+void cpqfcTSImplicitLogout( CPQFCHBA* cpqfcHBAdata,
+ PFC_LOGGEDIN_PORT pFcPort)
+{

+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;
+

+ if( pFcPort->port_id != 0xFFFC01 ) // don't care about Fabric
+ {
+ fcChip->fcStats.logouts++;
+ printk("cpqfcTS: Implicit logout of WWN %08X%08X, port_id %06X\n",
+ (ULONG)pFcPort->u.liWWN,
+ (ULONG)(pFcPort->u.liWWN >>32),
+ pFcPort->port_id);
+
+ // Terminate I/O with this (Linux) Scsi target
+ cpqfcTSTerminateExchange( cpqfcHBAdata,
+ &pFcPort->ScsiNexus,
+ DEVICE_REMOVED);
+ }
+
+ // Do an "implicit logout" - we can't really Logout the device
+ // (i.e. with LOGOut Request) because of port_id confusion
+ // (i.e. the Other port has no port_id).
+ // A new login for that WWN will have to re-write port_id (0 invalid)
+ pFcPort->port_id = 0; // invalid!
+ pFcPort->pdisc = FALSE;
+ pFcPort->prli = FALSE;
+ pFcPort->plogi = FALSE;
+ pFcPort->flogi = FALSE;
+ pFcPort->LOGO_timer = 0;
+ pFcPort->device_blocked = TRUE; // block Scsi Requests
+}
+
+
+// On FC-AL, there is a chance that a previously known device can
+// be quietly removed (e.g. with non-managed hub),
+// while a NEW device (with different WWN) took the same alpa or
+// even 24-bit port_id. This chance is unlikely but we must always
+// check for it.
+static void TestDuplicatePortId( CPQFCHBA* cpqfcHBAdata,
+ PFC_LOGGEDIN_PORT pLoggedInPort)
+{


+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;

+ // set "other port" at beginning of fcPorts list
+ PFC_LOGGEDIN_PORT pOtherPortWithPortId = fcChip->fcPorts.pNextPort;
+ while( pOtherPortWithPortId )
+ {
+ if( (pOtherPortWithPortId->port_id ==
+ pLoggedInPort->port_id)
+ &&
+ (pOtherPortWithPortId != pLoggedInPort) )
+ {
+ // trouble! (Implicitly) Log the other guy out
+ printk(" *port_id %Xh is duplicated!* ",
+ pOtherPortWithPortId->port_id);
+ cpqfcTSImplicitLogout( cpqfcHBAdata, pOtherPortWithPortId);
+ }
+ pOtherPortWithPortId = pOtherPortWithPortId->pNextPort;


+ }
+}
+
+
+
+
+
+

+// Dynamic Memory Allocation for newly discovered FC Ports.
+// For simplicity, maintain fcPorts structs for ALL
+// for discovered devices, including those we never do I/O with
+// (e.g. Fabric addresses)
+
+static PFC_LOGGEDIN_PORT CreateFcPort(
+ CPQFCHBA* cpqfcHBAdata,
+ PFC_LOGGEDIN_PORT pLastLoggedInPort,
+ TachFCHDR_GCMND* fchs,
+ LOGIN_PAYLOAD* plogi)
+{


+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;

+ PFC_LOGGEDIN_PORT pNextLoggedInPort = NULL;


+ int i;
+
+

+ printk("cpqfcTS: New FC port %06Xh WWN: ", fchs->s_id);


+ for( i=3; i>=0; i--) // copy the LOGIN port's WWN

+ printk("%02X", plogi->port_name[i]);


+ for( i=7; i>3; i--) // copy the LOGIN port's WWN

+ printk("%02X", plogi->port_name[i]);
+
+
+ // allocate mem for new port
+ // (these are small and rare allocations...)
+ pNextLoggedInPort = kmalloc( sizeof( FC_LOGGEDIN_PORT), GFP_ATOMIC );
+
+
+ // allocation succeeded? Fill out NEW PORT
+ if( pNextLoggedInPort )
+ {
+ // clear out any garbage (sometimes exists)
+ memset( pNextLoggedInPort, 0, sizeof( FC_LOGGEDIN_PORT));
+
+
+ // If we login to a Fabric, we don't want to treat it
+ // as a SCSI device...
+ if( (fchs->s_id & 0xFFF000) != 0xFFF000)


+ {
+ int i;
+

+ // create a unique "virtual" SCSI Nexus (for now, just a
+ // new target ID) -- we will update channel/target on REPORT_LUNS
+ // special case for very first SCSI target...
+ if( cpqfcHBAdata->HostAdapter->max_id == 0)
+ {
+ pNextLoggedInPort->ScsiNexus.target = 0;
+ fcChip->fcPorts.ScsiNexus.target = -1; // don't use "stub"
+ }
+ else
+ {
+ pNextLoggedInPort->ScsiNexus.target =
+ cpqfcHBAdata->HostAdapter->max_id;
+ }
+
+ // initialize the lun[] Nexus struct for lun masking
+ for( i=0; i< CPQFCTS_MAX_LUN; i++)
+ pNextLoggedInPort->ScsiNexus.lun[i] = 0xFF; // init to NOT USED
+
+ pNextLoggedInPort->ScsiNexus.channel = 0; // cpqfcTS has 1 FC port
+
+ printk(" SCSI Chan/Trgt %d/%d",
+ pNextLoggedInPort->ScsiNexus.channel,
+ pNextLoggedInPort->ScsiNexus.target);
+
+ // tell Scsi layers about the new target...
+ cpqfcHBAdata->HostAdapter->max_id++;
+// printk("HostAdapter->max_id = %d\n",
+// cpqfcHBAdata->HostAdapter->max_id);
+ }
+ else
+ {
+ // device is NOT SCSI (in case of Fabric)
+ pNextLoggedInPort->ScsiNexus.target = -1; // invalid
+ }
+
+ // create forward link to new port
+ pLastLoggedInPort->pNextPort = pNextLoggedInPort;
+ printk("\n");
+
+ }
+ return pNextLoggedInPort; // NULL on allocation failure
+} // end NEW PORT (WWN) logic
+
+
+
+// For certain cases, we want to terminate exchanges without
+// sending ABTS to the device. Examples include when an FC
+// device changed it's port_id after Loop re-init, or when
+// the device sent us a logout. In the case of changed port_id,
+// we want to complete the command and return SOFT_ERROR to
+// force a re-try. In the case of LOGOut, we might return
+// BAD_TARGET if the device is really gone.
+// Since we must ensure that Tachyon is not operating on the
+// exchange, we have to freeze the chip
+// sterminateex
+void cpqfcTSTerminateExchange(
+ CPQFCHBA* cpqfcHBAdata, SCSI_NEXUS *ScsiNexus, int TerminateStatus)
+{


+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;
+ FC_EXCHANGES *Exchanges = fcChip->Exchanges;

+ ULONG x_ID;
+
+ if( ScsiNexus )
+ {
+// printk("TerminateExchange: ScsiNexus chan/target %d/%d\n",
+// ScsiNexus->channel, ScsiNexus->target);
+
+ }
+

+ for( x_ID = 0; x_ID < TACH_SEST_LEN; x_ID++)

+ {
+ if( Exchanges->fcExchange[x_ID].type ) // in use?
+ {
+ if( ScsiNexus == NULL ) // our HBA changed - term. all
+ {
+ Exchanges->fcExchange[x_ID].status = TerminateStatus;
+ cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &x_ID );
+ }
+ else
+ {
+ // If a device, according to WWN, has been removed, it's
+ // port_id may be used by another working device, so we
+ // have to terminate by SCSI target, NOT port_id.
+ if( Exchanges->fcExchange[x_ID].Cmnd) // Cmnd in progress?
+ {
+ if( (Exchanges->fcExchange[x_ID].Cmnd->target == ScsiNexus->target)
+ &&
+ (Exchanges->fcExchange[x_ID].Cmnd->channel == ScsiNexus->channel))
+ {
+ Exchanges->fcExchange[x_ID].status = TerminateStatus;
+ cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &x_ID ); // timed-out
+ }
+ }
+
+ // (in case we ever need it...)
+ // all SEST structures have a remote node ID at SEST DWORD 2
+ // if( (fcChip->SEST->u[ x_ID ].TWE.Remote_Node_ID >> 8)
+ // == port_id)


+ }
+ }
+ }
+}
+
+

+static void ProcessELS_Request(

+ CPQFCHBA* cpqfcHBAdata, TachFCHDR_GCMND* fchs)

+{


+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;

+// FC_EXCHANGES *Exchanges = fcChip->Exchanges;
+// ULONG ox_id = (fchs->ox_rx_id >>16);
+ PFC_LOGGEDIN_PORT pLoggedInPort=NULL, pLastLoggedInPort;
+ BOOLEAN NeedReject = FALSE;
+ ULONG ls_reject_code = 0; // default don'n know??
+
+
+ // Check the incoming frame for a supported ELS type
+ switch( fchs->pl[0] & 0xFFFF)
+ {
+ case 0x0050: // PDISC?
+
+ // Payload for PLOGI and PDISC is identical (request & reply)
+ if( !verify_PLOGI( fcChip, fchs, &ls_reject_code) ) // valid payload?
+ {
+ LOGIN_PAYLOAD logi; // FC-PH Port Login
+
+ // PDISC payload OK. If critical login fields
+ // (e.g. WWN) matches last login for this port_id,
+ // we may resume any prior exchanges
+ // with the other port
+
+
+ BigEndianSwap( (UCHAR*)&fchs->pl[0], (UCHAR*)&logi, sizeof(logi));


+
+ pLoggedInPort = fcFindLoggedInPort(

+ fcChip,
+ NULL, // don't search Scsi Nexus
+ 0, // don't search linked list for port_id
+ &logi.port_name[0], // search linked list for WWN
+ &pLastLoggedInPort); // must return non-NULL; when a port_id
+ // is not found, this pointer marks the
+ // end of the singly linked list
+
+ if( pLoggedInPort != NULL) // WWN found (prior login OK)
+ {
+
+ if( (fchs->s_id & 0xFFFFFF) == pLoggedInPort->port_id)
+ {
+ // Yes. We were expecting PDISC?
+ if( pLoggedInPort->pdisc )
+ {
+ // Yes; set fields accordingly. (PDISC, not Originator)
+ SetLoginFields( pLoggedInPort, fchs, TRUE, FALSE);
+
+ // send 'ACC' reply
+ cpqfcTSPutLinkQue( cpqfcHBAdata,
+ ELS_PLOGI_ACC, // (PDISC same as PLOGI ACC)
+ fchs );
+
+ // OK to resume I/O...
+ }
+ else
+ {
+ printk("Not expecting PDISC (pdisc=FALSE)\n");
+ NeedReject = TRUE;
+ // set reject reason code
+ ls_reject_code =
+ LS_RJT_REASON( PROTOCOL_ERROR, INITIATOR_CTL_ERROR);


+ }
+ }
+ else
+ {

+ if( pLoggedInPort->port_id != 0)
+ {
+ printk("PDISC PortID change: old %Xh, new %Xh\n",
+ pLoggedInPort->port_id, fchs->s_id &0xFFFFFF);
+ }
+ NeedReject = TRUE;
+ // set reject reason code
+ ls_reject_code =
+ LS_RJT_REASON( PROTOCOL_ERROR, INITIATOR_CTL_ERROR);


+
+ }
+ }
+ else

+ {
+ printk("PDISC Request from unknown WWN\n");
+ NeedReject = TRUE;
+
+ // set reject reason code
+ ls_reject_code =
+ LS_RJT_REASON( LOGICAL_ERROR, INVALID_PORT_NAME);
+ }
+
+ }
+ else // Payload unacceptable
+ {
+ printk("payload unacceptable\n");
+ NeedReject = TRUE; // reject code already set
+
+ }
+
+ if( NeedReject)
+ {
+ ULONG port_id;
+ // The PDISC failed. Set login struct flags accordingly,
+ // terminate any I/O to this port, and Q a PLOGI


+ if( pLoggedInPort )
+ {

+ pLoggedInPort->pdisc = FALSE;
+ pLoggedInPort->prli = FALSE;

+ pLoggedInPort->plogi = FALSE;
+
+ cpqfcTSTerminateExchange( cpqfcHBAdata,
+ &pLoggedInPort->ScsiNexus, PORTID_CHANGED);
+ port_id = pLoggedInPort->port_id;
+ }
+ else
+ {
+ port_id = fchs->s_id &0xFFFFFF;
+ }
+ fchs->reserved = ls_reject_code; // borrow this (unused) field
+ cpqfcTSPutLinkQue( cpqfcHBAdata, ELS_RJT, fchs );


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 075'
echo 'File patch-2.4.0-test9 is continued in part 076'
echo "076" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part076

#!/bin/sh -x
# this is part 076 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 076; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&
+ }
+

+ break;
+
+
+

+ case 0x0003: // PLOGI?


+
+ // Payload for PLOGI and PDISC is identical (request & reply)
+ if( !verify_PLOGI( fcChip, fchs, &ls_reject_code) ) // valid payload?
+ {
+ LOGIN_PAYLOAD logi; // FC-PH Port Login

+ BOOLEAN NeedReject = FALSE;
+

+ // PDISC payload OK. If critical login fields
+ // (e.g. WWN) matches last login for this port_id,
+ // we may resume any prior exchanges
+ // with the other port
+
+
+ BigEndianSwap( (UCHAR*)&fchs->pl[0], (UCHAR*)&logi, sizeof(logi));
+
+ pLoggedInPort = fcFindLoggedInPort(
+ fcChip,
+ NULL, // don't search Scsi Nexus
+ 0, // don't search linked list for port_id
+ &logi.port_name[0], // search linked list for WWN
+ &pLastLoggedInPort); // must return non-NULL; when a port_id
+ // is not found, this pointer marks the
+ // end of the singly linked list
+

+ if( pLoggedInPort == NULL) // WWN not found -New Port
+ {
+ pLoggedInPort = CreateFcPort(
+ cpqfcHBAdata,
+ pLastLoggedInPort,
+ fchs,
+ &logi);


+ if( pLoggedInPort == NULL )

+ {
+ printk(" cpqfcTS: New port allocation failed - lost FC device!\n");
+ // Now Q a LOGOut Request, since we won't be talking to that device


+
+ NeedReject = TRUE;
+

+ // set reject reason code
+ ls_reject_code =

+ LS_RJT_REASON( LOGICAL_ERROR, NO_LOGIN_RESOURCES);
+
+ }
+ }
+ if( !NeedReject )
+ {
+
+ // OK - we have valid fcPort ptr; set fields accordingly.
+ // (not PDISC, not Originator)
+ SetLoginFields( pLoggedInPort, fchs, FALSE, FALSE);

+
+ // send 'ACC' reply
+ cpqfcTSPutLinkQue( cpqfcHBAdata,
+ ELS_PLOGI_ACC, // (PDISC same as PLOGI ACC)
+ fchs );
+ }
+ }

+ else // Payload unacceptable
+ {
+ printk("payload unacceptable\n");
+ NeedReject = TRUE; // reject code already set
+ }
+

+ if( NeedReject)
+ {


+ // The PDISC failed. Set login struct flags accordingly,
+ // terminate any I/O to this port, and Q a PLOGI

+ pLoggedInPort->pdisc = FALSE;
+ pLoggedInPort->prli = FALSE;
+ pLoggedInPort->plogi = FALSE;
+

+ fchs->reserved = ls_reject_code; // borrow this (unused) field
+

+ // send 'RJT' reply

+ cpqfcTSPutLinkQue( cpqfcHBAdata, ELS_RJT, fchs );

+ }
+
+ // terminate any exchanges with this device...


+ if( pLoggedInPort )
+ {

+ cpqfcTSTerminateExchange( cpqfcHBAdata,
+ &pLoggedInPort->ScsiNexus, PORTID_CHANGED);
+ }

+ break;
+
+
+

+ case 0x1020: // PRLI?
+ {
+ BOOLEAN NeedReject = TRUE;


+ pLoggedInPort = fcFindLoggedInPort(
+ fcChip,
+ NULL, // don't search Scsi Nexus

+ (fchs->s_id & 0xFFFFFF), // search linked list for port_id
+ NULL, // DON'T search linked list for WWN
+ NULL); // don't care


+
+ if( pLoggedInPort == NULL )

+ {
+ // huh?
+ printk(" Unexpected PRLI Request -not logged in!\n");


+
+ // set reject reason code

+ ls_reject_code = LS_RJT_REASON( PROTOCOL_ERROR, INITIATOR_CTL_ERROR);
+
+ // Q a LOGOut here?
+ }
+ else
+ {
+ // verify the PRLI ACC payload
+ if( !verify_PRLI( fchs, &ls_reject_code) )
+ {
+ // PRLI Reply is acceptable; were we expecting it?
+ if( pLoggedInPort->plogi )
+ {
+ // yes, we expected the PRLI ACC (not PDISC; not Originator)
+ SetLoginFields( pLoggedInPort, fchs, FALSE, FALSE);
+
+ // Q an ACCept Reply
+ cpqfcTSPutLinkQue( cpqfcHBAdata,
+ ELS_PRLI_ACC,
+ fchs );
+
+ NeedReject = FALSE;
+ }
+ else
+ {
+ // huh?
+ printk(" (unexpected) PRLI REQEST with plogi FALSE\n");


+
+ // set reject reason code

+ ls_reject_code = LS_RJT_REASON( PROTOCOL_ERROR, INITIATOR_CTL_ERROR);
+
+ // Q a LOGOut here?


+
+ }
+ }
+ else
+ {

+ printk(" PRLI REQUEST payload failed verify\n");
+ // (reject code set by "verify")
+
+ // Q a LOGOut here?
+ }
+ }
+
+ if( NeedReject )
+ {
+ // Q a ReJecT Reply with reason code


+ fchs->reserved = ls_reject_code;

+ cpqfcTSPutLinkQue( cpqfcHBAdata,
+ ELS_RJT, // Q Type


+ fchs );
+ }
+ }

+ break;
+
+
+
+

+ case 0x0005: // LOGOut?
+ {
+ // was this LOGOUT because we sent a ELS_PDISC to an FC device
+ // with changed (or new) port_id, or does the port refuse
+ // to communicate to us?
+ // We maintain a logout counter - if we get 3 consecutive LOGOuts,
+ // give up!
+ LOGOUT_PAYLOAD logo;
+ BOOLEAN GiveUpOnDevice = FALSE;


+ ULONG ls_reject_code = 0;

+
+ BigEndianSwap( (UCHAR*)&fchs->pl[0], (UCHAR*)&logo, sizeof(logo));


+
+ pLoggedInPort = fcFindLoggedInPort(
+ fcChip,
+ NULL, // don't search Scsi Nexus
+ 0, // don't search linked list for port_id

+ &logo.port_name[0], // search linked list for WWN
+ NULL); // don't care about end of list
+
+ if( pLoggedInPort ) // found the device?
+ {
+ // Q an ACC reply
+ cpqfcTSPutLinkQue( cpqfcHBAdata,
+ ELS_LOGO_ACC, // Q Type
+ fchs ); // device to respond to
+
+ // set login struct fields (LOGO_counter increment)
+ SetLoginFields( pLoggedInPort, fchs, FALSE, FALSE);
+
+ // are we an Initiator?
+ if( fcChip->Options.initiator)
+ {
+ // we're an Initiator, so check if we should
+ // try (another?) login
+
+ // Fabrics routinely log out from us after
+ // getting device info - don't try to log them
+ // back in.
+ if( (fchs->s_id & 0xFFF000) == 0xFFF000 )
+ {
+ ; // do nothing
+ }
+ else if( pLoggedInPort->LOGO_counter <= 3)
+ {
+ // try (another) login (PLOGI request)
+
+ cpqfcTSPutLinkQue( cpqfcHBAdata,
+ ELS_PLOGI, // Q Type
+ fchs );
+
+ // Terminate I/O with "retry" potential


+ cpqfcTSTerminateExchange( cpqfcHBAdata,
+ &pLoggedInPort->ScsiNexus,

+ PORTID_CHANGED);
+ }
+ else
+ {
+ printk(" Got 3 LOGOuts - terminating comm. with port_id %Xh\n",
+ fchs->s_id &&0xFFFFFF);
+ GiveUpOnDevice = TRUE;


+ }
+ }
+ else
+ {

+ GiveUpOnDevice = TRUE;
+ }
+
+
+ if( GiveUpOnDevice == TRUE )


+ {
+ cpqfcTSTerminateExchange( cpqfcHBAdata,
+ &pLoggedInPort->ScsiNexus,

+ DEVICE_REMOVED);
+ }
+ }
+ else // we don't know this WWN!
+ {
+ // Q a ReJecT Reply with reason code


+ fchs->reserved = ls_reject_code;

+ cpqfcTSPutLinkQue( cpqfcHBAdata,
+ ELS_RJT, // Q Type


+ fchs );
+ }
+ }

+ break;
+
+
+
+

+ // FABRIC only case
+ case 0x0461: // ELS RSCN (Registered State Change Notification)?
+ {
+ int Ports;
+ int i;
+ __u32 Buff;
+ // Typically, one or more devices have been added to or dropped
+ // from the Fabric.
+ // The format of this frame is defined in FC-FLA (Rev 2.7, Aug 1997)
+ // The first 32-bit word has a 2-byte Payload Length, which
+ // includes the 4 bytes of the first word. Consequently,
+ // this PL len must never be less than 4, must be a multiple of 4,
+ // and has a specified max value 256.
+ // (Endianess!)
+ Ports = ((fchs->pl[0] >>24) - 4) / 4;
+ Ports = Ports > 63 ? 63 : Ports;
+
+ printk(" RSCN ports: %d\n", Ports);
+ if( Ports <= 0 ) // huh?
+ {
+ // ReJecT the command
+ fchs->reserved = LS_RJT_REASON( UNABLE_TO_PERFORM, 0);
+
+ cpqfcTSPutLinkQue( cpqfcHBAdata,
+ ELS_RJT, // Q Type
+ fchs );
+
+ break;
+ }
+ else // Accept the command
+ {
+ cpqfcTSPutLinkQue( cpqfcHBAdata,
+ ELS_ACC, // Q Type


+ fchs );
+ }
+

+ // Check the "address format" to determine action.
+ // We have 3 cases:
+ // 0 = Port Address; 24-bit address of affected device
+ // 1 = Area Address; MS 16 bits valid
+ // 2 = Domain Address; MS 8 bits valid
+ for( i=0; i<Ports; i++)
+ {
+ BigEndianSwap( (UCHAR*)&fchs->pl[i+1],(UCHAR*)&Buff, 4);
+ switch( Buff & 0xFF000000)
+ {
+
+ case 0: // Port Address?
+
+ case 0x01000000: // Area Domain?
+ case 0x02000000: // Domain Address
+ // For example, "port_id" 0x201300
+ // OK, let's try a Name Service Request (Query)
+ fchs->s_id = 0xFFFFFC; // Name Server Address
+ cpqfcTSPutLinkQue( cpqfcHBAdata, FCS_NSR, fchs);


+
+ break;
+
+

+ default: // huh? new value on version change?


+ break;
+ }
+ }
+ }

+ break;
+
+
+
+

+ default: // don't support this request (yet)


+ // set reject reason code

+ fchs->reserved = LS_RJT_REASON( UNABLE_TO_PERFORM,
+ REQUEST_NOT_SUPPORTED);
+
+ cpqfcTSPutLinkQue( cpqfcHBAdata,
+ ELS_RJT, // Q Type
+ fchs );

+ break;
+ }
+}
+

+
+static void ProcessELS_Reply(

+ CPQFCHBA* cpqfcHBAdata, TachFCHDR_GCMND* fchs)
+{
+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;

+ FC_EXCHANGES *Exchanges = fcChip->Exchanges;

+ ULONG ox_id = (fchs->ox_rx_id >>16);
+ ULONG ls_reject_code;
+ PFC_LOGGEDIN_PORT pLoggedInPort, pLastLoggedInPort;
+
+ // If this is a valid reply, then we MUST have sent a request.
+ // Verify that we can find a valid request OX_ID corresponding to
+ // this reply
+
+
+ if( Exchanges->fcExchange[(fchs->ox_rx_id >>16)].type == 0)
+ {
+ printk(" *Discarding ACC/RJT frame, xID %04X/%04X* ",
+ ox_id, fchs->ox_rx_id & 0xffff);
+ goto Quit; // exit this routine
+ }
+
+
+ // Is the reply a RJT (reject)?
+ if( (fchs->pl[0] & 0xFFFFL) == 0x01) // Reject reply?
+ {
+// ****** REJECT REPLY ********
+ switch( Exchanges->fcExchange[ox_id].type )
+ {
+
+ case ELS_FDISC: // we sent out Fabric Discovery
+ case ELS_FLOGI: // we sent out FLOGI
+
+ printk("RJT received on Fabric Login from %Xh, reason %Xh\n",
+ fchs->s_id, fchs->pl[1]);
+
+ break;
+
+ default:
+ break;
+ }
+
+ goto Done;
+ }
+
+ // OK, we have an ACCept...
+ // What's the ACC type? (according to what we sent)
+ switch( Exchanges->fcExchange[ox_id].type )
+ {
+
+ case ELS_PLOGI: // we sent out PLOGI


+ if( !verify_PLOGI( fcChip, fchs, &ls_reject_code) )

+ {
+ LOGIN_PAYLOAD logi; // FC-PH Port Login
+

+ // login ACC payload acceptable; search for WWN in our list
+ // of fcPorts


+
+ BigEndianSwap( (UCHAR*)&fchs->pl[0], (UCHAR*)&logi, sizeof(logi));
+
+ pLoggedInPort = fcFindLoggedInPort(
+ fcChip,
+ NULL, // don't search Scsi Nexus
+ 0, // don't search linked list for port_id
+ &logi.port_name[0], // search linked list for WWN
+ &pLastLoggedInPort); // must return non-NULL; when a port_id
+ // is not found, this pointer marks the
+ // end of the singly linked list
+

+ if( pLoggedInPort == NULL) // WWN not found - new port
+ {
+
+ pLoggedInPort = CreateFcPort(
+ cpqfcHBAdata,
+ pLastLoggedInPort,
+ fchs,
+ &logi);


+
+ if( pLoggedInPort == NULL )

+ {
+ printk(" cpqfcTS: New port allocation failed - lost FC device!\n");
+ // Now Q a LOGOut Request, since we won't be talking to that device
+
+ goto Done; // exit with error! dropped login frame
+ }
+ }
+ else // WWN was already known. Ensure that any open
+ // exchanges for this WWN are terminated.
+ // NOTE: It's possible that a device can change its
+ // 24-bit port_id after a Link init or Fabric change
+ // (e.g. LIP or Fabric RSCN). In that case, the old
+ // 24-bit port_id may be duplicated, or no longer exist.
+ {


+
+ cpqfcTSTerminateExchange( cpqfcHBAdata,
+ &pLoggedInPort->ScsiNexus, PORTID_CHANGED);
+ }

+
+ // We have an fcPort struct - set fields accordingly
+ // not PDISC, originator
+ SetLoginFields( pLoggedInPort, fchs, FALSE, TRUE);
+
+ // We just set a "port_id"; is it duplicated?
+ TestDuplicatePortId( cpqfcHBAdata, pLoggedInPort);
+
+ // For Fabric operation, we issued PLOGI to 0xFFFFFC
+ // so we can send SCR (State Change Registration)
+ // Check for this special case...
+ if( fchs->s_id == 0xFFFFFC )
+ {
+ // PLOGI ACC was a Fabric response... issue SCR
+ fchs->s_id = 0xFFFFFD; // address for SCR
+ cpqfcTSPutLinkQue( cpqfcHBAdata, ELS_SCR, fchs);


+ }
+
+ else
+ {

+ // Now we need a PRLI to enable FCP-SCSI operation
+ // set flags and Q up a ELS_PRLI
+ cpqfcTSPutLinkQue( cpqfcHBAdata, ELS_PRLI, fchs);


+ }
+ }
+ else
+ {

+ // login payload unacceptable - reason in ls_reject_code
+ // Q up a Logout Request
+ printk("Login Payload unacceptable\n");
+
+ }
+ break;
+
+
+ // PDISC logic very similar to PLOGI, except we never want
+ // to allocate mem for "new" port, and we set flags differently
+ // (might combine later with PLOGI logic for efficiency)
+ case ELS_PDISC: // we sent out PDISC


+ if( !verify_PLOGI( fcChip, fchs, &ls_reject_code) )

+ {
+ LOGIN_PAYLOAD logi; // FC-PH Port Login

+ BOOLEAN NeedLogin = FALSE;
+
+ // login payload acceptable; search for WWN in our list
+ // of (previously seen) fcPorts


+
+ BigEndianSwap( (UCHAR*)&fchs->pl[0], (UCHAR*)&logi, sizeof(logi));
+
+ pLoggedInPort = fcFindLoggedInPort(
+ fcChip,
+ NULL, // don't search Scsi Nexus
+ 0, // don't search linked list for port_id
+ &logi.port_name[0], // search linked list for WWN
+ &pLastLoggedInPort); // must return non-NULL; when a port_id
+ // is not found, this pointer marks the
+ // end of the singly linked list
+

+ if( pLoggedInPort != NULL) // WWN found?
+ {
+ // WWN has same port_id as last login? (Of course, a properly
+ // working FC device should NEVER ACCept a PDISC if it's
+ // port_id changed, but check just in case...)


+ if( (fchs->s_id & 0xFFFFFF) == pLoggedInPort->port_id)
+ {
+ // Yes. We were expecting PDISC?
+ if( pLoggedInPort->pdisc )
+ {

+ int i;
+
+

+ // PDISC expected -- set fields. (PDISC, Originator)
+ SetLoginFields( pLoggedInPort, fchs, TRUE, TRUE);
+
+ // We are ready to resume FCP-SCSI to this device...
+ // Do we need to start anything that was Queued?
+
+ for( i=0; i< TACH_SEST_LEN; i++)
+ {
+ // see if any exchange for this PDISC'd port was queued
+ if( ((fchs->s_id &0xFFFFFF) ==
+ (Exchanges->fcExchange[i].fchs.d_id & 0xFFFFFF))
+ &&
+ (Exchanges->fcExchange[i].status & EXCHANGE_QUEUED))
+ {
+ fchs->reserved = i; // copy ExchangeID
+// printk(" *Q x_ID %Xh after PDISC* ",i);
+
+ cpqfcTSPutLinkQue( cpqfcHBAdata, EXCHANGE_QUEUED, fchs );
+ }
+ }
+
+ // Complete commands Q'd while we were waiting for Login
+
+ UnblockScsiDevice( cpqfcHBAdata->HostAdapter, pLoggedInPort);


+ }
+ else
+ {
+ printk("Not expecting PDISC (pdisc=FALSE)\n");

+ NeedLogin = TRUE;


+ }
+ }
+ else
+ {

+ printk("PDISC PortID change: old %Xh, new %Xh\n",
+ pLoggedInPort->port_id, fchs->s_id &0xFFFFFF);

+ NeedLogin = TRUE;


+
+ }
+ }
+ else
+ {

+ printk("PDISC ACC from unknown WWN\n");
+ NeedLogin = TRUE;
+ }
+
+ if( NeedLogin)
+ {
+

+ // The PDISC failed. Set login struct flags accordingly,
+ // terminate any I/O to this port, and Q a PLOGI

+ if( pLoggedInPort ) // FC device previously known?
+ {
+
+ cpqfcTSPutLinkQue( cpqfcHBAdata,
+ ELS_LOGO, // Q Type
+ fchs ); // has port_id to send to
+
+ // There are a variety of error scenarios which can result
+ // in PDISC failure, so as a catchall, add the check for
+ // duplicate port_id.
+ TestDuplicatePortId( cpqfcHBAdata, pLoggedInPort);
+
+// TriggerHBA( fcChip->Registers.ReMapMemBase, 0);


+ pLoggedInPort->pdisc = FALSE;
+ pLoggedInPort->prli = FALSE;
+ pLoggedInPort->plogi = FALSE;
+
+ cpqfcTSTerminateExchange( cpqfcHBAdata,
+ &pLoggedInPort->ScsiNexus, PORTID_CHANGED);
+ }

+ cpqfcTSPutLinkQue( cpqfcHBAdata, ELS_PLOGI, fchs );


+ }
+ }
+ else
+ {

+ // login payload unacceptable - reason in ls_reject_code
+ // Q up a Logout Request
+ printk("ERROR: Login Payload unacceptable!\n");
+
+ }
+

+ break;
+
+
+

+ case ELS_PRLI: // we sent out PRLI
+


+
+ pLoggedInPort = fcFindLoggedInPort(
+ fcChip,
+ NULL, // don't search Scsi Nexus

+ (fchs->s_id & 0xFFFFFF), // search linked list for port_id
+ NULL, // DON'T search linked list for WWN
+ NULL); // don't care


+
+ if( pLoggedInPort == NULL )

+ {
+ // huh?
+ printk(" Unexpected PRLI ACCept frame!\n");
+
+ // Q a LOGOut here?
+


+ goto Done;
+ }
+

+ // verify the PRLI ACC payload
+ if( !verify_PRLI( fchs, &ls_reject_code) )
+ {
+ // PRLI Reply is acceptable; were we expecting it?
+ if( pLoggedInPort->plogi )
+ {
+ // yes, we expected the PRLI ACC (not PDISC; Originator)
+ SetLoginFields( pLoggedInPort, fchs, FALSE, TRUE);
+
+ // OK, let's send a REPORT_LUNS command to determine
+ // whether VSA or PDA FCP-LUN addressing is used.
+
+ cpqfcTSPutLinkQue( cpqfcHBAdata, SCSI_REPORT_LUNS, fchs );
+
+ // It's possible that a device we were talking to changed
+ // port_id, and has logged back in. This function ensures
+ // that I/O will resume.
+ UnblockScsiDevice( cpqfcHBAdata->HostAdapter, pLoggedInPort);


+
+ }
+ else
+ {

+ // huh?
+ printk(" (unexpected) PRLI ACCept with plogi FALSE\n");
+
+ // Q a LOGOut here?
+ goto Done;


+ }
+ }
+ else
+ {

+ printk(" PRLI ACCept payload failed verify\n");
+
+ // Q a LOGOut here?


+ }
+
+ break;
+

+ case ELS_FLOGI: // we sent out FLOGI (Fabric Login)
+
+ // update the upper 16 bits of our port_id in Tachyon
+ // the switch adds those upper 16 bits when responding
+ // to us (i.e. we are the destination_id)
+ fcChip->Registers.my_al_pa = (fchs->d_id & 0xFFFFFF);


+ writel( fcChip->Registers.my_al_pa,
+ fcChip->Registers.ReMapMemBase + TL_MEM_TACH_My_ID);
+

+ // now send out a PLOGI to the well known port_id 0xFFFFFC
+ fchs->s_id = 0xFFFFFC;
+ cpqfcTSPutLinkQue( cpqfcHBAdata, ELS_PLOGI, fchs);


+
+ break;
+
+

+ case ELS_FDISC: // we sent out FDISC (Fabric Discovery (Login))
+
+ printk( " ELS_FDISC success ");
+ break;
+
+
+ case ELS_SCR: // we sent out State Change Registration
+ // now we can issue Name Service Request to find any
+ // Fabric-connected devices we might want to login to.
+
+
+ fchs->s_id = 0xFFFFFC; // Name Server Address
+ cpqfcTSPutLinkQue( cpqfcHBAdata, FCS_NSR, fchs);


+
+
+ break;
+
+

+ default:
+ printk(" *Discarding unknown ACC frame, xID %04X/%04X* ",
+ ox_id, fchs->ox_rx_id & 0xffff);


+ break;
+ }
+
+

+Done:
+ // Regardless of whether the Reply is valid or not, the
+ // the exchange is done - complete
+ cpqfcTSCompleteExchange( fcChip, (fchs->ox_rx_id >>16)); // complete
+
+Quit:

+ return;
+}
+
+
+
+
+

+
+// **************** Fibre Channel Services **************
+// This is where we process the Directory (Name) Service Reply
+// to know which devices are on the Fabric
+
+static void ProcessFCS_Reply(

+ CPQFCHBA* cpqfcHBAdata, TachFCHDR_GCMND* fchs)
+{
+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;

+ FC_EXCHANGES *Exchanges = fcChip->Exchanges;

+ ULONG ox_id = (fchs->ox_rx_id >>16);
+// ULONG ls_reject_code;
+// PFC_LOGGEDIN_PORT pLoggedInPort, pLastLoggedInPort;
+
+ // If this is a valid reply, then we MUST have sent a request.
+ // Verify that we can find a valid request OX_ID corresponding to
+ // this reply
+
+ if( Exchanges->fcExchange[(fchs->ox_rx_id >>16)].type == 0)
+ {
+ printk(" *Discarding Reply frame, xID %04X/%04X* ",
+ ox_id, fchs->ox_rx_id & 0xffff);
+ goto Quit; // exit this routine
+ }
+
+
+ // OK, we were expecting it. Now check to see if it's a
+ // "Name Service" Reply, and if so force a re-validation of
+ // Fabric device logins (i.e. Start the login timeout and
+ // send PDISC or PLOGI)
+ // (Endianess Byte Swap?)
+ if( fchs->pl[1] == 0x02FC ) // Name Service
+ {
+ // got a new (or NULL) list of Fabric attach devices...
+ // Invalidate current logins
+
+ PFC_LOGGEDIN_PORT pLoggedInPort = &fcChip->fcPorts;


+ while( pLoggedInPort ) // for all ports which are expecting
+ // PDISC after the next LIP, set the
+ // logoutTimer
+ {
+

+ if( (pLoggedInPort->port_id & 0xFFFF00) // Fabric device?
+ &&
+ (pLoggedInPort->port_id != 0xFFFFFC) ) // NOT the F_Port
+ {
+ pLoggedInPort->LOGO_timer = 6; // what's the Fabric timeout??


+ // suspend any I/O in progress until
+ // PDISC received...
+ pLoggedInPort->prli = FALSE; // block FCP-SCSI commands
+ }
+
+ pLoggedInPort = pLoggedInPort->pNextPort;
+ }

+
+ if( fchs->pl[2] == 0x0280) // ACCept?
+ {
+ // Send PLOGI or PDISC to these Fabric devices
+ SendLogins( cpqfcHBAdata, &fchs->pl[4] );
+ }
+
+
+ // As of this writing, the only reason to reject is because NO
+ // devices are left on the Fabric. We already started
+ // "logged out" timers; if the device(s) don't come
+ // back, we'll do the implicit logout in the heart beat
+ // timer routine
+ else // ReJecT
+ {
+ // this just means no Fabric device is visible at this instant
+ }
+ }
+
+ // Regardless of whether the Reply is valid or not, the
+ // the exchange is done - complete
+ cpqfcTSCompleteExchange( fcChip, (fchs->ox_rx_id >>16)); // complete
+
+Quit:

+ return;
+}
+
+
+
+

+
+
+


+static void AnalyzeIncomingFrame(
+ CPQFCHBA *cpqfcHBAdata,
+ ULONG QNdx )

+{


+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;
+ FC_EXCHANGES *Exchanges = fcChip->Exchanges;

+ PFC_LINK_QUE fcLQ = cpqfcHBAdata->fcLQ;

+ TachFCHDR_GCMND* fchs =
+ (TachFCHDR_GCMND*)fcLQ->Qitem[QNdx].ulBuff;
+// ULONG ls_reject_code; // reason for rejecting login
+ LONG ExchangeID;
+// FC_LOGGEDIN_PORT *pLoggedInPort;
+ BOOLEAN AbortAccept;
+
+ ENTER("AnalyzeIncomingFrame");
+
+
+
+ switch( fcLQ->Qitem[QNdx].Type) // FCP or Unknown
+ {
+
+ case SFQ_UNKNOWN: // unknown frame (e.g. LIP position frame, NOP, etc.)
+
+
+ // ********* FC-4 Device Data/ Fibre Channel Service *************
+ if( ((fchs->d_id &0xF0000000) == 0) // R_CTL (upper nibble) 0x0?
+ &&
+ (fchs->f_ctl & 0x20000000) ) // TYPE 20h is Fibre Channel Service
+ {
+
+ // ************** FCS Reply **********************
+
+ if( (fchs->d_id & 0xff000000L) == 0x03000000L) // (31:23 R_CTL)
+ {
+ ProcessFCS_Reply( cpqfcHBAdata, fchs );
+
+ } // end of FCS logic
+
+ }
+
+
+ // *********** Extended Link Service **************
+
+ else if( fchs->d_id & 0x20000000 // R_CTL 0x2?
+ &&
+ (fchs->f_ctl & 0x01000000) ) // TYPE = 1
+ {
+
+ // these frames are either a response to
+ // something we sent (0x23) or "unsolicited"
+ // frames (0x22).
+
+
+ // **************Extended Link REPLY **********************
+ // R_CTL Solicited Control Reply
+
+ if( (fchs->d_id & 0xff000000L) == 0x23000000L) // (31:23 R_CTL)
+ {
+
+ ProcessELS_Reply( cpqfcHBAdata, fchs );
+
+ } // end of "R_CTL Solicited Control Reply"
+
+
+
+
+ // **************Extended Link REQUEST **********************
+ // (unsolicited commands from another port or task...)
+
+ // R_CTL Ext Link REQUEST
+ else if( (fchs->d_id & 0xff000000L) == 0x22000000L &&
+ (fchs->ox_rx_id != 0xFFFFFFFFL) ) // (ignore LIP frame)
+ {
+
+
+
+ ProcessELS_Request( cpqfcHBAdata, fchs );


+
+ }
+
+
+

+ // ************** LILP **********************
+ else if( (fchs->d_id & 0xff000000L) == 0x22000000L &&
+ (fchs->ox_rx_id == 0xFFFFFFFFL)) // (e.g., LIP frames)
+
+ {
+ // SANMark specifies that when available, we must use
+ // the LILP frame to determine which ALPAs to send Port Discovery
+ // to...
+
+ if( fchs->pl[0] == 0x0711L) // ELS_PLOGI?
+ {
+// UCHAR *ptr = (UCHAR*)&fchs->pl[1];
+// printk(" %d ALPAs found\n", *ptr);
+ memcpy( fcChip->LILPmap, &fchs->pl[1], 32*4); // 32 DWORDs
+ fcChip->Options.LILPin = 1; // our LILPmap is valid!
+ // now post to make Port Discovery happen...
+ cpqfcTSPutLinkQue( cpqfcHBAdata, LINKACTIVE, fchs);

+ }
+ }
+ }
+
+

+ // ***************** BASIC LINK SERVICE *****************
+
+ else if( fchs->d_id & 0x80000000 // R_CTL:
+ && // Basic Link Service Request
+ !(fchs->f_ctl & 0xFF000000) ) // type=0 for BLS
+ {
+
+ // Check for ABTS (Abort Sequence)
+ if( (fchs->d_id & 0x8F000000) == 0x81000000)
+ {
+ // look for OX_ID, S_ID pair that matches in our
+ // fcExchanges table; if found, reply with ACCept and complete
+ // the exchange
+
+ // Per PLDA, an ABTS is sent by an initiator; therefore
+ // assume that if we have an exhange open to the port who
+ // sent ABTS, it will be the d_id of what we sent.
+ for( ExchangeID = 0, AbortAccept=FALSE;
+ ExchangeID < TACH_SEST_LEN; ExchangeID++)
+ {
+ // Valid "target" exchange 24-bit port_id matches?
+ // NOTE: For the case of handling Intiator AND Target
+ // functions on the same chip, we can have TWO Exchanges
+ // with the same OX_ID -- OX_ID/FFFF for the CMND, and
+ // OX_ID/RX_ID for the XRDY or DATA frame(s). Ideally,
+ // we would like to support ABTS from Initiators or Targets,
+ // but it's not clear that can be supported on Tachyon for
+ // all cases (requires more investigation).
+
+ if( (Exchanges->fcExchange[ ExchangeID].type == SCSI_TWE ||
+ Exchanges->fcExchange[ ExchangeID].type == SCSI_TRE)
+ &&
+ ((Exchanges->fcExchange[ ExchangeID].fchs.d_id & 0xFFFFFF) ==
+ (fchs->s_id & 0xFFFFFF)) )
+ {
+
+ // target xchnge port_id matches -- how about OX_ID?
+ if( (Exchanges->fcExchange[ ExchangeID].fchs.ox_rx_id &0xFFFF0000)
+ == (fchs->ox_rx_id & 0xFFFF0000) )
+ // yes! post ACCept response; will be completed by fcStart
+ {
+ Exchanges->fcExchange[ ExchangeID].status = TARGET_ABORT;
+
+ // copy (add) rx_id field for simplified ACCept reply
+ fchs->ox_rx_id =
+ Exchanges->fcExchange[ ExchangeID].fchs.ox_rx_id;
+
+ cpqfcTSPutLinkQue( cpqfcHBAdata,
+ BLS_ABTS_ACC, // Q Type
+ fchs ); // void QueContent
+ AbortAccept = TRUE;
+ printk("ACCepting ABTS for x_ID %8.8Xh, SEST pair %8.8Xh\n",
+ fchs->ox_rx_id, Exchanges->fcExchange[ ExchangeID].fchs.ox_rx_id);
+ break; // ABTS can affect only ONE exchange -exit loop
+ }
+ }
+ } // end of FOR loop
+ if( !AbortAccept ) // can't ACCept ABTS - send Reject
+ {
+ printk("ReJecTing: can't find ExchangeID %8.8Xh for ABTS command\n",
+ fchs->ox_rx_id);
+ if( Exchanges->fcExchange[ ExchangeID].type
+ &&
+ !(fcChip->SEST->u[ ExchangeID].IWE.Hdr_Len
+ & 0x80000000))
+ {
+ cpqfcTSCompleteExchange( fcChip, ExchangeID);
+ }
+ else
+ {
+ printk("Unexpected ABTS ReJecT! SEST[%X] Dword 0: %Xh\n",
+ ExchangeID, fcChip->SEST->u[ ExchangeID].IWE.Hdr_Len);
+ }
+ }
+ }
+
+ // Check for BLS {ABTS? (Abort Sequence)} ACCept
+ else if( (fchs->d_id & 0x8F000000) == 0x84000000)
+ {
+ // target has responded with ACC for our ABTS;
+ // complete the indicated exchange with ABORTED status
+ // Make no checks for correct RX_ID, since
+ // all we need to conform ABTS ACC is the OX_ID.
+ // Verify that the d_id matches!
+
+ ExchangeID = (fchs->ox_rx_id >> 16) & 0x7FFF; // x_id from ACC
+// printk("ABTS ACC x_ID 0x%04X 0x%04X, status %Xh\n",
+// fchs->ox_rx_id >> 16, fchs->ox_rx_id & 0xffff,
+// Exchanges->fcExchange[ExchangeID].status);
+
+
+
+ if( ExchangeID < TACH_SEST_LEN ) // x_ID makes sense
+ {
+ // Does "target" exchange 24-bit port_id match?
+ // (See "NOTE" above for handling Intiator AND Target in
+ // the same device driver)
+ // First, if this is a target response, then we originated
+ // (initiated) it with BLS_ABTS:
+
+ if( (Exchanges->fcExchange[ ExchangeID].type == BLS_ABTS)
+
+ &&
+ // Second, does the source of this ACC match the destination
+ // of who we originally sent it to?
+ ((Exchanges->fcExchange[ ExchangeID].fchs.d_id & 0xFFFFFF) ==
+ (fchs->s_id & 0xFFFFFF)) )
+ {
+ cpqfcTSCompleteExchange( fcChip, ExchangeID );
+ }
+ }
+ }
+ // Check for BLS {ABTS? (Abort Sequence)} ReJecT
+ else if( (fchs->d_id & 0x8F000000) == 0x85000000)
+ {
+ // target has responded with RJT for our ABTS;
+ // complete the indicated exchange with ABORTED status
+ // Make no checks for correct RX_ID, since
+ // all we need to conform ABTS ACC is the OX_ID.
+ // Verify that the d_id matches!
+
+ ExchangeID = (fchs->ox_rx_id >> 16) & 0x7FFF; // x_id from ACC
+// printk("BLS_ABTS RJT on Exchange 0x%04X 0x%04X\n",
+// fchs->ox_rx_id >> 16, fchs->ox_rx_id & 0xffff);
+
+ if( ExchangeID < TACH_SEST_LEN ) // x_ID makes sense
+ {
+ // Does "target" exchange 24-bit port_id match?
+ // (See "NOTE" above for handling Intiator AND Target in
+ // the same device driver)
+ // First, if this is a target response, then we originated
+ // (initiated) it with BLS_ABTS:
+
+ if( (Exchanges->fcExchange[ ExchangeID].type == BLS_ABTS)
+
+ &&
+ // Second, does the source of this ACC match the destination
+ // of who we originally sent it to?
+ ((Exchanges->fcExchange[ ExchangeID].fchs.d_id & 0xFFFFFF) ==
+ (fchs->s_id & 0xFFFFFF)) )
+ {
+ // YES! NOTE: There is a bug in CPQ's RA-4000 box
+ // where the "reason code" isn't returned in the payload
+ // For now, simply presume the reject is because the target
+ // already completed the exchange...
+
+// printk("complete x_ID %Xh on ABTS RJT\n", ExchangeID);
+ cpqfcTSCompleteExchange( fcChip, ExchangeID );
+ }
+ }
+ } // end of ABTS check
+ } // end of Basic Link Service Request


+ break;
+
+ default:

+ printk("AnalyzeIncomingFrame: unknown type: %Xh(%d)\n",
+ fcLQ->Qitem[QNdx].Type,
+ fcLQ->Qitem[QNdx].Type);


+ break;
+ }
+}
+
+

+// Function for Port Discovery necessary after every FC
+// initialization (e.g. LIP).
+// Also may be called if from Fabric Name Service logic.


+
+static void SendLogins( CPQFCHBA *cpqfcHBAdata, __u32 *FabricPortIds )

+{


+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;
+ FC_EXCHANGES *Exchanges = fcChip->Exchanges;

+ ULONG ulStatus=0;
+ TachFCHDR_GCMND fchs; // copy fields for transmission
+ int i;
+ ULONG loginType;
+ LONG ExchangeID;
+ PFC_LOGGEDIN_PORT pLoggedInPort;
+ __u32 PortIds[ number_of_al_pa];
+ int NumberOfPorts=0;
+
+ // We're going to presume (for now) that our limit of Fabric devices
+ // is the same as the number of alpa on a private loop (126 devices).
+ // (Of course this could be changed to support however many we have
+ // memory for).
+ memset( &PortIds[0], 0, sizeof(PortIds));
+
+ // First, check if this login is for our own Link Initialization
+ // (e.g. LIP on FC-AL), or if we have knowledge of Fabric devices
+ // from a switch. If we are logging into Fabric devices, we'll
+ // have a non-NULL FabricPortId pointer
+
+ if( FabricPortIds != NULL) // may need logins
+ {
+ int LastPort=FALSE;
+ i = 0;
+ while( !LastPort)
+ {
+ // port IDs From NSR payload; byte swap needed?
+ BigEndianSwap( (UCHAR*)FabricPortIds, (UCHAR*)&PortIds[i], 4);
+
+// printk("FPortId[%d] %Xh ", i, PortIds[i]);
+ if( PortIds[i] & 0x80000000)
+ LastPort = TRUE;
+
+ PortIds[i] &= 0xFFFFFF; // get 24-bit port_id
+ // some non-Fabric devices (like the Crossroads Fibre/Scsi bridge)
+ // erroneously use ALPA 0.
+ if( PortIds[i] ) // need non-zero port_id...
+ i++;
+
+ if( i >= number_of_al_pa ) // (in)sanity check
+ break;
+ FabricPortIds++; // next...
+ }
+
+ NumberOfPorts = i;
+// printk("NumberOf Fabric ports %d", NumberOfPorts);
+ }
+
+ else // need to send logins on our "local" link
+ {
+
+ // are we a loop port? If so, check for reception of LILP frame,
+ // and if received use it (SANMark requirement)
+ if( fcChip->Options.LILPin )
+ {
+ int j=0;
+ // sanity check on number of ALPAs from LILP frame...
+ // For format of LILP frame, see FC-AL specs or
+ // "Fibre Channel Bench Reference", J. Stai, 1995 (ISBN 1-879936-17-8)
+ // First byte is number of ALPAs
+ i = fcChip->LILPmap[0] >= (32*4) ? 32*4 : fcChip->LILPmap[0];
+ NumberOfPorts = i;
+// printk(" LILP alpa count %d ", i);
+ while( i > 0)
+ {
+ PortIds[j] = fcChip->LILPmap[1+ j];
+ j++; i--;
+ }
+ }
+ else // have to send login to everybody
+ {
+ int j=0;
+ i = number_of_al_pa;
+ NumberOfPorts = i;
+ while( i > 0)
+ {
+ PortIds[j] = valid_al_pa[j]; // all legal ALPAs
+ j++; i--;


+ }
+ }
+ }
+
+

+ // Now we have a copy of the port_ids (and how many)...
+ for( i = 0; i < NumberOfPorts; i++)
+ {
+ // 24-bit FC Port ID
+ fchs.s_id = PortIds[i]; // note: only 8-bits used for ALPA
+
+
+ // don't log into ourselves (Linux Scsi disk scan will stop on
+ // no TARGET support error on us, and quit trying for rest of devices)
+ if( (fchs.s_id & 0xFF ) == (fcChip->Registers.my_al_pa & 0xFF) )
+ continue;
+
+ // fabric login needed?
+ if( (fchs.s_id == 0) ||
+ (fcChip->Options.fabric == 1) )
+ {
+ fcChip->Options.flogi = 1; // fabric needs longer for login
+ // Do we need FLOGI or FDISC?


+ pLoggedInPort = fcFindLoggedInPort(
+ fcChip,

+ NULL, // don't search SCSI Nexus
+ 0xFFFFFC, // search linked list for Fabric port_id
+ NULL, // don't search WWN
+ NULL); // (don't care about end of list)
+
+ if( pLoggedInPort ) // If found, we have prior experience with
+ // this port -- check whether PDISC is needed
+ {
+ if( pLoggedInPort->flogi )
+ {
+ // does the switch support FDISC?? (FLOGI for now...)
+ loginType = ELS_FLOGI; // prior FLOGI still valid
+ }
+ else
+ loginType = ELS_FLOGI; // expired FLOGI
+ }
+ else // first FLOGI?
+ loginType = ELS_FLOGI;
+
+
+ fchs.s_id = 0xFFFFFE; // well known F_Port address
+
+ // Fabrics are not required to support FDISC, and
+ // it's not clear if that helps us anyway, since
+ // we'll want a Name Service Request to re-verify
+ // visible devices...
+ // Consequently, we always want our upper 16 bit
+ // port_id to be zero (we'll be rejected if we
+ // use our prior port_id if we've been plugged into
+ // a different switch port).
+ // Trick Tachyon to send to ALPA 0 (see TL/TS UG, pg 87)
+ // If our ALPA is 55h for instance, we want the FC frame
+ // s_id to be 0x000055, while Tach's my_al_pa register
+ // must be 0x000155, to force an OPN at ALPA 0
+ // (the Fabric port)
+ fcChip->Registers.my_al_pa &= 0xFF; // only use ALPA for FLOGI
+ writel( fcChip->Registers.my_al_pa | 0x0100,
+ fcChip->Registers.ReMapMemBase + TL_MEM_TACH_My_ID);
+ }
+
+ else // not FLOGI...
+ {
+ // should we send PLOGI or PDISC? Check if any prior port_id
+ // (e.g. alpa) completed a PLOGI/PRLI exchange by checking
+ // the pdisc flag.


+
+ pLoggedInPort = fcFindLoggedInPort(
+ fcChip,

+ NULL, // don't search SCSI Nexus
+ fchs.s_id, // search linked list for al_pa
+ NULL, // don't search WWN
+ NULL); // (don't care about end of list)
+
+
+
+ if( pLoggedInPort ) // If found, we have prior experience with
+ // this port -- check whether PDISC is needed
+ {


+ if( pLoggedInPort->pdisc )
+ {

+ loginType = ELS_PDISC; // prior PLOGI and PRLI maybe still valid
+
+ }
+ else
+ loginType = ELS_PLOGI; // prior knowledge, but can't use PDISC
+ }
+ else // never talked to this port_id before
+ loginType = ELS_PLOGI; // prior knowledge, but can't use PDISC
+ }
+
+
+

+ ulStatus = cpqfcTSBuildExchange(
+ cpqfcHBAdata,

+ loginType, // e.g. PLOGI
+ &fchs, // no incoming frame (we are originator)


+ NULL, // no data (no scatter/gather list)
+ &ExchangeID );// fcController->fcExchanges index, -1 if failed
+
+ if( !ulStatus ) // Exchange setup OK?
+ {
+ ulStatus = cpqfcTSStartExchange( cpqfcHBAdata, ExchangeID );

+ if( !ulStatus )
+ {
+ // submitted to Tach's Outbound Que (ERQ PI incremented)
+ // waited for completion for ELS type (Login frames issued
+ // synchronously)
+

+ if( loginType == ELS_PDISC )
+ {
+ // now, we really shouldn't Revalidate SEST exchanges until
+ // we get an ACC reply from our target and verify that
+ // the target address/WWN is unchanged. However, when a fast
+ // target gets the PDISC, they can send SEST Exchange data
+ // before we even get around to processing the PDISC ACC.
+ // Consequently, we lose the I/O.
+ // To avoid this, go ahead and Revalidate when the PDISC goes
+ // out, anticipating that the ACC will be truly acceptable
+ // (this happens 99.9999....% of the time).
+ // If we revalidate a SEST write, and write data goes to a
+ // target that is NOT the one we originated the WRITE to,
+ // that target is required (FCP-SCSI specs, etc) to discard
+ // our WRITE data.
+
+ // Re-validate SEST entries (Tachyon hardware assists)
+ RevalidateSEST( cpqfcHBAdata->HostAdapter, pLoggedInPort);
+ //TriggerHBA( fcChip->Registers.ReMapMemBase, 1);
+ }
+ }
+ else // give up immediately on error
+ {
+#ifdef LOGIN_DBG
+ printk("SendLogins: fcStartExchange failed: %Xh\n", ulStatus );
+#endif


+ break;
+ }
+
+

+ if( fcChip->Registers.FMstatus.value & 0x080 ) // LDn during Port Disc.
+ {
+ ulStatus = LNKDWN_OSLS;
+#ifdef LOGIN_DBG
+ printk("SendLogins: PortDisc aborted (LDn) @alpa %Xh\n", fchs.s_id);
+#endif
+ break;
+ }
+ // Check the exchange for bad status (i.e. FrameTimeOut),
+ // and complete on bad status (most likely due to BAD_ALPA)
+ // on LDn, DPC function may already complete (ABORT) a started
+ // exchange, so check type first (type = 0 on complete).
+ if( Exchanges->fcExchange[ExchangeID].status )
+ {
+#ifdef LOGIN_DBG
+ printk("completing x_ID %X on status %Xh\n",
+ ExchangeID, Exchanges->fcExchange[ExchangeID].status);
+#endif
+ cpqfcTSCompleteExchange( fcChip, ExchangeID);


+ }
+ }
+ else // Xchange setup failed...

+ {
+#ifdef LOGIN_DBG
+ printk("FC: cpqfcTSBuildExchange failed: %Xh\n", ulStatus );
+#endif
+ break;
+ }
+ }


+ if( !ulStatus )
+ {

+ // set the event signifying that all ALPAs were sent out.
+#ifdef LOGIN_DBG
+ printk("SendLogins: PortDiscDone\n");
+#endif
+ cpqfcHBAdata->PortDiscDone = 1;
+


+
+ // TL/TS UG, pg. 184
+ // 0x0065 = 100ms for RT_TOV
+ // 0x01f5 = 500ms for ED_TOV

+ fcChip->Registers.ed_tov.value = 0x006501f5L;

+ writel( fcChip->Registers.ed_tov.value,
+ (fcChip->Registers.ed_tov.address));
+

+ // set the LP_TOV back to ED_TOV (i.e. 500 ms)
+ writel( 0x00000010, fcChip->Registers.ReMapMemBase +TL_MEM_FM_TIMEOUT2);
+ }
+ else
+ {
+ printk("SendLogins: failed at xchng %Xh, alpa %Xh, status %Xh\n",
+ ExchangeID, fchs.s_id, ulStatus);
+ }
+ LEAVE("SendLogins");
+
+}
+
+
+// for REPORT_LUNS documentation, see "In-Depth Exploration of Scsi",
+// D. Deming, 1994, pg 7-19 (ISBN 1-879936-08-9)
+static void ScsiReportLunsDone(Scsi_Cmnd *Cmnd)
+{
+ struct Scsi_Host *HostAdapter = Cmnd->host;


+ CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;
+ FC_EXCHANGES *Exchanges = fcChip->Exchanges;

+ PFC_LOGGEDIN_PORT pLoggedInPort;
+ int LunListLen=0;
+ int i;
+ ULONG x_ID = 0xFFFFFFFF;
+ UCHAR *ucBuff = Cmnd->request_buffer;
+
+// printk("cpqfcTS: ReportLunsDone \n");
+ // first, we need to find the Exchange for this command,
+ // so we can find the fcPort struct to make the indicated
+ // changes.


+ for( i=0; i< TACH_SEST_LEN; i++)

+ {
+ if( Exchanges->fcExchange[i].type // exchange defined?
+ &&
+ (Exchanges->fcExchange[i].Cmnd == Cmnd) ) // matches?
+
+ {
+ x_ID = i; // found exchange!
+ break;
+ }
+ }
+ if( x_ID == 0xFFFFFFFF)
+ {
+// printk("cpqfcTS: ReportLuns failed - no FC Exchange\n");
+ goto Done; // Report Luns FC Exchange gone;
+ // exchange probably Terminated by Implicit logout
+ }
+
+
+ // search linked list for the port_id we sent INQUIRY to


+ pLoggedInPort = fcFindLoggedInPort( fcChip,

+ NULL, // DON'T search Scsi Nexus (we will set it)
+ Exchanges->fcExchange[ x_ID].fchs.d_id & 0xFFFFFF,

+ NULL, // DON'T search linked list for FC WWN
+ NULL); // DON'T care about end of list
+

+ if( !pLoggedInPort )
+ {
+// printk("cpqfcTS: ReportLuns failed - device gone\n");
+ goto Done; // error! can't find logged in Port
+ }
+ LunListLen = ucBuff[3];
+ LunListLen += ucBuff[2]>>8;
+
+ if( !LunListLen ) // failed
+ {
+ // generically speaking, a soft error means we should retry...
+ if( (Cmnd->result >> 16) == DID_SOFT_ERROR )
+ {
+ if( ((Cmnd->sense_buffer[2] & 0xF) == 0x6) &&
+ (Cmnd->sense_buffer[12] == 0x29) ) // Sense Code "reset"
+ {
+ TachFCHDR_GCMND *fchs = &Exchanges->fcExchange[ x_ID].fchs;
+ // did we fail because of "check condition, device reset?"
+ // e.g. the device was reset (i.e., at every power up)
+ // retry the Report Luns
+
+ // who are we sending it to?
+ // we know this because we have a copy of the command
+ // frame from the original Report Lun command -
+ // switch the d_id/s_id fields, because the Exchange Build
+ // context is "reply to source".
+
+ fchs->s_id = fchs->d_id; // (temporarily re-use the struct)
+ cpqfcTSPutLinkQue( cpqfcHBAdata, SCSI_REPORT_LUNS, fchs );
+ }
+ }
+ else // probably, the device doesn't support Report Luns
+ pLoggedInPort->ScsiNexus.VolumeSetAddressing = 0;
+ }
+ else // we have LUN info - check VSA mode
+ {
+ // for now, assume all LUNs will have same addr mode
+ // for VSA, payload byte 8 will be 0x40; otherwise, 0
+ pLoggedInPort->ScsiNexus.VolumeSetAddressing = ucBuff[8];
+
+ // Since we got a Report Luns answer, set lun masking flag
+ pLoggedInPort->ScsiNexus.LunMasking = 1;
+
+ if( LunListLen > 8*CPQFCTS_MAX_LUN) // We expect CPQFCTS_MAX_LUN max
+ LunListLen = 8*CPQFCTS_MAX_LUN;
+
+/*
+ printk("Device WWN %08X%08X Reports Luns @: ",
+ (ULONG)(pLoggedInPort->u.liWWN &0xFFFFFFFF),
+ (ULONG)(pLoggedInPort->u.liWWN>>32));
+
+ for( i=8; i<LunListLen+8; i+=8)
+ {
+ printk("%02X%02X ", ucBuff[i], ucBuff[i+1] );


+ }
+ printk("\n");

+*/
+
+ // Since the device was kind enough to tell us where the
+ // LUNs are, lets ensure they are contiguous for Linux's
+ // SCSI driver scan, which expects them to start at 0.
+ // Since Linux only supports 8 LUNs, only copy the first
+ // eight from the report luns command
+
+ // e.g., the Compaq RA4x00 f/w Rev 2.54 and above may report
+ // LUNs 4001, 4004, etc., because other LUNs are masked from
+ // this HBA (owned by someone else). We'll make those appear as
+ // LUN 0, 1... to Linux
+ {
+ int j;
+ int AppendLunList = 0;
+ // Walk through the LUN list. The 'j' array number is
+ // Linux's lun #, while the value of .lun[j] is the target's
+ // lun #.
+ // Once we build a LUN list, it's possible for a known device
+ // to go offline while volumes (LUNs) are added. Later,
+ // the device will do another PLOGI ... Report Luns command,
+ // and we must not alter the existing Linux Lun map.
+ // (This will be very rare).
+ for( j=0; j < CPQFCTS_MAX_LUN; j++)
+ {
+ if( pLoggedInPort->ScsiNexus.lun[j] != 0xFF )
+ {
+ AppendLunList = 1;
+ break;
+ }
+ }
+ if( AppendLunList )
+ {
+ int k;
+ int FreeLunIndex;
+// printk("cpqfcTS: AppendLunList\n");
+
+ // If we get a new Report Luns, we cannot change
+ // any existing LUN mapping! (Only additive entry)
+ // For all LUNs in ReportLun list
+ // if RL lun != ScsiNexus lun
+ // if RL lun present in ScsiNexus lun[], continue
+ // else find ScsiNexus lun[]==FF and add, continue
+
+ for( i=8, j=0; i<LunListLen+8 && j< CPQFCTS_MAX_LUN; i+=8, j++)
+ {
+ if( pLoggedInPort->ScsiNexus.lun[j] != ucBuff[i+1] )
+ {
+ // something changed from the last Report Luns
+ printk(" cpqfcTS: Report Lun change!\n");
+ for( k=0, FreeLunIndex=CPQFCTS_MAX_LUN;
+ k < CPQFCTS_MAX_LUN; k++)
+ {
+ if( pLoggedInPort->ScsiNexus.lun[k] == 0xFF)
+ {
+ FreeLunIndex = k;
+ break;
+ }
+ if( pLoggedInPort->ScsiNexus.lun[k] == ucBuff[i+1] )
+ break; // we already masked this lun
+ }
+ if( k >= CPQFCTS_MAX_LUN )
+ {
+ printk(" no room for new LUN %d\n", ucBuff[i+1]);
+ }
+ else if( k == FreeLunIndex ) // need to add LUN
+ {
+ pLoggedInPort->ScsiNexus.lun[k] = ucBuff[i+1];
+// printk("add [%d]->%02d\n", k, pLoggedInPort->ScsiNexus.lun[k]);


+
+ }
+ else
+ {

+ // lun already known


+ }
+ break;
+ }
+ }

+ // print out the new list...
+ for( j=0; j< CPQFCTS_MAX_LUN; j++)
+ {
+ if( pLoggedInPort->ScsiNexus.lun[j] == 0xFF)
+ break; // done
+// printk("[%d]->%02d ", j, pLoggedInPort->ScsiNexus.lun[j]);


+ }
+ }
+ else
+ {

+// printk("Linux SCSI LUNs[] -> Device LUNs: ");
+ // first time - this is easy
+ for( i=8, j=0; i<LunListLen+8 && j< CPQFCTS_MAX_LUN; i+=8, j++)
+ {
+ pLoggedInPort->ScsiNexus.lun[j] = ucBuff[i+1];
+// printk("[%d]->%02d ", j, pLoggedInPort->ScsiNexus.lun[j]);
+ }
+// printk("\n");
+ }
+ }
+ }
+
+Done:
+}
+
+// After successfully getting a "Process Login" (PRLI) from an
+// FC port, we want to Discover the LUNs so that we know the
+// addressing type (e.g., FCP-SCSI Volume Set Address, Peripheral
+// Unit Device), and whether SSP (Selective Storage Presentation or
+// Lun Masking) has made the LUN numbers non-zero based or
+// non-contiguous. To remain backward compatible with the SCSI-2
+// driver model, which expects a contiguous LUNs starting at 0,
+// will use the ReportLuns info to map from "device" to "Linux"
+// LUNs.


+static void IssueReportLunsCommand(
+ CPQFCHBA* cpqfcHBAdata,
+ TachFCHDR_GCMND* fchs)
+{

+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;

+ PFC_LOGGEDIN_PORT pLoggedInPort;
+ Scsi_Cmnd *Cmnd;
+ LONG x_ID;
+ ULONG ulStatus;
+ UCHAR *ucBuff;
+
+


+ if( !cpqfcHBAdata->PortDiscDone) // cleared by LDn
+ {

+ printk("Discard Q'd ReportLun command\n");


+ goto Done;
+ }
+

+ // find the device (from port_id) we're talking to


+ pLoggedInPort = fcFindLoggedInPort( fcChip,

+ NULL, // DON'T search Scsi Nexus
+ fchs->s_id & 0xFFFFFF,

+ NULL, // DON'T search linked list for FC WWN
+ NULL); // DON'T care about end of list

+ if( pLoggedInPort ) // we'd BETTER find it!
+ {
+
+


+ if( !(pLoggedInPort->fcp_info & TARGET_FUNCTION) )

+ goto Done; // forget it - FC device not a "target"
+
+ // now use the port's Scsi Command buffer for the
+ // Report Luns Command
+
+ Cmnd = &pLoggedInPort->ScsiCmnd;
+ ucBuff = pLoggedInPort->ReportLunsPayload;
+
+ memset( Cmnd, 0, sizeof(Scsi_Cmnd));
+ memset( ucBuff, 0, REPORT_LUNS_PL);
+
+ Cmnd->scsi_done = ScsiReportLunsDone;
+ Cmnd->host = cpqfcHBAdata->HostAdapter;
+
+ Cmnd->request_buffer = pLoggedInPort->ReportLunsPayload;
+ Cmnd->request_bufflen = REPORT_LUNS_PL;
+
+ Cmnd->cmnd[0] = 0xA0;
+ Cmnd->cmnd[8] = REPORT_LUNS_PL >> 8;
+ Cmnd->cmnd[9] = (UCHAR)REPORT_LUNS_PL;
+ Cmnd->cmd_len = 12;
+
+ Cmnd->channel = pLoggedInPort->ScsiNexus.channel;
+ Cmnd->target = pLoggedInPort->ScsiNexus.target;


+
+
+ ulStatus = cpqfcTSBuildExchange(
+ cpqfcHBAdata,

+ SCSI_IRE,
+ fchs,
+ Cmnd, // buffer for Report Lun data
+ &x_ID );// fcController->fcExchanges index, -1 if failed


+
+ if( !ulStatus ) // Exchange setup?
+ {

+ ulStatus = cpqfcTSStartExchange( cpqfcHBAdata, x_ID );
+ if( !ulStatus )
+ {

+ // submitted to Tach's Outbound Que (ERQ PI incremented)
+ // waited for completion for ELS type (Login frames issued
+ // synchronously)
+ }
+ else
+ // check reason for Exchange not being started - we might
+ // want to Queue and start later, or fail with error
+ {
+
+ }
+ }
+
+ else // Xchange setup failed...
+ printk(" cpqfcTSBuildExchange failed: %Xh\n", ulStatus );
+ }

+ else // like, we just got a PRLI ACC, and now the port is gone?
+ {
+ printk(" can't send ReportLuns - no login for port_id %Xh\n",
+ fchs->s_id & 0xFFFFFF);
+ }
+
+
+
+Done:


+
+}
+
+
+
+
+
+

+
+static void CompleteBoardLockCmnd( CPQFCHBA *cpqfcHBAdata)

+{
+ int i;
+ for( i = CPQFCTS_REQ_QUEUE_LEN-1; i>= 0; i--)
+ {
+ if( cpqfcHBAdata->BoardLockCmnd[i] != NULL )
+ {
+ Scsi_Cmnd *Cmnd = cpqfcHBAdata->BoardLockCmnd[i];


+ cpqfcHBAdata->BoardLockCmnd[i] = NULL;

+ Cmnd->result = (DID_SOFT_ERROR << 16); // ask for retry
+// printk(" BoardLockCmnd[%d] %p Complete, chnl/target/lun %d/%d/%d\n",


+// i,Cmnd, Cmnd->channel, Cmnd->target, Cmnd->lun);

+ if( Cmnd->scsi_done != NULL)
+ (*Cmnd->scsi_done)(Cmnd);


+ }
+ }
+}
+
+
+
+
+
+

+// runs every 1 second for FC exchange timeouts and implicit FC device logouts
+


+void cpqfcTSheartbeat( unsigned long ptr )

+{
+ CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)ptr;


+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;
+ FC_EXCHANGES *Exchanges = fcChip->Exchanges;

+ PFC_LOGGEDIN_PORT pLoggedInPort = &fcChip->fcPorts;
+ ULONG i;
+ unsigned long flags;
+ DECLARE_MUTEX_LOCKED(BoardLock);
+
+ PCI_TRACE( 0xA8)
+
+ if( cpqfcHBAdata->BoardLock) // Worker Task Running?
+ goto Skip;
+


+ spin_lock_irqsave( &io_request_lock, flags); // STOP _que function
+

+ PCI_TRACE( 0xA8)
+
+
+ cpqfcHBAdata->BoardLock = &BoardLock; // stop Linux SCSI command queuing


+
+ // release the IO lock (and re-enable interrupts)
+ spin_unlock_irqrestore( &io_request_lock, flags);
+

+ // Ensure no contention from _quecommand or Worker process
+ CPQ_SPINLOCK_HBA( cpqfcHBAdata)
+
+ PCI_TRACE( 0xA8)
+
+
+ disable_irq( cpqfcHBAdata->HostAdapter->irq); // our IRQ
+
+ // Complete the "bad target" commands (normally only used during
+ // initialization, since we aren't supposed to call "scsi_done"
+ // inside the queuecommand() function).
+


+ for( i=0; i< CPQFCTS_MAX_TARGET_ID; i++)
+ {

+ if( cpqfcHBAdata->BadTargetCmnd[i] )
+ {
+ Scsi_Cmnd *Cmnd = cpqfcHBAdata->BadTargetCmnd[i];


+ cpqfcHBAdata->BadTargetCmnd[i] = NULL;

+ Cmnd->result = (DID_BAD_TARGET << 16);
+ if( Cmnd->scsi_done != NULL)
+ (*Cmnd->scsi_done)(Cmnd);
+ }
+ else


+ break;
+ }
+
+

+ // logged in ports -- re-login check (ports required to verify login with
+ // PDISC after LIP within 2 secs)
+
+ // prevent contention


+ while( pLoggedInPort ) // for all ports which are expecting

+ // PDISC after the next LIP, check to see if
+ // time is up!
+ {
+ // Important: we only detect "timeout" condition on TRANSITION
+ // from non-zero to zero
+ if( pLoggedInPort->LOGO_timer ) // time-out "armed"?
+ {
+ if( !(--pLoggedInPort->LOGO_timer) ) // DEC from 1 to 0?
+ {
+ // LOGOUT time! Per PLDA, PDISC hasn't complete in 2 secs, so
+ // issue LOGO request and destroy all I/O with other FC port(s).
+
+/*
+ printk(" ~cpqfcTS heartbeat: LOGOut!~ ");
+ printk("Linux SCSI Chanl/Target %d/%d (port_id %06Xh) WWN %08X%08X\n",
+ pLoggedInPort->ScsiNexus.channel,
+ pLoggedInPort->ScsiNexus.target,
+ pLoggedInPort->port_id,
+ (ULONG)(pLoggedInPort->u.liWWN &0xFFFFFFFF),
+ (ULONG)(pLoggedInPort->u.liWWN>>32));
+
+*/


+ cpqfcTSImplicitLogout( cpqfcHBAdata, pLoggedInPort);
+
+ }

+ // else simply decremented - maybe next time...
+ }
+ pLoggedInPort = pLoggedInPort->pNextPort;


+ }
+
+
+
+
+

+ // ************ FC EXCHANGE TIMEOUT CHECK **************
+
+ for( i=0; i< TACH_MAX_XID; i++)
+ {
+ if( Exchanges->fcExchange[i].type ) // exchange defined?
+ {
+
+ if( !Exchanges->fcExchange[i].timeOut ) // time expired
+ {
+ // Set Exchange timeout status
+ Exchanges->fcExchange[i].status |= FC2_TIMEOUT;
+
+ if( i >= TACH_SEST_LEN ) // Link Service Exchange
+ {
+ cpqfcTSCompleteExchange( fcChip, i); // Don't "abort" LinkService
+ }
+
+ else // SEST Exchange TO -- may post ABTS to Worker Thread Que
+ {
+ // (Make sure we don't keep timing it out; let other functions
+ // complete it or set the timeOut as needed)
+ Exchanges->fcExchange[i].timeOut = 30000; // seconds default
+
+ if( Exchanges->fcExchange[i].type
+ &
+ (BLS_ABTS | BLS_ABTS_ACC ) )
+ {
+ // For BLS_ABTS*, an upper level might still have
+ // an outstanding command waiting for low-level completion.
+ // Also, in the case of a WRITE, we MUST get confirmation
+ // of either ABTS ACC or RJT before re-using the Exchange.
+ // It's possible that the RAID cache algorithm can hang
+ // if we fail to complete a WRITE to a LBA, when a READ
+ // comes later to that same LBA. Therefore, we must
+ // ensure that the target verifies receipt of ABTS for
+ // the exchange
+
+ printk("~TO Q'd ABTS (x_ID %Xh)~ ", i);
+// TriggerHBA( fcChip->Registers.ReMapMemBase);
+
+ // On timeout of a ABTS exchange, check to
+ // see if the FC device has a current valid login.
+ // If so, restart it.


+ pLoggedInPort = fcFindLoggedInPort( fcChip,

+ Exchanges->fcExchange[i].Cmnd, // find Scsi Nexus


+ 0, // DON'T search linked list for FC port id
+ NULL, // DON'T search linked list for FC WWN
+ NULL); // DON'T care about end of list
+

+ // device exists?
+ if( pLoggedInPort ) // device exists?
+ {
+ if( pLoggedInPort->prli ) // logged in for FCP-SCSI?


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 076'
echo 'File patch-2.4.0-test9 is continued in part 077'
echo "077" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part077

#!/bin/sh -x
# this is part 077 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 077; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&
+ {

+ // attempt to restart the ABTS
+ printk(" ~restarting ABTS~ ");
+ cpqfcTSStartExchange( cpqfcHBAdata, i );
+
+ }
+ }
+ }
+ else // not an ABTS
+ {
+
+ // We expect the WorkerThread to change the xchng type to
+ // abort and set appropriate timeout.
+ cpqfcTSPutLinkQue( cpqfcHBAdata, BLS_ABTS, &i ); // timed-out
+ }
+ }
+ }
+ else // time not expired...
+ {
+ // decrement timeout: 1 or more seconds left
+ --Exchanges->fcExchange[i].timeOut;


+ }
+ }
+ }
+
+

+ enable_irq( cpqfcHBAdata->HostAdapter->irq);
+
+

+ CPQ_SPINUNLOCK_HBA( cpqfcHBAdata)
+
+ cpqfcHBAdata->BoardLock = NULL; // Linux SCSI commands may be queued


+
+ // Now, complete any Cmnd we Q'd up while BoardLock was held
+
+ CompleteBoardLockCmnd( cpqfcHBAdata);
+
+

+ // restart the timer to run again (1 sec later)
+Skip:
+ mod_timer( &cpqfcHBAdata->cpqfcTStimer, jiffies + HZ);
+
+ PCI_TRACEO( i, 0xA8)


+ return;
+}
+
+

+// put valid FC-AL physical address in spec order
+static const UCHAR valid_al_pa[]={
+ 0xef, 0xe8, 0xe4, 0xe2,
+ 0xe1, 0xE0, 0xDC, 0xDA,
+ 0xD9, 0xD6, 0xD5, 0xD4,
+ 0xD3, 0xD2, 0xD1, 0xCe,
+ 0xCd, 0xCc, 0xCb, 0xCa,
+ 0xC9, 0xC7, 0xC6, 0xC5,
+ 0xC3, 0xBc, 0xBa, 0xB9,
+ 0xB6, 0xB5, 0xB4, 0xB3,
+ 0xB2, 0xB1, 0xae, 0xad,
+ 0xAc, 0xAb, 0xAa, 0xA9,
+
+ 0xA7, 0xA6, 0xA5, 0xA3,
+ 0x9f, 0x9e, 0x9d, 0x9b,
+ 0x98, 0x97, 0x90, 0x8f,
+ 0x88, 0x84, 0x82, 0x81,
+ 0x80, 0x7c, 0x7a, 0x79,
+ 0x76, 0x75, 0x74, 0x73,
+ 0x72, 0x71, 0x6e, 0x6d,
+ 0x6c, 0x6b, 0x6a, 0x69,
+ 0x67, 0x66, 0x65, 0x63,
+ 0x5c, 0x5a, 0x59, 0x56,
+
+ 0x55, 0x54, 0x53, 0x52,
+ 0x51, 0x4e, 0x4d, 0x4c,
+ 0x4b, 0x4a, 0x49, 0x47,
+ 0x46, 0x45, 0x43, 0x3c,
+ 0x3a, 0x39, 0x36, 0x35,
+ 0x34, 0x33, 0x32, 0x31,
+ 0x2e, 0x2d, 0x2c, 0x2b,
+ 0x2a, 0x29, 0x27, 0x26,
+ 0x25, 0x23, 0x1f, 0x1E,
+ 0x1d, 0x1b, 0x18, 0x17,
+
+ 0x10, 0x0f, 8, 4, 2, 1 }; // ALPA 0 (Fabric) is special case
+
+const int number_of_al_pa = (sizeof(valid_al_pa) );
+
+
+
+// this function looks up an al_pa from the table of valid al_pa's
+// we decrement from the last decimal loop ID, because soft al_pa
+// (our typical case) are assigned with highest priority (and high al_pa)
+// first. See "In-Depth FC-AL", R. Kembel pg. 38
+// INPUTS:
+// al_pa - 24 bit port identifier (8 bit al_pa on private loop)
+// RETURN:
+// Loop ID - serves are index to array of logged in ports
+// -1 - invalid al_pa (not all 8 bit values are legal)
+
+#if (0)
+static int GetLoopID( ULONG al_pa )


+{
+ int i;
+

+ for( i = number_of_al_pa -1; i >= 0; i--) // dec.
+ {
+ if( valid_al_pa[i] == (UCHAR)al_pa ) // take lowest 8 bits
+ return i; // success - found valid al_pa; return decimal LoopID
+ }
+ return -1; // failed - not found
+}
+#endif
+
+
+// Search the singly (forward) linked list "fcPorts" looking for
+// either the SCSI target (if != -1), port_id (if not NULL),
+// or WWN (if not null), in that specific order.
+// If we find a SCSI nexus (from Cmnd arg), set the SCp.phase
+// field according to VSA or PDU
+// RETURNS:
+// Ptr to logged in port struct if found
+// (NULL if not found)
+// pLastLoggedInPort - ptr to last struct (for adding new ones)
+//

+PFC_LOGGEDIN_PORT fcFindLoggedInPort(
+ PTACHYON fcChip,

+ Scsi_Cmnd *Cmnd, // search linked list for Scsi Nexus (channel/target/lun)


+ ULONG port_id, // search linked list for al_pa, or
+ UCHAR wwn[8], // search linked list for WWN, or...

+ PFC_LOGGEDIN_PORT *pLastLoggedInPort )
+

+{
+ PFC_LOGGEDIN_PORT pLoggedInPort = &fcChip->fcPorts;

+ BOOLEAN target_id_valid=FALSE;
+ BOOLEAN port_id_valid=FALSE;
+ BOOLEAN wwn_valid=FALSE;


+ int i;
+
+

+ if( Cmnd != NULL )
+ target_id_valid = TRUE;
+
+ else if( port_id ) // note! 24-bit NULL address is illegal
+ port_id_valid = TRUE;
+
+ else
+ {
+ for( i=0; i<8; i++) // valid WWN passed? NULL WWN invalid
+ {
+ if( wwn ) // non-null arg? (OK to pass NULL when not searching WWN)
+ {
+ if( wwn[i] != 0 )
+ wwn_valid = TRUE; // any non-zero byte makes (presumably) valid
+ }
+ }
+ }
+ // check other options ...
+
+
+ // In case multiple search options are given, we use a priority
+ // scheme:
+ // While valid pLoggedIn Ptr
+ // If port_id is valid
+ // if port_id matches, return Ptr
+ // If wwn is valid
+ // if wwn matches, return Ptr
+ // Next Ptr in list
+ //
+ // Return NULL (not found)
+
+
+ while( pLoggedInPort ) // NULL marks end of list (1st ptr always valid)
+ {
+ if( pLastLoggedInPort ) // caller's pointer valid?
+ *pLastLoggedInPort = pLoggedInPort; // end of linked list
+
+ if( target_id_valid )
+ {
+ // check Linux Scsi Cmnd for channel/target Nexus match
+ // (all luns are accessed through matching "pLoggedInPort")
+ if( (pLoggedInPort->ScsiNexus.target == Cmnd->target)
+ &&
+ (pLoggedInPort->ScsiNexus.channel == Cmnd->channel))
+ {
+ // For "passthru" modes, the IOCTL caller is responsible
+ // for setting the FCP-LUN addressing
+ if( !Cmnd->SCp.sent_command ) // NOT passthru?
+ {
+
+ // set the FCP-LUN addressing type
+ Cmnd->SCp.phase = pLoggedInPort->ScsiNexus.VolumeSetAddressing;
+
+ // set the Device Type we got from the snooped INQUIRY string
+ Cmnd->SCp.Message = pLoggedInPort->ScsiNexus.InqDeviceType;
+
+ // handle LUN masking; if not "default" (illegal) lun value,
+ // the use it. These lun values are set by a successful
+ // Report Luns command
+ if( pLoggedInPort->ScsiNexus.LunMasking == 1)
+ {
+ // we KNOW all the valid LUNs... 0xFF is invalid!
+ Cmnd->SCp.have_data_in = pLoggedInPort->ScsiNexus.lun[Cmnd->lun];
+ }
+ else
+ Cmnd->SCp.have_data_in = Cmnd->lun; // Linux & target luns match
+ }
+ break; // found it!
+ }
+ }
+
+ if( port_id_valid ) // look for alpa first
+ {
+ if( pLoggedInPort->port_id == port_id )
+ break; // found it!
+ }
+ if( wwn_valid ) // look for wwn second
+ {
+
+ if( !memcmp( &pLoggedInPort->u.ucWWN[0], &wwn[0], 8))
+ {
+ // all 8 bytes of WWN match
+ break; // found it!
+ }
+ }
+
+ pLoggedInPort = pLoggedInPort->pNextPort; // try next port
+ }
+
+ return pLoggedInPort;


+}
+
+
+
+
+//

+// We need to examine the SEST table and re-validate
+// any open Exchanges for this LoggedInPort
+// To make Tachyon pay attention, Freeze FCP assists,
+// set VAL bits, Unfreeze FCP assists


+static void RevalidateSEST( struct Scsi_Host *HostAdapter,
+ PFC_LOGGEDIN_PORT pLoggedInPort)

+{


+ CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;
+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;
+ FC_EXCHANGES *Exchanges = fcChip->Exchanges;

+ ULONG x_ID;
+ BOOLEAN TachFroze = FALSE;
+
+
+ // re-validate any SEST exchanges that are permitted
+ // to survive the link down (e.g., good PDISC performed)


+ for( x_ID = 0; x_ID < TACH_SEST_LEN; x_ID++)
+ {
+

+ // If the SEST entry port_id matches the pLoggedInPort,
+ // we need to re-validate
+ if( (Exchanges->fcExchange[ x_ID].type == SCSI_IRE)
+ ||
+ (Exchanges->fcExchange[ x_ID].type == SCSI_IWE))
+ {
+
+ if( (Exchanges->fcExchange[ x_ID].fchs.d_id & 0xFFFFFF) // (24-bit port ID)
+ == pLoggedInPort->port_id)
+ {
+// printk(" re-val xID %Xh ", x_ID);
+ if( !TachFroze ) // freeze if not already frozen
+ TachFroze |= FreezeTach( cpqfcHBAdata);
+ fcChip->SEST->u[ x_ID].IWE.Hdr_Len |= 0x80000000; // set VAL bit
+ }
+ }
+ }
+
+ if( TachFroze)
+ {

+ fcChip->UnFreezeTachyon( fcChip, 2); // both ERQ and FCP assists

+ }
+}
+
+
+// Complete an Linux Cmnds that we Queued because
+// our FC link was down (cause immediate retry)


+
+static void UnblockScsiDevice( struct Scsi_Host *HostAdapter,
+ PFC_LOGGEDIN_PORT pLoggedInPort)

+{
+// Scsi_Device *sdev = HostAdapter->host_queue;


+ CPQFCHBA *cpqfcHBAdata = (CPQFCHBA *)HostAdapter->hostdata;

+ Scsi_Cmnd* *SCptr = &cpqfcHBAdata->LinkDnCmnd[0];
+ Scsi_Cmnd *Cmnd;
+ int indx;
+
+
+
+ // if the device was previously "blocked", make sure
+ // we unblock it so Linux SCSI will resume
+
+ pLoggedInPort->device_blocked = FALSE; // clear our flag
+
+ // check the Link Down command ptr buffer;
+ // we can complete now causing immediate retry
+ for( indx=0; indx < CPQFCTS_REQ_QUEUE_LEN; indx++, SCptr++)
+ {
+ if( *SCptr != NULL ) // scsi command to complete?
+ {
+#ifdef DUMMYCMND_DBG
+ printk("complete Cmnd %p in LinkDnCmnd[%d]\n", *SCptr,indx);
+#endif
+ Cmnd = *SCptr;
+
+
+ // Are there any Q'd commands for this target?
+ if( (Cmnd->target == pLoggedInPort->ScsiNexus.target)
+ &&
+ (Cmnd->channel == pLoggedInPort->ScsiNexus.channel) )
+ {
+ Cmnd->result = (DID_SOFT_ERROR <<16); // force retry


+ if( Cmnd->scsi_done != NULL)
+ (*Cmnd->scsi_done)(Cmnd);

+ else
+ printk("LinkDnCmnd scsi_done ptr null, port_id %Xh\n",
+ pLoggedInPort->port_id);
+ *SCptr = NULL; // free this slot for next use


+ }
+ }
+ }
+}
+
+

+//#define WWN_DBG 1


+
+static void SetLoginFields(
+ PFC_LOGGEDIN_PORT pLoggedInPort,
+ TachFCHDR_GCMND* fchs,
+ BOOLEAN PDisc,
+ BOOLEAN Originator)

+{
+ LOGIN_PAYLOAD logi; // FC-PH Port Login

+ PRLI_REQUEST prli; // copy for BIG ENDIAN switch
+ int i;
+#ifdef WWN_DBG
+ ULONG ulBuff;
+#endif


+
+ BigEndianSwap( (UCHAR*)&fchs->pl[0], (UCHAR*)&logi, sizeof(logi));
+

+ pLoggedInPort->Originator = Originator;
+ pLoggedInPort->port_id = fchs->s_id & 0xFFFFFF;
+
+ switch( fchs->pl[0] & 0xffff )
+ {
+ case 0x00000002: // PLOGI or PDISC ACCept?
+ if( PDisc ) // PDISC accept
+ goto PDISC_case;
+
+ case 0x00000003: // ELS_PLOGI or ELS_PLOGI_ACC
+
+ // Login BB_credit typically 0 for Tachyons
+ pLoggedInPort->BB_credit = logi.cmn_services.bb_credit;
+
+ // e.g. 128, 256, 1024, 2048 per FC-PH spec
+ // We have to use this when setting up SEST Writes,
+ // since that determines frame size we send.
+ pLoggedInPort->rx_data_size = logi.class3.rx_data_size;
+ pLoggedInPort->plogi = TRUE;


+ pLoggedInPort->pdisc = FALSE;

+ pLoggedInPort->prli = FALSE; // ELS_PLOGI resets
+ pLoggedInPort->flogi = FALSE; // ELS_PLOGI resets
+ pLoggedInPort->logo = FALSE; // ELS_PLOGI resets
+ pLoggedInPort->LOGO_counter = 0;// ELS_PLOGI resets
+ pLoggedInPort->LOGO_timer = 0;// ELS_PLOGI resets
+
+ // was this PLOGI to a Fabric?
+ if( pLoggedInPort->port_id == 0xFFFFFC ) // well know address
+ pLoggedInPort->flogi = TRUE;
+
+
+ for( i=0; i<8; i++) // copy the LOGIN port's WWN
+ pLoggedInPort->u.ucWWN[i] = logi.port_name[i];
+
+#ifdef WWN_DBG
+ ulBuff = (ULONG)pLoggedInPort->u.liWWN;
+ if( pLoggedInPort->Originator)
+ printk("o");
+ else
+ printk("r");
+ printk("PLOGI port_id %Xh, WWN %08X",
+ pLoggedInPort->port_id, ulBuff);
+
+ ulBuff = (ULONG)(pLoggedInPort->u.liWWN >> 32);
+ printk("%08Xh fcPort %p\n", ulBuff, pLoggedInPort);


+#endif
+ break;
+
+
+
+

+ case 0x00000005: // ELS_LOGO (logout)
+
+


+ pLoggedInPort->plogi = FALSE;
+ pLoggedInPort->pdisc = FALSE;

+ pLoggedInPort->prli = FALSE; // ELS_PLOGI resets
+ pLoggedInPort->flogi = FALSE; // ELS_PLOGI resets
+ pLoggedInPort->logo = TRUE; // ELS_PLOGI resets
+ pLoggedInPort->LOGO_counter++; // ELS_PLOGI resets
+ pLoggedInPort->LOGO_timer = 0;
+#ifdef WWN_DBG
+ ulBuff = (ULONG)pLoggedInPort->u.liWWN;
+ if( pLoggedInPort->Originator)
+ printk("o");
+ else
+ printk("r");
+ printk("LOGO port_id %Xh, WWN %08X",
+ pLoggedInPort->port_id, ulBuff);
+
+ ulBuff = (ULONG)(pLoggedInPort->u.liWWN >> 32);
+ printk("%08Xh\n", ulBuff);


+#endif
+ break;
+
+
+

+PDISC_case:
+ case 0x00000050: // ELS_PDISC or ELS_PDISC_ACC
+ pLoggedInPort->LOGO_timer = 0; // stop the time-out
+
+ pLoggedInPort->prli = TRUE; // ready to accept FCP-SCSI I/O
+
+
+
+#ifdef WWN_DBG
+ ulBuff = (ULONG)pLoggedInPort->u.liWWN;
+ if( pLoggedInPort->Originator)
+ printk("o");
+ else
+ printk("r");
+ printk("PDISC port_id %Xh, WWN %08X",
+ pLoggedInPort->port_id, ulBuff);
+
+ ulBuff = (ULONG)(pLoggedInPort->u.liWWN >> 32);
+ printk("%08Xh\n", ulBuff);
+#endif


+
+
+
+ break;
+
+
+

+ case 0x1020L: // PRLI?
+ case 0x1002L: // PRLI ACCept?
+ BigEndianSwap( (UCHAR*)&fchs->pl[0], (UCHAR*)&prli, sizeof(prli));
+
+ pLoggedInPort->fcp_info = prli.fcp_info; // target/initiator flags
+ pLoggedInPort->prli = TRUE; // PLOGI resets, PDISC doesn't
+
+ pLoggedInPort->pdisc = TRUE; // expect to send (or receive) PDISC
+ // next time
+ pLoggedInPort->LOGO_timer = 0; // will be set next LinkDown
+#ifdef WWN_DBG
+ ulBuff = (ULONG)pLoggedInPort->u.liWWN;
+ if( pLoggedInPort->Originator)
+ printk("o");
+ else
+ printk("r");
+ printk("PRLI port_id %Xh, WWN %08X",
+ pLoggedInPort->port_id, ulBuff);
+
+ ulBuff = (ULONG)(pLoggedInPort->u.liWWN >> 32);
+ printk("%08Xh\n", ulBuff);
+#endif


+
+ break;
+
+ }
+

+ return;
+}
+
+
+
+
+
+

+static void BuildLinkServicePayload( PTACHYON fcChip, ULONG type, void* payload)
+{
+ LOGIN_PAYLOAD *plogi; // FC-PH Port Login
+ LOGIN_PAYLOAD PlogiPayload; // copy for BIG ENDIAN switch
+ PRLI_REQUEST *prli; // FCP-SCSI Process Login
+ PRLI_REQUEST PrliPayload; // copy for BIG ENDIAN switch
+ LOGOUT_PAYLOAD *logo;
+ LOGOUT_PAYLOAD LogoutPayload;
+// PRLO_REQUEST *prlo;
+// PRLO_REQUEST PrloPayload;
+ REJECT_MESSAGE rjt, *prjt;
+
+ memset( &PlogiPayload, 0, sizeof( PlogiPayload));
+ plogi = &PlogiPayload; // load into stack buffer,
+ // then BIG-ENDIAN switch a copy to caller
+
+
+ switch( type ) // payload type can be ELS_PLOGI, ELS_PRLI, ADISC, ...
+ {
+ case ELS_FDISC:
+ case ELS_FLOGI:
+ case ELS_PLOGI_ACC: // FC-PH PORT Login Accept
+ case ELS_PLOGI: // FC-PH PORT Login
+ case ELS_PDISC: // FC-PH2 Port Discovery - same payload as ELS_PLOGI
+ plogi->login_cmd = LS_PLOGI;
+ if( type == ELS_PDISC)
+ plogi->login_cmd = LS_PDISC;
+ else if( type == ELS_PLOGI_ACC )
+ plogi->login_cmd = LS_ACC;
+
+ plogi->cmn_services.bb_credit = 0x00;
+ plogi->cmn_services.lowest_ver = fcChip->lowest_FCPH_ver;
+ plogi->cmn_services.highest_ver = fcChip->highest_FCPH_ver;
+ plogi->cmn_services.bb_rx_size = TACHLITE_TS_RX_SIZE;
+ plogi->cmn_services.common_features = CONTINUOSLY_INCREASING |
+ RANDOM_RELATIVE_OFFSET;
+
+ // fill in with World Wide Name based Port Name - 8 UCHARs
+ // get from Tach registers WWN hi & lo
+ LoadWWN( fcChip, plogi->port_name, 0);
+ // fill in with World Wide Name based Node/Fabric Name - 8 UCHARs
+ // get from Tach registers WWN hi & lo
+ LoadWWN( fcChip, plogi->node_name, 1);
+
+ // For Seagate Drives.
+ //
+ plogi->cmn_services.common_features |= 0x800;
+ plogi->cmn_services.rel_offset = 0xFE;
+ plogi->cmn_services.concurrent_seq = 1;
+ plogi->class1.service_options = 0x00;
+ plogi->class2.service_options = 0x00;
+ plogi->class3.service_options = CLASS_VALID;
+ plogi->class3.initiator_control = 0x00;
+ plogi->class3.rx_data_size = MAX_RX_PAYLOAD;
+ plogi->class3.recipient_control =
+ ERROR_DISCARD | ONE_CATEGORY_SEQUENCE;
+ plogi->class3.concurrent_sequences = 1;
+ plogi->class3.open_sequences = 1;
+ plogi->vendor_id[0] = 'C'; plogi->vendor_id[1] = 'Q';
+ plogi->vendor_version[0] = 'C'; plogi->vendor_version[1] = 'Q';
+ plogi->vendor_version[2] = ' '; plogi->vendor_version[3] = '0';
+ plogi->vendor_version[4] = '0'; plogi->vendor_version[5] = '0';
+
+
+ // FLOGI specific fields... (see FC-FLA, Rev 2.7, Aug 1999, sec 5.1)
+ if( (type == ELS_FLOGI) || (type == ELS_FDISC) )
+ {
+ if( type == ELS_FLOGI )
+ plogi->login_cmd = LS_FLOGI;
+ else
+ plogi->login_cmd = LS_FDISC;
+
+ plogi->cmn_services.lowest_ver = 0x20;
+ plogi->cmn_services.common_features = 0x0800;
+ plogi->cmn_services.rel_offset = 0;
+ plogi->cmn_services.concurrent_seq = 0;
+
+ plogi->class3.service_options = 0x8800;
+ plogi->class3.rx_data_size = 0;
+ plogi->class3.recipient_control = 0;
+ plogi->class3.concurrent_sequences = 0;
+ plogi->class3.open_sequences = 0;
+ }
+
+ // copy back to caller's buff, w/ BIG ENDIAN swap
+ BigEndianSwap( (UCHAR*)&PlogiPayload, payload, sizeof(PlogiPayload));
+ break;
+
+
+ case ELS_ACC: // generic Extended Link Service ACCept
+ plogi->login_cmd = LS_ACC;
+ // copy back to caller's buff, w/ BIG ENDIAN swap
+ BigEndianSwap( (UCHAR*)&PlogiPayload, payload, 4);


+ break;
+
+
+

+ case ELS_SCR: // Fabric State Change Registration
+ {
+ SCR_PL scr; // state change registration
+
+ memset( &scr, 0, sizeof(scr));
+
+ scr.command = LS_SCR; // 0x62000000
+ // see FC-FLA, Rev 2.7, Table A.22 (pg 82)
+ scr.function = 3; // 1 = Events detected by Fabric
+ // 2 = N_Port detected registration
+ // 3 = Full registration
+
+ // copy back to caller's buff, w/ BIG ENDIAN swap
+ BigEndianSwap( (UCHAR*)&scr, payload, sizeof(SCR_PL));


+ }
+
+ break;
+
+

+ case FCS_NSR: // Fabric Name Service Request
+ {
+ NSR_PL nsr; // Name Server Req. payload
+
+ memset( &nsr, 0, sizeof(NSR_PL));
+
+ // see Brocade Fabric Programming Guide,
+ // Rev 1.3, pg 4-44
+ nsr.CT_Rev = 0x01000000;
+ nsr.FCS_Type = 0xFC020000;
+ nsr.Command_code = 0x01710000;
+ nsr.FCP = 8;
+
+ // copy back to caller's buff, w/ BIG ENDIAN swap
+ BigEndianSwap( (UCHAR*)&nsr, payload, sizeof(NSR_PL));


+ }
+
+ break;
+
+
+
+

+ case ELS_LOGO: // FC-PH PORT LogOut
+ logo = &LogoutPayload; // load into stack buffer,
+ // then BIG-ENDIAN switch a copy to caller
+ logo->cmd = LS_LOGO;
+ // load the 3 UCHARs of the node name
+ // (if private loop, upper two UCHARs 0)
+ logo->reserved = 0;
+
+ logo->n_port_identifier[0] = (UCHAR)(fcChip->Registers.my_al_pa);
+ logo->n_port_identifier[1] =
+ (UCHAR)(fcChip->Registers.my_al_pa>>8);
+ logo->n_port_identifier[2] =
+ (UCHAR)(fcChip->Registers.my_al_pa>>16);
+ // fill in with World Wide Name based Port Name - 8 UCHARs
+ // get from Tach registers WWN hi & lo
+ LoadWWN( fcChip, logo->port_name, 0);
+
+ BigEndianSwap( (UCHAR*)&LogoutPayload,
+ payload, sizeof(LogoutPayload) ); // 16 UCHAR struct
+ break;
+
+
+ case ELS_LOGO_ACC: // Logout Accept (FH-PH pg 149, table 74)
+ logo = &LogoutPayload; // load into stack buffer,
+ // then BIG-ENDIAN switch a copy to caller
+ logo->cmd = LS_ACC;
+ BigEndianSwap( (UCHAR*)&LogoutPayload, payload, 4 ); // 4 UCHAR cmnd
+ break;
+
+
+ case ELS_RJT: // ELS_RJT link service reject (FH-PH pg 155)
+
+ prjt = (REJECT_MESSAGE*)payload; // pick up passed data
+ rjt.command_code = ELS_RJT;
+ // reverse fields, because of Swap that follows...
+ rjt.vendor = prjt->reserved; // vendor specific
+ rjt.explain = prjt->reason; //
+ rjt.reason = prjt->explain; //
+ rjt.reserved = prjt->vendor; //
+ // BIG-ENDIAN switch a copy to caller
+ BigEndianSwap( (UCHAR*)&rjt, payload, 8 ); // 8 UCHAR cmnd


+ break;
+
+
+
+
+

+ case ELS_PRLI_ACC: // Process Login ACCept
+ case ELS_PRLI: // Process Login
+ case ELS_PRLO: // Process Logout
+ memset( &PrliPayload, 0, sizeof( PrliPayload));
+ prli = &PrliPayload; // load into stack buffer,
+
+ if( type == ELS_PRLI )
+ prli->cmd = 0x20; // Login
+ else if( type == ELS_PRLO )
+ prli->cmd = 0x21; // Logout
+ else if( type == ELS_PRLI_ACC )
+ {
+ prli->cmd = 0x02; // Login ACCept
+ prli->valid = REQUEST_EXECUTED;
+ }
+
+
+ prli->valid |= SCSI_FCP | ESTABLISH_PAIR;
+ prli->fcp_info = READ_XFER_RDY;
+ prli->page_length = 0x10;
+ prli->payload_length = 20;
+ // Can be initiator AND target


+
+ if( fcChip->Options.initiator )

+ prli->fcp_info |= INITIATOR_FUNCTION;
+ if( fcChip->Options.target )
+ prli->fcp_info |= TARGET_FUNCTION;
+
+ BigEndianSwap( (UCHAR*)&PrliPayload, payload, prli->payload_length);


+ break;
+
+
+

+ default: // no can do - programming error
+ printk(" BuildLinkServicePayload unknown!\n");


+ break;
+ }
+}
+

+// loads 8 UCHARs for PORT name or NODE name base on
+// controller's WWN.
+void LoadWWN( PTACHYON fcChip, UCHAR* dest, UCHAR type)
+{
+ UCHAR* bPtr, i;


+
+ switch( type )

+ {
+ case 0: // Port_Name
+ bPtr = (UCHAR*)&fcChip->Registers.wwn_hi;
+ for( i =0; i<4; i++)
+ dest[i] = *bPtr++;
+ bPtr = (UCHAR*)&fcChip->Registers.wwn_lo;
+ for( i =4; i<8; i++)
+ dest[i] = *bPtr++;
+ break;
+ case 1: // Node/Fabric _Name
+ bPtr = (UCHAR*)&fcChip->Registers.wwn_hi;
+ for( i =0; i<4; i++)
+ dest[i] = *bPtr++;
+ bPtr = (UCHAR*)&fcChip->Registers.wwn_lo;
+ for( i =4; i<8; i++)
+ dest[i] = *bPtr++;


+ break;
+ }
+
+}
+
+

+
+// We check the Port Login payload for required values. Note that
+// ELS_PLOGI and ELS_PDISC (Port DISCover) use the same payload.
+
+
+int verify_PLOGI( PTACHYON fcChip,
+ TachFCHDR_GCMND* fchs,
+ ULONG* reject_explain)
+{
+ LOGIN_PAYLOAD login;
+
+ // source, dest, len (should be mult. of 4)
+ BigEndianSwap( (UCHAR*)&fchs->pl[0], (UCHAR*)&login, sizeof(login));
+
+ // check FC version
+ // if other port's highest supported version
+ // is less than our lowest, and
+ // if other port's lowest
+ if( login.cmn_services.highest_ver < fcChip->lowest_FCPH_ver ||
+ login.cmn_services.lowest_ver > fcChip->highest_FCPH_ver )
+ {
+ *reject_explain = LS_RJT_REASON( LOGICAL_ERROR, OPTIONS_ERROR);
+ return LOGICAL_ERROR;
+ }
+
+ // Receive Data Field Size must be >=128
+ // per FC-PH
+ if (login.cmn_services.bb_rx_size < 128)
+ {
+ *reject_explain = LS_RJT_REASON( LOGICAL_ERROR, DATA_FIELD_SIZE_ERROR);
+ return LOGICAL_ERROR;
+ }
+
+ // Only check Class 3 params
+ if( login.class3.service_options & CLASS_VALID)
+ {
+ if (login.class3.rx_data_size < 128)
+ {
+ *reject_explain = LS_RJT_REASON( LOGICAL_ERROR, INVALID_CSP);
+ return LOGICAL_ERROR;
+ }
+ if( login.class3.initiator_control & XID_REQUIRED)
+ {
+ *reject_explain = LS_RJT_REASON( LOGICAL_ERROR, INITIATOR_CTL_ERROR);
+ return LOGICAL_ERROR;
+ }
+ }
+ return 0; // success


+}
+
+
+
+

+int verify_PRLI( TachFCHDR_GCMND* fchs, ULONG* reject_explain)
+{
+ PRLI_REQUEST prli; // buffer for BIG ENDIAN
+
+ // source, dest, len (should be mult. of 4)
+ BigEndianSwap( (UCHAR*)&fchs->pl[0], (UCHAR*)&prli, sizeof(prli));
+
+ if( prli.fcp_info == 0 ) // i.e., not target or initiator?
+ {
+ *reject_explain = LS_RJT_REASON( LOGICAL_ERROR, OPTIONS_ERROR);
+ return LOGICAL_ERROR;
+ }
+
+ return 0; // success
+}
+
+
+// SWAP UCHARs as required by Fibre Channel (i.e. BIG ENDIAN)
+// INPUTS:
+// source - ptr to LITTLE ENDIAN ULONGS
+// cnt - number of UCHARs to switch (should be mult. of ULONG)
+// OUTPUTS:
+// dest - ptr to BIG ENDIAN copy
+// RETURN:
+// none
+//


+void BigEndianSwap( UCHAR *source, UCHAR *dest, USHORT cnt)

+{
+ int i,j;
+
+ source+=3; // start at MSB of 1st ULONG
+ for( j=0; j < cnt; j+=4, source+=4, dest+=4) // every ULONG
+ {
+ for( i=0; i<4; i++) // every UCHAR in ULONG
+ *(dest+i) = *(source-i);


+ }
+}
+
+
+
+

+// Build FC Exchanges............
+
+static void buildFCPstatus(
+ PTACHYON fcChip,
+ ULONG ExchangeID);
+
+static LONG FindFreeExchange( PTACHYON fcChip, ULONG type );
+
+static ULONG build_SEST_sgList(
+ ULONG *SESTalPairStart,
+ Scsi_Cmnd *Cmnd,
+ ULONG *sgPairs,
+ PSGPAGES sgPages // link list of TL Ext. S/G pages from O/S Pool
+);
+
+static int build_FCP_payload( Scsi_Cmnd *Cmnd,
+ UCHAR* payload, ULONG type, ULONG fcp_dl );
+
+
+/*
+ IRB
+ ERQ __________________
+ | | / | Req_A_SFS_Len | ____________________
+ |----------| / | Req_A_SFS_Addr |------->| Reserved |
+ | IRB | / | Req_A_D_ID | | SOF EOF TimeStamp |
+ |-----------/ | Req_A_SEST_Index |-+ | R_CTL | D_ID |
+ | IRB | | Req_B... | | | CS_CTL| S_ID |
+ |-----------\ | | | | TYPE | F_CTL |
+ | IRB | \ | | | | SEQ_ID | SEQ_CNT |
+ |----------- \ | | +-->+--| OX_ID | RX_ID |
+ | | \ |__________________| | | RO |
+ | | pl (payload/cmnd) |
+ | | ..... |
+ | |___________________|
+ |
+ |
++-------------------------------------------+
+|
+|
+| e.g. IWE
+| SEST __________________ for FCP_DATA
+| | | / | | Hdr_Len | ____________________
+| |----------| / | Hdr_Addr_Addr |------->| Reserved |
+| | [0] | / |Remote_ID| RSP_Len| | SOF EOF TimeStamp |
+| |-----------/ | RSP_Addr |---+ | R_CTL | D_ID |
++-> [1] | | | Buff_Off | | | CS_CTL| S_ID |
+ |-----------\ |BuffIndex| Link | | | TYPE | F_CTL |
+ | [2] | \ | Rsvd | RX_ID | | | SEQ_ID | SEQ_CNT |
+ |----------- \ | Data_Len | | | OX_ID | RX_ID |
+ | ... | \ | Exp_RO | | | RO |
+ |----------| | Exp_Byte_Cnt | | |___________________|
+ | SEST_LEN | +--| Len | |
+ |__________| | | Address | |
+ | | ... | | for FCP_RSP
+ | |__________________| | ____________________
+ | +----| Reserved |
+ | | SOF EOF TimeStamp |
+ | | R_CTL | D_ID |
+ | | CS_CTL| S_ID |
+ +--- local or extended | .... |
+ scatter/gather lists
+ defining upper-layer
+ data (e.g. from user's App)
+
+
+*/
+// All TachLite commands must start with a SFS (Single Frame Sequence)
+// command. In the simplest case (a NOP Basic Link command),
+// only one frame header and ERQ entry is required. The most complex
+// case is the SCSI assisted command, which requires an ERQ entry,
+// SEST entry, and several frame headers and data buffers all
+// logically linked together.
+// Inputs:
+// cpqfcHBAdata - controller struct
+// type - PLOGI, SCSI_IWE, etc.
+// InFCHS - Incoming Tachlite FCHS which prompted this exchange
+// (only s_id set if we are originating)
+// Data - PVOID to data struct consistent with "type"
+// fcExchangeIndex - pointer to OX/RD ID value of built exchange
+// Return:
+// fcExchangeIndex - OX/RD ID value if successful
+// 0 - success
+// INVALID_ARGS - NULL/ invalid passed args
+// BAD_ALPA - Bad source al_pa address
+// LNKDWN_OSLS - Link Down (according to this controller)
+// OUTQUE_FULL - Outbound Que full
+// DRIVERQ_FULL - controller's Exchange array full
+// SEST_FULL - SEST table full
+//
+// Remarks:
+// Psuedo code:
+// Check for NULL pointers / bad args
+// Build outgoing FCHS - the header/payload struct
+// Build IRB (for ERQ entry)
+// if SCSI command, build SEST entry (e.g. IWE, TRE,...)
+// return success
+
+//sbuildex
+ULONG cpqfcTSBuildExchange(
+ CPQFCHBA *cpqfcHBAdata,


+ ULONG type, // e.g. PLOGI
+ TachFCHDR_GCMND* InFCHS, // incoming FCHS
+ void *Data, // the CDB, scatter/gather, etc.

+ LONG *fcExchangeIndex ) // points to allocated exchange,

+{
+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;
+ FC_EXCHANGES *Exchanges = fcChip->Exchanges;

+ ULONG ulStatus = 0; // assume OK
+ USHORT ox_ID, rx_ID=0xFFFF;
+ ULONG SfsLen=0L;
+ TachLiteIRB* pIRB;
+ IRBflags IRB_flags;
+ UCHAR *pIRB_flags = (UCHAR*)&IRB_flags;
+ TachFCHDR_GCMND* CMDfchs;
+ TachFCHDR* dataHDR; // 32 byte HEADER ONLY FCP-DATA buffer
+ TachFCHDR_RSP* rspHDR; // 32 byte header + RSP payload
+ Scsi_Cmnd *Cmnd = (Scsi_Cmnd*)Data; // Linux Scsi CDB, S/G, ...
+ TachLiteIWE* pIWE;
+ TachLiteIRE* pIRE;
+ TachLiteTWE* pTWE;
+ TachLiteTRE* pTRE;
+ ULONG fcp_dl; // total byte length of DATA transfered
+ ULONG fl; // frame length (FC frame size, 128, 256, 512, 1024)
+ ULONG sgPairs; // number of valid scatter/gather pairs
+ int FCP_SCSI_command;
+ BA_ACC_PAYLOAD *ba_acc;
+ BA_RJT_PAYLOAD *ba_rjt;
+
+ // check passed ARGS
+ if( !fcChip->ERQ ) // NULL ptr means uninitialized Tachlite chip
+ return INVALID_ARGS;
+
+
+ if( type == SCSI_IRE ||
+ type == SCSI_TRE ||
+ type == SCSI_IWE ||
+ type == SCSI_TWE)
+ FCP_SCSI_command = 1;
+
+ else
+ FCP_SCSI_command = 0;
+
+
+ // for commands that pass payload data (e.g. SCSI write)
+ // examine command struct - verify that the
+ // length of s/g buffers is adequate for total payload
+ // length (end of list is NULL address)
+
+ if( FCP_SCSI_command )
+ {
+ if( Data ) // must have data descriptor (S/G list -- at least
+ // one address with at least 1 byte of data)
+ {
+ // something to do (later)?
+ }
+
+ else
+ return INVALID_ARGS; // invalid DATA ptr
+ }
+
+
+
+ // we can build an Exchange for later Queuing (on the TL chip)
+ // if an empty slot is available in the DevExt for this controller
+ // look for available Exchange slot...
+
+ if( type != FCP_RESPONSE &&
+ type != BLS_ABTS &&
+ type != BLS_ABTS_ACC ) // already have Exchange slot!
+ *fcExchangeIndex = FindFreeExchange( fcChip, type );
+
+ if( *fcExchangeIndex != -1 ) // Exchange is available?
+ {
+ // assign tmp ptr (shorthand)
+ CMDfchs = &Exchanges->fcExchange[ *fcExchangeIndex].fchs;
+
+
+ if( Cmnd != NULL ) // (necessary for ABTS cases)
+ {
+ Exchanges->fcExchange[ *fcExchangeIndex].Cmnd = Cmnd; // Linux Scsi
+ Exchanges->fcExchange[ *fcExchangeIndex].pLoggedInPort =
+ fcFindLoggedInPort( fcChip,
+ Exchanges->fcExchange[ *fcExchangeIndex].Cmnd, // find Scsi Nexus


+ 0, // DON'T search linked list for FC port id
+ NULL, // DON'T search linked list for FC WWN
+ NULL); // DON'T care about end of list
+
+ }

+
+
+ // Build the command frame header (& data) according
+ // to command type
+
+ // fields common for all SFS frame types
+ CMDfchs->reserved = 0L; // must clear
+ CMDfchs->sof_eof = 0x75000000L; // SOFi3:EOFn no UAM; LCr=0, no TS
+
+ // get the destination port_id from incoming FCHS
+ // (initialized before calling if we're Originator)
+ // Frame goes to port it was from - the source_id
+
+ CMDfchs->d_id = InFCHS->s_id &0xFFFFFF; // destination (add R_CTL later)
+ CMDfchs->s_id = fcChip->Registers.my_al_pa; // CS_CTL = 0
+
+
+ // now enter command-specific fields
+ switch( type )
+ {
+
+ case BLS_NOP: // FC defined basic link service command NO-OP
+ // ensure unique X_IDs! (use tracking function)
+
+ *pIRB_flags = 0; // clear IRB flags
+ IRB_flags.SFA = 1; // send SFS (not SEST index)
+ SfsLen = *pIRB_flags;
+
+ SfsLen <<= 24; // shift flags to MSB
+ SfsLen += 32L; // add len to LSB (header only - no payload)
+
+ // TYPE[31-24] 00 Basic Link Service
+ // f_ctl[23:0] exchg originator, 1st seq, xfer S.I.
+ CMDfchs->d_id |= 0x80000000L; // R_CTL = 80 for NOP (Basic Link Ser.)
+ CMDfchs->f_ctl = 0x00310000L; // xchng originator, 1st seq,....
+ CMDfchs->seq_cnt = 0x0L;
+ CMDfchs->ox_rx_id = 0xFFFF; // RX_ID for now; OX_ID on start
+ CMDfchs->ro = 0x0L; // relative offset (n/a)
+ CMDfchs->pl[0] = 0xaabbccddL; // words 8-15 frame data payload (n/a)
+ Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 1; // seconds
+ // (NOP should complete ~instantly)


+ break;
+
+
+
+

+ case BLS_ABTS_ACC: // Abort Sequence ACCept
+ *pIRB_flags = 0; // clear IRB flags
+ IRB_flags.SFA = 1; // send SFS (not SEST index)
+ SfsLen = *pIRB_flags;
+
+ SfsLen <<= 24; // shift flags to MSB
+ SfsLen += 32 + 12; // add len to LSB (header + 3 DWORD payload)
+
+ CMDfchs->d_id |= 0x84000000L; // R_CTL = 84 for BASIC ACCept
+ // TYPE[31-24] 00 Basic Link Service
+ // f_ctl[23:0] exchg originator, not 1st seq, xfer S.I.
+ CMDfchs->f_ctl = 0x00910000L; // xchnge responder, last seq, xfer SI
+ // CMDfchs->seq_id & count might be set from DataHdr?
+ CMDfchs->ro = 0x0L; // relative offset (n/a)
+ Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 5; // seconds
+ // (Timeout in case of weird error)
+
+ // now set the ACCept payload...
+ ba_acc = (BA_ACC_PAYLOAD*)&CMDfchs->pl[0];
+ memset( ba_acc, 0, sizeof( BA_ACC_PAYLOAD));
+ // Since PLDA requires (only) entire Exchange aborts, we don't need
+ // to worry about what the last sequence was.
+
+ // We expect that a "target" task is accepting the abort, so we
+ // can use the OX/RX ID pair
+ ba_acc->ox_rx_id = CMDfchs->ox_rx_id;
+
+ // source, dest, #bytes
+ BigEndianSwap((UCHAR *)&CMDfchs->ox_rx_id, (UCHAR *)&ba_acc->ox_rx_id, 4);
+
+ ba_acc->low_seq_cnt = 0;
+ ba_acc->high_seq_cnt = 0xFFFF;


+
+
+ break;
+
+

+ case BLS_ABTS_RJT: // Abort Sequence ACCept
+ *pIRB_flags = 0; // clear IRB flags
+ IRB_flags.SFA = 1; // send SFS (not SEST index)
+ SfsLen = *pIRB_flags;
+
+ SfsLen <<= 24; // shift flags to MSB
+ SfsLen += 32 + 12; // add len to LSB (header + 3 DWORD payload)
+
+ CMDfchs->d_id |= 0x85000000L; // R_CTL = 85 for BASIC ReJecT
+ // f_ctl[23:0] exchg originator, not 1st seq, xfer S.I.
+ // TYPE[31-24] 00 Basic Link Service
+ CMDfchs->f_ctl = 0x00910000L; // xchnge responder, last seq, xfer SI
+ // CMDfchs->seq_id & count might be set from DataHdr?
+ CMDfchs->ro = 0x0L; // relative offset (n/a)
+ Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 5; // seconds
+ // (Timeout in case of weird error)
+
+ CMDfchs->ox_rx_id = InFCHS->ox_rx_id; // copy from sender!
+
+ // now set the ReJecT payload...
+ ba_rjt = (BA_RJT_PAYLOAD*)&CMDfchs->pl[0];
+ memset( ba_rjt, 0, sizeof( BA_RJT_PAYLOAD));
+
+ // We expect that a "target" task couldn't find the Exhange in the
+ // array of active exchanges, so we use a new LinkService X_ID.
+ // See Reject payload description in FC-PH (Rev 4.3), pg. 140
+ ba_rjt->reason_code = 0x09; // "unable to perform command request"
+ ba_rjt->reason_explain = 0x03; // invalid OX/RX ID pair


+
+
+ break;
+
+
+

+ case BLS_ABTS: // FC defined basic link service command ABTS
+ // Abort Sequence
+
+
+ *pIRB_flags = 0; // clear IRB flags
+ IRB_flags.SFA = 1; // send SFS (not SEST index)
+ SfsLen = *pIRB_flags;
+
+ SfsLen <<= 24; // shift flags to MSB
+ SfsLen += 32L; // add len to LSB (header only - no payload)
+
+ // TYPE[31-24] 00 Basic Link Service
+ // f_ctl[23:0] exchg originator, not 1st seq, xfer S.I.
+ CMDfchs->d_id |= 0x81000000L; // R_CTL = 81 for ABTS
+ CMDfchs->f_ctl = 0x00110000L; // xchnge originator, last seq, xfer SI
+ // CMDfchs->seq_id & count might be set from DataHdr?
+ CMDfchs->ro = 0x0L; // relative offset (n/a)
+ Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 2; // seconds
+ // (ABTS must timeout when responder is gone)


+ break;
+
+
+

+ case FCS_NSR: // Fabric Name Service Request
+ Exchanges->fcExchange[ *fcExchangeIndex].reTries = 2;
+
+
+ Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 2; // seconds
+ // OX_ID, linked to Driver Transaction ID
+ // (fix-up at Queing time)
+ CMDfchs->ox_rx_id = 0xFFFF; // RX_ID - Responder (target) to modify
+ // OX_ID set at ERQueing time
+ *pIRB_flags = 0; // clear IRB flags
+ IRB_flags.SFA = 1; // send SFS (not SEST index)
+ SfsLen = *pIRB_flags;
+
+ SfsLen <<= 24; // shift flags to MSB
+ SfsLen += (32L + sizeof(NSR_PL)); // add len (header & NSR payload)
+
+ CMDfchs->d_id |= 0x02000000L; // R_CTL = 02 for -
+ // Name Service Request: Unsolicited
+ // TYPE[31-24] 01 Extended Link Service
+ // f_ctl[23:0] exchg originator, 1st seq, xfer S.I.
+ CMDfchs->f_ctl = 0x20210000L;
+ // OX_ID will be fixed-up at Tachyon enqueing time
+ CMDfchs->seq_cnt = 0; // seq ID, DF_ctl, seq cnt
+ CMDfchs->ro = 0x0L; // relative offset (n/a)
+
+ BuildLinkServicePayload( fcChip, type, &CMDfchs->pl[0]);


+
+
+
+
+
+

+ break;
+
+
+
+

+ case ELS_PLOGI: // FC-PH extended link service command Port Login
+ // (May, 2000)
+ // NOTE! This special case facilitates SANMark testing. The SANMark
+ // test script for initialization-timeout.fcal.SANMark-1.fc
+ // "eats" the OPN() primitive without issuing an R_RDY, causing
+ // Tachyon to report LST (loop state timeout), which causes a
+ // LIP. To avoid this, simply send out the frame (i.e. assuming a
+ // buffer credit of 1) without waiting for R_RDY. Many FC devices
+ // (other than Tachyon) have been doing this for years. We don't
+ // ever want to do this for non-Link Service frames unless the
+ // other device really did report non-zero login BB credit (i.e.
+ // in the PLOGI ACCept frame).
+// CMDfchs->sof_eof |= 0x00000400L; // LCr=1
+
+ case ELS_FDISC: // Fabric Discovery (Login)
+ case ELS_FLOGI: // Fabric Login
+ case ELS_SCR: // Fabric State Change Registration
+ case ELS_LOGO: // FC-PH extended link service command Port Logout
+ case ELS_PDISC: // FC-PH extended link service cmnd Port Discovery
+ case ELS_PRLI: // FC-PH extended link service cmnd Process Login
+
+ Exchanges->fcExchange[ *fcExchangeIndex].reTries = 2;
+
+
+ Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 2; // seconds
+ // OX_ID, linked to Driver Transaction ID
+ // (fix-up at Queing time)
+ CMDfchs->ox_rx_id = 0xFFFF; // RX_ID - Responder (target) to modify
+ // OX_ID set at ERQueing time
+ *pIRB_flags = 0; // clear IRB flags
+ IRB_flags.SFA = 1; // send SFS (not SEST index)
+ SfsLen = *pIRB_flags;
+
+ SfsLen <<= 24; // shift flags to MSB
+ if( type == ELS_LOGO )
+ SfsLen += (32L + 16L); // add len (header & PLOGI payload)
+ else if( type == ELS_PRLI )
+ SfsLen += (32L + 20L); // add len (header & PRLI payload)
+ else if( type == ELS_SCR )
+ SfsLen += (32L + sizeof(SCR_PL)); // add len (header & SCR payload)
+ else
+ SfsLen += (32L + 116L); // add len (header & PLOGI payload)
+
+ CMDfchs->d_id |= 0x22000000L; // R_CTL = 22 for -
+ // Extended Link_Data: Unsolicited Control
+ // TYPE[31-24] 01 Extended Link Service
+ // f_ctl[23:0] exchg originator, 1st seq, xfer S.I.
+ CMDfchs->f_ctl = 0x01210000L;
+ // OX_ID will be fixed-up at Tachyon enqueing time
+ CMDfchs->seq_cnt = 0; // seq ID, DF_ctl, seq cnt
+ CMDfchs->ro = 0x0L; // relative offset (n/a)
+
+ BuildLinkServicePayload( fcChip, type, &CMDfchs->pl[0]);


+
+ break;
+
+

+
+ case ELS_LOGO_ACC: // FC-PH extended link service logout accept
+ case ELS_RJT: // extended link service reject (add reason)
+ case ELS_ACC: // ext. link service generic accept
+ case ELS_PLOGI_ACC:// ext. link service login accept (PLOGI or PDISC)
+ case ELS_PRLI_ACC: // ext. link service process login accept
+
+
+ Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 1; // assume done
+ // ensure unique X_IDs! (use tracking function)
+ // OX_ID from initiator cmd
+ ox_ID = (USHORT)(InFCHS->ox_rx_id >> 16);
+ rx_ID = 0xFFFF; // RX_ID, linked to Driver Exchange ID
+
+ *pIRB_flags = 0; // clear IRB flags
+ IRB_flags.SFA = 1; // send SFS (not SEST index)
+ SfsLen = *pIRB_flags;
+
+ SfsLen <<= 24; // shift flags to MSB
+ if( type == ELS_RJT )
+ {
+ SfsLen += (32L + 8L); // add len (header + payload)
+
+ // ELS_RJT reason codes (utilize unused "reserved" field)
+ CMDfchs->pl[0] = 1;
+ CMDfchs->pl[1] = InFCHS->reserved;
+
+ }
+ else if( (type == ELS_LOGO_ACC) || (type == ELS_ACC) )
+ SfsLen += (32L + 4L); // add len (header + payload)
+ else if( type == ELS_PLOGI_ACC )
+ SfsLen += (32L + 116L); // add len (header + payload)
+ else if( type == ELS_PRLI_ACC )
+ SfsLen += (32L + 20L); // add len (header + payload)
+
+ CMDfchs->d_id |= 0x23000000L; // R_CTL = 23 for -
+ // Extended Link_Data: Control Reply
+ // TYPE[31-24] 01 Extended Link Service
+ // f_ctl[23:0] exchg responder, last seq, e_s, tsi
+ CMDfchs->f_ctl = 0x01990000L;
+ CMDfchs->seq_cnt = 0x0L;
+ CMDfchs->ox_rx_id = 0L; // clear
+ CMDfchs->ox_rx_id = ox_ID; // load upper 16 bits
+ CMDfchs->ox_rx_id <<= 16; // shift them
+
+ CMDfchs->ro = 0x0L; // relative offset (n/a)
+
+ BuildLinkServicePayload( fcChip, type, &CMDfchs->pl[0]);


+
+ break;
+
+

+ // Fibre Channel SCSI 'originator' sequences...
+ // (originator means 'initiator' in FCP-SCSI)
+ case SCSI_IWE: // TachLite Initiator Write Entry


+ {
+ PFC_LOGGEDIN_PORT pLoggedInPort =

+ Exchanges->fcExchange[ *fcExchangeIndex].pLoggedInPort;
+
+ Exchanges->fcExchange[ *fcExchangeIndex].reTries = 1;
+ Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 7; // FC2 timeout
+
+ // first, build FCP_CMND
+ // unique X_ID fix-ups in StartExchange
+
+ *pIRB_flags = 0; // clear IRB flags
+ IRB_flags.SFA = 1; // send SFS FCP-CMND (not SEST index)
+
+ // NOTE: unlike FC LinkService login frames, normal
+ // SCSI commands are sent without outgoing verification
+ IRB_flags.DCM = 1; // Disable completion message for Cmnd frame
+ SfsLen = *pIRB_flags;
+
+ SfsLen <<= 24; // shift flags to MSB
+ SfsLen += 64L; // add len to LSB (header & CMND payload)
+
+ CMDfchs->d_id |= (0x06000000L); // R_CTL = 6 for command
+
+ // TYPE[31-24] 8 for FCP SCSI
+ // f_ctl[23:0] exchg originator, 1st seq, xfer S.I.
+ // valid RO
+ CMDfchs->f_ctl = 0x08210008L;
+ CMDfchs->seq_cnt = 0x0L;
+ CMDfchs->ox_rx_id = 0L; // clear for now (-or- in later)
+ CMDfchs->ro = 0x0L; // relative offset (n/a)
+
+ // now, fill out FCP-DATA header
+ // (use buffer inside SEST object)
+ dataHDR = &fcChip->SEST->DataHDR[ *fcExchangeIndex ];
+ dataHDR->reserved = 0L; // must clear
+ dataHDR->sof_eof = 0x75002000L; // SOFi3:EOFn no UAM; no CLS, noLCr, no TS
+ dataHDR->d_id = (InFCHS->s_id | 0x01000000L); // R_CTL= FCP_DATA
+ dataHDR->s_id = fcChip->Registers.my_al_pa; // CS_CTL = 0
+ // TYPE[31-24] 8 for FCP SCSI
+ // f_ctl[23:0] xfer S.I.| valid RO
+ dataHDR->f_ctl = 0x08010008L;
+ dataHDR->seq_cnt = 0x02000000L; // sequence ID: df_ctl : seqence count
+ dataHDR->ox_rx_id = 0L; // clear; fix-up dataHDR fields later
+ dataHDR->ro = 0x0L; // relative offset (n/a)
+
+ // Now setup the SEST entry
+ pIWE = &fcChip->SEST->u[ *fcExchangeIndex ].IWE;
+
+ // fill out the IWE:
+
+ // VALid entry:Dir outbound:DCM:enable CM:enal INT: FC frame len
+ pIWE->Hdr_Len = 0x8e000020L; // data frame Len always 32 bytes
+
+
+ // from login parameters with other port, what's the largest frame
+ // we can send?

+ if( pLoggedInPort == NULL)

+ {
+ ulStatus = INVALID_ARGS; // failed! give up
+ break;
+ }
+ if( pLoggedInPort->rx_data_size >= 2048)
+ fl = 0x00020000; // 2048 code (only support 1024!)
+ else if( pLoggedInPort->rx_data_size >= 1024)
+ fl = 0x00020000; // 1024 code
+ else if( pLoggedInPort->rx_data_size >= 512)
+ fl = 0x00010000; // 512 code
+ else
+ fl = 0; // 128 bytes -- should never happen
+
+
+ pIWE->Hdr_Len |= fl; // add xmit FC frame len for data phase
+ pIWE->Hdr_Addr = virt_to_bus( dataHDR );
+ pIWE->RSP_Len = sizeof(TachFCHDR_RSP) ; // hdr+data (recv'd RSP frame)
+ pIWE->RSP_Len |= (InFCHS->s_id << 8); // MS 24 bits Remote_ID
+
+ memset( &fcChip->SEST->RspHDR[ *fcExchangeIndex].pl, 0,
+ sizeof( FCP_STATUS_RESPONSE) ); // clear out previous status
+
+ pIWE->RSP_Addr = virt_to_bus(
+ &fcChip->SEST->RspHDR[ *fcExchangeIndex ]);
+
+ // Do we need local or extended gather list?
+ // depends on size - we can handle 3 len/addr pairs
+ // locally.
+
+ fcp_dl = build_SEST_sgList(
+ &pIWE->GLen1,
+ Cmnd, // S/G list
+ &sgPairs, // return # of pairs in S/G list (from "Data" descriptor)
+ &fcChip->SEST->sgPages[ *fcExchangeIndex ]);// (for Freeing later)
+
+ if( !fcp_dl ) // error building S/G list?
+ {
+ ulStatus = MEMPOOL_FAIL;
+ break; // give up
+ }
+
+ // Now that we know total data length in
+ // the passed S/G buffer, set FCP CMND frame
+ build_FCP_payload( Cmnd, (UCHAR*)&CMDfchs->pl[0], type, fcp_dl );
+
+
+
+ if( sgPairs > 3 ) // need extended s/g list
+ pIWE->Buff_Off = 0x78000000L; // extended data | (no offset)
+ else // local data pointers (in SEST)
+ pIWE->Buff_Off = 0xf8000000L; // local data | (no offset)
+
+ // ULONG 5
+ pIWE->Link = 0x0000ffffL; // Buff_Index | Link
+
+ pIWE->RX_ID = 0x0L; // DWord 6: RX_ID set by target XFER_RDY
+
+ // DWord 7
+ pIWE->Data_Len = 0L; // TL enters rcv'd XFER_RDY BURST_LEN
+ pIWE->Exp_RO = 0L; // DWord 8
+ // DWord 9
+ pIWE->Exp_Byte_Cnt = fcp_dl; // sum of gather buffers


+ }
+ break;
+
+
+
+
+

+ case SCSI_IRE: // TachLite Initiator Read Entry
+
+ if( Cmnd->timeout != 0)
+ {
+// printk("Cmnd->timeout %d\n", Cmnd->timeout);
+ // per Linux Scsi
+ Exchanges->fcExchange[ *fcExchangeIndex].timeOut = Cmnd->timeout;
+ }
+ else // use our best guess, based on FC & device
+ {
+
+ if( Cmnd->SCp.Message == 1 ) // Tape device? (from INQUIRY)
+ {
+ // turn off our timeouts (for now...)
+ Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 0xFFFFFFFF;
+ }
+ else
+ {
+ Exchanges->fcExchange[ *fcExchangeIndex].reTries = 1;
+ Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 7; // per SCSI req.
+ }
+ }
+
+
+ // first, build FCP_CMND
+
+
+ *pIRB_flags = 0; // clear IRB flags
+ IRB_flags.SFA = 1; // send SFS FCP-CMND (not SEST index)
+ // NOTE: unlike FC LinkService login frames,
+ // normal SCSI commands are sent "open loop"
+ IRB_flags.DCM = 1; // Disable completion message for Cmnd frame
+ SfsLen = *pIRB_flags;
+
+ SfsLen <<= 24; // shift flags to MSB
+ SfsLen += 64L; // add len to LSB (header & CMND payload)
+
+ CMDfchs->d_id |= (0x06000000L); // R_CTL = 6 for command
+
+ // TYPE[31-24] 8 for FCP SCSI
+ // f_ctl[23:0] exchg originator, 1st seq, xfer S.I.
+ // valid RO
+ CMDfchs->f_ctl = 0x08210008L;
+ CMDfchs->seq_cnt = 0x0L;
+ // x_ID & data direction bit set later
+ CMDfchs->ox_rx_id = 0xFFFF; // clear
+ CMDfchs->ro = 0x0L; // relative offset (n/a)
+
+
+
+ // Now setup the SEST entry
+ pIRE = &fcChip->SEST->u[ *fcExchangeIndex ].IRE;
+
+ // fill out the IRE:
+ // VALid entry:Dir outbound:enable CM:enal INT:
+ pIRE->Seq_Accum = 0xCE000000L; // VAL,DIR inbound,DCM| INI,DAT,RSP
+
+ pIRE->reserved = 0L;
+ pIRE->RSP_Len = sizeof(TachFCHDR_RSP) ; // hdr+data (recv'd RSP frame)
+ pIRE->RSP_Len |= (InFCHS->s_id << 8); // MS 24 bits Remote_ID
+
+
+ pIRE->RSP_Addr = virt_to_bus(
+ &fcChip->SEST->RspHDR[ *fcExchangeIndex ]);
+
+
+ // Do we need local or extended gather list?
+ // depends on size - we can handle 3 len/addr pairs
+ // locally.
+
+ fcp_dl = build_SEST_sgList(
+ &pIRE->SLen1,
+ Cmnd, // SCSI command Data desc. with S/G list
+ &sgPairs, // return # of pairs in S/G list (from "Data" descriptor)
+ &fcChip->SEST->sgPages[ *fcExchangeIndex ]);// (for Freeing later)
+
+
+ if( !fcp_dl ) // error building S/G list?
+ {
+ // It is permissible to have a ZERO LENGTH Read command.
+ // If there is the case, simply set fcp_dl (and Exp_Byte_Cnt)
+ // to 0 and continue.
+ if( Cmnd->request_bufflen == 0 )
+ {
+ fcp_dl = 0; // no FC DATA frames expected


+
+ }
+ else
+ {

+ ulStatus = MEMPOOL_FAIL;
+ break; // give up
+ }
+ }
+
+ // now that we know the S/G length, build CMND payload
+ build_FCP_payload( Cmnd, (UCHAR*)&CMDfchs->pl[0], type, fcp_dl );
+
+
+ if( sgPairs > 3 ) // need extended s/g list
+ pIRE->Buff_Off = 0x00000000; // DWord 4: extended s/g list, no offset
+ else
+ pIRE->Buff_Off = 0x80000000; // local data, no offset
+
+ pIRE->Buff_Index = 0x0L; // DWord 5: Buff_Index | Reserved
+
+ pIRE->Exp_RO = 0x0L; // DWord 6: Expected Rel. Offset
+
+ pIRE->Byte_Count = 0; // DWord 7: filled in by TL on err
+ pIRE->reserved_ = 0; // DWord 8: reserved
+ // NOTE: 0 length READ is OK.
+ pIRE->Exp_Byte_Cnt = fcp_dl;// DWord 9: sum of scatter buffers


+
+ break;
+
+
+
+

+ // Fibre Channel SCSI 'responder' sequences...
+ // (originator means 'target' in FCP-SCSI)
+ case SCSI_TWE: // TachLite Target Write Entry
+
+ Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 10; // per SCSI req.
+
+ // first, build FCP_CMND
+
+ *pIRB_flags = 0; // clear IRB flags
+ IRB_flags.SFA = 1; // send SFS (XFER_RDY)
+ SfsLen = *pIRB_flags;
+
+ SfsLen <<= 24; // shift flags to MSB
+ SfsLen += (32L + 12L);// add SFS len (header & XFER_RDY payload)
+
+ CMDfchs->d_id |= (0x05000000L); // R_CTL = 5 for XFER_RDY
+
+ // TYPE[31-24] 8 for FCP SCSI
+ // f_ctl[23:0] exchg responder, 1st seq, xfer S.I.
+ // valid RO
+ CMDfchs->f_ctl = 0x08810008L;
+ CMDfchs->seq_cnt = 0x01000000; // sequence ID: df_ctl: sequence count
+ // use originator (other port's) OX_ID
+ CMDfchs->ox_rx_id = InFCHS->ox_rx_id; // we want upper 16 bits
+ CMDfchs->ro = 0x0L; // relative offset (n/a)
+
+ // now, fill out FCP-RSP header
+ // (use buffer inside SEST object)
+
+ rspHDR = &fcChip->SEST->RspHDR[ *fcExchangeIndex ];
+ rspHDR->reserved = 0L; // must clear
+ rspHDR->sof_eof = 0x75000000L; // SOFi3:EOFn no UAM; no CLS, noLCr, no TS
+ rspHDR->d_id = (InFCHS->s_id | 0x07000000L); // R_CTL= FCP_RSP
+ rspHDR->s_id = fcChip->Registers.my_al_pa; // CS_CTL = 0
+ // TYPE[31-24] 8 for FCP SCSI
+ // f_ctl[23:0] responder|last seq| xfer S.I.
+ rspHDR->f_ctl = 0x08910000L;
+ rspHDR->seq_cnt = 0x03000000; // sequence ID
+ rspHDR->ox_rx_id = InFCHS->ox_rx_id; // gives us OX_ID
+ rspHDR->ro = 0x0L; // relative offset (n/a)
+
+
+ // Now setup the SEST entry
+
+ pTWE = &fcChip->SEST->u[ *fcExchangeIndex ].TWE;
+
+ // fill out the TWE:
+
+ // VALid entry:Dir outbound:enable CM:enal INT:
+ pTWE->Seq_Accum = 0xC4000000L; // upper word flags
+ pTWE->reserved = 0L;
+ pTWE->Remote_Node_ID = 0L; // no more auto RSP frame! (TL/TS change)
+ pTWE->Remote_Node_ID |= (InFCHS->s_id << 8); // MS 24 bits Remote_ID
+
+
+ // Do we need local or extended gather list?
+ // depends on size - we can handle 3 len/addr pairs
+ // locally.
+
+ fcp_dl = build_SEST_sgList(
+ &pTWE->SLen1,
+ Cmnd, // S/G list
+ &sgPairs, // return # of pairs in S/G list (from "Data" descriptor)
+ &fcChip->SEST->sgPages[ *fcExchangeIndex ]);// (for Freeing later)
+
+
+ if( !fcp_dl ) // error building S/G list?
+ {
+ ulStatus = MEMPOOL_FAIL;
+ break; // give up
+ }
+
+ // now that we know the S/G length, build CMND payload
+ build_FCP_payload( Cmnd, (UCHAR*)&CMDfchs->pl[0], type, fcp_dl );
+
+
+ if( sgPairs > 3 ) // need extended s/g list
+ pTWE->Buff_Off = 0x00000000; // extended s/g list, no offset
+ else
+ pTWE->Buff_Off = 0x80000000; // local data, no offset
+
+ pTWE->Buff_Index = 0; // Buff_Index | Link
+ pTWE->Exp_RO = 0;
+ pTWE->Byte_Count = 0; // filled in by TL on err
+ pTWE->reserved_ = 0;
+ pTWE->Exp_Byte_Cnt = fcp_dl;// sum of scatter buffers


+
+ break;
+
+
+
+
+

+
+ case SCSI_TRE: // TachLite Target Read Entry
+
+ // It doesn't make much sense for us to "time-out" a READ,
+ // but we'll use it for design consistency and internal error recovery.
+ Exchanges->fcExchange[ *fcExchangeIndex].timeOut = 10; // per SCSI req.
+
+ // I/O request block settings...
+ *pIRB_flags = 0; // clear IRB flags
+ // check PRLI (process login) info
+ // to see if Initiator Requires XFER_RDY
+ // if not, don't send one!
+ // { PRLI check...}
+ IRB_flags.SFA = 0; // don't send XFER_RDY - start data
+ SfsLen = *pIRB_flags;
+
+ SfsLen <<= 24; // shift flags to MSB
+ SfsLen += (32L + 12L);// add SFS len (header & XFER_RDY payload)
+
+
+
+ // now, fill out FCP-DATA header


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 077'
echo 'File patch-2.4.0-test9 is continued in part 078'
echo "078" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part078

#!/bin/sh -x
# this is part 078 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 078; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ // (use buffer inside SEST object)
+ dataHDR = &fcChip->SEST->DataHDR[ *fcExchangeIndex ];
+
+ dataHDR->reserved = 0L; // must clear

+ dataHDR->sof_eof = 0x75000000L; // SOFi3:EOFn no UAM; no CLS,noLCr,no TS


+ dataHDR->d_id = (InFCHS->s_id | 0x01000000L); // R_CTL= FCP_DATA
+ dataHDR->s_id = fcChip->Registers.my_al_pa; // CS_CTL = 0
+

+
+ // TYPE[31-24] 8 for FCP SCSI

+ // f_ctl[23:0] exchg responder, not 1st seq, xfer S.I.
+ // valid RO
+ dataHDR->f_ctl = 0x08810008L;
+ dataHDR->seq_cnt = 0x01000000; // sequence ID (no XRDY)
+ dataHDR->ox_rx_id = InFCHS->ox_rx_id & 0xFFFF0000; // we want upper 16 bits


+ dataHDR->ro = 0x0L; // relative offset (n/a)
+

+ // now, fill out FCP-RSP header
+ // (use buffer inside SEST object)
+ rspHDR = &fcChip->SEST->RspHDR[ *fcExchangeIndex ];
+
+ rspHDR->reserved = 0L; // must clear
+ rspHDR->sof_eof = 0x75000000L; // SOFi3:EOFn no UAM; no CLS, noLCr, no TS
+ rspHDR->d_id = (InFCHS->s_id | 0x07000000L); // R_CTL= FCP_RSP
+ rspHDR->s_id = fcChip->Registers.my_al_pa; // CS_CTL = 0
+ // TYPE[31-24] 8 for FCP SCSI
+ // f_ctl[23:0] responder|last seq| xfer S.I.
+ rspHDR->f_ctl = 0x08910000L;

+ rspHDR->seq_cnt = 0x02000000; // sequence ID: df_ctl: sequence count
+


+ rspHDR->ro = 0x0L; // relative offset (n/a)
+
+
+ // Now setup the SEST entry

+ pTRE = &fcChip->SEST->u[ *fcExchangeIndex ].TRE;
+


+
+ // VALid entry:Dir outbound:enable CM:enal INT:

+ pTRE->Hdr_Len = 0x86010020L; // data frame Len always 32 bytes
+ pTRE->Hdr_Addr = virt_to_bus( dataHDR );
+ pTRE->RSP_Len = 64L; // hdr+data (TL assisted RSP frame)
+ pTRE->RSP_Len |= (InFCHS->s_id << 8); // MS 24 bits Remote_ID
+ pTRE->RSP_Addr = virt_to_bus( rspHDR );


+
+
+ // Do we need local or extended gather list?
+ // depends on size - we can handle 3 len/addr pairs
+ // locally.
+
+ fcp_dl = build_SEST_sgList(

+ &pTRE->GLen1,

+ Cmnd, // S/G list
+ &sgPairs, // return # of pairs in S/G list (from "Data" descriptor)
+ &fcChip->SEST->sgPages[ *fcExchangeIndex ]);// (for Freeing later)
+
+
+ if( !fcp_dl ) // error building S/G list?
+ {
+ ulStatus = MEMPOOL_FAIL;
+ break; // give up
+ }
+

+ // no payload or command to build -- READ doesn't need XRDY


+
+
+ if( sgPairs > 3 ) // need extended s/g list

+ pTRE->Buff_Off = 0x78000000L; // extended data | (no offset)


+ else // local data pointers (in SEST)

+ pTRE->Buff_Off = 0xf8000000L; // local data | (no offset)


+
+ // ULONG 5

+ pTRE->Buff_Index = 0L; // Buff_Index | reserved
+ pTRE->reserved = 0x0L; // DWord 6
+
+ // DWord 7: NOTE: zero length will
+ // hang TachLite!
+ pTRE->Data_Len = fcp_dl; // e.g. sum of scatter buffers
+
+ pTRE->reserved_ = 0L; // DWord 8
+ pTRE->reserved__ = 0L; // DWord 9


+
+ break;
+
+
+
+
+
+
+

+ case FCP_RESPONSE:
+ // Target response frame: this sequence uses an OX/RX ID
+ // pair from a completed SEST exchange. We built most
+ // of the response frame when we created the TWE/TRE.


+
+ *pIRB_flags = 0; // clear IRB flags

+ IRB_flags.SFA = 1; // send SFS (RSP)


+ SfsLen = *pIRB_flags;
+
+ SfsLen <<= 24; // shift flags to MSB

+ SfsLen += sizeof(TachFCHDR_RSP);// add SFS len (header & RSP payload)
+
+
+ Exchanges->fcExchange[ *fcExchangeIndex].type =
+ FCP_RESPONSE; // change Exchange type to "response" phase
+
+ // take advantage of prior knowledge of OX/RX_ID pair from
+ // previous XFER outbound frame (still in fchs of exchange)
+ fcChip->SEST->RspHDR[ *fcExchangeIndex ].ox_rx_id =
+ CMDfchs->ox_rx_id;
+
+ // Check the status of the DATA phase of the exchange so we can report
+ // status to the initiator
+ buildFCPstatus( fcChip, *fcExchangeIndex); // set RSP payload fields
+
+ memcpy(
+ CMDfchs, // re-use same XFER fchs for Response frame
+ &fcChip->SEST->RspHDR[ *fcExchangeIndex ],
+ sizeof( TachFCHDR_RSP ));


+
+
+ break;
+

+ default:
+ printk("cpqfcTS: don't know how to build FC type: %Xh(%d)\n", type,type);


+ break;
+
+ }
+
+
+

+ if( !ulStatus) // no errors above?
+ {
+ // FCHS is built; now build IRB
+
+ // link the just built FCHS (the "command") to the IRB entry
+ // for this Exchange.
+ pIRB = &Exchanges->fcExchange[ *fcExchangeIndex].IRB;
+
+ // len & flags according to command type above
+ pIRB->Req_A_SFS_Len = SfsLen; // includes IRB flags & len
+ pIRB->Req_A_SFS_Addr = virt_to_bus(CMDfchs); // TL needs physical addr
+ // of frame to send
+ pIRB->Req_A_SFS_D_ID = CMDfchs->d_id << 8; // Dest_ID must be consistent!
+
+ // Exchange is complete except for "fix-up" fields to be set
+ // at Tachyon Queuing time:
+ // IRB->Req_A_Trans_ID (OX_ID/ RX_ID):
+ // for SEST entry, lower bits correspond to actual FC Exchange ID
+ // fchs->OX_ID or RX_ID


+ }
+ else
+ {
+#ifdef DBG

+ printk( "FC Error: SEST build Pool Allocation failed\n");
+#endif
+ // return resources...
+ cpqfcTSCompleteExchange( fcChip, *fcExchangeIndex); // SEST build failed
+ }
+ }
+ else // no Exchanges available
+ {
+ ulStatus = SEST_FULL;
+ printk( "FC Error: no fcExchanges available\n");
+ }
+ return ulStatus;


+}
+
+
+
+
+
+

+// set RSP payload fields
+static void buildFCPstatus( PTACHYON fcChip, ULONG ExchangeID)
+{


+ FC_EXCHANGES *Exchanges = fcChip->Exchanges;

+ FC_EXCHANGE *pExchange = &Exchanges->fcExchange[ExchangeID]; // shorthand
+ PFCP_STATUS_RESPONSE pFcpStatus;
+
+ memset( &fcChip->SEST->RspHDR[ ExchangeID ].pl, 0,
+ sizeof( FCP_STATUS_RESPONSE) );
+ if( pExchange->status ) // something wrong?
+ {
+ pFcpStatus = (PFCP_STATUS_RESPONSE) // cast RSP buffer for this xchng
+ &fcChip->SEST->RspHDR[ ExchangeID ].pl;
+ if( pExchange->status & COUNT_ERROR )
+ {
+
+ // set FCP response len valid (so we can report count error)
+ pFcpStatus->fcp_status |= FCP_RSP_LEN_VALID;
+ pFcpStatus->fcp_rsp_len = 0x04000000; // 4 byte len (BIG Endian)
+
+ pFcpStatus->fcp_rsp_info = FCP_DATA_LEN_NOT_BURST_LEN; // RSP_CODE


+ }
+ }
+}
+
+
+
+

+// This routine builds scatter/gather lists into SEST entries
+// INPUTS:
+// SESTalPair - SEST address @DWordA "Local Buffer Length"
+// sgList - Scatter/Gather linked list of Len/Address data buffers
+// OUTPUT:
+// sgPairs - number of valid address/length pairs
+// Remarks:
+// The SEST data buffer pointers only depend on number of
+// length/ address pairs, NOT on the type (IWE, TRE,...)
+// Up to 3 pairs can be referenced in the SEST - more than 3
+// require this Extended S/G list page. The page holds 4, 8, 16...
+// len/addr pairs, per Scatter/Gather List Page Length Reg.
+// TachLite allows pages to be linked to any depth.
+
+//#define DBG_SEST_SGLIST 1 // for printing out S/G pairs with Ext. pages
+
+static ULONG build_SEST_sgList(
+ ULONG *SESTalPairStart, // the 3 len/address buffers in SEST


+ Scsi_Cmnd *Cmnd,
+ ULONG *sgPairs,

+ PSGPAGES sgPages) // link list of TL Ext. S/G pages from O/S Pool
+
+{
+ ULONG i, AllocatedPages=0; // Tach Ext. S/G page allocations
+ ULONG* alPair = SESTalPairStart;
+ ULONG alignedPageAddress; // TL hardware alignment requirement
+ int PairCount;
+ unsigned long ulBuff;
+ ULONG total_data_len=0; // (in bytes)
+ ULONG bytes_to_go = Cmnd->request_bufflen; // total xfer (S/G sum)
+ ULONG thisMappingLen;
+ struct scatterlist *sgl; // S/G list (Linux format)
+
+
+
+ if( !Cmnd->use_sg ) // no S/G list?
+ {
+ *sgPairs = 1; // use "local" S/G pair in SEST entry
+ // (for now, ignore address bits above #31)
+ *alPair++ = bytes_to_go & 0x7ffff; // bits 18-0, length
+ ulBuff = virt_to_bus( Cmnd->request_buffer);
+#if BITS_PER_LONG > 32
+ if( ulBuff >>32 )
+ {
+ printk("FATAL! Tachyon DMA address %p exceeds 32 bits\n", (void*)ulBuff );
+ return 0;
+ }
+#endif
+ *alPair = (ULONG)ulBuff;
+ return bytes_to_go;
+ }
+
+
+ // [TBD - update for Linux to support > 32 bits addressing]
+ // since the format for local & extended S/G lists is different,
+ // check if S/G pairs exceeds 3.
+ *sgPairs = Cmnd->use_sg;
+ sgl = (struct scatterlist*)Cmnd->request_buffer;
+
+ if( *sgPairs <= 3 ) // need "local" SEST list
+ {
+ while( bytes_to_go)
+ {
+ thisMappingLen = sgl->length; // we want them ALL on every pass
+ bytes_to_go = bytes_to_go - thisMappingLen;
+
+ // we have L/A pair; L = thisMappingLen, A = physicalAddress
+ // load into SEST...
+ total_data_len += thisMappingLen & 0x7ffff; // mask in valid bits
+ // per SEST format
+ *alPair = thisMappingLen & 0x7ffff; // bits 18-0, length
+// physicalAddress.HighPart <= 19; // shift to bit 19
+
+ // pick up bits 44-32 of upper 64-bit address
+ // and load into 31-19 LBAU (upper addr) of SEST entry
+// *alPair++ |=(ULONG)((physicalAddress.HighPart & 0xFFF8));
+ // on Tachlite TS's local S/G, we can handle 13 extra address bits
+ // i.e., bits 31-19 are actually bits 44-32 of physicalAddress
+
+ alPair++;
+
+ ulBuff = virt_to_bus( sgl->address);
+#if BITS_PER_LONG > 32
+ if( ulBuff >>32 )
+ {
+ printk("cqpfcTS: Tach DMA address %p > 32 bits\n", (void*)ulBuff );
+ return 0;
+ }
+#endif
+ *alPair++ = (ULONG)ulBuff; // lower 32 bits (31-0)
+
+ ++sgl; // next S/G pair
+#ifdef DBG_SEST_SGLIST
+ printk(" thisLen %d ", thisMappingLen);
+ printk(" remain %d\n", bytes_to_go);


+#endif
+
+ }
+ }
+

+
+
+
+ else // more than 3 pairs requires Extended S/G page (Pool Allocation)
+ {
+ // clear out SEST DWORDs (local S/G addr) C-F (A-B set in following logic)
+
+
+
+ for( i=2; i<6; i++)
+ alPair[i] = 0;
+
+ PairCount = TL_EXT_SG_PAGE_COUNT; // forces initial page allocation
+
+ while( bytes_to_go )
+ {
+
+
+ // Per SEST format, we can support 524287 byte lenghts per
+ // S/G pair. Typical user buffers are 4k, and very rarely
+ // exceed 12k due to fragmentation of physical memory pages.
+ // However, on certain O/S system (not "user") buffers (on platforms
+ // with huge memories like 256Meg), it's possible to exceed this
+ // length in a single S/G address/len mapping.
+ //
+ // Check for Tachyon length boundary
+ //
+ if( sgl->length > 0x7ffff )
+ {
+ // never ask for more than we can handle
+ thisMappingLen = sgl->length & 0x7ffff;
+ }
+ else
+ thisMappingLen = sgl->length;
+
+
+
+ // should we load into "this" extended S/G page, or allocate
+ // new page?
+
+ if( PairCount >= TL_EXT_SG_PAGE_COUNT )
+ {
+ // have we exceeded the max possible extended pages?
+ if( AllocatedPages >= TL_MAX_SGPAGES)
+ {
+ printk("Error: aborted loop on %d Ext. S/G page allocations\n",
+ AllocatedPages);
+
+ total_data_len = 0; // failure!! Ext. S/G is All-or-none affair
+ break; // failed
+ }
+
+ // Allocate the TL Extended S/G list page from O/S pool. We have
+ // to allocated twice what we want to ensure required TL alignment
+ // (Tachlite TL/TS User Man. Rev 6.0, p 168)
+ // We store the original allocated PVOID so we can free later
+
+ sgPages->PoolPage[ AllocatedPages] =
+ kmalloc( TL_EXT_SG_PAGE_BYTELEN*2,GFP_ATOMIC); // double for alignment
+
+
+ if( !sgPages->PoolPage[ AllocatedPages] ) // Allocation failed?
+ {
+
+ printk("Error: Allocation failed @ %d S/G page allocations\n",
+ AllocatedPages);
+
+ total_data_len = 0; // failure!! Ext. S/G is All-or-none affair


+ break; // give up
+ }

+ // clear out memory we just allocated
+ memset( sgPages->PoolPage[AllocatedPages], 0,
+ TL_EXT_SG_PAGE_BYTELEN*2);
+
+
+ // align the memory - TL requires sizeof() Ext. S/G page alignment.
+ // We doubled the actual required size so we could mask off LSBs
+ // to get desired offset
+
+ ulBuff = virt_to_bus( sgPages->PoolPage[AllocatedPages]);
+
+#if BITS_PER_LONG > 32
+ if( ulBuff >>32 )
+ {
+ printk("cqpfcTS: Tach ext. S/G DMA address %p > 32 bits\n",
+ (void*)ulBuff );
+ return 0;
+ }
+#endif
+
+ ulBuff += TL_EXT_SG_PAGE_BYTELEN; // ensures we pass align. boundary
+ ulBuff &= (0xFFFFFFFF - (TL_EXT_SG_PAGE_BYTELEN -1) );// mask off LSBs
+
+ alignedPageAddress = (ULONG)ulBuff;
+#ifdef DBG_SEST_SGLIST
+ printk("new PoolPage: %p, alignedPageAddress %lXh\n",
+ sgPages->PoolPage[AllocatedPages], ulBuff);
+#endif
+
+
+ // set pointer, in SEST if first Ext. S/G page, or in last pair
+ // of linked Ext. S/G pages...
+ // (Only 32-bit PVOIDs, so just load lower 32 bits)
+ // NOTE: the Len field must be '0' if this is the first Ext. S/G
+ // pointer in SEST, and not 0 otherwise.
+ if( alPair == SESTalPairStart) // initial Ext. S/G list?
+ *alPair = 0;
+ else // not the SEST entry... Len must be non-0, so
+ // arbitrarily set it to number bytes remaining
+ *alPair = ( bytes_to_go & 0x7ffff);
+
+#ifdef DBG_SEST_SGLIST
+ printk("PairCount %d @%p even %Xh, ",
+ PairCount, alPair, *alPair);
+#endif
+ alPair++; // next DWORD
+
+ *alPair = alignedPageAddress; // TL needs 32-bit physical
+#ifdef DBG_SEST_SGLIST
+ printk("odd %Xh\n", *alPair);
+#endif
+
+ // now reset the pointer to the ACTUAL (Extended) S/G page
+ // which will accept the Len/ PhysicalAddress pairs
+ alPair = bus_to_virt(alignedPageAddress);
+
+ AllocatedPages++;
+ PairCount = 1; // starting new Ext. S/G page
+ } // end of new TL Ext. S/G page allocation
+
+
+ *alPair = thisMappingLen; // bits 18-0, length (range check above)
+
+
+// physicalAddress.HighPart <= 19; // shift to bit 19
+
+ // pick up bits 44-32 of upper 64-bit address
+ // and load into 31-19 LBAU (upper addr) of SEST entry
+// *alPair |=(ULONG)((physicalAddress.HighPart & 0xFFF8));
+
+
+#ifdef DBG_SEST_SGLIST
+ printk("PairCount %d @%p, even %Xh, ",
+ PairCount, alPair, *alPair);
+#endif
+
+ alPair++; // next DWORD
+ // on Tachlite TS's local S/G, we can handle 13 extra address bits
+ // i.e., bits 31-19 are actually bits 44-32 of physicalAddress
+
+
+ ulBuff = virt_to_bus( sgl->address);
+#if BITS_PER_LONG > 32
+ if( ulBuff >>32 )
+ {
+ printk("cqpfcTS: Tach DMA address %p > 32 bits\n", (void*)ulBuff );
+ return 0;
+ }
+#endif
+ *alPair = (ULONG)ulBuff; // lower 32 bits (31-0)
+
+
+#ifdef DBG_SEST_SGLIST
+ printk("odd %Xh\n", *alPair);
+#endif
+ alPair++; // next DWORD
+
+
+ PairCount++; // next Length/Address pair
+ bytes_to_go -= thisMappingLen;
+ total_data_len += thisMappingLen;
+ sgl++; // next S/G pair
+ }
+ }
+ return total_data_len;
+}
+
+
+
+// The Tachlite SEST table is referenced to OX_ID (or RX_ID). To optimize
+// performance and debuggability, we index the Exchange structure to FC X_ID
+// This enables us to build exchanges for later en-queing to Tachyon,
+// provided we have an open X_ID slot. At Tachyon queing time, we only
+// need an ERQ slot; then "fix-up" references in the
+// IRB, FCHS, etc. as needed.
+// RETURNS:
+// 0 if successful
+// non-zero on error
+//sstartex


+ULONG cpqfcTSStartExchange(
+ CPQFCHBA *cpqfcHBAdata,
+ LONG ExchangeID )

+{
+ PTACHYON fcChip = &cpqfcHBAdata->fcChip;
+ FC_EXCHANGES *Exchanges = fcChip->Exchanges;

+ FC_EXCHANGE *pExchange = &Exchanges->fcExchange[ ExchangeID ]; // shorthand
+ USHORT producer, consumer;
+ ULONG ulStatus=0;
+ short int ErqIndex;
+ BOOLEAN CompleteExchange = FALSE; // e.g. ACC replies are complete
+ BOOLEAN SestType=FALSE;
+ ULONG InboundData=0;
+
+ // We will manipulate Tachlite chip registers here to successfully
+ // start exchanges.
+
+ // Check that link is not down -- we can't start an exchange on a
+ // down link!
+
+ if( fcChip->Registers.FMstatus.value & 0x80) // LPSM offline?
+ {
+printk("fcStartExchange: PSM offline (%Xh), x_ID %Xh, type %Xh, port_id %Xh\n",
+ fcChip->Registers.FMstatus.value & 0xFF,
+ ExchangeID,
+ pExchange->type,
+ pExchange->fchs.d_id);
+
+ if( ExchangeID >= TACH_SEST_LEN ) // Link Service Outbound frame?
+ {
+ // Our most popular LinkService commands are port discovery types
+ // (PLOGI/ PDISC...), which are implicitly nullified by Link Down
+ // events, so it makes no sense to Que them. However, ABTS should
+ // be queued, since exchange sequences are likely destroyed by
+ // Link Down events, and we want to notify other ports of broken
+ // sequences by aborting the corresponding exchanges.
+ if( pExchange->type != BLS_ABTS )


+ {
+ ulStatus = LNKDWN_OSLS;

+ goto Done;
+ // don't Que most LinkServ exchanges on LINK DOWN
+ }
+ }
+
+ printk("fcStartExchange: Que x_ID %Xh, type %Xh\n",
+ ExchangeID, pExchange->type);
+ pExchange->status |= EXCHANGE_QUEUED;
+ ulStatus = EXCHANGE_QUEUED;


+ goto Done;
+ }
+

+ // Make sure ERQ has available space.
+
+ producer = (USHORT)fcChip->ERQ->producerIndex; // copies for logical arith.
+ consumer = (USHORT)fcChip->ERQ->consumerIndex;
+ producer++; // We are testing for full que by incrementing
+
+ if( producer >= ERQ_LEN ) // rollover condition?
+ producer = 0;
+ if( consumer != producer ) // ERQ not full?
+ {
+ // ****************** Need Atomic access to chip registers!!********
+
+ // remember ERQ PI for copying IRB
+ ErqIndex = (USHORT)fcChip->ERQ->producerIndex;
+ fcChip->ERQ->producerIndex = producer; // this is written to Tachyon
+ // we have an ERQ slot! If SCSI command, need SEST slot
+ // otherwise we are done.
+
+ // Note that Tachyon requires that bit 15 of the OX_ID or RX_ID be
+ // set according to direction of data to/from Tachyon for SEST assists.
+ // For consistency, enforce this rule for Link Service (non-SEST)
+ // exchanges as well.
+
+ // fix-up the X_ID field in IRB
+ pExchange->IRB.Req_A_Trans_ID = ExchangeID & 0x7FFF; // 15-bit field
+
+ // fix-up the X_ID field in fchs -- depends on Originator or Responder,
+ // outgoing or incoming data?
+ switch( pExchange->type )
+ {
+ // ORIGINATOR types... we're setting our OX_ID and
+ // defaulting the responder's RX_ID to 0xFFFF
+
+ case SCSI_IRE:
+ // Requirement: set MSB of x_ID for Incoming TL data
+ // (see "Tachyon TL/TS User's Manual", Rev 6.0, Sept.'98, pg. 50)
+ InboundData = 0x8000;
+
+ case SCSI_IWE:
+ SestType = TRUE;
+ pExchange->fchs.ox_rx_id = (ExchangeID | InboundData);
+ pExchange->fchs.ox_rx_id <<= 16; // MSW shift
+ pExchange->fchs.ox_rx_id |= 0xffff; // add default RX_ID
+
+ // now fix-up the Data HDR OX_ID (TL automatically does rx_id)
+ // (not necessary for IRE -- data buffer unused)
+ if( pExchange->type == SCSI_IWE)
+ {
+ fcChip->SEST->DataHDR[ ExchangeID ].ox_rx_id =
+ pExchange->fchs.ox_rx_id;


+
+ }
+
+ break;
+
+

+ case FCS_NSR: // ext. link service Name Service Request
+ case ELS_SCR: // ext. link service State Change Registration
+ case ELS_FDISC:// ext. link service login
+ case ELS_FLOGI:// ext. link service login
+ case ELS_LOGO: // FC-PH extended link service logout
+ case BLS_NOP: // Basic link service No OPeration
+ case ELS_PLOGI:// ext. link service login (PLOGI)
+ case ELS_PDISC:// ext. link service login (PDISC)
+ case ELS_PRLI: // ext. link service process login
+
+ pExchange->fchs.ox_rx_id = ExchangeID;
+ pExchange->fchs.ox_rx_id <<= 16; // MSW shift
+ pExchange->fchs.ox_rx_id |= 0xffff; // and RX_ID


+
+ break;
+
+
+
+

+ // RESPONDER types... we must set our RX_ID while preserving
+ // sender's OX_ID
+ // outgoing (or no) data


+ case ELS_RJT: // extended link service reject
+ case ELS_LOGO_ACC: // FC-PH extended link service logout accept

+ case ELS_ACC: // ext. generic link service accept


+ case ELS_PLOGI_ACC:// ext. link service login accept (PLOGI or PDISC)
+ case ELS_PRLI_ACC: // ext. link service process login accept
+

+ CompleteExchange = TRUE; // Reply (ACC or RJT) is end of exchange
+ pExchange->fchs.ox_rx_id |= (ExchangeID & 0xFFFF);


+
+ break;
+
+

+ // since we are a Responder, OX_ID should already be set by
+ // cpqfcTSBuildExchange(). We need to -OR- in RX_ID
+ case SCSI_TWE:
+ SestType = TRUE;
+ // Requirement: set MSB of x_ID for Incoming TL data
+ // (see "Tachyon TL/TS User's Manual", Rev 6.0, Sept.'98, pg. 50)
+
+ pExchange->fchs.ox_rx_id &= 0xFFFF0000; // clear RX_ID
+ // Requirement: set MSB of RX_ID for Incoming TL data
+ // (see "Tachyon TL/TS User's Manual", Rev 6.0, Sept.'98, pg. 50)
+ pExchange->fchs.ox_rx_id |= (ExchangeID | 0x8000);
+ break;
+
+
+ case SCSI_TRE:
+ SestType = TRUE;
+
+ // there is no XRDY for SEST target read; the data
+ // header needs to be updated. Also update the RSP
+ // exchange IDs for the status frame, in case it is sent automatically
+ fcChip->SEST->DataHDR[ ExchangeID ].ox_rx_id |= ExchangeID;
+ fcChip->SEST->RspHDR[ ExchangeID ].ox_rx_id =
+ fcChip->SEST->DataHDR[ ExchangeID ].ox_rx_id;
+
+ // for easier FCP response logic (works for TWE and TRE),
+ // copy exchange IDs. (Not needed if TRE 'RSP' bit set)
+ pExchange->fchs.ox_rx_id =
+ fcChip->SEST->DataHDR[ ExchangeID ].ox_rx_id;


+
+ break;
+
+

+ case FCP_RESPONSE: // using existing OX_ID/ RX_ID pair,
+ // start SFS FCP-RESPONSE frame
+ // OX/RX_ID should already be set! (See "fcBuild" above)
+ CompleteExchange = TRUE; // RSP is end of FCP-SCSI exchange


+
+
+ break;
+
+

+ case BLS_ABTS_RJT: // uses new RX_ID, since SEST x_ID non-existent
+ case BLS_ABTS_ACC: // using existing OX_ID/ RX_ID pair from SEST entry
+ CompleteExchange = TRUE; // ACC or RJT marks end of FCP-SCSI exchange
+ case BLS_ABTS: // using existing OX_ID/ RX_ID pair from SEST entry


+
+
+ break;
+
+

+ default:
+ printk("Error on fcStartExchange: undefined type %Xh(%d)\n",
+ pExchange->type, pExchange->type);


+ return INVALID_ARGS;
+ }
+
+

+ // X_ID fields are entered -- copy IRB to Tachyon's ERQ
+
+
+ memcpy(
+ &fcChip->ERQ->QEntry[ ErqIndex ], // dest.
+ &pExchange->IRB,
+ 32); // fixed (hardware) length!
+
+ PCI_TRACEO( ExchangeID, 0xA0)
+
+ // ACTION! May generate INT and IMQ entry


+ writel( fcChip->ERQ->producerIndex,

+ fcChip->Registers.ERQproducerIndex.address);
+
+
+ if( ExchangeID >= TACH_SEST_LEN ) // Link Service Outbound frame?
+ {
+
+ // wait for completion! (TDB -- timeout and chip reset)
+
+
+ PCI_TRACEO( ExchangeID, 0xA4)
+
+ enable_irq( cpqfcHBAdata->HostAdapter->irq); // only way to get Sem.
+
+ down_interruptible( cpqfcHBAdata->TYOBcomplete);

+
+ disable_irq( cpqfcHBAdata->HostAdapter->irq);

+ PCI_TRACE( 0xA4)
+
+ // On login exchanges, BAD_ALPA (non-existent port_id) results in
+ // FTO (Frame Time Out) on the Outbound Completion message.
+ // If we got an FTO status, complete the exchange (free up slot)
+ if( CompleteExchange || // flag from Reply frames
+ pExchange->status ) // typically, can get FRAME_TO


+ {
+ cpqfcTSCompleteExchange( fcChip, ExchangeID);

+ }
+ }
+
+ else // SEST Exchange
+ {
+ ulStatus = 0; // ship & pray success (e.g. FCP-SCSI)
+
+ if( CompleteExchange ) // by Type of exchange (e.g. end-of-xchng)


+ {
+ cpqfcTSCompleteExchange( fcChip, ExchangeID);

+ }
+
+ else
+ pExchange->status &= ~EXCHANGE_QUEUED; // clear ExchangeQueued flag

+
+ }
+ }
+
+

+ else // ERQ 'producer' = 'consumer' and QUE is full
+ {
+ ulStatus = OUTQUE_FULL; // Outbound (ERQ) Que full
+ }
+
+Done:
+ PCI_TRACE( 0xA0)
+ return ulStatus;

+}
+
+
+
+
+

+// Scan fcController->fcExchanges array for a usuable index (a "free"
+// exchange).
+// Inputs:
+// fcChip - pointer to TachLite chip structure
+// Return:
+// index - exchange array element where exchange can be built
+// -1 - exchange array is full
+// REMARKS:
+// Although this is a (yuk!) linear search, we presume
+// that the system will complete exchanges about as quickly as
+// they are submitted. A full Exchange array (and hence, max linear
+// search time for free exchange slot) almost guarantees a Fibre problem
+// of some sort.
+// In the interest of making exchanges easier to debug, we want a LRU
+// (Least Recently Used) scheme.
+


+
+static LONG FindFreeExchange( PTACHYON fcChip, ULONG type )

+{


+ FC_EXCHANGES *Exchanges = fcChip->Exchanges;

+ ULONG i;
+ ULONG ulStatus=-1; // assume failure


+
+
+ if( type == SCSI_IRE ||
+ type == SCSI_TRE ||
+ type == SCSI_IWE ||
+ type == SCSI_TWE)

+ {
+ // SCSI type - X_IDs should be from 0 to TACH_SEST_LEN-1
+ if( fcChip->fcSestExchangeLRU >= TACH_SEST_LEN) // rollover?
+ fcChip->fcSestExchangeLRU = 0;
+ i = fcChip->fcSestExchangeLRU; // typically it's already free!
+
+ if( Exchanges->fcExchange[i].type == 0 ) // check for "free" element
+ {
+ ulStatus = 0; // success!
+ }
+
+ else
+ { // YUK! we need to do a linear search for free element.
+ // Fragmentation of the fcExchange array is due to excessively
+ // long completions or timeouts.
+
+ while( TRUE )
+ {
+ if( ++i >= TACH_SEST_LEN ) // rollover check
+ i = 0; // beginning of SEST X_IDs
+
+// printk( "looping for SCSI xchng ID: i=%d, type=%Xh\n",
+// i, Exchanges->fcExchange[i].type);
+
+ if( Exchanges->fcExchange[i].type == 0 ) // "free"?
+ {
+ ulStatus = 0; // success!
+ break;
+ }
+ if( i == fcChip->fcSestExchangeLRU ) // wrapped-around array?
+ {
+ printk( "SEST X_ID space full\n");
+ break; // failed - prevent inf. loop
+ }
+ }
+ }
+ fcChip->fcSestExchangeLRU = i + 1; // next! (rollover check next pass)
+ }
+
+
+
+ else // Link Service type - X_IDs should be from TACH_SEST_LEN
+ // to TACH_MAX_XID
+ {
+ if( fcChip->fcLsExchangeLRU >= TACH_MAX_XID || // range check
+ fcChip->fcLsExchangeLRU < TACH_SEST_LEN ) // (e.g. startup)
+ fcChip->fcLsExchangeLRU = TACH_SEST_LEN;
+
+ i = fcChip->fcLsExchangeLRU; // typically it's already free!
+ if( Exchanges->fcExchange[i].type == 0 ) // check for "free" element
+ {
+ ulStatus = 0; // success!
+ }
+
+ else
+ { // YUK! we need to do a linear search for free element
+ // Fragmentation of the fcExchange array is due to excessively
+ // long completions or timeouts.
+
+ while( TRUE )
+ {
+ if( ++i >= TACH_MAX_XID ) // rollover check
+ i = TACH_SEST_LEN;// beginning of Link Service X_IDs
+
+// printk( "looping for xchng ID: i=%d, type=%Xh\n",
+// i, Exchanges->fcExchange[i].type);
+
+ if( Exchanges->fcExchange[i].type == 0 ) // "free"?
+ {
+ ulStatus = 0; // success!
+ break;
+ }
+ if( i == fcChip->fcLsExchangeLRU ) // wrapped-around array?
+ {
+ printk( "LinkService X_ID space full\n");
+ break; // failed - prevent inf. loop
+ }
+ }
+ }
+ fcChip->fcLsExchangeLRU = i + 1; // next! (rollover check next pass)
+
+ }
+
+ if( !ulStatus ) // success?
+ Exchanges->fcExchange[i].type = type; // allocate it.
+
+ else
+ i = -1; // error - all exchanges "open"
+
+ return i;

+}
+
+
+
+
+

+// We call this routine to free an Exchange for any reason:
+// completed successfully, completed with error, aborted, etc.
+
+// returns FALSE if Exchange failed and "retry" is acceptable
+// returns TRUE if Exchange was successful, or retry is impossible
+// (e.g. port/device gone).
+//scompleteexchange
+
+void cpqfcTSCompleteExchange(
+ PTACHYON fcChip,
+ ULONG x_ID)
+{


+ FC_EXCHANGES *Exchanges = fcChip->Exchanges;
+

+ if( x_ID < TACH_SEST_LEN ) // SEST-based (or LinkServ for FCP exchange)
+ {
+ if( Exchanges->fcExchange[ x_ID ].Cmnd == NULL ) // what#@!


+ {
+// TriggerHBA( fcChip->Registers.ReMapMemBase, 0);

+ printk(" x_ID %Xh, type %Xh, NULL ptr!\n", x_ID,
+ Exchanges->fcExchange[ x_ID ].type);
+
+ goto CleanUpSestResources; // this path should be very rare.
+ }
+
+ // we have Linux Scsi Cmnd ptr..., now check our Exchange status
+ // to decide how to complete this SEST FCP exchange
+
+ if( Exchanges->fcExchange[ x_ID ].status ) // perhaps a Tach indicated problem,
+ // or abnormal exchange completion
+ {
+ // set FCP Link statistics
+
+ if( Exchanges->fcExchange[ x_ID ].status & FC2_TIMEOUT)
+ fcChip->fcStats.timeouts++;


+ if( Exchanges->fcExchange[ x_ID ].status & INITIATOR_ABORT)

+ fcChip->fcStats.FC4aborted++;
+ if( Exchanges->fcExchange[ x_ID ].status & COUNT_ERROR)
+ fcChip->fcStats.CntErrors++;


+ if( Exchanges->fcExchange[ x_ID ].status & LINKFAIL_TX)

+ fcChip->fcStats.linkFailTX++;
+ if( Exchanges->fcExchange[ x_ID ].status & LINKFAIL_RX)
+ fcChip->fcStats.linkFailRX++;
+ if( Exchanges->fcExchange[ x_ID ].status & OVERFLOW)
+ fcChip->fcStats.CntErrors++;
+
+ // First, see if the Scsi upper level initiated an ABORT on this
+ // exchange...
+ if( Exchanges->fcExchange[ x_ID ].status == INITIATOR_ABORT )
+ {
+ printk(" DID_ABORT, x_ID %Xh, Cmnd %p ",
+ x_ID, Exchanges->fcExchange[ x_ID ].Cmnd);
+ goto CleanUpSestResources; // (we don't expect Linux _aborts)
+ }
+
+ // Did our driver timeout the Exchange, or did Tachyon indicate
+ // a failure during transmission? Ask for retry with "SOFT_ERROR"
+ else if( Exchanges->fcExchange[ x_ID ].status & FC2_TIMEOUT)
+ {
+// printk("result DID_SOFT_ERROR, x_ID %Xh, Cmnd %p\n",
+// x_ID, Exchanges->fcExchange[ x_ID ].Cmnd);
+ Exchanges->fcExchange[ x_ID ].Cmnd->result = (DID_SOFT_ERROR <<16);
+ }
+
+ // Did frame(s) for an open exchange arrive in the SFQ,
+ // meaning the SEST was unable to process them?
+ else if( Exchanges->fcExchange[ x_ID ].status & SFQ_FRAME)
+ {
+// printk("result DID_SOFT_ERROR, x_ID %Xh, Cmnd %p\n",
+// x_ID, Exchanges->fcExchange[ x_ID ].Cmnd);
+ Exchanges->fcExchange[ x_ID ].Cmnd->result = (DID_SOFT_ERROR <<16);
+ }
+
+ // Did our driver timeout the Exchange, or did Tachyon indicate
+ // a failure during transmission? Ask for retry with "SOFT_ERROR"
+ else if(
+ (Exchanges->fcExchange[ x_ID ].status & LINKFAIL_TX) ||
+ (Exchanges->fcExchange[ x_ID ].status & PORTID_CHANGED) ||
+ (Exchanges->fcExchange[ x_ID ].status & FRAME_TO) ||
+ (Exchanges->fcExchange[ x_ID ].status & INV_ENTRY) ||
+ (Exchanges->fcExchange[ x_ID ].status & ABORTSEQ_NOTIFY) )
+
+
+ {
+// printk("result DID_SOFT_ERROR, x_ID %Xh, Cmnd %p\n",
+// x_ID, Exchanges->fcExchange[ x_ID ].Cmnd);
+ Exchanges->fcExchange[ x_ID ].Cmnd->result = (DID_SOFT_ERROR <<16);
+
+
+ }
+
+ // e.g., a LOGOut happened, or device never logged back in.
+ else if( Exchanges->fcExchange[ x_ID ].status & DEVICE_REMOVED)
+ {
+// printk(" *LOGOut or timeout on login!* ");
+ // trigger?


+// TriggerHBA( fcChip->Registers.ReMapMemBase, 0);
+

+ Exchanges->fcExchange[ x_ID ].Cmnd->result = (DID_BAD_TARGET <<16);
+ }
+
+
+ // Did Tachyon indicate a CNT error? We need further analysis
+ // to determine if the exchange is acceptable
+ else if( Exchanges->fcExchange[ x_ID ].status == COUNT_ERROR)
+ {
+ UCHAR ScsiStatus;
+ FCP_STATUS_RESPONSE *pFcpStatus =
+ (PFCP_STATUS_RESPONSE)&fcChip->SEST->RspHDR[ x_ID ].pl;
+
+ ScsiStatus = pFcpStatus->fcp_status >>24;
+
+ // If the command is a SCSI Read/Write type, we don't tolerate
+ // count errors of any kind; assume the count error is due to
+ // a dropped frame and ask for retry...
+
+ if(( (Exchanges->fcExchange[ x_ID ].Cmnd->cmnd[0] == 0x8) ||
+ (Exchanges->fcExchange[ x_ID ].Cmnd->cmnd[0] == 0x28) ||
+ (Exchanges->fcExchange[ x_ID ].Cmnd->cmnd[0] == 0xA) ||
+ (Exchanges->fcExchange[ x_ID ].Cmnd->cmnd[0] == 0x2A) )
+ &&
+ ScsiStatus == 0 )
+ {
+ // ask for retry
+/* printk("COUNT_ERROR retry, x_ID %Xh, status %Xh, Cmnd %p\n",
+ x_ID, Exchanges->fcExchange[ x_ID ].status,
+ Exchanges->fcExchange[ x_ID ].Cmnd);*/
+ Exchanges->fcExchange[ x_ID ].Cmnd->result = (DID_SOFT_ERROR <<16);
+ }
+
+ else // need more analysis
+ {
+ cpqfcTSCheckandSnoopFCP(fcChip, x_ID); // (will set ->result)
+ }
+ }
+
+ // default: NOTE! We don't ever want to get here. Getting here
+ // implies something new is happening that we've never had a test
+ // case for. Need code maintenance! Return "ERROR"
+ else
+ {
+ printk("DEFAULT result %Xh, x_ID %Xh, Cmnd %p\n",
+ Exchanges->fcExchange[ x_ID ].status, x_ID,

+ Exchanges->fcExchange[ x_ID ].Cmnd);

+ Exchanges->fcExchange[ x_ID ].Cmnd->result = (DID_ERROR <<16);
+ }
+ }
+ else // definitely no Tach problem, but perhaps an FCP problem
+ {
+ // set FCP Link statistic
+ fcChip->fcStats.ok++;
+ cpqfcTSCheckandSnoopFCP( fcChip, x_ID); // (will set ->result)
+ }
+
+ // OK, we've set the Scsi "->result" field, so proceed with calling
+ // Linux Scsi "done" (if not NULL), and free any kernel memory we
+ // may have allocated for the exchange.
+
+ PCI_TRACEO( (ULONG)Exchanges->fcExchange[x_ID].Cmnd, 0xAC);
+ // complete the command back to upper Scsi drivers
+ if( Exchanges->fcExchange[ x_ID ].Cmnd->scsi_done != NULL)
+ {
+ // Calling "done" on an Linux _abort() aborted
+ // Cmnd causes a kernel panic trying to re-free mem.
+ // Actually, we shouldn't do anything with an _abort CMND
+ if( Exchanges->fcExchange[ x_ID ].Cmnd->result != (DID_ABORT<<16) )
+ {
+ PCI_TRACE(0xAC)
+ (*Exchanges->fcExchange[ x_ID ].Cmnd->scsi_done)
+ (Exchanges->fcExchange[ x_ID ].Cmnd);


+ }
+ else
+ {
+

+// printk(" not calling scsi_done on x_ID %Xh, Cmnd %p\n",
+// x_ID, Exchanges->fcExchange[ x_ID ].Cmnd);
+ }
+ }
+ else{
+ printk(" x_ID %Xh, type %Xh, Cdb0 %Xh\n", x_ID,
+ Exchanges->fcExchange[ x_ID ].type,
+ Exchanges->fcExchange[ x_ID ].Cmnd->cmnd[0]);
+ printk(" cpqfcTS: Null scsi_done function pointer!\n");
+ }
+
+
+ // Now, clean up non-Scsi_Cmnd items...
+CleanUpSestResources:
+
+ // Was an Extended Scatter/Gather page allocated? We know
+ // this by checking DWORD 4, bit 31 ("LOC") of SEST entry
+ if( !(fcChip->SEST->u[ x_ID ].IWE.Buff_Off & 0x80000000))
+ {
+ int i = 0;
+
+ // extended S/G list was used -- Free the allocated ext. S/G pages
+
+ while( fcChip->SEST->sgPages[x_ID].PoolPage[i] &&
+ (i < TL_MAX_SGPAGES) )
+ {
+ kfree( fcChip->SEST->sgPages[x_ID].PoolPage[i]);
+ fcChip->SEST->sgPages[x_ID].PoolPage[i] = NULL;
+ i++;
+ }
+ }
+
+ Exchanges->fcExchange[ x_ID ].Cmnd = NULL;
+ } // Done with FCP (SEST) exchanges
+
+
+ // the remaining logic is common to ALL Exchanges:
+ // FCP(SEST) and LinkServ.
+
+ Exchanges->fcExchange[ x_ID ].type = 0; // there -- FREE!
+ Exchanges->fcExchange[ x_ID ].status = 0;
+
+ PCI_TRACEO( x_ID, 0xAC)
+
+
+ return;
+} // (END of CompleteExchange function)
+
+
+
+
+// Unfortunately, we must snoop all command completions in
+// order to manipulate certain return fields, and take note of
+// device types, etc., to facilitate the Fibre-Channel to SCSI
+// "mapping".
+// (Watch for BIG Endian confusion on some payload fields)
+void cpqfcTSCheckandSnoopFCP( PTACHYON fcChip, ULONG x_ID)
+{


+ FC_EXCHANGES *Exchanges = fcChip->Exchanges;

+ Scsi_Cmnd *Cmnd = Exchanges->fcExchange[ x_ID].Cmnd;
+ FCP_STATUS_RESPONSE *pFcpStatus =
+ (PFCP_STATUS_RESPONSE)&fcChip->SEST->RspHDR[ x_ID ].pl;
+ UCHAR ScsiStatus;
+
+ ScsiStatus = pFcpStatus->fcp_status >>24;
+
+#ifdef FCP_COMPLETION_DBG
+ printk("ScsiStatus = 0x%X\n", ScsiStatus);
+#endif
+
+ // First, check FCP status
+ if( pFcpStatus->fcp_status & FCP_RSP_LEN_VALID )
+ {
+ // check response code (RSP_CODE) -- most popular is bad len
+ // 1st 4 bytes of rsp info -- only byte 3 interesting
+ if( pFcpStatus->fcp_rsp_info & FCP_DATA_LEN_NOT_BURST_LEN )
+ {
+
+ // do we EVER get here?
+ printk("cpqfcTS: FCP data len not burst len, x_ID %Xh\n", x_ID);
+ }
+ }
+
+ // for now, go by the ScsiStatus, and manipulate certain
+ // commands when necessary...
+ if( ScsiStatus == 0) // SCSI status byte "good"?
+ {
+ Cmnd->result = 0; // everything's OK
+
+ if( (Cmnd->cmnd[0] == INQUIRY))
+ {
+ UCHAR *InquiryData = Cmnd->request_buffer;
+ PFC_LOGGEDIN_PORT pLoggedInPort;
+
+ // We need to manipulate INQUIRY
+ // strings for COMPAQ RAID controllers to force
+ // Linux to scan additional LUNs. Namely, set
+ // the Inquiry string byte 2 (ANSI-approved version)
+ // to 2.
+
+ if( !memcmp( &InquiryData[8], "COMPAQ", 6 ))
+ {
+ InquiryData[2] = 0x2; // claim SCSI-2 compliance,
+ // so multiple LUNs may be scanned.
+ // (no SCSI-2 problems known in CPQ)
+ }
+
+ // snoop the Inquiry to detect Disk, Tape, etc. type
+ // (search linked list for the port_id we sent INQUIRY to)


+ pLoggedInPort = fcFindLoggedInPort( fcChip,
+ NULL, // DON'T search Scsi Nexus (we will set it)
+ Exchanges->fcExchange[ x_ID].fchs.d_id & 0xFFFFFF,

+ NULL, // DON'T search linked list for FC WWN
+ NULL); // DON'T care about end of list
+

+ if( pLoggedInPort )
+ {

+ pLoggedInPort->ScsiNexus.InqDeviceType = InquiryData[0];
+ }
+ else
+ {
+ printk("cpqfcTS: can't find LoggedIn FC port %06X for INQUIRY\n",
+ Exchanges->fcExchange[ x_ID].fchs.d_id & 0xFFFFFF);


+ }
+ }
+ }
+
+

+ // Scsi Status not good -- pass it back to caller
+
+ else
+ {
+ Cmnd->result = ScsiStatus; // SCSI status byte is 1st
+
+ // check for valid "sense" data
+
+ if( pFcpStatus->fcp_status & FCP_SNS_LEN_VALID )
+ { // limit Scsi Sense field length!
+ int SenseLen = pFcpStatus->fcp_sns_len >>24; // (BigEndian) lower byte
+
+ SenseLen = SenseLen > sizeof( Cmnd->sense_buffer) ?
+ sizeof( Cmnd->sense_buffer) : SenseLen;
+
+
+#ifdef FCP_COMPLETION_DBG
+ printk("copy sense_buffer %p, len %d, result %Xh\n",
+ Cmnd->sense_buffer, SenseLen, Cmnd->result);
+#endif
+
+ // NOTE: There is some dispute over the FCP response
+ // format. Most FC devices assume that FCP_RSP_INFO
+ // is 8 bytes long, in spite of the fact that FCP_RSP_LEN
+ // is (virtually) always 0 and the field is "invalid".
+ // Some other devices assume that
+ // the FCP_SNS_INFO begins after FCP_RSP_LEN bytes (i.e. 0)
+ // when the FCP_RSP is invalid (this almost appears to be
+ // one of those "religious" issues).
+ // Consequently, we test the usual position of FCP_SNS_INFO
+ // for 7Xh, since the SCSI sense format says the first
+ // byte ("error code") should be 0x70 or 0x71. In practice,
+ // we find that every device does in fact have 0x70 or 0x71
+ // in the first byte position, so this test works for all
+ // FC devices.
+ // (This logic is especially effective for the CPQ/DEC HSG80
+ // & HSG60 controllers).
+
+ if( (pFcpStatus->fcp_sns_info[0] & 0x70) == 0x70 )
+ memcpy( Cmnd->sense_buffer,
+ &pFcpStatus->fcp_sns_info[0], SenseLen);
+ else
+ {
+ unsigned char *sbPtr =
+ (unsigned char *)&pFcpStatus->fcp_sns_info[0];
+ sbPtr -= 8; // back up 8 bytes hoping to find the
+ // start of the sense buffer
+ memcpy( Cmnd->sense_buffer, sbPtr, SenseLen);
+ }
+
+ // in the special case of Device Reset, tell upper layer
+ // to immediately retry (with SOFT_ERROR status)
+ // look for Sense Key Unit Attention (0x6) with ASC Device
+ // Reset (0x29)
+ // printk("SenseLen %d, Key = 0x%X, ASC = 0x%X\n",
+ // SenseLen, Cmnd->sense_buffer[2],
+ // Cmnd->sense_buffer[12]);


+ if( ((Cmnd->sense_buffer[2] & 0xF) == 0x6) &&
+ (Cmnd->sense_buffer[12] == 0x29) ) // Sense Code "reset"

+ {
+ Cmnd->result |= (DID_SOFT_ERROR << 16); // "Host" status byte 3rd
+ }
+
+ // check for SenseKey "HARDWARE ERROR", ASC InternalTargetFailure
+ else if( ((Cmnd->sense_buffer[2] & 0xF) == 0x4) && // "hardware error"
+ (Cmnd->sense_buffer[12] == 0x44) ) // Addtl. Sense Code
+ {
+// printk("HARDWARE_ERROR, Channel/Target/Lun %d/%d/%d\n",
+// Cmnd->channel, Cmnd->target, Cmnd->lun);
+ Cmnd->result |= (DID_ERROR << 16); // "Host" status byte 3rd
+ }
+
+ } // (end of sense len valid)
+
+ // there is no sense data to help out Linux's Scsi layers...
+ // We'll just return the Scsi status and hope he will "do the
+ // right thing"
+ else
+ {
+ // as far as we know, the Scsi status is sufficient
+ Cmnd->result |= (DID_OK << 16); // "Host" status byte 3rd


+ }
+ }
+}
+
+
+

+//PPPPPPPPPPPPPPPPPPPPPPPPP PAYLOAD PPPPPPPPP
+// build data PAYLOAD; SCSI FCP_CMND I.U.
+// remember BIG ENDIAN payload - DWord values must be byte-reversed
+// (hence the affinity for byte pointer building).


+
+static int build_FCP_payload( Scsi_Cmnd *Cmnd,
+ UCHAR* payload, ULONG type, ULONG fcp_dl )
+{

+ int i;
+
+

+ switch( type)
+ {
+
+ case SCSI_IWE:
+ case SCSI_IRE:
+ // 8 bytes FCP_LUN
+ // Peripheral Device or Volume Set addressing, and LUN mapping
+ // When the FC port was looked up, we copied address mode
+ // and any LUN mask to the scratch pad SCp.phase & .mode
+
+ *payload++ = (UCHAR)Cmnd->SCp.phase;
+
+ // Now, because of "lun masking"
+ // (aka selective storage presentation),
+ // the contiguous Linux Scsi lun number may not match the
+ // device's lun number, so we may have to "map".
+
+ *payload++ = (UCHAR)Cmnd->SCp.have_data_in;
+
+ // We don't know of anyone in the FC business using these
+ // extra "levels" of addressing. In fact, confusion still exists
+ // just using the FIRST level... ;-)
+
+ *payload++ = 0; // 2nd level addressing
+ *payload++ = 0;
+ *payload++ = 0; // 3rd level addressing
+ *payload++ = 0;
+ *payload++ = 0; // 4th level addressing
+ *payload++ = 0;
+
+ // 4 bytes Control Field FCP_CNTL
+ *payload++ = 0; // byte 0: (MSB) reserved
+ *payload++ = 0; // byte 1: task codes
+ *payload++ = 0; // byte 2: task management flags
+ // byte 3: (LSB) execution management codes
+ // bit 0 write, bit 1 read (don't set together)
+
+ if( fcp_dl != 0 )
+ {
+ if( type == SCSI_IWE ) // WRITE
+ *payload++ = 1;
+ else // READ
+ *payload++ = 2;
+ }
+ else
+ {
+ // On some devices, if RD or WR bits are set,
+ // and fcp_dl is 0, they will generate an error on the command.
+ // (i.e., if direction is specified, they insist on a length).
+ *payload++ = 0; // no data (necessary for CPQ)
+ }
+
+
+ // NOTE: clean this up if/when MAX_COMMAND_SIZE is increased to 16
+ // FCP_CDB allows 16 byte SCSI command descriptor blk;
+ // Linux SCSI CDB array is MAX_COMMAND_SIZE (12 at this time...)
+ for( i=0; (i < Cmnd->cmd_len) && i < MAX_COMMAND_SIZE; i++)
+ *payload++ = Cmnd->cmnd[i];
+
+ if( Cmnd->cmd_len == 16 )
+ {
+ memcpy( payload, &Cmnd->SCp.buffers_residual, 4);
+ }
+ payload+= (16 - i);
+
+ // FCP_DL is largest number of expected data bytes
+ // per CDB (i.e. read/write command)
+ *payload++ = (UCHAR)(fcp_dl >>24); // (MSB) 8 bytes data len FCP_DL
+ *payload++ = (UCHAR)(fcp_dl >>16);
+ *payload++ = (UCHAR)(fcp_dl >>8);
+ *payload++ = (UCHAR)fcp_dl; // (LSB)
+ break;
+
+ case SCSI_TWE: // need FCP_XFER_RDY
+ *payload++ = 0; // (4 bytes) DATA_RO (MSB byte 0)
+ *payload++ = 0;
+ *payload++ = 0;
+ *payload++ = 0; // LSB (byte 3)
+ // (4 bytes) BURST_LEN
+ // size of following FCP_DATA payload
+ *payload++ = (UCHAR)(fcp_dl >>24); // (MSB) 8 bytes data len FCP_DL
+ *payload++ = (UCHAR)(fcp_dl >>16);
+ *payload++ = (UCHAR)(fcp_dl >>8);
+ *payload++ = (UCHAR)fcp_dl; // (LSB)
+ // 4 bytes RESERVED
+ *payload++ = 0;
+ *payload++ = 0;
+ *payload++ = 0;
+ *payload++ = 0;


+ break;
+
+ default:

+ break;
+ }
+
+ return 0;
+}
+
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/cpqioctl.c linux/drivers/scsi/cpqioctl.c
--- v2.4.0-test8/linux/drivers/scsi/cpqioctl.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/scsi/cpqioctl.c Tue Sep 19 08:01:35 2000
@@ -0,0 +1,76 @@
+// Test program for CPQFCTS ioctl calls
+// build with:
+// gcc -o cpqioctl cpqioctl.c
+// ld -o cpqioctl /lib/crt0.o cpqioctl.o -lc
+
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <linux/types.h>
+#include "../../include/scsi/scsi.h"
+#include "cpqfcTSioctl.h"
+
+typedef struct scsi_fctargaddress {
+ unsigned long host_port_id;
+ unsigned char host_wwn[8];
+} Scsi_FCTargAddress;
+
+int main(int argc, char **argv) {
+
+ int fd, i;
+ Scsi_FCTargAddress targ;
+ int uselect=0;
+
+
+
+ if ( argc < 2 ) {
+ printf("usage: cpqioctl <Devfile>\n");
+ exit(1);
+ }
+
+ if ( (fd = open(argv[1], O_RDONLY)) == -1) {
+ perror("open");
+ exit(1);
+ }
+
+ if ( ioctl(fd, SCSI_IOCTL_FC_TARGET_ADDRESS, &targ) ) {
+ perror("ioctl");
+ exit(1);
+ }
+
+
+ printf("portid: %08x. wwn: ", targ.host_port_id);
+
+ for (i=0;i<8;i++) printf(" %02x", targ.host_wwn[i]);
+ printf("\n");
+
+ while( uselect != 27 ) // not ESC key
+ {
+ printf("\n IOCTL \n");
+ printf( "1. Get PCI info\n");
+ printf( "2. Send Passthru\n");
+ printf( " ==> ");
+ scanf("%c", &uselect);
+
+ switch( uselect )
+ {
+ case '1':
+ {
+ cciss_pci_info_struct pciinfo;
+
+ if( ioctl( fd, CCPQFCTS_GETPCIINFO ,&pciinfo ))
+ perror("ioctl");
+ else
+ printf( "\nPCI bus %d, dev_fn %d, board_id %Xh\n",
+ pciinfo.bus, pciinfo.dev_fn, pciinfo.board_id);


+ }
+
+ }
+ }
+
+

+ close(fd);
+ return 0;
+}
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/cyberstorm.c linux/drivers/scsi/cyberstorm.c
--- v2.4.0-test8/linux/drivers/scsi/cyberstorm.c Fri Jan 28 08:04:58 2000
+++ linux/drivers/scsi/cyberstorm.c Mon Sep 18 13:36:25 2000
@@ -302,17 +302,13 @@


X }
X }
X
-#ifdef MODULE
-
X #define HOSTS_C
X

X #include "cyberstorm.h"
X
-Scsi_Host_Template driver_template = SCSI_CYBERSTORM;
+static Scsi_Host_Template driver_template = SCSI_CYBERSTORM;


X
X #include "scsi_module.c"
-
-#endif
X

X int cyber_esp_release(struct Scsi_Host *instance)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/cyberstormII.c linux/drivers/scsi/cyberstormII.c
--- v2.4.0-test8/linux/drivers/scsi/cyberstormII.c Fri Jan 28 08:04:58 2000
+++ linux/drivers/scsi/cyberstormII.c Mon Sep 18 13:36:25 2000
@@ -251,17 +251,14 @@


X }
X }
X
-#ifdef MODULE
-
X #define HOSTS_C
X

X #include "cyberstormII.h"
X
-Scsi_Host_Template driver_template = SCSI_CYBERSTORMII;
+static Scsi_Host_Template driver_template = SCSI_CYBERSTORMII;
X
X #include "scsi_module.c"
X
-#endif
X
X int cyberII_esp_release(struct Scsi_Host *instance)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/dc390.h linux/drivers/scsi/dc390.h
--- v2.4.0-test8/linux/drivers/scsi/dc390.h Fri Sep 8 12:54:35 2000
+++ linux/drivers/scsi/dc390.h Mon Sep 18 14:09:49 2000
@@ -18,8 +18,6 @@
X #define DC390_BANNER "Tekram DC390/AM53C974"
X #define DC390_VERSION "2.0d 1998/12/25"
X
-#if defined(HOSTS_C) || defined(MODULE)
-
X #include <scsi/scsicam.h>
X
X extern int DC390_detect(Scsi_Host_Template *psht);
@@ -52,7 +50,5 @@
X cmd_per_lun: 8, \
X use_clustering: DISABLE_CLUSTERING \
X }


-
-#endif /* defined(HOSTS_C) || defined(MODULE) */
X

X #endif /* DC390_H */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/dmx3191d.c linux/drivers/scsi/dmx3191d.c
--- v2.4.0-test8/linux/drivers/scsi/dmx3191d.c Mon Jun 19 13:42:40 2000
+++ linux/drivers/scsi/dmx3191d.c Mon Sep 18 13:36:25 2000
@@ -115,10 +115,6 @@


X }
X
X
-#ifdef MODULE

-Scsi_Host_Template driver_template = DMX3191D;
-
+static Scsi_Host_Template driver_template = DMX3191D;
X #include "scsi_module.c"
-
-#endif /* MODULE */
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/dmx3191d.h linux/drivers/scsi/dmx3191d.h
--- v2.4.0-test8/linux/drivers/scsi/dmx3191d.h Mon Mar 27 09:48:11 2000
+++ linux/drivers/scsi/dmx3191d.h Mon Sep 18 14:12:01 2000
@@ -32,7 +32,6 @@
X int dmx3191d_reset(Scsi_Cmnd *, unsigned int);
X
X
-#if defined(HOSTS_C) || defined(MODULE)
X #define DMX3191D { \
X proc_info: dmx3191d_proc_info, \
X name: "Domex DMX3191D", \
@@ -49,10 +48,8 @@
X cmd_per_lun: 2, \
X use_clustering: DISABLE_CLUSTERING \
X }
-#endif /* HOSTS_C || MODULE */
X
X
-#ifndef HOSTS_C
X #define NCR5380_read(reg) inb(port + reg)
X #define NCR5380_write(reg, value) outb(value, port + reg)
X
@@ -67,7 +64,6 @@
X #define NCR5380_queue_command dmx3191d_queue_command
X #define NCR5380_reset dmx3191d_reset
X
-#endif /* HOSTS_C */
X #endif /* ASM */
X
X #endif /* __DMX3191D_H */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/dtc.c linux/drivers/scsi/dtc.c
--- v2.4.0-test8/linux/drivers/scsi/dtc.c Fri Nov 19 11:30:54 1999
+++ linux/drivers/scsi/dtc.c Mon Sep 18 13:36:25 2000
@@ -432,9 +432,6 @@
X
X #include "NCR5380.c"


X
-#ifdef MODULE
X /* Eventually this will go into an include file, but this will be later */

-Scsi_Host_Template driver_template = DTC3x80;
-
+static Scsi_Host_Template driver_template = DTC3x80;
X #include "scsi_module.c"
-#endif
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/dtc.h linux/drivers/scsi/dtc.h
--- v2.4.0-test8/linux/drivers/scsi/dtc.h Sat Apr 11 11:13:25 1998
+++ linux/drivers/scsi/dtc.h Mon Sep 18 14:12:01 2000
@@ -55,8 +55,6 @@
X * macros when this is being used solely for the host stub.


X */
X
-#if defined(HOSTS_C) || defined(MODULE)

-
X #define DTC3x80 { \
X name: "DTC 3180/3280 ", \
X detect: dtc_detect, \
@@ -70,10 +68,6 @@
X cmd_per_lun: CMD_PER_LUN , \


X use_clustering: DISABLE_CLUSTERING}
X
-#endif
-
-#ifndef HOSTS_C
-

X #define NCR5380_implementation_fields \
X volatile unsigned int base
X
@@ -124,6 +118,5 @@
X #define DTC_IRQS 0x9c00


X
X
-#endif /* else def HOSTS_C */
X #endif /* ndef ASM */

X #endif /* DTC3280_H */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/eata.c linux/drivers/scsi/eata.c
--- v2.4.0-test8/linux/drivers/scsi/eata.c Mon Jun 19 13:42:40 2000
+++ linux/drivers/scsi/eata.c Mon Sep 18 13:36:25 2000
@@ -2292,12 +2292,11 @@
X return FALSE;
X }
X
-#if defined(MODULE)
-Scsi_Host_Template driver_template = EATA;
+static Scsi_Host_Template driver_template = EATA;
X
X #include "scsi_module.c"
X
-#else
+#ifndef MODULE
X
X #if LINUX_VERSION_CODE < LinuxVersionCode(2,3,18)
X void eata2x_setup(char *str, int *ints) {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/eata_dma.c linux/drivers/scsi/eata_dma.c
--- v2.4.0-test8/linux/drivers/scsi/eata_dma.c Mon Jun 19 13:42:40 2000
+++ linux/drivers/scsi/eata_dma.c Mon Sep 18 13:36:25 2000
@@ -1520,11 +1520,9 @@
X return(registered_HBAs);


X }
X
-#ifdef MODULE
X /* Eventually this will go into an include file, but this will be later */

-Scsi_Host_Template driver_template = EATA_DMA;
+static Scsi_Host_Template driver_template = EATA_DMA;


X #include "scsi_module.c"
-#endif
X
X /*
X * Overrides for Emacs so that we almost follow Linus's tabbing style.

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/eata_dma.h linux/drivers/scsi/eata_dma.h
--- v2.4.0-test8/linux/drivers/scsi/eata_dma.h Tue Jan 25 13:01:14 2000
+++ linux/drivers/scsi/eata_dma.h Mon Sep 18 14:12:01 2000
@@ -10,8 +10,6 @@
X #ifndef _EATA_DMA_H
X #define _EATA_DMA_H
X
-#ifndef HOSTS_C
-
X #include "eata_generic.h"
X
X
@@ -66,8 +64,6 @@
X #else
X #define DBG(x, y)
X #endif
-
-#endif /* !HOSTS_C */
X
X int eata_detect(Scsi_Host_Template *);
X const char *eata_info(struct Scsi_Host *);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/eata_pio.c linux/drivers/scsi/eata_pio.c
--- v2.4.0-test8/linux/drivers/scsi/eata_pio.c Mon Jun 19 13:42:40 2000
+++ linux/drivers/scsi/eata_pio.c Mon Sep 18 13:36:25 2000
@@ -985,12 +985,10 @@
X return (registered_HBAs);


X }
X
-#ifdef MODULE
X /* Eventually this will go into an include file, but this will be later */

-Scsi_Host_Template driver_template = EATA_PIO;
+static Scsi_Host_Template driver_template = EATA_PIO;


X
X #include "scsi_module.c"
-#endif
X
X /*
X * Overrides for Emacs so that we almost follow Linus's tabbing style.

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/esp.c linux/drivers/scsi/esp.c
--- v2.4.0-test8/linux/drivers/scsi/esp.c Mon Aug 28 21:20:03 2000
+++ linux/drivers/scsi/esp.c Mon Sep 18 13:36:25 2000
@@ -4364,10 +4364,8 @@


X return 0;
X }
X
-#ifdef MODULE

-Scsi_Host_Template driver_template = SCSI_SPARC_ESP;
+static Scsi_Host_Template driver_template = SCSI_SPARC_ESP;
X
X #include "scsi_module.c"
X
X EXPORT_NO_SYMBOLS;
-#endif /* MODULE */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/fastlane.c linux/drivers/scsi/fastlane.c
--- v2.4.0-test8/linux/drivers/scsi/fastlane.c Fri Jan 28 08:04:58 2000
+++ linux/drivers/scsi/fastlane.c Mon Sep 18 13:36:25 2000
@@ -349,17 +349,12 @@


X }
X }
X
-#ifdef MODULE
-
X #define HOSTS_C
X

X #include "fastlane.h"
X
-Scsi_Host_Template driver_template = SCSI_FASTLANE;
-
+static Scsi_Host_Template driver_template = SCSI_FASTLANE;


X #include "scsi_module.c"
-
-#endif
X

X int fastlane_esp_release(struct Scsi_Host *instance)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/fcal.c linux/drivers/scsi/fcal.c
--- v2.4.0-test8/linux/drivers/scsi/fcal.c Mon Dec 20 22:06:42 1999
+++ linux/drivers/scsi/fcal.c Mon Sep 18 13:36:25 2000
@@ -292,11 +292,8 @@


X return 0;
X }
X
-#ifdef MODULE

-
-Scsi_Host_Template driver_template = FCAL;
+static Scsi_Host_Template driver_template = FCAL;
X
X #include "scsi_module.c"
X
X EXPORT_NO_SYMBOLS;
-#endif /* MODULE */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/fd_mcs.c linux/drivers/scsi/fd_mcs.c
--- v2.4.0-test8/linux/drivers/scsi/fd_mcs.c Thu Nov 11 16:57:30 1999
+++ linux/drivers/scsi/fd_mcs.c Mon Sep 18 13:36:25 2000
@@ -1465,9 +1465,7 @@


X return 0;
X }
X
-#ifdef MODULE
X /* Eventually this will go into an include file, but this will be later */

-Scsi_Host_Template driver_template = FD_MCS;
+static Scsi_Host_Template driver_template = FD_MCS;


X
X #include "scsi_module.c"
-#endif

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/fdomain.c linux/drivers/scsi/fdomain.c
--- v2.4.0-test8/linux/drivers/scsi/fdomain.c Thu Jul 6 19:25:21 2000


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 078'
echo 'File patch-2.4.0-test9 is continued in part 079'
echo "079" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part084

#!/bin/sh -x
# this is part 084 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 084; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

X MODULE_PARM(spdif_loop, "i");
X MODULE_PARM(four_ch, "i");
X MODULE_PARM(rear_out, "i");
-
-int __init init_module(void)
X #else
X #ifdef CONFIG_SOUND_CMPCI_SPDIFLOOP
X static int spdif_loop = 1;
@@ -2305,9 +2303,9 @@
X #else
X static int rear_out = 0;
X #endif
-
-int __init init_cmpci(void)
X #endif
+
+static int __init init_cmpci(void)
X {
X struct cm_state *s;
X struct pci_dev *pcidev = NULL;
@@ -2372,28 +2370,25 @@
X continue;
X s->irq = pcidev->irq;
X
- if (check_region(s->iobase, CM_EXTENT_CODEC)) {
+ if (!request_region(s->iobase, CM_EXTENT_CODEC, "cmpci")) {
X printk(KERN_ERR "cmpci: io ports %#x-%#x in use\n", s->iobase, s->iobase+CM_EXTENT_CODEC-1);
X goto err_region5;
X }
- request_region(s->iobase, CM_EXTENT_CODEC, "cmpci");
- if (check_region(s->iomidi, CM_EXTENT_MIDI)) {
+ if (!request_region(s->iomidi, CM_EXTENT_MIDI, "cmpci Midi")) {
X printk(KERN_WARNING "cmpci: io ports %#x-%#x in use, midi disabled.\n", s->iomidi, s->iomidi+CM_EXTENT_MIDI-1);
X s->iomidi = 0;
X }
X else
X {
- request_region(s->iomidi, CM_EXTENT_MIDI, "cmpci Midi");
X /* set IO based at 0x330 */
X outb(inb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3) & ~0x60, s->iobase + CODEC_CMI_LEGACY_CTRL + 3);
X }
- if (check_region(s->iosynth, CM_EXTENT_SYNTH)) {
+ if (!request_region(s->iosynth, CM_EXTENT_SYNTH, "cmpci FM")) {
X printk(KERN_WARNING "cmpci: io ports %#x-%#x in use, synth disabled.\n", s->iosynth, s->iosynth+CM_EXTENT_SYNTH-1);
X s->iosynth = 0;
X }
X else
X {
- request_region(s->iosynth, CM_EXTENT_SYNTH, "cmpci FM");
X /* enable FM */
X outb(inb(s->iobase + CODEC_CMI_MISC_CTRL + 2) | 8, s->iobase + CODEC_CMI_MISC_CTRL);
X }
@@ -2499,12 +2494,10 @@
X
X /* --------------------------------------------------------------------- */
X
-#ifdef MODULE
-
X MODULE_AUTHOR("ChenLi Tien, clt...@home.com");
X MODULE_DESCRIPTION("CMPCI Audio Driver");
X
-void cleanup_module(void)
+static void __exit cleanup_cmpci(void)
X {
X struct cm_state *s;
X
@@ -2538,4 +2531,5 @@
X printk(KERN_INFO "cmpci: unloading\n");
X }


X
-#endif /* MODULE */

+module_init(init_cmpci);
+module_exit(cleanup_cmpci);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/cs4232.c linux/drivers/sound/cs4232.c
--- v2.4.0-test8/linux/drivers/sound/cs4232.c Fri Aug 11 08:26:43 2000
+++ linux/drivers/sound/cs4232.c Wed Sep 27 13:53:56 2000
@@ -39,6 +39,7 @@
X * Tropez+ (WaveFront) support
X * Christoph Hellwig Adapted to module_init/module_exit,
X * simple cleanups
+ * Arnaldo C. de Melo got rid of attach_uart401
X */
X
X #include <linux/config.h>
@@ -255,10 +256,9 @@
X hw_config2.driver_use_2 = 0;
X hw_config2.card_subtype = 0;
X
- if (probe_uart401(&hw_config2))
+ if (probe_uart401(&hw_config2, THIS_MODULE))
X {
X mpu_detected = 1;
- attach_uart401(&hw_config2, THIS_MODULE);
X }
X else
X {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/cs4281.c linux/drivers/sound/cs4281.c
--- v2.4.0-test8/linux/drivers/sound/cs4281.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/sound/cs4281.c Sat Sep 23 20:34:58 2000
@@ -0,0 +1,2678 @@
+//*****************************************************************************
+//
+// "cs4281.c" -- Cirrus Logic-Crystal CS4281 linux audio driver.
+//
+// Copyright (C) 2000 Cirrus Logic Corp.
+// -- adapted from drivers by Thomas Sailer,
+// -- but don't bug him; Problems should go to:
+// -- gw boynton (we...@crystal.cirrus.com) or
+// -- tom woller (two...@crystal.cirrus.com).
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// Module command line parameters:
+// none
+//
+// Supported devices:
+// /dev/dsp standard /dev/dsp device, (mostly) OSS compatible
+// /dev/mixer standard /dev/mixer device, (mostly) OSS compatible
+// /dev/midi simple MIDI UART interface, no ioctl
+//
+//
+//
+
+// *****************************************************************************
+
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/sound.h>
+#include <linux/malloc.h>
+#include <linux/soundcard.h>
+#include <linux/pci.h>
+#include <linux/bitops.h>
+#include <linux/spinlock.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <asm/uaccess.h>
+#include <asm/hardirq.h>
+#include <linux/vmalloc.h>
+#include "dm.h"
+#include "cs4281_hwdefs.h"
+
+EXPORT_NO_SYMBOLS;
+
+#undef OSS_DOCUMENTED_MIXER_SEMANTICS
+
+// ---------------------------------------------------------------------
+
+#ifndef PCI_VENDOR_ID_CIRRUS
+#define PCI_VENDOR_ID_CIRRUS 0x1013
+#endif
+#ifndef PCI_DEVICE_ID_CRYSTAL_CS4281
+#define PCI_DEVICE_ID_CRYSTAL_CS4281 0x6005
+#endif
+
+#define CS4281_MAGIC ((PCI_DEVICE_ID_CRYSTAL_CS4281<<16) | PCI_VENDOR_ID_CIRRUS)
+
+#define CSDEBUG 1
+//
+// Turn on/off debugging compilation by using 1/0 respectively for CSDEBUG
+//
+//
+// CSDEBUG is usual mode is set to 1, then use the
+// cs_debuglevel and cs_debugmask to turn on or off debugging.
+// Debug level of 1 has been defined to be kernel errors and info
+// that should be printed on any released driver.
+//
+#if CSDEBUG
+extern unsigned cs_debugmask;
+extern unsigned cs_debuglevel;
+#define CS_DBGOUT(mask,level,x) if((cs_debuglevel >= (level)) && ((mask) & cs_debugmask)) {x;}
+#else
+#define CS_DBGOUT(mask,level,x)
+#endif
+//
+// cs_debugmask areas
+//
+#define CS_INIT 0x00000001 // initialization and probe functions
+#define CS_ERROR 0x00000002 // tmp debugging bit placeholder
+#define CS_INTERRUPT 0x00000004 // interrupt handler (separate from all other)
+#define CS_FUNCTION 0x00000008 // enter/leave functions
+#define CS_WAVE_WRITE 0x00000010 // write information for wave
+#define CS_WAVE_READ 0x00000020 // read information for wave
+#define CS_MIDI_WRITE 0x00000040 // write information for midi
+#define CS_MIDI_READ 0x00000080 // read information for midi
+#define CS_MPU401_WRITE 0x00000100 // write information for mpu401
+#define CS_MPU401_READ 0x00000200 // read information for mpu401
+#define CS_OPEN 0x00000400 // all open functions in the driver
+#define CS_RELEASE 0x00000800 // all release functions in the driver
+#define CS_PARMS 0x00001000 // functional and operational parameters
+#define CS_TMP 0x10000000 // tmp debug mask bit
+
+unsigned cs_debuglevel=1; // levels range from 1-9
+unsigned cs_debugmask=CS_INIT | CS_ERROR; // use CS_DBGOUT with various mask values
+#if MODULE
+MODULE_PARM(cs_debuglevel, "i");
+MODULE_PARM(cs_debugmask, "i");
+#endif
+
+// MIDI buffer sizes
+#define MIDIINBUF 500
+#define MIDIOUTBUF 500
+
+#define FMODE_MIDI_SHIFT 3
+#define FMODE_MIDI_READ (FMODE_READ << FMODE_MIDI_SHIFT)
+#define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT)
+
+#define RSRCISIOREGION(dev,num) ((dev)->resource[(num)].start != 0 && \
+ ((dev)->resource[(num)].flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
+#define RSRCISMEMORYREGION(dev,num) ((dev)->resource[(num)].start != 0 && \
+ ((dev)->resource[(num)].flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY)
+#define RSRCADDRESS(dev,num) ((dev)->resource[(num)].start)
+
+#define CS4281_MAJOR_VERSION 0
+#define CS4281_MINOR_VERSION 4
+#ifdef __ia64__
+#define CS4281_ARCH 64 //architecture key
+#else
+#define CS4281_ARCH 32 //architecture key
+#endif
+
+struct cs4281_state {
+ // magic
+ unsigned int magic;
+
+ // we keep the cards in a linked list
+ struct cs4281_state *next;
+
+ // pcidev is needed to turn off the DDMA controller at driver shutdown
+ struct pci_dev *pcidev;
+
+ // soundcore stuff
+ int dev_audio;
+ int dev_mixer;
+ int dev_midi;
+
+ // hardware resources
+ unsigned int pBA0phys, pBA1phys;
+ char *pBA0, *pBA1;
+ unsigned int irq;
+ int endofbuffer;
+
+ // mixer registers
+ struct {
+ unsigned short vol[10];
+ unsigned int recsrc;
+ unsigned int modcnt;
+ unsigned short micpreamp;
+ } mix;
+
+ // wave stuff // Note that play & record formats must be the same *wb.
+ unsigned fmt;
+ unsigned channels;
+ unsigned rate;
+ unsigned char clkdiv;
+ unsigned ena;
+
+ spinlock_t lock;
+ struct semaphore open_sem;
+ mode_t open_mode;
+ wait_queue_head_t open_wait;
+
+ struct dmabuf {
+ void *rawbuf; // Physical address of
+ dma_addr_t dmaaddr;
+ unsigned buforder; // Log base 2 of 'rawbuf' size in bytes..
+ unsigned numfrag; // # of 'fragments' in the buffer.
+ unsigned fragshift; // Log base 2 of fragment size.
+ unsigned hwptr, swptr;
+ unsigned total_bytes; // # bytes process since open.
+ unsigned blocks; // last returned blocks value GETOPTR
+ int count;
+ unsigned error; // over/underrun
+ wait_queue_head_t wait;
+ // redundant, but makes calculations easier
+ unsigned fragsize; // 2**fragshift..
+ unsigned dmasize; // 2**buforder.
+ unsigned fragsamples;
+ // OSS stuff
+ unsigned mapped:1; // Buffer mapped in cs4281_mmap()?
+ unsigned ready:1; // prog_dmabuf_dac()/adc() successful?
+ unsigned endcleared:1;
+ unsigned ossfragshift;
+ int ossmaxfrags;
+ unsigned subdivision;
+ } dma_dac, dma_adc;
+
+ // midi stuff
+ struct {
+ unsigned ird, iwr, icnt;
+ unsigned ord, owr, ocnt;
+ wait_queue_head_t iwait;
+ wait_queue_head_t owait;
+ struct timer_list timer;
+ unsigned char ibuf[MIDIINBUF];
+ unsigned char obuf[MIDIOUTBUF];
+ } midi;
+
+};
+
+
+struct cs4281_state *devs = NULL;
+// ---------------------------------------------------------------------
+//
+// Hardware Interfaces For the CS4281
+//
+
+
+//******************************************************************************
+// "delayus()-- Delay for the specified # of microseconds.
+//******************************************************************************
+static void delayus(u32 delay)
+{
+ u32 j;
+ if(delay > 9999)
+ {
+ j = (delay * HZ)/1000000; /* calculate delay in jiffies */
+ if(j<1)
+ j=1; /* minimum one jiffy. */


+ current->state = TASK_UNINTERRUPTIBLE;

+ schedule_timeout(j);
+ }
+ else
+ udelay(delay);


+ return;
+}
+
+

+//******************************************************************************
+// "cs4281_read_ac97" -- Reads a word from the specified location in the
+// CS4281's address space(based on the BA0 register).
+//
+// 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
+// 2. Write ACCDA = Command Data Register = 470h for data to write to AC97 register,
+// 0h for reads.
+// 3. Write ACCTL = Control Register = 460h for initiating the write
+// 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 17h
+// 5. if DCV not cleared, break and return error
+// 6. Read ACSTS = Status Register = 464h, check VSTS bit
+//****************************************************************************
+static int cs4281_read_ac97(struct cs4281_state *card, u32 offset, u32 *value)
+{
+ u32 count, status;
+
+ // Make sure that there is not data sitting
+ // around from a previous uncompleted access.
+ // ACSDA = Status Data Register = 47Ch
+ status = readl(card->pBA0+BA0_ACSDA);
+
+ // Setup the AC97 control registers on the CS4281 to send the
+ // appropriate command to the AC97 to perform the read.
+ // ACCAD = Command Address Register = 46Ch
+ // ACCDA = Command Data Register = 470h
+ // ACCTL = Control Register = 460h
+ // bit DCV - will clear when process completed
+ // bit CRW - Read command
+ // bit VFRM - valid frame enabled
+ // bit ESYN - ASYNC generation enabled
+
+ // Get the actual AC97 register from the offset
+ writel(offset - BA0_AC97_RESET, card->pBA0+BA0_ACCAD);
+ writel(0, card->pBA0+BA0_ACCDA);
+ writel(ACCTL_DCV | ACCTL_CRW | ACCTL_VFRM | ACCTL_ESYN, card->pBA0+BA0_ACCTL);
+
+ // Wait for the read to occur.
+ for(count = 0; count < 10; count++)
+ {
+ // First, we want to wait for a short time.
+ udelay(25);
+
+ // Now, check to see if the read has completed.
+ // ACCTL = 460h, DCV should be reset by now and 460h = 17h
+ if( !(readl(card->pBA0+BA0_ACCTL) & ACCTL_DCV))
+ break;
+ }
+
+ // Make sure the read completed.
+ if(readl(card->pBA0+BA0_ACCTL) & ACCTL_DCV)
+ return 1;
+
+ // Wait for the valid status bit to go active.
+ for(count = 0; count < 10; count++)
+ {
+ // Read the AC97 status register.
+ // ACSTS = Status Register = 464h
+ status = readl(card->pBA0+BA0_ACSTS);
+
+ // See if we have valid status.
+ // VSTS - Valid Status
+ if(status & ACSTS_VSTS)
+ break;
+ // Wait for a short while.
+ udelay(25);
+ }
+
+ // Make sure we got valid status.
+ if(!(status & ACSTS_VSTS))
+ return 1;
+
+ // Read the data returned from the AC97 register.
+ // ACSDA = Status Data Register = 474h
+ *value = readl(card->pBA0+BA0_ACSDA);
+
+ // Success.
+ return(0);
+}
+
+
+//****************************************************************************
+//
+// "cs4281_write_ac97()"-- writes a word to the specified location in the
+// CS461x's address space (based on the part's base address zero register).
+//
+// 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
+// 2. Write ACCDA = Command Data Register = 470h for data to write to AC97 reg.
+// 3. Write ACCTL = Control Register = 460h for initiating the write
+// 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 07h
+// 5. if DCV not cleared, break and return error
+//
+//****************************************************************************
+static int cs4281_write_ac97(struct cs4281_state *card, u32 offset, u32 value)
+{
+ u32 count, status;
+
+ CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_INFO "cs4281: cs_4281_write_ac97()+ \n") );
+
+ // Setup the AC97 control registers on the CS4281 to send the
+ // appropriate command to the AC97 to perform the read.
+ // ACCAD = Command Address Register = 46Ch
+ // ACCDA = Command Data Register = 470h
+ // ACCTL = Control Register = 460h
+ // set DCV - will clear when process completed
+ // reset CRW - Write command
+ // set VFRM - valid frame enabled
+ // set ESYN - ASYNC generation enabled
+ // set RSTN - ARST# inactive, AC97 codec not reset
+
+ // Get the actual AC97 register from the offset
+
+ writel(offset - BA0_AC97_RESET, card->pBA0+BA0_ACCAD);
+ writel(value, card->pBA0+BA0_ACCDA);
+ writel(ACCTL_DCV | ACCTL_VFRM | ACCTL_ESYN, card->pBA0+BA0_ACCTL);
+
+ // Wait for the write to occur.
+ for(count = 0; count < 10; count++)
+ {
+ // First, we want to wait for a short time.
+ udelay(25);
+ // Now, check to see if the write has completed.
+ // ACCTL = 460h, DCV should be reset by now and 460h = 07h
+ status = readl(card->pBA0+BA0_ACCTL);
+ if(!(status & ACCTL_DCV))
+ break;
+ }
+
+ // Make sure the write completed.
+ if(status & ACCTL_DCV)
+ {
+ CS_DBGOUT(CS_ERROR, 1, printk(KERN_INFO
+ "cs4281: cs_4281_write_ac97()- unable to write. ACCTL_DCV active\n") );
+ return 1;
+ }
+ CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_INFO "cs4281: cs_4281_write_ac97()- 0\n") );
+ // Success.


+ return 0;
+}
+

+
+//******************************************************************************
+// "Init4281()" -- Bring up the part.
+//******************************************************************************
+static int cs4281_hw_init(struct cs4281_state *card)
+{
+ u32 ac97_slotid;
+ u32 temp1, temp2;
+
+ CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_INFO "cs4281: cs4281_hw_init()+ \n") );
+ //***************************************7
+ // Set up the Sound System Configuration
+ //***************************************
+
+ // Set the 'Configuration Write Protect' register
+ // to 4281h. Allows vendor-defined configuration
+ // space between 0e4h and 0ffh to be written.
+
+ writel(0x4281, card->pBA0+BA0_CWPR); // (3e0h)
+
+ // (0), Blast the clock control register to zero so that the
+ // PLL starts out in a known state, and blast the master serial
+ // port control register to zero so that the serial ports also
+ // start out in a known state.
+
+ writel(0, card->pBA0+BA0_CLKCR1); // (400h)
+ writel(0, card->pBA0+BA0_SERMC); // (420h)
+
+
+ // (1), Make ESYN go to zero to turn off
+ // the Sync pulse on the AC97 link.
+
+ writel(0, card->pBA0+BA0_ACCTL);
+ udelay(50);
+
+
+ // (2) Drive the ARST# pin low for a minimum of 1uS (as defined in
+ // the AC97 spec) and then drive it high. This is done for non
+ // AC97 modes since there might be logic external to the CS461x
+ // that uses the ARST# line for a reset.
+
+ writel(0, card->pBA0+BA0_SPMC); // (3ech)
+ udelay(100);
+ writel(SPMC_RSTN, card->pBA0+BA0_SPMC);
+ delayus(50000); // Wait 50 ms for ABITCLK to become stable.
+
+ // (3) Turn on the Sound System Clocks.
+ writel(CLKCR1_PLLP, card->pBA0+BA0_CLKCR1); // (400h)
+ delayus(50000); // Wait for the PLL to stabilize.
+ // Turn on clocking of the core (CLKCR1(400h) = 0x00000030)
+ writel(CLKCR1_PLLP | CLKCR1_SWCE, card->pBA0+BA0_CLKCR1);
+
+ // (4) Power on everything for now..
+ writel(0x7E, card->pBA0 + BA0_SSPM); // (740h)
+
+ // (5) Wait for clock stabilization.
+ for(temp1=0; temp1<1000; temp1++)
+ {
+ udelay(1000);
+ if(readl(card->pBA0+BA0_CLKCR1) & CLKCR1_DLLRDY)
+ break;
+ }
+ if(!(readl(card->pBA0+BA0_CLKCR1) & CLKCR1_DLLRDY))
+ {
+ CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR "cs4281: DLLRDY failed!\n") );


+ return -EIO;
+ }
+

+ // (6) Enable ASYNC generation.
+ writel(ACCTL_ESYN, card->pBA0+BA0_ACCTL); // (460h)
+
+ // Now wait 'for a short while' to allow the AC97
+ // part to start generating bit clock. (so we don't
+ // Try to start the PLL without an input clock.)
+ delayus(50000);
+
+ // Set the serial port timing configuration, so that the
+ // clock control circuit gets its clock from the right place.
+ writel(SERMC_PTC_AC97, card->pBA0+BA0_SERMC); // (420h)=2.
+
+ // (7) Wait for the codec ready signal from the AC97 codec.
+
+ for(temp1=0; temp1<1000; temp1++)
+ {
+ // Delay a mil to let things settle out and
+ // to prevent retrying the read too quickly.
+ udelay(1000);
+ if( readl(card->pBA0+BA0_ACSTS) & ACSTS_CRDY ) // If ready, (464h)
+ break; // exit the 'for' loop.
+ }
+ if( !(readl(card->pBA0+BA0_ACSTS) & ACSTS_CRDY) ) // If never came ready,
+ {
+ CS_DBGOUT(CS_FUNCTION, 2,
+ printk(KERN_ERR "cs4281: ACSTS never came ready!\n") );
+ return -EIO; // exit initialization.
+ }
+
+ // (8) Assert the 'valid frame' signal so we can
+ // begin sending commands to the AC97 codec.
+ writel(ACCTL_VFRM | ACCTL_ESYN, card->pBA0+BA0_ACCTL); // (460h)
+
+ // (9), Wait until CODEC calibration is finished.
+ // Print an error message if it doesn't.
+ for(temp1 = 0; temp1 < 1000; temp1++)
+ {
+ delayus(10000);
+ // Read the AC97 Powerdown Control/Status Register.
+ cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp2);
+ if( (temp2 & 0x0000000F) == 0x0000000F )
+ break;
+ }
+ if ( (temp2 & 0x0000000F) != 0x0000000F )
+ {
+ CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_ERR
+ "cs4281: Codec failed to calibrate. Status = %.8x.\n", temp2) );


+ return -EIO;
+ }
+

+ // (10), Set the serial port timing configuration, so that the
+ // clock control circuit gets its clock from the right place.
+ writel(SERMC_PTC_AC97, card->pBA0+BA0_SERMC); // (420h)=2.
+
+
+ // (11) Wait until we've sampled input slots 3 & 4 as valid, meaning
+ // that the codec is pumping ADC data across the AC link.
+ for(temp1=0; temp1<1000; temp1++)
+ {
+ // Delay a mil to let things settle out and
+ // to prevent retrying the read too quickly.
+ delayus(1000); //(test)
+
+ // Read the input slot valid register; See
+ // if input slots 3 and 4 are valid yet.
+ if( (readl(card->pBA0+BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4) )
+ == (ACISV_ISV3 | ACISV_ISV4))
+ break; // Exit the 'for' if slots are valid.
+ }
+ // If we never got valid data, exit initialization.
+ if( (readl(card->pBA0+BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4) )
+ != (ACISV_ISV3 | ACISV_ISV4))
+ {
+ CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_ERR "cs4281: Never got valid data!\n"));
+ return -EIO; // If no valid data, exit initialization.
+ }
+
+ // (12), Start digital data transfer of audio data to the codec.
+ writel(ACOSV_SLV3 | ACOSV_SLV4, card->pBA0+BA0_ACOSV); // (468h)
+
+
+ //**************************************
+ // Unmute the Master and Alternate
+ // (headphone) volumes. Set to max.
+ //**************************************
+ cs4281_write_ac97(card,BA0_AC97_HEADPHONE_VOLUME, 0);
+ cs4281_write_ac97(card,BA0_AC97_MASTER_VOLUME, 0);
+
+ //******************************************
+ // Power on the DAC(AddDACUser()from main())
+ //******************************************
+ cs4281_read_ac97(card,BA0_AC97_POWERDOWN, &temp1);
+ cs4281_write_ac97(card,BA0_AC97_POWERDOWN, temp1 &= 0xfdff);
+
+ // Wait until we sample a DAC ready state.
+ for(temp2=0; temp2<32; temp2++)
+ {
+ // Let's wait a mil to let things settle.
+ delayus(1000);
+ // Read the current state of the power control reg.
+ cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1);
+ // If the DAC ready state bit is set, stop waiting.
+ if(temp1 & 0x2)
+ break;
+ }
+
+ //******************************************
+ // Power on the ADC(AddADCUser()from main())
+ //******************************************
+ cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1);
+ cs4281_write_ac97(card, BA0_AC97_POWERDOWN, temp1 &= 0xfeff);
+
+ // Wait until we sample ADC ready state.
+ for(temp2=0; temp2<32; temp2++)
+ {
+ // Let's wait a mil to let things settle.
+ delayus(1000);
+ // Read the current state of the power control reg.
+ cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1);
+ // If the ADC ready state bit is set, stop waiting.
+ if(temp1 & 0x1)
+ break;
+ }
+ // Set up 4281 Register contents that
+ // don't change for boot duration.
+
+ // For playback, we map AC97 slot 3 and 4(Left
+ // & Right PCM playback) to DMA Channel 0.
+ // Set the fifo to be 15 bytes at offset zero.
+
+ ac97_slotid = 0x01000f00; // FCR0.RS[4:0]=1(=>slot4, right PCM playback).
+ // FCR0.LS[4:0]=0(=>slot3, left PCM playback).
+ // FCR0.SZ[6-0]=15; FCR0.OF[6-0]=0.
+ writel(ac97_slotid, card->pBA0 + BA0_FCR0); // (180h)
+ writel(ac97_slotid | FCRn_FEN, card->pBA0 + BA0_FCR0); // Turn on FIFO Enable.
+
+ // For capture, we map AC97 slot 10 and 11(Left
+ // and Right PCM Record) to DMA Channel 1.
+ // Set the fifo to be 15 bytes at offset sixteen.
+ ac97_slotid = 0x0B0A0f10; // FCR1.RS[4:0]=11(=>slot11, right PCM record).
+ // FCR1.LS[4:0]=10(=>slot10, left PCM record).
+ // FCR1.SZ[6-0]=15; FCR1.OF[6-0]=16.
+ writel(ac97_slotid | FCRn_PSH, card->pBA0 + BA0_FCR1); // (184h)
+ writel(ac97_slotid | FCRn_FEN, card->pBA0 + BA0_FCR1); // Turn on FIFO Enable.
+
+ // Map the Playback SRC to the same AC97 slots(3 & 4--
+ // --Playback left & right)as DMA channel 0.
+ // Map the record SRC to the same AC97 slots(10 & 11--
+ // -- Record left & right) as DMA channel 1.
+
+ ac97_slotid = 0x0b0a0100; // SCRSA.PRSS[4:0]=1(=>slot4, right PCM playback).
+ // SCRSA.PLSS[4:0]=0(=>slot3, left PCM playback).
+ // SCRSA.CRSS[4:0]=11(=>slot11, right PCM record)
+ // SCRSA.CLSS[4:0]=10(=>slot10, left PCM record).
+ writel(ac97_slotid, card->pBA0 + BA0_SRCSA); // (75ch)
+
+ // Set 'Half Terminal Count Interrupt Enable' and 'Terminal
+ // Count Interrupt Enable' in DMA Control Registers 0 & 1.
+ // Set 'MSK' flag to 1 to keep the DMA engines paused.
+ temp1 = (DCRn_HTCIE | DCRn_TCIE | DCRn_MSK); // (00030001h)
+ writel(temp1, card->pBA0 + BA0_DCR0); // (154h
+ writel(temp1, card->pBA0 + BA0_DCR1); // (15ch)
+
+ // Set 'Auto-Initialize Control' to 'enabled'; For playback,
+ // set 'Transfer Type Control'(TR[1:0]) to 'read transfer',
+ // for record, set Transfer Type Control to 'write transfer'.
+ // All other bits set to zero; Some will be changed @ transfer start.
+ temp1 = (DMRn_DMA | DMRn_AUTO | DMRn_TR_READ); // (20000018h)
+ writel(temp1, card->pBA0 + BA0_DMR0); // (150h)
+ temp1 = (DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE); // (20000014h)
+ writel(temp1, card->pBA0 + BA0_DMR1); // (158h)
+
+ // Enable DMA interrupts generally, and
+ // DMA0 & DMA1 interrupts specifically.
+ temp1 = readl(card->pBA0 + BA0_HIMR) & 0xfffbfcff;
+ writel(temp1, card->pBA0+BA0_HIMR);
+
+ CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_INFO "cs4281: cs4281_hw_init()- 0\n") );


+ return 0;
+}
+

+
+//******************************************************************************
+// "cs4281_play_rate()" --
+//******************************************************************************
+static void cs4281_play_rate(struct cs4281_state *card, u32 playrate)
+{
+ u32 DACSRvalue = 1;
+
+ // Based on the sample rate, program the DACSR register.
+ if(playrate == 8000)
+ DACSRvalue = 5;
+ if(playrate == 11025)
+ DACSRvalue = 4;
+ else if(playrate == 22050)
+ DACSRvalue = 2;
+ else if(playrate == 44100)
+ DACSRvalue = 1;
+ else if((playrate <= 48000) && (playrate >= 6023))
+ DACSRvalue = 24576000/(playrate*16);
+ else if(playrate < 6023)
+ // Not allowed by open.
+ return;
+ else if(playrate > 48000)
+ // Not allowed by open.
+ return;
+ CS_DBGOUT(CS_WAVE_WRITE | CS_PARMS, 2, printk(KERN_INFO
+ "cs4281: cs4281_play_rate(): DACSRvalue=0x%.8x playrate=%d\n",
+ DACSRvalue,playrate));
+ // Write the 'sample rate select code'
+ // to the 'DAC Sample Rate' register.
+ writel(DACSRvalue, card->pBA0 + BA0_DACSR); // (744h)
+}
+
+//******************************************************************************
+// "cs4281_record_rate()" -- Initialize the record sample rate converter.
+//******************************************************************************
+static void cs4281_record_rate(struct cs4281_state *card, u32 outrate)
+{
+ u32 ADCSRvalue = 1;
+
+ //
+ // Based on the sample rate, program the ADCSR register
+ //
+ if(outrate == 8000)
+ ADCSRvalue = 5;
+ if(outrate == 11025)
+ ADCSRvalue = 4;
+ else if(outrate == 22050)
+ ADCSRvalue = 2;
+ else if(outrate == 44100)
+ ADCSRvalue = 1;
+ else if((outrate <= 48000) && (outrate >= 6023))
+ ADCSRvalue = 24576000/(outrate*16);
+ else if(outrate < 6023)
+ {
+ // Not allowed by open.
+ return;
+ }
+ else if(outrate > 48000)
+ {
+ // Not allowed by open.
+ return;
+ }
+ CS_DBGOUT(CS_WAVE_READ | CS_PARMS, 2, printk(KERN_INFO
+ "cs4281: cs4281_record_rate(): ADCSRvalue=0x%.8x outrate=%d\n",
+ ADCSRvalue,outrate) );
+ // Write the 'sample rate select code
+ // to the 'ADC Sample Rate' register.
+ writel(ADCSRvalue, card->pBA0 + BA0_ADCSR); // (748h)
+}
+
+
+
+static void stop_dac(struct cs4281_state *s)
+{
+ unsigned long flags;
+ unsigned temp1;
+
+ CS_DBGOUT(CS_WAVE_WRITE, 3, printk(KERN_INFO "cs4281: stop_dac():\n") );
+ spin_lock_irqsave(&s->lock, flags);
+ s->ena &= ~FMODE_WRITE;
+ temp1 = readl(s->pBA0+ BA0_DCR0) | DCRn_MSK;
+ writel(temp1, s->pBA0+BA0_DCR0);
+
+ spin_unlock_irqrestore(&s->lock, flags);
+}
+
+
+static void start_dac(struct cs4281_state *s)
+{
+ unsigned long flags;
+ unsigned temp1;
+
+ CS_DBGOUT(CS_WAVE_WRITE, 3, printk(KERN_INFO "cs4281: start_dac():\n") );
+ spin_lock_irqsave(&s->lock, flags);
+ if (!(s->ena & FMODE_WRITE) && (s->dma_dac.mapped ||
+ s->dma_dac.count > 0) && s->dma_dac.ready) {
+ s->ena |= FMODE_WRITE;
+ temp1 = readl(s->pBA0+BA0_DCR0) & ~DCRn_MSK; // Clear DMA0 channel mask.
+ writel(temp1, s->pBA0+BA0_DCR0); // Start DMA'ing.
+ writel(HICR_IEV | HICR_CHGM, s->pBA0+BA0_HICR); // Enable interrupts.
+
+ writel(7, s->pBA0+BA0_PPRVC);
+ writel(7, s->pBA0+BA0_PPLVC);
+
+ }
+ spin_unlock_irqrestore(&s->lock, flags);
+}
+
+
+static void stop_adc(struct cs4281_state *s)
+{
+ unsigned long flags;
+ unsigned temp1;
+
+ CS_DBGOUT(CS_WAVE_READ, 3, printk(KERN_INFO "cs4281: stop_adc():\n") );
+
+ spin_lock_irqsave(&s->lock, flags);
+ s->ena &= ~FMODE_READ;
+ temp1 = readl(s->pBA0+ BA0_DCR1) | DCRn_MSK;
+ writel(temp1, s->pBA0+BA0_DCR1);
+ spin_unlock_irqrestore(&s->lock, flags);
+}
+
+
+static void start_adc(struct cs4281_state *s)
+{
+ unsigned long flags;
+ unsigned temp1;
+
+ CS_DBGOUT(CS_WAVE_WRITE, 3, printk(KERN_INFO "cs4281: start_adc():\n") );
+
+ spin_lock_irqsave(&s->lock, flags);
+ if (!(s->ena & FMODE_READ) && (s->dma_adc.mapped
+ || s->dma_adc.count <=
+ (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize))
+ && s->dma_adc.ready)
+ {
+ s->ena |= FMODE_READ;
+ temp1 = readl(s->pBA0+BA0_DCR1) & ~ DCRn_MSK; // Clear DMA1 channel mask bit.
+ writel(temp1, s->pBA0+BA0_DCR1); // Start recording
+ writel(HICR_IEV | HICR_CHGM, s->pBA0+BA0_HICR); // Enable interrupts.
+ }
+ spin_unlock_irqrestore(&s->lock, flags);
+
+}
+
+
+// ---------------------------------------------------------------------
+#define DMABUF_DEFAULTORDER (15-PAGE_SHIFT) // == 3(for PC), = log base 2( buff sz = 32k).
+#define DMABUF_MINORDER 1 // ==> min buffer size = 8K.
+
+
+extern void dealloc_dmabuf(struct cs4281_state *s, struct dmabuf *db)
+{
+ struct page *map, *mapend;
+
+ if (db->rawbuf) {
+ // Undo prog_dmabuf()'s marking the pages as reserved
+ mapend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
+ for (map = virt_to_page(db->rawbuf); map <= mapend; map++)
+ clear_bit(PG_reserved, &map->flags);
+ pci_free_consistent(s->pcidev,PAGE_SIZE<<db->buforder,
+ db->rawbuf,db->dmaaddr);
+ }
+ db->rawbuf = NULL;
+ db->mapped = db->ready = 0;
+}
+
+static int prog_dmabuf(struct cs4281_state *s, struct dmabuf *db)
+{
+ int order;
+ unsigned bytespersec, temp1;
+ unsigned bufs, sample_shift = 0;
+ struct page *map, *mapend;
+
+ db->hwptr = db->swptr = db->total_bytes = db->count =
+ db->error = db->endcleared = db->blocks = 0;
+ if (!db->rawbuf) {
+ db->ready = db->mapped = 0;
+ for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
+ if ((db->rawbuf = (void *)pci_alloc_consistent(
+ s->pcidev, PAGE_SIZE << order, &db->dmaaddr)))
+ break;
+ if (!db->rawbuf)
+ {
+ CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
+ "cs4281: prog_dmabuf(): unable to allocate rawbuf\n") );
+ return -ENOMEM;
+ }
+ db->buforder = order;
+ // Now mark the pages as reserved; otherwise the
+ // remap_page_range() in cs4281_mmap doesn't work.
+ // 1. get index to last page in mem_map array for rawbuf.
+ mapend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
+
+ // 2. mark each physical page in range as 'reserved'.
+ for (map = virt_to_page(db->rawbuf); map <= mapend; map++)
+ set_bit(PG_reserved, &map->flags);
+ }
+ if (s->fmt & (AFMT_S16_LE | AFMT_U16_LE))
+ sample_shift++;
+ if (s->channels > 1)
+ sample_shift++;
+ bytespersec = s->rate << sample_shift;
+ bufs = PAGE_SIZE << db->buforder;
+
+
+#define INTERRUPT_RATE_MS 100 // Interrupt rate in milliseconds.
+ db->numfrag = 2;
+ temp1 = bytespersec/(1000/INTERRUPT_RATE_MS); // Nominal frag size(bytes/interrupt)
+ db->fragshift = 8; // Min 256 bytes.
+ while( 1 << db->fragshift < temp1) // Calc power of 2 frag size.
+ db->fragshift +=1;
+ db->fragsize = 1 << db->fragshift;
+ db->dmasize = db->fragsize * 2;
+
+ // If the calculated size is larger than the allocated
+ // buffer, divide the allocated buffer into 2 fragments.
+ if(db->dmasize > bufs) {
+ db->numfrag = 2; // Two fragments.
+ db->fragsize = bufs >> 1; // Each 1/2 the alloc'ed buffer.
+ db->fragsamples = db->fragsize >> sample_shift; // # samples/fragment.
+ db->dmasize = bufs; // Use all the alloc'ed buffer.
+
+ db->fragshift = 0; // Calculate 'fragshift'.
+ temp1 = db->fragsize; // update_ptr() uses it
+ while( (temp1 >>=1) > 1) // to calc 'total-bytes'
+ db->fragshift +=1; // returned in DSP_GETI/OPTR.
+ }
+ CS_DBGOUT(CS_PARMS, 3, printk(KERN_INFO
+ "cs4281: prog_dmabuf(): numfrag=%d fragsize=%d fragsamples=%d fragshift=%d\n",
+ db->numfrag,db->fragsize,db->fragsamples,db->fragshift) );


+ return 0;
+}
+

+
+static int prog_dmabuf_adc(struct cs4281_state *s)
+{
+ unsigned long va;
+ unsigned count;
+ int c;
+ stop_adc(s);
+ if ((c = prog_dmabuf(s, &s->dma_adc)))
+ return c;
+
+ va = virt_to_bus(s->dma_adc.rawbuf);
+
+ count = s->dma_adc.dmasize;
+
+ if(s->fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE))
+ count /= 2; // 16-bit.
+
+ if(s->channels > 1)
+ count /= 2; // Assume stereo.
+
+ CS_DBGOUT(CS_WAVE_READ, 3, printk(KERN_INFO
+ "cs4281: prog_dmabuf_adc(): count=%d va=0x%.8x\n", count,(unsigned)va) );
+
+ writel(va, s->pBA0+BA0_DBA1); // Set buffer start address.
+ writel(count-1, s->pBA0+BA0_DBC1); // Set count.
+ s->dma_adc.ready = 1;


+ return 0;
+}
+

+
+static int prog_dmabuf_dac(struct cs4281_state *s)
+{
+ unsigned long va;
+ unsigned count;
+ int c;
+ stop_dac(s);
+ if ((c = prog_dmabuf(s, &s->dma_dac)))
+ return c;
+ memset(s->dma_dac.rawbuf, (s->fmt & (AFMT_U8 | AFMT_U16_LE))
+ ? 0x80 : 0, s->dma_dac.dmasize);
+
+ va = virt_to_bus(s->dma_dac.rawbuf);
+
+ count = s->dma_dac.dmasize;
+ if(s->fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE))
+ count /= 2; // 16-bit.
+
+ if(s->channels > 1)
+ count /= 2; // Assume stereo.
+
+ writel(va, s->pBA0+BA0_DBA0); // Set buffer start address.
+ writel(count-1, s->pBA0+BA0_DBC0); // Set count.
+
+ CS_DBGOUT(CS_WAVE_WRITE, 3, printk(KERN_INFO
+ "cs4281: prog_dmabuf_dac(): count=%d va=0x%.8x\n", count,(unsigned)va) );
+
+ s->dma_dac.ready = 1;


+ return 0;
+}
+

+
+static void clear_advance(void *buf, unsigned bsize, unsigned bptr, unsigned len, unsigned char c)
+{
+ if (bptr + len > bsize) {
+ unsigned x = bsize - bptr;
+ memset(((char *)buf) + bptr, c, x);
+ bptr = 0;
+ len -= x;
+ }
+ CS_DBGOUT(CS_WAVE_WRITE, 4, printk(KERN_INFO
+ "cs4281: clear_advance(): memset %d at 0x%.8x for %d size \n",
+ (unsigned)c,(unsigned)((char *)buf) + bptr, len) );
+ memset(((char *)buf) + bptr, c, len);
+}
+
+
+
+// call with spinlock held!
+static void cs4281_update_ptr(struct cs4281_state *s)
+{
+ int diff;
+ unsigned hwptr, va, temp1;
+
+ // update ADC pointer
+ if (s->ena & FMODE_READ) {
+ hwptr = readl(s->pBA0+BA0_DCA1); // Read capture DMA address.
+ va = virt_to_bus(s->dma_adc.rawbuf);
+ hwptr -= (unsigned)va;
+ diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize;
+ s->dma_adc.hwptr = hwptr;
+ s->dma_adc.total_bytes += diff;
+ s->dma_adc.count += diff;
+ if (s->dma_adc.mapped) {
+ if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
+ wake_up(&s->dma_adc.wait);
+ } else {
+ if (s->dma_adc.count > 0)
+ wake_up(&s->dma_adc.wait);
+ }
+ CS_DBGOUT(CS_PARMS, 8, printk(KERN_INFO
+ "cs4281: cs4281_update_ptr(): s=0x%.8x hwptr=%d total_bytes=%d count=%d \n",
+ (unsigned)s,s->dma_adc.hwptr,s->dma_adc.total_bytes,s->dma_adc.count) );
+ }
+ // update DAC pointer
+ //
+ // check for end of buffer, means that we are going to wait for another interrupt
+ // to allow silence to fill the fifos on the part, to keep pops down to a minimum.
+ //
+ if ( (s->ena & FMODE_WRITE) && (!s->endofbuffer) )
+ {
+ hwptr = readl(s->pBA0+BA0_DCA0); // Read play DMA address.
+ va = virt_to_bus(s->dma_dac.rawbuf);
+ hwptr -= (unsigned)va;
+ diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize;
+ s->dma_dac.hwptr = hwptr;
+ s->dma_dac.total_bytes += diff;
+ if (s->dma_dac.mapped) {
+ s->dma_dac.count += diff;
+ if (s->dma_dac.count >= (signed)s->dma_dac.fragsize)
+ wake_up(&s->dma_dac.wait);
+ } else {
+ s->dma_dac.count -= diff;
+ if (s->dma_dac.count <= 0) {
+ s->ena &= ~FMODE_WRITE;
+ temp1 = readl(s->pBA0+BA0_DCR0);
+ //
+ // fill with silence, and wait on turning off the DAC until interrupt routine.
+ // wait on "Poke(pBA0+BA0_DCR0, temp1 | DCRn_MSK); // Stop Play DMA"
+ //
+ CS_DBGOUT(CS_WAVE_WRITE, 6, printk(KERN_INFO
+ "cs4281: cs4281_update_ptr(): memset %d at 0x%.8x for %d size \n",
+ (unsigned)(s->fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0,
+ (unsigned)s->dma_dac.rawbuf, s->dma_dac.dmasize) );
+ memset(s->dma_dac.rawbuf, (s->fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0,
+ s->dma_dac.dmasize);
+ s->endofbuffer = 1;
+ } else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize
+ && !s->dma_dac.endcleared) {
+ clear_advance(s->dma_dac.rawbuf,
+ s->dma_dac.dmasize, s->dma_dac.swptr,
+ s->dma_dac.fragsize,
+ (s->fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0);
+ s->dma_dac.endcleared = 1;
+ }
+ if (s->dma_dac.count < (signed)s->dma_dac.dmasize)
+ wake_up(&s->dma_dac.wait);
+ }
+ CS_DBGOUT(CS_PARMS, 8, printk(KERN_INFO
+ "cs4281: cs4281_update_ptr(): s=0x%.8x hwptr=%d total_bytes=%d count=%d \n",
+ (unsigned)s,s->dma_dac.hwptr,s->dma_dac.total_bytes,s->dma_dac.count) );
+ }
+}
+
+
+// ---------------------------------------------------------------------
+
+static void prog_codec(struct cs4281_state *s)
+{
+ unsigned long flags;
+ unsigned temp1, format;
+
+ CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO "cs4281: prog_codec()+ \n") );
+
+ spin_lock_irqsave(&s->lock, flags);
+ temp1 = readl(s->pBA0+BA0_DCR0);
+ writel(temp1 | DCRn_MSK, s->pBA0+BA0_DCR0); // Stop play DMA, if active.
+ temp1 = readl(s->pBA0+BA0_DCR1);
+ writel(temp1 | DCRn_MSK, s->pBA0+BA0_DCR1); // Stop capture DMA, if active.
+
+ // program sampling rates
+ // Note, for CS4281, capture & play rates can be set independently.
+ cs4281_record_rate(s, s->rate);
+
+ // program ADC parameters
+ format = DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE;
+ if(s->fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE)) { // 16-bit
+ if(s->fmt & (AFMT_S16_BE | AFMT_U16_BE)) // Big-endian?
+ format |= DMRn_BEND;
+ if(s->fmt & (AFMT_U16_LE | AFMT_U16_BE))
+ format |= DMRn_USIGN; // Unsigned.
+ }
+ else
+ format |= DMRn_SIZE8 | DMRn_USIGN; // 8-bit, unsigned
+ if(s->channels < 2)
+ format |= DMRn_MONO;
+
+ writel(format, s->pBA0+BA0_DMR1);
+
+
+ // program DAC parameters
+ format = DMRn_DMA | DMRn_AUTO | DMRn_TR_READ;
+ if(s->fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE)) { // 16-bit
+ if(s->fmt & (AFMT_S16_BE | AFMT_U16_BE))
+ format |= DMRn_BEND; // Big Endian.
+ if(s->fmt & (AFMT_U16_LE | AFMT_U16_BE))
+ format |= DMRn_USIGN; // Unsigned.
+ }
+ else
+ format |= DMRn_SIZE8 | DMRn_USIGN; // 8-bit, unsigned
+
+ if(s->channels < 2)
+ format |= DMRn_MONO;
+
+ writel(format, s->pBA0+BA0_DMR0);
+
+ CS_DBGOUT(CS_PARMS, 2, printk(KERN_INFO
+ "cs4281: prog_codec(): format=0x%.8x rate=%d\n", format,s->rate) );
+
+ cs4281_play_rate(s, s->rate);
+
+ s->ena = 0; // Neither writing or reading.
+ spin_unlock_irqrestore(&s->lock, flags);
+}
+
+
+// ---------------------------------------------------------------------
+
+static const char invalid_magic[] = KERN_CRIT "cs4281: invalid magic value\n";
+
+#define VALIDATE_STATE(s) \
+({ \
+ if (!(s) || (s)->magic != CS4281_MAGIC) { \
+ printk(invalid_magic); \
+ return -ENXIO; \
+ } \
+})
+
+// ---------------------------------------------------------------------
+
+
+static int mixer_ioctl(struct cs4281_state *s, unsigned int cmd, unsigned long arg)
+{
+ // Index to mixer_src[] is value of AC97 Input Mux Select Reg.
+ // Value of array member is recording source Device ID Mask.
+ static const unsigned int mixer_src[8] = {
+ SOUND_MASK_MIC, SOUND_MASK_CD, 0, SOUND_MASK_LINE1,
+ SOUND_MASK_LINE, SOUND_MASK_VOLUME, 0, 0
+ };
+
+ // Index of mixtable1[] member is Device ID
+ // and must be <= SOUND_MIXER_NRDEVICES.
+ // Value of array member is index into s->mix.vol[]
+ static const unsigned char mixtable1[SOUND_MIXER_NRDEVICES] = {
+ [SOUND_MIXER_PCM] = 1, // voice
+ [SOUND_MIXER_LINE1] = 2, // AUX
+ [SOUND_MIXER_CD] = 3, // CD
+ [SOUND_MIXER_LINE] = 4, // Line
+ [SOUND_MIXER_SYNTH] = 5, // FM
+ [SOUND_MIXER_MIC] = 6, // Mic
+ [SOUND_MIXER_SPEAKER] = 7, // Speaker
+ [SOUND_MIXER_RECLEV] = 8, // Recording level
+ [SOUND_MIXER_VOLUME] = 9 // Master Volume
+ };
+
+
+ static const unsigned mixreg[] = {
+ BA0_AC97_PCM_OUT_VOLUME,
+ BA0_AC97_AUX_VOLUME,
+ BA0_AC97_CD_VOLUME,
+ BA0_AC97_LINE_IN_VOLUME
+ };
+ unsigned char l, r, rl, rr, vidx;
+ unsigned char attentbl[11] = {63,42,26,17,14,11,8,6,4,2,0};
+ unsigned temp1;
+ int i, val;
+
+ VALIDATE_STATE(s);
+
+ if (cmd == SOUND_MIXER_PRIVATE1) {
+ // enable/disable/query mixer preamp
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ if (val != -1) {
+ cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1);
+ temp1 = val ? (temp1 | 0x40) : (temp1 & 0xffbf);
+ cs4281_write_ac97(s, BA0_AC97_MIC_VOLUME, temp1);
+ }
+ cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1);
+ val = (temp1 & 0x40) ? 1 : 0;
+ return put_user(val, (int *)arg);
+ }
+ if (cmd == SOUND_MIXER_PRIVATE2) {
+ // enable/disable/query spatializer
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ if (val != -1) {
+ temp1 = (val & 0x3f) >> 2;
+ cs4281_write_ac97(s, BA0_AC97_3D_CONTROL, temp1);
+ cs4281_read_ac97(s, BA0_AC97_GENERAL_PURPOSE, &temp1);
+ cs4281_write_ac97(s, BA0_AC97_GENERAL_PURPOSE,temp1 | 0x2000);
+ }
+ cs4281_read_ac97(s, BA0_AC97_3D_CONTROL, &temp1);
+ return put_user((temp1 << 2) | 3, (int *)arg);
+ }
+ if (cmd == SOUND_MIXER_INFO) {
+ mixer_info info;
+ strncpy(info.id, "CS4281", sizeof(info.id));
+ strncpy(info.name, "Crystal CS4281", sizeof(info.name));
+ info.modify_counter = s->mix.modcnt;
+ if (copy_to_user((void *)arg, &info, sizeof(info)))
+ return -EFAULT;
+ return 0;
+ }
+ if (cmd == SOUND_OLD_MIXER_INFO) {
+ _old_mixer_info info;
+ strncpy(info.id, "CS4281", sizeof(info.id));
+ strncpy(info.name, "Crystal CS4281", sizeof(info.name));
+ if (copy_to_user((void *)arg, &info, sizeof(info)))
+ return -EFAULT;
+ return 0;
+ }
+ if (cmd == OSS_GETVERSION)
+ return put_user(SOUND_VERSION, (int *)arg);
+
+ if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int))
+ return -EINVAL;
+
+ // If ioctl has only the IOC_READ bit(bit 31)
+ // on, process the only-read commands.
+ if (_IOC_DIR(cmd) == _IOC_READ) {
+ switch (_IOC_NR(cmd)) {
+ case SOUND_MIXER_RECSRC: // Arg contains a bit for each recording source
+ cs4281_read_ac97(s, BA0_AC97_RECORD_SELECT, &temp1);
+ return put_user(mixer_src[temp1 & 7], (int *)arg);
+
+ case SOUND_MIXER_DEVMASK: // Arg contains a bit for each supported device
+ return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH | SOUND_MASK_CD |
+ SOUND_MASK_LINE | SOUND_MASK_LINE1 | SOUND_MASK_MIC |
+ SOUND_MASK_VOLUME | SOUND_MASK_RECLEV |
+ SOUND_MASK_SPEAKER, (int *)arg);
+
+ case SOUND_MIXER_RECMASK: // Arg contains a bit for each supported recording source
+ return put_user(SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD
+ | SOUND_MASK_VOLUME | SOUND_MASK_LINE1, (int *)arg);
+
+ case SOUND_MIXER_STEREODEVS: // Mixer channels supporting stereo
+ return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH | SOUND_MASK_CD |
+ SOUND_MASK_LINE | SOUND_MASK_LINE1 | SOUND_MASK_MIC |
+ SOUND_MASK_VOLUME | SOUND_MASK_RECLEV, (int *)arg);
+
+ case SOUND_MIXER_CAPS:
+ return put_user(SOUND_CAP_EXCL_INPUT, (int *)arg);
+
+ default:
+ i = _IOC_NR(cmd);
+ if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i]))
+ return -EINVAL;
+ return put_user(s->mix.vol[vidx-1], (int *)arg);
+ }
+ }
+
+ // If ioctl doesn't have both the IOC_READ and
+ // the IOC_WRITE bit set, return invalid.
+ if (_IOC_DIR(cmd) != (_IOC_READ|_IOC_WRITE))
+ return -EINVAL;
+
+ // Increment the count of volume writes.
+ s->mix.modcnt++;
+
+ // Isolate the command; it must be a write.
+ switch (_IOC_NR(cmd)) {
+
+ case SOUND_MIXER_RECSRC: // Arg contains a bit for each recording source
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ i = hweight32(val); // i = # bits on in val.
+ if (i != 1) // One & only 1 bit must be on.
+ return 0;
+ for(i=0; i<sizeof(mixer_src)/sizeof(int); i++) {
+ if(val == mixer_src[i]) {
+ temp1 = (i << 8) | i;
+ cs4281_write_ac97(s, BA0_AC97_RECORD_SELECT, temp1);


+ return 0;
+ }
+ }
+ return 0;
+

+ case SOUND_MIXER_VOLUME:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ l = val & 0xff;
+ if(l > 100)
+ l = 100; // Max soundcard.h vol is 100.
+ if(l < 6) {
+ rl = 63;
+ l = 0;
+ }
+ else
+ rl = attentbl[(10*l)/100]; // Convert 0-100 vol to 63-0 atten.
+
+ r = (val >> 8) & 0xff;
+ if (r > 100)
+ r = 100; // Max right volume is 100, too
+ if(r < 6) {
+ rr = 63;
+ r = 0;
+ }
+ else
+ rr = attentbl[(10*r)/100]; // Convert volume to attenuation.
+
+ if ((rl > 60 ) && (rr > 60)) // If both l & r are 'low',
+ temp1 = 0x8000; // turn on the mute bit.
+ else
+ temp1 = 0;
+
+ temp1 |= (rl << 8) | rr;
+
+ cs4281_write_ac97(s, BA0_AC97_MASTER_VOLUME, temp1);
+ cs4281_write_ac97(s, BA0_AC97_HEADPHONE_VOLUME, temp1);
+
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+ s->mix.vol[8] = ((unsigned int)r << 8) | l;
+#else
+ s->mix.vol[8] = val;
+#endif
+ return put_user(s->mix.vol[8], (int *)arg);
+
+ case SOUND_MIXER_SPEAKER:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ l = val & 0xff;
+ if (l > 100)
+ l = 100;
+ if(l < 3 ) {
+ rl = 0;
+ l = 0;
+ }
+ else {
+ rl = (l*2 - 5)/13; // Convert 0-100 range to 0-15.
+ l = (rl*13 +5)/2;
+ }
+
+ if (rl < 3){
+ temp1 = 0x8000;
+ rl = 0;
+ }
+ else
+ temp1 = 0;
+ rl = 15 - rl; // Convert volume to attenuation.
+ temp1 |= rl << 1;
+ cs4281_write_ac97(s, BA0_AC97_PC_BEEP_VOLUME, temp1);
+
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+ s->mix.vol[6] = l << 8;
+#else
+ s->mix.vol[6] = val;
+#endif
+ return put_user(s->mix.vol[6], (int *)arg);
+
+ case SOUND_MIXER_RECLEV:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ l = val & 0xff;
+ if (l > 100)
+ l = 100;
+ r = (val >> 8) & 0xff;
+ if (r > 100)
+ r = 100;
+ rl = (l*2 - 5) / 13; // Convert 0-100 scale to 0-15.
+ rr = (r*2 - 5) / 13;
+ if (rl <3 && rr <3)
+ temp1 = 0x8000;
+ else
+ temp1 = 0;
+
+ temp1 = temp1 | (rl << 8) | rr;
+ cs4281_write_ac97(s, BA0_AC97_RECORD_GAIN, temp1);
+
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+ s->mix.vol[7] = ((unsigned int)r << 8) | l;
+#else
+ s->mix.vol[7] = val;
+#endif
+ return put_user(s->mix.vol[7], (int *)arg);
+
+ case SOUND_MIXER_MIC:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ l = val & 0xff;
+ if (l > 100)
+ l = 100;
+ if (l < 1) {
+ l = 0;
+ rl = 0;
+ }
+ else {
+ rl = ((unsigned)l*5 - 4)/16; // Convert 0-100 range to 0-31.
+ l = (rl*16 +4)/5;
+ }
+ cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1);
+ temp1 &= 0x40; // Isolate 20db gain bit.
+ if (rl < 3){
+ temp1 |= 0x8000;
+ rl = 0;
+ }
+ rl = 31 - rl; // Convert volume to attenuation.
+ temp1 |= rl;
+ cs4281_write_ac97(s, BA0_AC97_MIC_VOLUME, temp1);
+
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+ s->mix.vol[5] = val << 8;
+#else
+ s->mix.vol[5] = val;
+#endif
+ return put_user(s->mix.vol[5], (int *)arg);
+
+
+ case SOUND_MIXER_SYNTH:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ l = val & 0xff;
+ if (l > 100)
+ l = 100;
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ r = (val >> 8) & 0xff;
+ if (r > 100)
+ r = 100;
+ rl = (l * 2 - 11)/3; // Convert 0-100 range to 0-63.
+ rr = (r * 2 - 11)/3;
+ if (rl < 3) // If l is low, turn on
+ temp1 = 0x0080; // the mute bit.
+ else
+ temp1 = 0;
+
+ rl = 63 - rl; // Convert vol to attenuation.
+ writel(temp1|rl, s->pBA0+BA0_FMLVC);
+ if (rr < 3) // If rr is low, turn on
+ temp1 = 0x0080; // the mute bit.
+ else
+ temp1 = 0;
+ rr = 63 - rr; // Convert vol to attenuation.
+ writel(temp1 | rr, s->pBA0+BA0_FMRVC);
+
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+ s->mix.vol[4] = (r << 8) | l;
+#else
+ s->mix.vol[4] = val;
+#endif
+ return put_user(s->mix.vol[4], (int *)arg);
+
+
+ default:
+ i = _IOC_NR(cmd);
+ if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i]))
+ return -EINVAL;
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ l = val & 0xff;
+ if (l > 100)
+ l = 100;
+ if (l < 1) {
+ l = 0;
+ rl = 31;
+ }
+ else
+ rl = (attentbl[(l*10)/100])>>1;
+
+ r = (val >> 8) & 0xff;
+ if (r > 100)
+ r = 100;
+ if (r < 1) {
+ r = 0;
+ rr = 31;
+ }
+ else
+ rr = (attentbl[(r*10)/100])>>1;
+ if ((rl > 30) && (rr > 30))
+ temp1 = 0x8000;
+ else
+ temp1 = 0;
+ temp1 = temp1 | (rl << 8) | rr;
+ cs4281_write_ac97(s, mixreg[vidx-1], temp1);
+
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+ s->mix.vol[vidx-1] = ((unsigned int)r << 8) | l;
+#else
+ s->mix.vol[vidx-1] = val;
+#endif
+ return put_user(s->mix.vol[vidx-1], (int *)arg);
+ }
+}
+
+
+// ---------------------------------------------------------------------
+
+static loff_t cs4281_llseek(struct file *file, loff_t offset, int origin)
+{
+ return -ESPIPE;
+}
+
+
+// ---------------------------------------------------------------------
+
+static int cs4281_open_mixdev(struct inode *inode, struct file *file)
+{


+ int minor = MINOR(inode->i_rdev);

+ struct cs4281_state *s = devs;
+
+ while (s && s->dev_mixer != minor)
+ s = s->next;
+ if (!s)
+ return -ENODEV;
+ VALIDATE_STATE(s);
+ file->private_data = s;
+ MOD_INC_USE_COUNT;


+ return 0;
+}
+

+
+static int cs4281_release_mixdev(struct inode *inode, struct file *file)
+{
+ struct cs4281_state *s = (struct cs4281_state *)file->private_data;
+
+ VALIDATE_STATE(s);
+ MOD_DEC_USE_COUNT;


+ return 0;
+}
+

+
+static int cs4281_ioctl_mixdev(struct inode *inode, struct file *file,


+ unsigned int cmd, unsigned long arg)
+{

+ return mixer_ioctl((struct cs4281_state *)file->private_data, cmd, arg);
+}
+
+
+// ******************************************************************************************
+// Mixer file operations struct.
+// ******************************************************************************************
+static /*const*/ struct file_operations cs4281_mixer_fops = {
+ llseek: cs4281_llseek,
+ ioctl: cs4281_ioctl_mixdev,
+ open: cs4281_open_mixdev,
+ release: cs4281_release_mixdev,
+};
+
+// ---------------------------------------------------------------------
+
+static int drain_dac(struct cs4281_state *s, int nonblock)
+{
+ DECLARE_WAITQUEUE(wait, current);
+ unsigned long flags;
+ int count;
+ unsigned tmo;
+
+ if (s->dma_dac.mapped)
+ return 0;


+ current->state = TASK_INTERRUPTIBLE;

+ add_wait_queue(&s->dma_dac.wait, &wait);
+ for (;;) {
+ spin_lock_irqsave(&s->lock, flags);
+ count = s->dma_dac.count;
+ spin_unlock_irqrestore(&s->lock, flags);
+ if (count <= 0)
+ break;
+ if (signal_pending(current))
+ break;
+ if (nonblock) {
+ remove_wait_queue(&s->dma_dac.wait, &wait);


+ current->state = TASK_RUNNING;

+ return -EBUSY;
+ }
+ tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->rate;
+ if (s->fmt & (AFMT_S16_LE | AFMT_U16_LE))
+ tmo >>= 1;
+ if (s->channels > 1)
+ tmo >>= 1;
+ if (!schedule_timeout(tmo + 1))
+ printk(KERN_DEBUG "cs4281: dma timed out??\n");
+ }
+ remove_wait_queue(&s->dma_dac.wait, &wait);


+ current->state = TASK_RUNNING;

+ if (signal_pending(current))
+ return -ERESTARTSYS;


+ return 0;
+}
+

+
+// ---------------------------------------------------------------------
+
+static ssize_t cs4281_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+{
+ struct cs4281_state *s = (struct cs4281_state *)file->private_data;
+ ssize_t ret;
+ unsigned long flags;
+ unsigned swptr;
+ int cnt;
+
+ CS_DBGOUT(CS_FUNCTION | CS_WAVE_READ, 2,
+ printk(KERN_INFO "cs4281: cs4281_read()+ \n") );
+
+ VALIDATE_STATE(s);
+ if (ppos != &file->f_pos)
+ return -ESPIPE;
+ if (s->dma_adc.mapped)
+ return -ENXIO;
+ if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
+ return ret;
+ if (!access_ok(VERIFY_WRITE, buffer, count))
+ return -EFAULT;
+ ret = 0;
+ while (count > 0) {
+ spin_lock_irqsave(&s->lock, flags);
+ swptr = s->dma_adc.swptr;
+ cnt = s->dma_adc.dmasize-swptr;
+ if (s->dma_adc.count < cnt)
+ cnt = s->dma_adc.count;
+ spin_unlock_irqrestore(&s->lock, flags);
+ if (cnt > count)
+ cnt = count;
+ if (cnt <= 0) {
+ start_adc(s);
+ if (file->f_flags & O_NONBLOCK)
+ return ret ? ret : -EAGAIN;
+ interruptible_sleep_on(&s->dma_adc.wait);
+ if (signal_pending(current))
+ return ret ? ret : -ERESTARTSYS;
+ continue;
+ }
+ if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt))
+ return ret ? ret : -EFAULT;
+ swptr = (swptr + cnt) % s->dma_adc.dmasize;
+ spin_lock_irqsave(&s->lock, flags);
+ s->dma_adc.swptr = swptr;
+ s->dma_adc.count -= cnt;
+ spin_unlock_irqrestore(&s->lock, flags);
+ count -= cnt;
+ buffer += cnt;
+ ret += cnt;
+ start_adc(s);
+ }
+ CS_DBGOUT(CS_FUNCTION | CS_WAVE_READ, 2,
+ printk(KERN_INFO "cs4281: cs4281_read()- %d\n",ret) );


+ return ret;
+}
+
+

+static ssize_t cs4281_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+{
+ struct cs4281_state *s = (struct cs4281_state *)file->private_data;
+ ssize_t ret;
+ unsigned long flags;
+ unsigned swptr;
+ int cnt;
+
+ CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE, 2,
+ printk(KERN_INFO "cs4281: cs4281_write()+ \n") );
+ VALIDATE_STATE(s);
+
+ if (ppos != &file->f_pos)
+ return -ESPIPE;
+ if (s->dma_dac.mapped)
+ return -ENXIO;
+ if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s)))
+ return ret;
+ if (!access_ok(VERIFY_READ, buffer, count))
+ return -EFAULT;
+ ret = 0;
+ while (count > 0) {
+ spin_lock_irqsave(&s->lock, flags);
+ if (s->dma_dac.count < 0) {
+ s->dma_dac.count = 0;
+ s->dma_dac.swptr = s->dma_dac.hwptr;
+ }
+ swptr = s->dma_dac.swptr;
+ cnt = s->dma_dac.dmasize-swptr;
+ if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
+ cnt = s->dma_dac.dmasize - s->dma_dac.count;
+ spin_unlock_irqrestore(&s->lock, flags);
+ if (cnt > count)
+ cnt = count;
+ if (cnt <= 0) {
+ start_dac(s);
+ if (file->f_flags & O_NONBLOCK)
+ return ret ? ret : -EAGAIN;
+ interruptible_sleep_on(&s->dma_dac.wait);
+ if (signal_pending(current))
+ return ret ? ret : -ERESTARTSYS;
+ continue;
+ }
+ if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt))
+ return ret ? ret : -EFAULT;
+ swptr = (swptr + cnt) % s->dma_dac.dmasize;
+ spin_lock_irqsave(&s->lock, flags);
+ s->dma_dac.swptr = swptr;
+ s->dma_dac.count += cnt;
+ s->dma_dac.endcleared = 0;
+ spin_unlock_irqrestore(&s->lock, flags);
+ count -= cnt;
+ buffer += cnt;
+ ret += cnt;
+ start_dac(s);
+ }
+ CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE, 2,
+ printk(KERN_INFO "cs4281: cs4281_write()- %d\n",ret) );


+ return ret;
+}
+
+

+static unsigned int cs4281_poll(struct file *file, struct poll_table_struct *wait)
+{
+ struct cs4281_state *s = (struct cs4281_state *)file->private_data;
+ unsigned long flags;
+ unsigned int mask = 0;
+
+ CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,
+ printk(KERN_INFO "cs4281: cs4281_poll()+\n") );
+ VALIDATE_STATE(s);
+ if (file->f_mode & FMODE_WRITE)
+ poll_wait(file, &s->dma_dac.wait, wait);
+ if (file->f_mode & FMODE_READ)
+ poll_wait(file, &s->dma_adc.wait, wait);
+ spin_lock_irqsave(&s->lock, flags);
+ cs4281_update_ptr(s);
+ if (file->f_mode & FMODE_READ) {
+ if (s->dma_adc.mapped) {
+ if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
+ mask |= POLLIN | POLLRDNORM;
+ } else {
+ if (s->dma_adc.count > 0)
+ mask |= POLLIN | POLLRDNORM;
+ }
+ }
+ if (file->f_mode & FMODE_WRITE) {
+ if (s->dma_dac.mapped) {
+ if (s->dma_dac.count >= (signed)s->dma_dac.fragsize)
+ mask |= POLLOUT | POLLWRNORM;
+ } else {
+ if ((signed)s->dma_dac.dmasize > s->dma_dac.count)


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 084'
echo 'File patch-2.4.0-test9 is continued in part 085'
echo "085" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part079

#!/bin/sh -x
# this is part 079 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 079; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+++ linux/drivers/scsi/fdomain.c Mon Sep 18 13:36:25 2000
@@ -2028,9 +2028,7 @@


X return 0;
X }
X
-#ifdef MODULE
X /* Eventually this will go into an include file, but this will be later */

-Scsi_Host_Template driver_template = FDOMAIN_16X0;
+static Scsi_Host_Template driver_template = FDOMAIN_16X0;


X
X #include "scsi_module.c"
-#endif

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/g_NCR5380.c linux/drivers/scsi/g_NCR5380.c
--- v2.4.0-test8/linux/drivers/scsi/g_NCR5380.c Thu Jan 20 10:44:46 2000
+++ linux/drivers/scsi/g_NCR5380.c Mon Sep 18 13:36:25 2000
@@ -885,12 +885,13 @@
X #undef PRINTP
X #undef ANDP


X
-#ifdef MODULE
X /* Eventually this will go into an include file, but this will be later */

-Scsi_Host_Template driver_template = GENERIC_NCR5380;
+static Scsi_Host_Template driver_template = GENERIC_NCR5380;
X
X #include <linux/module.h>
X #include "scsi_module.c"
+
+#ifdef MODULE
X
X MODULE_PARM(ncr_irq, "i");
X MODULE_PARM(ncr_dma, "i");
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/g_NCR5380.h linux/drivers/scsi/g_NCR5380.h
--- v2.4.0-test8/linux/drivers/scsi/g_NCR5380.h Wed Dec 8 15:17:55 1999
+++ linux/drivers/scsi/g_NCR5380.h Mon Sep 18 14:25:56 2000
@@ -70,8 +70,6 @@
X #define CAN_QUEUE 16
X #endif


X
-#if defined(HOSTS_C) || defined(MODULE)
-

X #define GENERIC_NCR5380 { \
X proc_info: generic_NCR5380_proc_info, \
X name: "Generic NCR5380/NCR53C400 Scsi Driver", \
@@ -87,8 +85,6 @@
X sg_tablesize: SG_ALL, \


X cmd_per_lun: CMD_PER_LUN , \
X use_clustering: DISABLE_CLUSTERING}

-
-#endif
X
X #ifndef HOSTS_C
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/gdth.c linux/drivers/scsi/gdth.c
--- v2.4.0-test8/linux/drivers/scsi/gdth.c Mon Jun 26 18:06:55 2000
+++ linux/drivers/scsi/gdth.c Mon Sep 18 13:36:25 2000
@@ -3704,7 +3704,5 @@


X }
X
X
-#ifdef MODULE

-Scsi_Host_Template driver_template = GDTH;
+static Scsi_Host_Template driver_template = GDTH;
X #include "scsi_module.c"
-#endif
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/gvp11.c linux/drivers/scsi/gvp11.c
--- v2.4.0-test8/linux/drivers/scsi/gvp11.c Wed Jan 26 12:45:20 2000
+++ linux/drivers/scsi/gvp11.c Mon Sep 18 13:36:25 2000
@@ -352,17 +352,13 @@


X }
X
X
-#ifdef MODULE
-
X #define HOSTS_C
X

X #include "gvp11.h"
X
-Scsi_Host_Template driver_template = GVP11_SCSI;
+static Scsi_Host_Template driver_template = GVP11_SCSI;


X
X #include "scsi_module.c"
-
-#endif
X

X int gvp11_release(struct Scsi_Host *instance)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/hosts.c linux/drivers/scsi/hosts.c
--- v2.4.0-test8/linux/drivers/scsi/hosts.c Tue Jul 11 11:17:45 2000
+++ linux/drivers/scsi/hosts.c Tue Sep 19 08:31:53 2000
@@ -11,6 +11,10 @@
X * Jiffies wrap fixes (host->resetting), 3 Dec 1998 Andrea Arcangeli
X * Added QLOGIC QLA1280 SCSI controller kernel host support.
X * August 4, 1999 Fred Lewis, Intel DuPont
+ *
+ * Updated to reflect the new initialization scheme for the higher
+ * level of scsi drivers (sd/sr/st)
+ * September 17, 2000 Torben Mathiasen <t...@image.dk>
X */
X
X
@@ -22,8 +26,6 @@
X
X #define __NO_VERSION__
X #include <linux/module.h>
-
-#include <linux/config.h>
X #include <linux/blk.h>
X #include <linux/kernel.h>
X #include <linux/string.h>
@@ -36,361 +38,8 @@
X #include <linux/unistd.h>
X
X #include "scsi.h"
-
-#ifndef NULL
-#define NULL 0L
-#endif
-
-#define HOSTS_C
-
X #include "hosts.h"
X
-#if defined(CONFIG_A4000T_SCSI) || \
- defined(CONFIG_WARPENGINE_SCSI) || \
- defined(CONFIG_A4091_SCSI) || \
- defined (CONFIG_GVP_TURBO_SCSI) || \
- defined (CONFIG_BLZ603EPLUS_SCSI)
-#define AMIGA7XXCONFIG
-#endif
-
-#ifdef AMIGA7XXCONFIG
-#include "amiga7xx.h"
-#endif
-
-#ifdef CONFIG_MVME16x_SCSI
-#include "mvme16x.h"
-#endif
-
-#ifdef CONFIG_BVME6000_SCSI
-#include "bvme6000.h"
-#endif
-
-#ifdef CONFIG_SCSI_SIM710
-#include "sim710.h"
-#endif
-
-#ifdef CONFIG_A3000_SCSI
-#include "a3000.h"
-#endif
-
-#ifdef CONFIG_A2091_SCSI
-#include "a2091.h"
-#endif
-
-#ifdef CONFIG_GVP11_SCSI
-#include "gvp11.h"
-#endif
-
-#ifdef CONFIG_CYBERSTORM_SCSI
-#include "cyberstorm.h"
-#endif
-
-#ifdef CONFIG_CYBERSTORMII_SCSI
-#include "cyberstormII.h"
-#endif
-
-#ifdef CONFIG_BLZ2060_SCSI
-#include "blz2060.h"
-#endif
-
-#ifdef CONFIG_BLZ1230_SCSI
-#include "blz1230.h"
-#endif
-
-#ifdef CONFIG_FASTLANE_SCSI
-#include "fastlane.h"
-#endif
-
-#ifdef CONFIG_OKTAGON_SCSI
-#include "oktagon_esp.h"
-#endif
-
-#ifdef CONFIG_ATARI_SCSI
-#include "atari_scsi.h"
-#endif
-
-#if defined(CONFIG_MAC_SCSI) || defined(CONFIG_MAC_SCSI_OLD)
-#include "mac_scsi.h"
-#endif
-
-#ifdef CONFIG_SUN3_SCSI
-#include "sun3_scsi.h"
-#endif
-
-#ifdef CONFIG_SCSI_MAC_ESP
-#include "mac_esp.h"
-#endif
-
-#ifdef CONFIG_SCSI_ADVANSYS
-#include "advansys.h"
-#endif
-
-#ifdef CONFIG_SCSI_AHA152X
-#include "aha152x.h"
-#endif
-
-#ifdef CONFIG_SCSI_AHA1542
-#include "aha1542.h"
-#endif
-
-#ifdef CONFIG_SCSI_AHA1740
-#include "aha1740.h"
-#endif
-
-#ifdef CONFIG_SCSI_AIC7XXX
-#include "aic7xxx.h"
-#endif
-
-#ifdef CONFIG_SCSI_IPS
-#include "ips.h"
-#endif
-
-#ifdef CONFIG_SCSI_BUSLOGIC
-#include "BusLogic.h"
-#endif
-
-#ifdef CONFIG_SCSI_EATA_DMA
-#include "eata_dma.h"
-#endif
-
-#ifdef CONFIG_SCSI_EATA_PIO
-#include "eata_pio.h"
-#endif
-
-#ifdef CONFIG_SCSI_U14_34F
-#include "u14-34f.h"
-#endif
-
-#ifdef CONFIG_SCSI_FD_MCS
-#include "fd_mcs.h"
-#endif
-
-#ifdef CONFIG_SCSI_FUTURE_DOMAIN
-#include "fdomain.h"
-#endif
-
-#ifdef CONFIG_SCSI_GENERIC_NCR5380
-#include "g_NCR5380.h"
-#endif
-
-#ifdef CONFIG_SCSI_IN2000
-#include "in2000.h"
-#endif
-
-#ifdef CONFIG_SCSI_PAS16
-#include "pas16.h"
-#endif
-
-#ifdef CONFIG_SCSI_QLOGIC_FAS
-#include "qlogicfas.h"
-#endif
-
-#ifdef CONFIG_SCSI_QLOGIC_ISP
-#include "qlogicisp.h"
-#endif
-
-#ifdef CONFIG_SCSI_QLOGIC_FC
-#include "qlogicfc.h"
-#endif
-
-#ifdef CONFIG_SCSI_QLOGIC_1280
-#include "qla1280.h"
-#endif
-
-#ifdef CONFIG_SCSI_SEAGATE
-#include "seagate.h"
-#endif
-
-#ifdef CONFIG_SCSI_T128
-#include "t128.h"
-#endif
-
-#ifdef CONFIG_SCSI_DMX3191D
-#include "dmx3191d.h"
-#endif
-
-#ifdef CONFIG_SCSI_DTC3280
-#include "dtc.h"
-#endif
-
-#ifdef CONFIG_SCSI_NCR53C7xx
-#include "53c7,8xx.h"
-#endif
-
-#ifdef CONFIG_SCSI_SYM53C8XX
-#include "sym53c8xx.h"
-#endif
-
-#ifdef CONFIG_SCSI_NCR53C8XX
-#include "ncr53c8xx.h"
-#endif
-
-#ifdef CONFIG_SCSI_ULTRASTOR
-#include "ultrastor.h"
-#endif
-
-#ifdef CONFIG_SCSI_7000FASST
-#include "wd7000.h"
-#endif
-
-#ifdef CONFIG_SCSI_MCA_53C9X
-#include "mca_53c9x.h"
-#endif
-
-#ifdef CONFIG_SCSI_IBMMCA
-#include "ibmmca.h"
-#endif
-
-#ifdef CONFIG_SCSI_EATA
-#include "eata.h"
-#endif
-
-#ifdef CONFIG_SCSI_NCR53C406A
-#include "NCR53c406a.h"
-#endif
-
-#ifdef CONFIG_SCSI_SYM53C416
-#include "sym53c416.h"
-#endif
-
-#ifdef CONFIG_SCSI_DC390T
-#include "dc390.h"
-#endif
-
-#ifdef CONFIG_SCSI_AM53C974
-#include "AM53C974.h"
-#endif
-
-#ifdef CONFIG_SCSI_MEGARAID
-#include "megaraid.h"
-#endif
-
-#ifdef CONFIG_SCSI_ACARD
-#include "atp870u.h"
-#endif
-
-#ifdef CONFIG_SCSI_SUNESP
-#include "esp.h"
-#endif
-
-#ifdef CONFIG_SCSI_SGIWD93
-#include "sgiwd93.h"
-#endif
-
-#ifdef CONFIG_SCSI_QLOGICPTI
-#include "qlogicpti.h"
-#endif
-
-#ifdef CONFIG_BLK_DEV_IDESCSI
-#include "ide-scsi.h"
-#endif
-
-#ifdef CONFIG_SCSI_MESH
-#include "mesh.h"
-#endif
-
-#ifdef CONFIG_SCSI_MAC53C94
-#include "mac53c94.h"
-#endif
-
-#ifdef CONFIG_SCSI_GDTH
-#include "gdth.h"
-#endif
-
-#ifdef CONFIG_SCSI_PCI2000
-#include "pci2000.h"
-#endif
-
-#ifdef CONFIG_SCSI_PCI2220I
-#include "pci2220i.h"
-#endif
-
-#ifdef CONFIG_SCSI_PSI240I
-#include "psi240i.h"
-#endif
-
-#ifdef CONFIG_SCSI_PLUTO
-#include "pluto.h"
-#endif
-
-#ifdef CONFIG_SCSI_INITIO
-#include "ini9100u.h"
-#endif
-
-#ifdef CONFIG_SCSI_INIA100
-#include "inia100.h"
-#endif
-
-#ifdef CONFIG_SCSI_DEBUG
-#include "scsi_debug.h"
-#endif
-
-#ifdef CONFIG_SCSI_ACORNSCSI_3
-#include "../acorn/scsi/acornscsi.h"
-#endif
-
-#ifdef CONFIG_SCSI_CUMANA_1
-#include "../acorn/scsi/cumana_1.h"
-#endif
-
-#ifdef CONFIG_SCSI_CUMANA_2
-#include "../acorn/scsi/cumana_2.h"
-#endif
-
-#ifdef CONFIG_SCSI_ECOSCSI
-#include "../acorn/scsi/ecoscsi.h"
-#endif
-
-#ifdef CONFIG_SCSI_OAK1
-#include "../acorn/scsi/oak.h"
-#endif
-
-#ifdef CONFIG_SCSI_POWERTECSCSI
-#include "../acorn/scsi/powertec.h"
-#endif
-
-#ifdef CONFIG_SCSI_ARXESCSI
-#include "../acorn/scsi/arxescsi.h"
-#endif
-
-#ifdef CONFIG_I2O_SCSI
-#include "../i2o/i2o_scsi.h"
-#endif
-
-#ifdef CONFIG_JAZZ_ESP
-#include "jazz_esp.h"
-#endif
-
-#ifdef CONFIG_SCSI_DECNCR
-#include "dec_esp.h"
-#endif
-
-#ifdef CONFIG_SUN3X_ESP
-#include "sun3x_esp.h"
-#endif
-
-#ifdef CONFIG_IPHASE5526
-#include "../net/fc/iph5526_scsi.h"
-#endif
-
-#ifdef CONFIG_BLK_DEV_3W_XXXX_RAID
-#include "3w-xxxx.h"
-#endif
-
-/*
- * Moved ppa driver to the end of the probe list
- * since it is a removable host adapter.
- * This means the parallel ZIP drive will not bump
- * the order of the /dev/sd devices - camp...@torque.net
- */
-#ifdef CONFIG_SCSI_PPA
-#include "ppa.h"
-#endif
-
-#ifdef CONFIG_SCSI_IMM
-#include "imm.h"
-#endif
-
X /*
X static const char RCSid[] = "$Header: /vger/u4/cvs/linux/drivers/scsi/hosts.c,v 1.20 1996/12/12 19:18:32 davem Exp $";
X */
@@ -422,281 +71,6 @@
X
X Scsi_Host_Template * scsi_hosts = NULL;
X
-static Scsi_Host_Template builtin_scsi_hosts[] =
-{
-#ifdef CONFIG_AMIGA
-#ifdef AMIGA7XXCONFIG
- AMIGA7XX_SCSI,
-#endif
-#ifdef CONFIG_A3000_SCSI
- A3000_SCSI,
-#endif
-#ifdef CONFIG_A2091_SCSI
- A2091_SCSI,
-#endif
-#ifdef CONFIG_GVP11_SCSI
- GVP11_SCSI,
-#endif
-#ifdef CONFIG_CYBERSTORM_SCSI
- SCSI_CYBERSTORM,
-#endif
-#ifdef CONFIG_CYBERSTORMII_SCSI
- SCSI_CYBERSTORMII,
-#endif
-#ifdef CONFIG_BLZ2060_SCSI
- SCSI_BLZ2060,
-#endif
-#ifdef CONFIG_BLZ1230_SCSI
- SCSI_BLZ1230,
-#endif
-#ifdef CONFIG_FASTLANE_SCSI
- SCSI_FASTLANE,
-#endif
-#ifdef CONFIG_OKTAGON_SCSI
- SCSI_OKTAGON_ESP,
-#endif
-#endif
-
-#ifdef CONFIG_ATARI
-#ifdef CONFIG_ATARI_SCSI
- ATARI_SCSI,
-#endif
-#endif
-
-#ifdef CONFIG_MAC
-#ifdef CONFIG_MAC_SCSI_OLD
- MAC_SCSI,
-#endif
-#ifdef CONFIG_SCSI_MAC_ESP
- SCSI_MAC_ESP,
-#endif
-#ifdef CONFIG_MAC_SCSI
- MAC_NCR5380,
-#endif
-#endif
-
-#ifdef CONFIG_SUN3_SCSI
- SUN3_NCR5380,
-#endif
-
-#ifdef CONFIG_MVME16x_SCSI
- MVME16x_SCSI,
-#endif
-#ifdef CONFIG_BVME6000_SCSI
- BVME6000_SCSI,
-#endif
-#ifdef CONFIG_SCSI_SIM710
- SIM710_SCSI,
-#endif
-#ifdef CONFIG_SCSI_ADVANSYS
- ADVANSYS,
-#endif
-
-#ifdef CONFIG_SCSI_PCI2000
- PCI2000,
-#endif
-#ifdef CONFIG_SCSI_PCI2220I
- PCI2220I,
-#endif
-#ifdef CONFIG_SCSI_PSI240I
- PSI240I,
-#endif
-
-/* BusLogic must come before aha1542.c */
-#ifdef CONFIG_SCSI_BUSLOGIC
- BUSLOGIC,
-#endif
-#ifdef CONFIG_SCSI_U14_34F
- ULTRASTOR_14_34F,
-#endif
-#ifdef CONFIG_SCSI_ULTRASTOR
- ULTRASTOR_14F,
-#endif
-#ifdef CONFIG_SCSI_AHA152X
- AHA152X,
-#endif
-#ifdef CONFIG_SCSI_AHA1542
- AHA1542,
-#endif
-#ifdef CONFIG_SCSI_AHA1740
- AHA1740,
-#endif
-#ifdef CONFIG_SCSI_AIC7XXX
- AIC7XXX,
-#endif
-#ifdef CONFIG_SCSI_IPS
- IPS,
-#endif
-#ifdef CONFIG_SCSI_FD_MCS
- FD_MCS,
-#endif
-#ifdef CONFIG_SCSI_FUTURE_DOMAIN
- FDOMAIN_16X0,
-#endif
-#ifdef CONFIG_SCSI_IN2000
- IN2000,
-#endif
-#ifdef CONFIG_SCSI_GENERIC_NCR5380
- GENERIC_NCR5380,
-#endif
-#ifdef CONFIG_SCSI_NCR53C406A /* 53C406A should come before QLOGIC */
- NCR53c406a,
-#endif
-#ifdef CONFIG_SCSI_SYM53C416
- SYM53C416,
-#endif
-#ifdef CONFIG_SCSI_QLOGIC_FAS
- QLOGICFAS,
-#endif
-#ifdef CONFIG_SCSI_QLOGIC_ISP
- QLOGICISP,
-#endif
-#ifdef CONFIG_SCSI_QLOGIC_FC
- QLOGICFC,
-#endif
-#ifdef CONFIG_SCSI_QLOGIC_1280
- QLA1280_LINUX_TEMPLATE,
-#endif
-#ifdef CONFIG_SCSI_PAS16
- MV_PAS16,
-#endif
-#ifdef CONFIG_SCSI_SEAGATE
- SEAGATE_ST0X,
-#endif
-#ifdef CONFIG_SCSI_T128
- TRANTOR_T128,
-#endif
-#ifdef CONFIG_SCSI_DMX3191D
- DMX3191D,
-#endif
-#ifdef CONFIG_SCSI_DTC3280
- DTC3x80,
-#endif
-#ifdef CONFIG_SCSI_NCR53C7xx
- NCR53c7xx,
-#endif
-#ifdef CONFIG_SCSI_SYM53C8XX
- SYM53C8XX,
-#endif
-#ifdef CONFIG_SCSI_NCR53C8XX
- NCR53C8XX,
-#endif
-#ifdef CONFIG_SCSI_EATA_DMA
- EATA_DMA,
-#endif
-#ifdef CONFIG_SCSI_EATA_PIO
- EATA_PIO,
-#endif
-#ifdef CONFIG_SCSI_7000FASST
- WD7000,
-#endif
-#ifdef CONFIG_SCSI_MCA_53C9X
- MCA_53C9X,
-#endif
-#ifdef CONFIG_SCSI_IBMMCA
- IBMMCA,
-#endif
-#ifdef CONFIG_SCSI_EATA
- EATA,
-#endif
-#ifdef CONFIG_SCSI_DC390T
- DC390_T,
-#endif
-#ifdef CONFIG_SCSI_AM53C974
- AM53C974,
-#endif
-#ifdef CONFIG_SCSI_MEGARAID
- MEGARAID,
-#endif
-#ifdef CONFIG_SCSI_ACARD
- ATP870U,
-#endif
-#ifdef CONFIG_SCSI_SUNESP
- SCSI_SPARC_ESP,
-#endif
-#ifdef CONFIG_SCSI_GDTH
- GDTH,
-#endif
-#ifdef CONFIG_SCSI_INITIO
- INI9100U,
-#endif
-#ifdef CONFIG_SCSI_INIA100
- INIA100,
-#endif
-#ifdef CONFIG_SCSI_QLOGICPTI
- QLOGICPTI,
-#endif
-#ifdef CONFIG_BLK_DEV_IDESCSI
- IDESCSI,
-#endif
-#ifdef CONFIG_SCSI_MESH
- SCSI_MESH,
-#endif
-#ifdef CONFIG_SCSI_MAC53C94
- SCSI_MAC53C94,
-#endif
-#ifdef CONFIG_SCSI_PLUTO
- PLUTO,
-#endif
-#ifdef CONFIG_ARCH_ACORN
-#ifdef CONFIG_SCSI_ACORNSCSI_3
- ACORNSCSI_3,
-#endif
-#ifdef CONFIG_SCSI_CUMANA_1
- CUMANA_NCR5380,
-#endif
-#ifdef CONFIG_SCSI_CUMANA_2
- CUMANA_FAS216,
-#endif
-#ifdef CONFIG_SCSI_ARXESCSI
- ARXEScsi,
-#endif
-#ifdef CONFIG_SCSI_ECOSCSI
- ECOSCSI_NCR5380,
-#endif
-#ifdef CONFIG_SCSI_OAK1
- OAK_NCR5380,
-#endif
-#ifdef CONFIG_SCSI_POWERTECSCSI
- POWERTECSCSI,
-#endif
-#endif
-#ifdef CONFIG_IPHASE5526
- IPH5526_SCSI_FC,
-#endif
-#ifdef CONFIG_SCSI_DECNCR
- SCSI_DEC_ESP,
-#endif
-#ifdef CONFIG_BLK_DEV_3W_XXXX_RAID
- TWXXXX,
-#endif
-/* Put I2O last so that host specific controllers always win */
-#ifdef CONFIG_I2O_SCSI
- I2OSCSI,
-#endif
-/* "Removable host adapters" below this line (Parallel Port/USB/other) */
-#ifdef CONFIG_SCSI_PPA
- PPA,
-#endif
-#ifdef CONFIG_SCSI_IMM
- IMM,
-#endif
-#ifdef CONFIG_SCSI_SGIWD93
- SGIWD93_SCSI,
-#endif
-#ifdef CONFIG_JAZZ_ESP
- SCSI_JAZZ_ESP,
-#endif
-#ifdef CONFIG_SUN3X_ESP
- SCSI_SUN3X_ESP,
-#endif
-#ifdef CONFIG_SCSI_DEBUG
- SCSI_DEBUG,
-#endif
-};
-
-#define MAX_SCSI_HOSTS (sizeof(builtin_scsi_hosts) / sizeof(Scsi_Host_Template))
-
X
X /*
X * Our semaphores and timeout counters, where size depends on
@@ -771,12 +145,12 @@
X hname = (tpnt->proc_name) ? tpnt->proc_name : "";
X hname_len = strlen(hname);
X for (shn = scsi_host_no_list;shn;shn = shn->next) {
- if (!(shn->host_registered) && shn->loaded_as_module &&
+ if (!(shn->host_registered) &&
X (hname_len > 0) && (0 == strncmp(hname, shn->name, hname_len))) {
X flag_new = 0;
X retval->host_no = shn->host_no;
X shn->host_registered = 1;
- shn->loaded_as_module = scsi_loadable_module_flag;
+ shn->loaded_as_module = 1;
X break;
X }
X }
@@ -785,7 +159,7 @@
X retval->host_failed = 0;
X if(j > 0xffff) panic("Too many extra bytes requested\n");
X retval->extra_bytes = j;
- retval->loaded_as_module = scsi_loadable_module_flag;
+ retval->loaded_as_module = 1;
X if (flag_new) {
X shn = (Scsi_Host_Name *) kmalloc(sizeof(Scsi_Host_Name), GFP_ATOMIC);
X shn->name = kmalloc(hname_len + 1, GFP_ATOMIC);
@@ -794,7 +168,7 @@
X shn->name[hname_len] = 0;
X shn->host_no = max_scsi_hosts++;
X shn->host_registered = 1;
- shn->loaded_as_module = scsi_loadable_module_flag;
+ shn->loaded_as_module = 1;
X shn->next = NULL;
X if (scsi_host_no_list) {
X for (shn2 = scsi_host_no_list;shn2->next;shn2 = shn2->next)
@@ -886,135 +260,6 @@
X if(sdpnt->next) panic("Device already registered");
X sdpnt->next = scsi_devicelist;
X scsi_devicelist = sdpnt;
- return 0;
-}
-
-/*
- * Why is this a separate function? Because the kernel_thread code
- * effectively does a fork, and there is a builtin exit() call when
- * the child returns. The difficulty is that scsi_init() is
- * marked __init, which means the memory is unmapped after bootup
- * is complete, which means that the thread's exit() call gets wiped.
- *
- * The lesson is to *NEVER*, *NEVER* call kernel_thread() from an
- * __init function, if that function could ever return.
- */
-static void launch_error_handler_thread(struct Scsi_Host * shpnt)
-{
- DECLARE_MUTEX_LOCKED(sem);
-
- shpnt->eh_notify = &sem;
-
- kernel_thread((int (*)(void *))scsi_error_handler,
- (void *) shpnt, 0);
-
- /*
- * Now wait for the kernel error thread to initialize itself
- * as it might be needed when we scan the bus.
- */
- down (&sem);
- shpnt->eh_notify = NULL;
-}
-
-unsigned int __init scsi_init(void)
-{
- static int called = 0;
- int i, pcount;
- unsigned long flags;
- Scsi_Host_Template * tpnt;
- struct Scsi_Host * shpnt;
- const char * name;
-
- if(called) return 0;
-
- called = 1;
- for (tpnt = &builtin_scsi_hosts[0], i = 0; i < MAX_SCSI_HOSTS; ++i, tpnt++)
- {
- /*
- * Initialize our semaphores. -1 is interpreted to mean
- * "inactive" - where as 0 will indicate a time out condition.
- */
-
- pcount = next_scsi_host;
- if (tpnt->detect) {
-
- /* The detect routine must carefully spinunlock/spinlock if
- it enables interrupts, since all interrupt handlers do
- spinlock as well.
- All lame drivers are going to fail due to the following
- spinlock. For the time beeing let's use it only for drivers
- using the new scsi code. NOTE: the detect routine could
- redefine the value tpnt->use_new_eh_code. (DB, 13 May 1998) */
-
- if (tpnt->use_new_eh_code) {
- spin_lock_irqsave(&io_request_lock, flags);
- tpnt->present = tpnt->detect(tpnt);
- spin_unlock_irqrestore(&io_request_lock, flags);
- }
- else
- tpnt->present = tpnt->detect(tpnt);
-
- }
-
- if (tpnt->detect && tpnt->present)
- {
- /* The only time this should come up is when people use
- * some kind of patched driver of some kind or another. */
- if(pcount == next_scsi_host) {
- if(tpnt->present > 1)
- panic("Failure to register low-level scsi driver");
- /* The low-level driver failed to register a driver. We
- * can do this now. */
- scsi_register(tpnt,0);
- }
- tpnt->next = scsi_hosts;
- scsi_hosts = tpnt;
-
- /* Add the driver to /proc/scsi */
-#if CONFIG_PROC_FS
- build_proc_dir_entries(tpnt);
-#endif
- }
- }
-
- for(shpnt=scsi_hostlist; shpnt; shpnt = shpnt->next)
- {
- if(shpnt->hostt->info)
- name = shpnt->hostt->info(shpnt);
- else
- name = shpnt->hostt->name;
- printk ("scsi%d : %s\n", /* And print a little message */
- shpnt->host_no, name);
-
- /*
- * Now start the error recovery thread for the host.
- */
- if( shpnt->hostt->use_new_eh_code )
- {
- launch_error_handler_thread(shpnt);
- }
- }
-
- printk ("scsi : %d host%s.\n", next_scsi_host,
- (next_scsi_host == 1) ? "" : "s");
-
- /* Now attach the high level drivers */
-#ifdef CONFIG_BLK_DEV_SD
- scsi_register_device(&sd_template);
-#endif
-#ifdef CONFIG_BLK_DEV_SR
- scsi_register_device(&sr_template);
-#endif
-#ifdef CONFIG_CHR_DEV_ST
- scsi_register_device(&st_template);
-#endif
-#ifdef CONFIG_CHR_DEV_SG
- scsi_register_device(&sg_template);
-#endif
-
-#if 0
- max_scsi_hosts = next_scsi_host;
-#endif


X return 0;
X }
X

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/hosts.h linux/drivers/scsi/hosts.h
--- v2.4.0-test8/linux/drivers/scsi/hosts.h Fri Sep 8 12:54:34 2000
+++ linux/drivers/scsi/hosts.h Mon Oct 2 12:06:21 2000
@@ -459,7 +459,6 @@
X
X extern int next_scsi_host;
X
-extern int scsi_loadable_module_flag;
X unsigned int scsi_init(void);
X extern struct Scsi_Host * scsi_register(Scsi_Host_Template *, int j);
X extern void scsi_unregister(struct Scsi_Host * i);
@@ -505,11 +504,6 @@
X };
X
X void scsi_initialize_queue(Scsi_Device * SDpnt, struct Scsi_Host * SHpnt);
-
-extern struct Scsi_Device_Template sd_template;
-extern struct Scsi_Device_Template st_template;
-extern struct Scsi_Device_Template sr_template;
-extern struct Scsi_Device_Template sg_template;
X
X int scsi_register_device(struct Scsi_Device_Template * sdpnt);
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/ibmmca.c linux/drivers/scsi/ibmmca.c
--- v2.4.0-test8/linux/drivers/scsi/ibmmca.c Mon Jul 31 11:35:12 2000
+++ linux/drivers/scsi/ibmmca.c Mon Sep 18 13:36:25 2000
@@ -3294,12 +3294,10 @@
X __setup("ibmmcascsi=", option_setup);
X #endif


X
-#ifdef MODULE
X /* Eventually this will go into an include file, but this will be later */

-Scsi_Host_Template driver_template = IBMMCA;
+static Scsi_Host_Template driver_template = IBMMCA;


X
X #include "scsi_module.c"
-#endif
X

X /*--------------------------------------------------------------------*/
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/ide-scsi.c linux/drivers/scsi/ide-scsi.c
--- v2.4.0-test8/linux/drivers/scsi/ide-scsi.c Thu Apr 13 22:50:32 2000
+++ linux/drivers/scsi/ide-scsi.c Thu Sep 21 13:22:05 2000
@@ -31,7 +31,6 @@
X
X #define IDESCSI_VERSION "0.9"
X
-#include <linux/config.h>
X #include <linux/module.h>
X #include <linux/types.h>
X #include <linux/string.h>
@@ -582,16 +581,6 @@
X failed = 0;
X while ((drive = ide_scan_devices (media[i], idescsi_driver.name, NULL, failed++)) != NULL) {
X
-#ifndef CONFIG_BLK_DEV_IDETAPE
- /*
- * The Onstream DI-30 does not handle clean emulation, yet.
- */
- if (strstr(drive->id->model, "OnStream DI-30")) {
- printk("ide-tape: ide-scsi emulation is not supported for %s.\n", drive->id->model);
- continue;
- }
-#endif /* CONFIG_BLK_DEV_IDETAPE */
-
X if ((scsi = (idescsi_scsi_t *) kmalloc (sizeof (idescsi_scsi_t), GFP_KERNEL)) == NULL) {
X printk (KERN_ERR "ide-scsi: %s: Can't allocate a scsi structure\n", drive->name);
X continue;
@@ -827,18 +816,17 @@


X return 0;
X }
X
-#ifdef MODULE

-Scsi_Host_Template idescsi_template = IDESCSI;
+static Scsi_Host_Template idescsi_template = IDESCSI;
X
-int init_module (void)
+static int __init init_idescsi_module(void)
X {
- idescsi_init ();
- idescsi_template.module = &__this_module;
+ idescsi_init();
+ idescsi_template.module = THIS_MODULE;
X scsi_register_module (MODULE_SCSI_HA, &idescsi_template);


X return 0;
X }
X

-void cleanup_module (void)
+static void __exit exit_idescsi_module(void)
X {
X ide_drive_t *drive;
X byte media[] = {TYPE_DISK, TYPE_TAPE, TYPE_PROCESSOR, TYPE_WORM, TYPE_ROM, TYPE_SCANNER, TYPE_MOD, 255};
@@ -855,4 +843,6 @@
X }
X ide_unregister_module(&idescsi_module);


X }
-#endif /* MODULE */
+

+module_init(init_idescsi_module);
+module_exit(exit_idescsi_module);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/imm.c linux/drivers/scsi/imm.c
--- v2.4.0-test8/linux/drivers/scsi/imm.c Mon Jul 24 18:59:27 2000
+++ linux/drivers/scsi/imm.c Mon Sep 18 13:36:25 2000
@@ -114,10 +114,8 @@
X * Parallel port probing routines *
X ***************************************************************************/
X
-#ifdef MODULE
-Scsi_Host_Template driver_template = IMM;
+static Scsi_Host_Template driver_template = IMM;


X #include "scsi_module.c"
-#endif
X

X int imm_detect(Scsi_Host_Template * host)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/in2000.c linux/drivers/scsi/in2000.c
--- v2.4.0-test8/linux/drivers/scsi/in2000.c Thu Nov 11 16:57:30 1999
+++ linux/drivers/scsi/in2000.c Mon Sep 18 13:36:25 2000
@@ -2359,11 +2359,6 @@


X }
X
X
-#ifdef MODULE
-

-Scsi_Host_Template driver_template = IN2000;
-
+static Scsi_Host_Template driver_template = IN2000;


X #include "scsi_module.c"
-
-#endif
X

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/ini9100u.c linux/drivers/scsi/ini9100u.c
--- v2.4.0-test8/linux/drivers/scsi/ini9100u.c Mon Jun 19 13:42:40 2000
+++ linux/drivers/scsi/ini9100u.c Mon Sep 18 13:36:25 2000
@@ -143,10 +143,8 @@
X unsigned int i91u_debug = DEBUG_DEFAULT;
X #endif
X
-#ifdef MODULE
-Scsi_Host_Template driver_template = INI9100U;
+static Scsi_Host_Template driver_template = INI9100U;


X #include "scsi_module.c"
-#endif
X

X char *i91uCopyright = "Copyright (C) 1996-98";
X char *i91uInitioName = "by Initio Corporation";
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/inia100.c linux/drivers/scsi/inia100.c
--- v2.4.0-test8/linux/drivers/scsi/inia100.c Wed Jul 5 17:57:27 2000
+++ linux/drivers/scsi/inia100.c Mon Sep 18 13:36:25 2000
@@ -92,10 +92,8 @@
X #include <linux/malloc.h>
X #include "inia100.h"
X
-#ifdef MODULE
-Scsi_Host_Template driver_template = INIA100;
+static Scsi_Host_Template driver_template = INIA100;


X #include "scsi_module.c"
-#endif
X

X #define ORC_RDWORD(x,y) (short)(inl((int)((ULONG)((ULONG)x+(UCHAR)y)) ))
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/ips.c linux/drivers/scsi/ips.c
--- v2.4.0-test8/linux/drivers/scsi/ips.c Fri Aug 4 17:58:10 2000
+++ linux/drivers/scsi/ips.c Tue Sep 19 08:01:34 2000
@@ -78,17 +78,40 @@
X /* - Sync with other changes from the 2.3 kernels */
X /* 4.00.06 - Fix timeout with initial FFDC command */
X /* 4.00.06a - Port to 2.4 (trivial) -- Christoph Hellwig <h...@caldera.de> */
+/* 4.10.00 - Add support for ServeRAID 4M/4L */
+/* 4.10.13 - Fix for dynamic unload and proc file system */
+/* 4.20.03 - Rename version to coincide with new release schedules */
+/* Performance fixes */
+/* Fix truncation of /proc files with cat */
+/* Merge in changes through kernel 2.4.0test1ac21 */
+/* 4.20.13 - Fix some failure cases / reset code */
+/* - Hook into the reboot_notifier to flush the controller cache */
X /* */
X /*****************************************************************************/
X
X /*
X * Conditional Compilation directives for this driver:
X *
- * NO_IPS_RESET - Don't reset the controller (no matter what)
- * IPS_DEBUG - More verbose error messages
- * IPS_PCI_PROBE_DEBUG - Print out more detail on the PCI probe
+ * IPS_DEBUG - Turn on debugging info
X *
+ *
+ * Parameters:
+ *
+ * debug:<number> - Set debug level to <number>
+ * NOTE: only works when IPS_DEBUG compile directive
+ * is used.
+ *
+ * 1 - Normal debug messages
+ * 2 - Verbose debug messages
+ * 11 - Method trace (non interrupt)
+ * 12 - Method trace (includes interrupt)
+ *
+ * noreset - Don't reset the controller
+ * nocmdline - Turn off passthru support
+ * noi2o - Don't use I2O Queues (ServeRAID 4 only)
+ * nommap - Don't use memory mapped I/O
X */
+

X
X #include <linux/module.h>
X

@@ -101,10 +124,12 @@
X #include <linux/kernel.h>
X #include <linux/ioport.h>
X #include <linux/malloc.h>
+#include <linux/vmalloc.h>
X #include <linux/delay.h>
X #include <linux/sched.h>
X #include <linux/pci.h>
X #include <linux/proc_fs.h>
+#include <linux/reboot.h>
X
X #include <linux/blk.h>
X #include <linux/types.h>
@@ -127,25 +152,29 @@
X #include <asm/spinlock.h>
X #endif
X
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
+#include <linux/init.h>
+#endif
+
X #include <linux/smp.h>
X
+#ifdef MODULE
+ static char *ips = NULL;
+ MODULE_PARM(ips, "s");
+#endif
+
X /*
X * DRIVER_VER
X */
-#define IPS_VERSION_HIGH "4.00" /* MUST be 4 chars */
-#define IPS_VERSION_LOW ".06 " /* MUST be 4 chars */
+#define IPS_VERSION_HIGH "4.20"
+#define IPS_VERSION_LOW ".20 "
X
X #if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27)
X struct proc_dir_entry proc_scsi_ips = {
-#if !defined(PROC_SCSI_IPS)
- 0, /* Use dynamic inode allocation */
-#else
- PROC_SCSI_IPS,
-#endif
+ 0,
X 3, "ips",
X S_IFDIR | S_IRUGO | S_IXUGO, 2
-}
-;
+};
X #endif
X
X #if !defined(__i386__)
@@ -160,12 +189,14 @@
X #error "To use the command-line interface you need to define SG_BIG_BUFF"
X #endif
X
-#if IPS_DEBUG >= 12
- #define DBG(s) printk(KERN_NOTICE s "\n"); MDELAY(2*IPS_ONE_SEC)
-#elif IPS_DEBUG >= 11
- #define DBG(s) printk(KERN_NOTICE s "\n")
+#ifdef IPS_DEBUG
+ #define METHOD_TRACE(s, i) if (ips_debug >= (i+10)) printk(KERN_NOTICE s "\n");
+ #define DEBUG(i, s) if (ips_debug >= i) printk(KERN_NOTICE s "\n");
+ #define DEBUG_VAR(i, s, v...) if (ips_debug >= i) printk(KERN_NOTICE s "\n", v);
X #else
- #define DBG(s)
+ #define METHOD_TRACE(s, i)
+ #define DEBUG(i, s)
+ #define DEBUG_VAR(i, s, v...)


X #endif
X
X /*

@@ -174,11 +205,26 @@
X static const char * ips_name = "ips";
X static struct Scsi_Host * ips_sh[IPS_MAX_ADAPTERS]; /* Array of host controller structures */
X static ips_ha_t * ips_ha[IPS_MAX_ADAPTERS]; /* Array of HA structures */
+static unsigned int ips_next_controller = 0;
X static unsigned int ips_num_controllers = 0;
+static unsigned int ips_released_controllers = 0;
X static int ips_cmd_timeout = 60;
X static int ips_reset_timeout = 60 * 5;
+static int ips_force_memio = 1; /* Always use Memory Mapped I/O */
+static int ips_force_i2o = 1; /* Always use I2O command delivery */
+static int ips_resetcontroller = 1; /* Reset the controller */
+static int ips_cmdline = 1; /* Support for passthru */
+
+#ifdef IPS_DEBUG
+static int ips_debug = 0; /* Debug mode */
+#endif
+
+/*
+ * Necessary forward function protoypes
+ */
+static int ips_halt(struct notifier_block *nb, ulong event, void *buf);
X
-#define MAX_ADAPTER_NAME 7
+#define MAX_ADAPTER_NAME 9
X
X static char ips_adapter_name[][30] = {
X "ServeRAID",
@@ -187,7 +233,13 @@
X "ServeRAID on motherboard",
X "ServeRAID 3H",
X "ServeRAID 3L",
- "ServeRAID 4H"
+ "ServeRAID 4H",
+ "ServeRAID 4M",
+ "ServeRAID 4L"
+};
+
+static struct notifier_block ips_notifier = {
+ ips_halt, NULL, 0
X };
X
X /*
@@ -252,8 +304,6 @@
X */
X int ips_detect(Scsi_Host_Template *);
X int ips_release(struct Scsi_Host *);
-int ips_abort(Scsi_Cmnd *);
-int ips_reset(Scsi_Cmnd *, unsigned int);
X int ips_eh_abort(Scsi_Cmnd *);
X int ips_eh_reset(Scsi_Cmnd *);
X int ips_queue(Scsi_Cmnd *, void (*) (Scsi_Cmnd *));
@@ -261,21 +311,26 @@
X const char * ips_info(struct Scsi_Host *);
X void do_ipsintr(int, void *, struct pt_regs *);
X static int ips_hainit(ips_ha_t *);
-static int ips_map_status(ips_scb_t *, ips_stat_t *);
+static int ips_map_status(ips_ha_t *, ips_scb_t *, ips_stat_t *);
X static int ips_send(ips_ha_t *, ips_scb_t *, ips_scb_callback);
X static int ips_send_wait(ips_ha_t *, ips_scb_t *, int, int);
X static int ips_send_cmd(ips_ha_t *, ips_scb_t *);
-static int ips_chkstatus(ips_ha_t *);
X static int ips_online(ips_ha_t *, ips_scb_t *);
X static int ips_inquiry(ips_ha_t *, ips_scb_t *);
X static int ips_rdcap(ips_ha_t *, ips_scb_t *);
X static int ips_msense(ips_ha_t *, ips_scb_t *);
X static int ips_reqsen(ips_ha_t *, ips_scb_t *);
X static int ips_allocatescbs(ips_ha_t *);
-static int ips_reset_adapter(ips_ha_t *);
-static int ips_statupd(ips_ha_t *);
-static int ips_issue(ips_ha_t *, ips_scb_t *);
-static int ips_isintr(ips_ha_t *);
+static int ips_reset_copperhead(ips_ha_t *);
+static int ips_reset_copperhead_memio(ips_ha_t *);
+static int ips_reset_morpheus(ips_ha_t *);
+static int ips_issue_copperhead(ips_ha_t *, ips_scb_t *);
+static int ips_issue_copperhead_memio(ips_ha_t *, ips_scb_t *);
+static int ips_issue_i2o(ips_ha_t *, ips_scb_t *);
+static int ips_issue_i2o_memio(ips_ha_t *, ips_scb_t *);
+static int ips_isintr_copperhead(ips_ha_t *);
+static int ips_isintr_copperhead_memio(ips_ha_t *);
+static int ips_isintr_morpheus(ips_ha_t *);
X static int ips_wait(ips_ha_t *, int, int);
X static int ips_write_driver_status(ips_ha_t *, int);
X static int ips_read_adapter_status(ips_ha_t *, int);
@@ -283,7 +338,22 @@
X static int ips_read_config(ips_ha_t *, int);
X static int ips_clear_adapter(ips_ha_t *, int);
X static int ips_readwrite_page5(ips_ha_t *, int, int);
-static void ips_intr(ips_ha_t *);
+static int ips_init_copperhead(ips_ha_t *);
+static int ips_init_copperhead_memio(ips_ha_t *);
+static int ips_init_morpheus(ips_ha_t *);
+static int ips_isinit_copperhead(ips_ha_t *);
+static int ips_isinit_copperhead_memio(ips_ha_t *);
+static int ips_isinit_morpheus(ips_ha_t *);
+static u32 ips_statupd_copperhead(ips_ha_t *);
+static u32 ips_statupd_copperhead_memio(ips_ha_t *);
+static u32 ips_statupd_morpheus(ips_ha_t *);
+static void ips_select_queue_depth(struct Scsi_Host *, Scsi_Device *);
+static void ips_chkstatus(ips_ha_t *, IPS_STATUS *);
+static void ips_enable_int_copperhead(ips_ha_t *);
+static void ips_enable_int_copperhead_memio(ips_ha_t *);
+static void ips_enable_int_morpheus(ips_ha_t *);
+static void ips_intr_copperhead(ips_ha_t *);
+static void ips_intr_morpheus(ips_ha_t *);
X static void ips_next(ips_ha_t *, int);
X static void ipsintr_blocking(ips_ha_t *, struct ips_scb *);
X static void ipsintr_done(ips_ha_t *, struct ips_scb *);
@@ -292,6 +362,7 @@
X static void ips_init_scb(ips_ha_t *, ips_scb_t *);
X static void ips_freescb(ips_ha_t *, ips_scb_t *);
X static void ips_statinit(ips_ha_t *);
+static void ips_statinit_memio(ips_ha_t *);
X static void ips_fix_ffdc_time(ips_ha_t *, ips_scb_t *, time_t);
X static void ips_ffdc_reset(ips_ha_t *, int);
X static void ips_ffdc_time(ips_ha_t *, int);
@@ -311,6 +382,9 @@
X static int ips_erase_bios(ips_ha_t *);
X static int ips_program_bios(ips_ha_t *, char *, int);
X static int ips_verify_bios(ips_ha_t *, char *, int);
+static int ips_erase_bios_memio(ips_ha_t *);
+static int ips_program_bios_memio(ips_ha_t *, char *, int);
+static int ips_verify_bios_memio(ips_ha_t *, char *, int);
X
X #ifndef NO_IPS_CMDLINE
X static int ips_is_passthru(Scsi_Cmnd *);
@@ -331,6 +405,76 @@
X
X /****************************************************************************/
X /* */
+/* Routine Name: ips_setup */
+/* */
+/* Routine Description: */
+/* */
+/* setup parameters to the driver */
+/* */
+/****************************************************************************/
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
+static int
+ips_setup(char *ips_str) {
+#else
+void
+ips_setup(char *ips_str, int *dummy) {
+#endif
+ int i;
+ char *p;
+ char *key;
+ char *value;
+ char tokens[3] = {',', '.', 0};
+ IPS_OPTION options[] = {
+ {"noreset", &ips_resetcontroller, 0},
+#ifdef IPS_DEBUG
+ {"debug", &ips_debug, 1},
+#endif
+ {"noi2o", &ips_force_i2o, 0},
+ {"nommap", &ips_force_memio, 0},
+ {"nocmdline", &ips_cmdline, 0},
+ };
+
+ METHOD_TRACE("ips_setup", 1);
+
+ for (key = strtok(ips_str, tokens); key; key = strtok(NULL, tokens)) {
+ p = key;
+
+ /* Search for value */
+ while ((p) && (*p != ':'))
+ p++;
+
+ if (p) {
+ *p = '\0';
+ value = p+1;
+ } else
+ value = NULL;
+
+ /*
+ * We now have key/value pairs.
+ * Update the variables
+ */
+ for (i = 0; i < (sizeof(options) / sizeof(options[0])); i++) {
+ if (strnicmp(key, options[i].option_name, strlen(ips_str)) == 0) {
+ if (value)
+ *options[i].option_flag = simple_strtoul(value, NULL, 0);
+ else
+ *options[i].option_flag = options[i].option_value;


+
+ break;
+ }
+ }
+ }

+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
+ return (1);
+#endif
+}
+
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
+__setup("ips=", ips_setup);
+#endif
+
+/****************************************************************************/
+/* */
X /* Routine Name: ips_detect */
X /* */
X /* Routine Description: */
@@ -345,15 +489,38 @@
X struct Scsi_Host *sh;
X ips_ha_t *ha;
X u32 io_addr;
+ u32 mem_addr;
+ u32 io_len;
+ u32 mem_len;
X u16 planer;
X u8 revision_id;
X u8 bus;
X u8 func;
X u8 irq;
- int index;
- struct pci_dev *dev = NULL;
-
- DBG("ips_detect");
+ u16 deviceID[2];
+ int i;
+ int j;
+ char *ioremap_ptr;
+ char *mem_ptr;
+ struct pci_dev *dev[2];
+ struct pci_dev *morpheus = NULL;
+ struct pci_dev *trombone = NULL;
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,14)
+ u32 currbar;
+ u32 maskbar;
+ u8 barnum;
+#endif
+
+ METHOD_TRACE("ips_detect", 1);
+
+#ifdef MODULE
+ if (ips)
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
+ ips_setup(ips);
+#else
+ ips_setup(ips, NULL);
+#endif
+#endif
X
X SHT->proc_info = ips_proc_info;
X #if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27)
@@ -363,226 +530,524 @@
X #endif
X
X #if defined(CONFIG_PCI)
-
+
X /* initalize number of controllers */
X ips_num_controllers = 0;
-
+ ips_next_controller = 0;
+ ips_released_controllers = 0;
+
X if (!pci_present())
X return (0);
X
- for (index = 0; index < IPS_MAX_ADAPTERS; index++) {
+ morpheus = pci_find_device(IPS_VENDORID, IPS_MORPHEUS_DEVICEID, morpheus);
+ trombone = pci_find_device(IPS_VENDORID, IPS_COPPERHEAD_DEVICEID, trombone);
+
+ /* determine which controller to probe first */
+ if (!morpheus) {
+ /* we only have trombone */
+ dev[0] = trombone;
+ dev[1] = NULL;
+ deviceID[0] = IPS_COPPERHEAD_DEVICEID;
+ } else if (!trombone) {
+ /* we only have morpheus */
+ dev[0] = morpheus;
+ dev[1] = NULL;
+ deviceID[0] = IPS_MORPHEUS_DEVICEID;
+ } else {
+ /* we have both in the system */
+ if (trombone->bus < morpheus->bus) {
+ dev[0] = trombone;
+ dev[1] = morpheus;
+ deviceID[0] = IPS_COPPERHEAD_DEVICEID;
+ deviceID[1] = IPS_MORPHEUS_DEVICEID;
+ } else if (trombone->bus > morpheus->bus) {
+ dev[0] = morpheus;
+ dev[1] = trombone;
+ deviceID[0] = IPS_MORPHEUS_DEVICEID;
+ deviceID[1] = IPS_COPPERHEAD_DEVICEID;
+ } else {
+ /* further detection required */
+ if (trombone->devfn < morpheus->devfn) {
+ dev[0] = trombone;
+ dev[1] = morpheus;
+ deviceID[0] = IPS_COPPERHEAD_DEVICEID;
+ deviceID[1] = IPS_MORPHEUS_DEVICEID;
+ } else {
+ dev[0] = morpheus;
+ dev[1] = trombone;
+ deviceID[0] = IPS_MORPHEUS_DEVICEID;
+ deviceID[1] = IPS_COPPERHEAD_DEVICEID;
+ }
+ }
+ }
X
- if (!(dev = pci_find_device(IPS_VENDORID, IPS_DEVICEID, dev)))
+ /* Now scan the controllers */
+ for (i = 0; i < 2; i++) {
+ if (!dev[i])
X break;
X
- if (pci_enable_device(dev))
- break;
-
- /* stuff that we get in dev */
- irq = dev->irq;
- bus = dev->bus->number;
- func = dev->devfn;
- io_addr = pci_resource_start(dev, 0);
-
- /* check I/O address */
- if (pci_resource_flags(dev, 0) & IORESOURCE_MEM)
- continue;
+ do {
+ if (ips_next_controller >= IPS_MAX_ADAPTERS)
+ break;
X
- /* get planer status */
- if (pci_read_config_word(dev, 0x04, &planer)) {
- printk(KERN_WARNING "(%s%d) can't get planer status.\n",
- ips_name, index);
- continue;
- }
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
+ if (pci_enable_device(dev[i]))
+ break;
+#endif
X
- /* check to see if an onboard planer controller is disabled */
- if (!(planer & 0x000C)) {
+ /* stuff that we get in dev */
+ irq = dev[i]->irq;
+ bus = dev[i]->bus->number;
+ func = dev[i]->devfn;
+
+ /* Init MEM/IO addresses to 0 */
+ mem_addr = 0;
+ io_addr = 0;
+ mem_len = 0;
+ io_len = 0;
+
+ for (j = 0; j < 2; j++) {
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
+ if (!pci_resource_start(dev[i], j))
+ break;
X
- #ifdef IPS_PCI_PROBE_DEBUG
- printk(KERN_NOTICE "(%s%d) detect, Onboard ServeRAID disabled by BIOS\n",
- ips_name, index);
- #endif
+ if (pci_resource_flags(dev[i], j) & IORESOURCE_IO) {
+ io_addr = pci_resource_start(dev[i], j);
+ io_len = pci_resource_len(dev[i], j);
+ } else {
+ mem_addr = pci_resource_start(dev[i], j);
+ mem_len = pci_resource_len(dev[i], j);
+ }
+#elif LINUX_VERSION_CODE >= LinuxVersionCode(2,3,14)
+ if (!dev[i]->resource[j].start)
+ break;
X
- continue;
- }
+ if ((dev[i]->resource[j].start & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
+ io_addr = dev[i]->resource[j].start;
+ io_len = dev[i]->resource[j].end - dev[i]->resource[j].start + 1;
+ } else {
+ mem_addr = dev[i]->resource[j].start;
+ mem_len = dev[i]->resource[j].end - dev[i]->resource[j].start + 1;
+ }
+#else
+ if (!dev[i]->base_address[j])
+ break;
X
- #ifdef IPS_PCI_PROBE_DEBUG
- printk(KERN_NOTICE "(%s%d) detect bus %d, func %x, irq %d, io %x\n",
- ips_name, index, bus, func, irq, io_addr);
- #endif
-
- /* get the revision ID */
- if (pci_read_config_byte(dev, 0x08, &revision_id)) {
- printk(KERN_WARNING "(%s%d) can't get revision id.\n",
- ips_name, index);
+ if ((dev[i]->base_address[j] & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
+ barnum = PCI_BASE_ADDRESS_0 + (j * 4);
+ io_addr = dev[i]->base_address[j] & PCI_BASE_ADDRESS_IO_MASK;
+
+ /* Get Size */
+ pci_read_config_dword(dev[i], barnum, &currbar);
+ pci_write_config_dword(dev[i], barnum, ~0);
+ pci_read_config_dword(dev[i], barnum, &maskbar);
+ pci_write_config_dword(dev[i], barnum, currbar);
X
- continue;
- }
+ io_len = ~(maskbar & PCI_BASE_ADDRESS_IO_MASK) + 1;
+ } else {
+ barnum = PCI_BASE_ADDRESS_0 + (j * 4);
+ mem_addr = dev[i]->base_address[j] & PCI_BASE_ADDRESS_MEM_MASK;
X
- /* found a controller */
- sh = scsi_register(SHT, sizeof(ips_ha_t));
+ /* Get Size */
+ pci_read_config_dword(dev[i], barnum, &currbar);
+ pci_write_config_dword(dev[i], barnum, ~0);
+ pci_read_config_dword(dev[i], barnum, &maskbar);
+ pci_write_config_dword(dev[i], barnum, currbar);
X
- if (sh == NULL) {
- printk(KERN_WARNING "(%s%d) Unable to register controller with SCSI subsystem - skipping controller\n",
- ips_name, index);
+ mem_len = ~(maskbar & PCI_BASE_ADDRESS_MEM_MASK) + 1;
+ }
+#endif
+ }
X
- continue;
- }
+ /* setup memory mapped area (if applicable) */
+ if (mem_addr) {
+ u32 base;
+ u32 offs;
+
+ DEBUG_VAR(1, "(%s%d) detect, Memory region %x, size: %d",
+ ips_name, ips_next_controller, mem_addr, mem_len);
+
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,17)
+ if (check_mem_region(mem_addr, mem_len)) {
+ /* Couldn't allocate io space */
+ printk(KERN_WARNING "(%s%d) couldn't allocate IO space %x len %d.\n",
+ ips_name, ips_next_controller, io_addr, io_len);
X
- ha = IPS_HA(sh);
- memset(ha, 0, sizeof(ips_ha_t));
+ ips_next_controller++;
X
- /* Initialize spin lock */
- spin_lock_init(&ha->scb_lock);
- spin_lock_init(&ha->copp_lock);
- spin_lock_init(&ha->ips_lock);
- spin_lock_init(&ha->copp_waitlist.lock);
- spin_lock_init(&ha->scb_waitlist.lock);
- spin_lock_init(&ha->scb_activelist.lock);
-
- ips_sh[ips_num_controllers] = sh;
- ips_ha[ips_num_controllers] = ha;
- ips_num_controllers++;
- ha->active = 1;
-
- ha->enq = kmalloc(sizeof(IPS_ENQ), GFP_KERNEL|GFP_DMA);
-
- if (!ha->enq) {
- printk(KERN_WARNING "(%s%d) Unable to allocate host inquiry structure - skipping contoller\n",
- ips_name, index);
+ continue;
+ }
X
- ha->active = 0;
+ request_mem_region(mem_addr, mem_len, "ips");
+#endif
X
- continue;
- }
+ base = mem_addr & PAGE_MASK;
+ offs = mem_addr - base;
X
- ha->adapt = kmalloc(sizeof(IPS_ADAPTER), GFP_KERNEL|GFP_DMA);
+ ioremap_ptr = ioremap(base, PAGE_SIZE);
+ mem_ptr = ioremap_ptr + offs;
+ } else {
+ ioremap_ptr = NULL;
+ mem_ptr = NULL;
+ }
X
- if (!ha->adapt) {
- printk(KERN_WARNING "(%s%d) Unable to allocate host adapt structure - skipping controller\n",
- ips_name, index);
+ /* setup I/O mapped area (if applicable) */
+ if (io_addr) {
+ DEBUG_VAR(1, "(%s%d) detect, IO region %x, size: %d",
+ ips_name, ips_next_controller, io_addr, io_len);
+
+ if (check_region(io_addr, io_len)) {
+ /* Couldn't allocate io space */
+ printk(KERN_WARNING "(%s%d) couldn't allocate IO space %x len %d.\n",
+ ips_name, ips_next_controller, io_addr, io_len);
X
- ha->active = 0;
+ ips_next_controller++;
X
- continue;
- }
+ continue;
+ }
X
- ha->conf = kmalloc(sizeof(IPS_CONF), GFP_KERNEL|GFP_DMA);
+ request_region(io_addr, io_len, "ips");
+ }
X
- if (!ha->conf) {
- printk(KERN_WARNING "(%s%d) Unable to allocate host conf structure - skipping controller\n",
- ips_name, index);
+ /* get planer status */
+ if (pci_read_config_word(dev[i], 0x04, &planer)) {
+ printk(KERN_WARNING "(%s%d) can't get planer status.\n",
+ ips_name, ips_next_controller);
X
- ha->active = 0;
+ ips_next_controller++;
X
- continue;
- }
+ continue;
+ }
+
+ /* check to see if an onboard planer controller is disabled */
+ if (!(planer & 0x000C)) {
X
- ha->nvram = kmalloc(sizeof(IPS_NVRAM_P5), GFP_KERNEL|GFP_DMA);
+ DEBUG_VAR(1, "(%s%d) detect, Onboard ServeRAID disabled by BIOS",
+ ips_name, ips_next_controller);
X
- if (!ha->nvram) {
- printk(KERN_WARNING "(%s%d) Unable to allocate host nvram structure - skipping controller\n",
- ips_name, index);
+ ips_next_controller++;
X
- ha->active = 0;
+ continue;
+ }
X
- continue;
- }
+ DEBUG_VAR(1, "(%s%d) detect bus %d, func %x, irq %d, io %x, mem: %x, ptr: %x",
+ ips_name, ips_next_controller, bus, func, irq, io_addr, mem_addr, (u32) mem_ptr);
X
- ha->subsys = kmalloc(sizeof(IPS_SUBSYS), GFP_KERNEL|GFP_DMA);
+ /* get the revision ID */
+ if (pci_read_config_byte(dev[i], 0x08, &revision_id)) {
+ printk(KERN_WARNING "(%s%d) can't get revision id.\n",
+ ips_name, ips_next_controller);
X
- if (!ha->subsys) {
- printk(KERN_WARNING "(%s%d) Unable to allocate host subsystem structure - skipping controller\n",
- ips_name, index);
+ ips_next_controller++;
X
- ha->active = 0;
+ continue;
+ }
X
- continue;
- }
+ /* found a controller */
+ sh = scsi_register(SHT, sizeof(ips_ha_t));
X
- ha->dummy = kmalloc(sizeof(IPS_IO_CMD), GFP_KERNEL|GFP_DMA);
+ if (sh == NULL) {
+ printk(KERN_WARNING "(%s%d) Unable to register controller with SCSI subsystem - skipping controller\n",
+ ips_name, ips_next_controller);
X
- if (!ha->dummy) {
- printk(KERN_WARNING "(%s%d) Unable to allocate host dummy structure - skipping controller\n",
- ips_name, index);
+ ips_next_controller++;
X
- ha->active = 0;
+ continue;
+ }
X
- continue;
- }
+ ha = IPS_HA(sh);
+ memset(ha, 0, sizeof(ips_ha_t));
X
- ha->ioctl_data = kmalloc(IPS_IOCTL_SIZE, GFP_KERNEL|GFP_DMA);
- ha->ioctl_datasize = IPS_IOCTL_SIZE;
- if (!ha->ioctl_data) {
- printk(KERN_WARNING "(%s%d) Unable to allocate ioctl data - skipping controller\n",
- ips_name, index);
+ /* Initialize spin lock */
+ spin_lock_init(&ha->scb_lock);
+ spin_lock_init(&ha->copp_lock);
+ spin_lock_init(&ha->ips_lock);
+ spin_lock_init(&ha->copp_waitlist.lock);
+ spin_lock_init(&ha->scb_waitlist.lock);
+ spin_lock_init(&ha->scb_activelist.lock);
+
+ ips_sh[ips_next_controller] = sh;
+ ips_ha[ips_next_controller] = ha;
+ ips_num_controllers++;
+ ha->active = 1;
+
+ ha->enq = kmalloc(sizeof(IPS_ENQ), GFP_ATOMIC|GFP_DMA);
+
+ if (!ha->enq) {
+ printk(KERN_WARNING "(%s%d) Unable to allocate host inquiry structure - skipping contoller\n",
+ ips_name, ips_next_controller);
+
+ ha->active = 0;
+ ips_free(ha);
+ ips_next_controller++;
+ ips_num_controllers--;
X
- ha->active = 0;
+ continue;
+ }
X
- continue;
- }
+ ha->adapt = kmalloc(sizeof(IPS_ADAPTER), GFP_ATOMIC|GFP_DMA);
X
- /* Store away needed values for later use */
- sh->io_port = io_addr;
- sh->n_io_port = 255;
- sh->unique_id = io_addr;
- sh->irq = irq;
- sh->select_queue_depths = NULL;
- sh->sg_tablesize = sh->hostt->sg_tablesize;
- sh->can_queue = sh->hostt->can_queue;
- sh->cmd_per_lun = sh->hostt->cmd_per_lun;
- sh->unchecked_isa_dma = sh->hostt->unchecked_isa_dma;
- sh->use_clustering = sh->hostt->use_clustering;
-
- /* Store info in HA structure */
- ha->io_addr = io_addr;
- ha->irq = irq;
- ha->host_num = index;
- ha->revision_id = revision_id;
-
- /* install the interrupt handler */
- if (request_irq(irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) {
- printk(KERN_WARNING "(%s%d) unable to install interrupt handler - skipping controller\n",
- ips_name, index);
+ if (!ha->adapt) {
+ printk(KERN_WARNING "(%s%d) Unable to allocate host adapt structure - skipping controller\n",
+ ips_name, ips_next_controller);
+ ha->active = 0;
+ ips_free(ha);
+ ips_next_controller++;
+ ips_num_controllers--;
X
- ha->active = 0;
+ continue;
+ }
X
- continue;
- }
+ ha->conf = kmalloc(sizeof(IPS_CONF), GFP_ATOMIC|GFP_DMA);
X
- /*
- * Allocate a temporary SCB for initialization
- */
- ha->scbs = (ips_scb_t *) kmalloc(sizeof(ips_scb_t), GFP_KERNEL|GFP_DMA);
- if (!ha->scbs) {
- /* couldn't allocate a temp SCB */
- printk(KERN_WARNING "(%s%d) unable to allocate CCBs - skipping contoller\n",
- ips_name, index);
+ if (!ha->conf) {
+ printk(KERN_WARNING "(%s%d) Unable to allocate host conf structure - skipping controller\n",
+ ips_name, ips_next_controller);
+
+ ha->active = 0;
+ ips_free(ha);
+ ips_next_controller++;
+ ips_num_controllers--;
X
- ha->active = 0;
+ continue;
+ }
X
- continue;
- }
+ ha->nvram = kmalloc(sizeof(IPS_NVRAM_P5), GFP_ATOMIC|GFP_DMA);
X
- memset(ha->scbs, 0, sizeof(ips_scb_t));
- ha->scbs->sg_list = (IPS_SG_LIST *) kmalloc(sizeof(IPS_SG_LIST) * IPS_MAX_SG, GFP_KERNEL|GFP_DMA);
- if (!ha->scbs->sg_list) {
- /* couldn't allocate a temp SCB S/G list */
- printk(KERN_WARNING "(%s%d) unable to allocate CCBs - skipping contoller\n",
- ips_name, index);
+ if (!ha->nvram) {
+ printk(KERN_WARNING "(%s%d) Unable to allocate host nvram structure - skipping controller\n",
+ ips_name, ips_next_controller);
+
+ ha->active = 0;
+ ips_free(ha);
+ ips_next_controller++;
+ ips_num_controllers--;
X
- ha->active = 0;
+ continue;
+ }
+
+ ha->subsys = kmalloc(sizeof(IPS_SUBSYS), GFP_ATOMIC|GFP_DMA);
+
+ if (!ha->subsys) {
+ printk(KERN_WARNING "(%s%d) Unable to allocate host subsystem structure - skipping controller\n",
+ ips_name, ips_next_controller);
+
+ ha->active = 0;
+ ips_free(ha);
+ ips_next_controller++;
+ ips_num_controllers--;
+
+ continue;
+ }
+
+ ha->dummy = kmalloc(sizeof(IPS_IO_CMD), GFP_ATOMIC|GFP_DMA);
+
+ if (!ha->dummy) {
+ printk(KERN_WARNING "(%s%d) Unable to allocate host dummy structure - skipping controller\n",
+ ips_name, ips_next_controller);
+
+ ha->active = 0;
+ ips_free(ha);
+ ips_next_controller++;
+ ips_num_controllers--;
+
+ continue;
+ }
+
+ ha->ioctl_data = kmalloc(IPS_IOCTL_SIZE, GFP_ATOMIC|GFP_DMA);
+ ha->ioctl_datasize = IPS_IOCTL_SIZE;
+ if (!ha->ioctl_data) {
+ printk(KERN_WARNING "(%s%d) Unable to allocate ioctl data - skipping controller\n",
+ ips_name, ips_next_controller);
+
+ ha->active = 0;
+ ips_free(ha);
+ ips_next_controller++;
+ ips_num_controllers--;
+
+ continue;
+ }
+
+ /* Store away needed values for later use */
+ sh->io_port = io_addr;
+ sh->n_io_port = io_addr ? 255 : 0;
+ sh->unique_id = (io_addr) ? io_addr : mem_addr;
+ sh->irq = irq;
+ sh->select_queue_depths = ips_select_queue_depth;
+ sh->sg_tablesize = sh->hostt->sg_tablesize;
+ sh->can_queue = sh->hostt->can_queue;
+ sh->cmd_per_lun = sh->hostt->cmd_per_lun;
+ sh->unchecked_isa_dma = sh->hostt->unchecked_isa_dma;
+ sh->use_clustering = sh->hostt->use_clustering;
+
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,32)
+ sh->wish_block = FALSE;
+#endif
+
+ /* Store info in HA structure */
+ ha->irq = irq;
+ ha->io_addr = io_addr;
+ ha->io_len = io_len;
+ ha->mem_addr = mem_addr;
+ ha->mem_len = mem_len;
+ ha->mem_ptr = mem_ptr;
+ ha->ioremap_ptr = ioremap_ptr;
+ ha->host_num = ips_next_controller;
+ ha->revision_id = revision_id;
+ ha->device_id = deviceID[i];
+ ha->pcidev = dev[i];
+
+ /*
+ * Setup Functions
+ */
+ if (IPS_IS_MORPHEUS(ha)) {
+ /* morpheus */
+ ha->func.isintr = ips_isintr_morpheus;
+ ha->func.isinit = ips_isinit_morpheus;
+ ha->func.issue = ips_issue_i2o_memio;
+ ha->func.init = ips_init_morpheus;
+ ha->func.statupd = ips_statupd_morpheus;
+ ha->func.reset = ips_reset_morpheus;
+ ha->func.intr = ips_intr_morpheus;
+ ha->func.enableint = ips_enable_int_morpheus;
+ } else if (IPS_USE_MEMIO(ha)) {
+ /* copperhead w/MEMIO */
+ ha->func.isintr = ips_isintr_copperhead_memio;
+ ha->func.isinit = ips_isinit_copperhead_memio;
+ ha->func.init = ips_init_copperhead_memio;
+ ha->func.statupd = ips_statupd_copperhead_memio;
+ ha->func.statinit = ips_statinit_memio;
+ ha->func.reset = ips_reset_copperhead_memio;
+ ha->func.intr = ips_intr_copperhead;
+ ha->func.erasebios = ips_erase_bios_memio;
+ ha->func.programbios = ips_program_bios_memio;
+ ha->func.verifybios = ips_verify_bios_memio;
+ ha->func.enableint = ips_enable_int_copperhead_memio;
+
+ if (IPS_USE_I2O_DELIVER(ha))
+ ha->func.issue = ips_issue_i2o_memio;


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 079'
echo 'File patch-2.4.0-test9 is continued in part 080'
echo "080" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part080

#!/bin/sh -x
# this is part 080 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 080; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ else
+ ha->func.issue = ips_issue_copperhead_memio;
+ } else {
+ /* copperhead */
+ ha->func.isintr = ips_isintr_copperhead;
+ ha->func.isinit = ips_isinit_copperhead;
+ ha->func.init = ips_init_copperhead;
+ ha->func.statupd = ips_statupd_copperhead;
+ ha->func.statinit = ips_statinit;
+ ha->func.reset = ips_reset_copperhead;


+ ha->func.intr = ips_intr_copperhead;

+ ha->func.erasebios = ips_erase_bios;
+ ha->func.programbios = ips_program_bios;
+ ha->func.verifybios = ips_verify_bios;
+ ha->func.enableint = ips_enable_int_copperhead;
+
+ if (IPS_USE_I2O_DELIVER(ha))
+ ha->func.issue = ips_issue_i2o;
+ else
+ ha->func.issue = ips_issue_copperhead;
+ }
+
+ /*
+ * Initialize the card if it isn't already
+ */
+ if (!(*ha->func.isinit)(ha)) {
+ if (!(*ha->func.init)(ha)) {
+ /*
+ * Initialization failed
+ */
+ printk(KERN_WARNING "(%s%d) unable to initialize controller - skipping controller\n",


+ ips_name, ips_next_controller);
+
+ ha->active = 0;
+ ips_free(ha);
+ ips_next_controller++;
+ ips_num_controllers--;
+
+ continue;
+ }
+ }
+

+ /* install the interrupt handler */
+ if (request_irq(irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) {
+ printk(KERN_WARNING "(%s%d) unable to install interrupt handler - skipping controller\n",


+ ips_name, ips_next_controller);
+
+ ha->active = 0;
+ ips_free(ha);
+ ips_next_controller++;
+ ips_num_controllers--;
+
+ continue;
+ }
+
+ /*

+ * Allocate a temporary SCB for initialization
+ */
+ ha->scbs = (ips_scb_t *) kmalloc(sizeof(ips_scb_t), GFP_ATOMIC|GFP_DMA);
+ if (!ha->scbs) {
+ /* couldn't allocate a temp SCB */
+ printk(KERN_WARNING "(%s%d) unable to allocate CCBs - skipping contoller\n",


+ ips_name, ips_next_controller);
+
+ ha->active = 0;
+ ips_free(ha);

+ free_irq(ha->irq, ha);


+ ips_next_controller++;
+ ips_num_controllers--;
+
+ continue;
+ }
+

+ memset(ha->scbs, 0, sizeof(ips_scb_t));
+ ha->scbs->sg_list = (IPS_SG_LIST *) kmalloc(sizeof(IPS_SG_LIST) * IPS_MAX_SG, GFP_ATOMIC|GFP_DMA);
+ if (!ha->scbs->sg_list) {
+ /* couldn't allocate a temp SCB S/G list */
+ printk(KERN_WARNING "(%s%d) unable to allocate CCBs - skipping contoller\n",


+ ips_name, ips_next_controller);
+
+ ha->active = 0;
+ ips_free(ha);

+ free_irq(ha->irq, ha);


+ ips_next_controller++;
+ ips_num_controllers--;
+
+ continue;
+ }
+

+ ha->max_cmds = 1;
+
+ ips_next_controller++;
+ } while ((dev[i] = pci_find_device(IPS_VENDORID, deviceID[i], dev[i])));
+ }
+
+ /*
+ * Do Phase 2 Initialization
+ * Controller init
+ */
+ for (i = 0; i < ips_next_controller; i++) {
+ ha = ips_ha[i];
+ sh = ips_sh[i];
+
+ if (!ha->active) {
+ scsi_unregister(sh);
+ ips_ha[i] = NULL;
+ ips_sh[i] = NULL;
X
X continue;
X }
X
- ha->max_cmds = 1;
-
X if (!ips_hainit(ha)) {
X printk(KERN_WARNING "(%s%d) unable to initialize controller - skipping\n",
- ips_name, index);
+ ips_name, i);
X
X ha->active = 0;
+ ips_free(ha);
+ free_irq(ha->irq, ha);
+ scsi_unregister(sh);
+ ips_ha[i] = NULL;
+ ips_sh[i] = NULL;
+ ips_num_controllers--;
X
X continue;
X }
@@ -597,9 +1062,15 @@
X /* allocate CCBs */
X if (!ips_allocatescbs(ha)) {
X printk(KERN_WARNING "(%s%d) unable to allocate CCBs - skipping contoller\n",
- ips_name, index);
+ ips_name, i);
X
X ha->active = 0;
+ ips_free(ha);
+ free_irq(ha->irq, ha);
+ scsi_unregister(sh);
+ ips_ha[i] = NULL;
+ ips_sh[i] = NULL;
+ ips_num_controllers--;
X
X continue;
X }
@@ -607,9 +1078,12 @@
X /* finish setting values */
X sh->max_id = ha->ntargets;
X sh->max_lun = ha->nlun;
- sh->max_channel = ha->nbus;
+ sh->max_channel = ha->nbus - 1;
X sh->can_queue = ha->max_cmds-1;
- } /* end for */
+ }
+
+ if (ips_num_controllers > 0)
+ register_reboot_notifier(&ips_notifier);
X
X return (ips_num_controllers);
X
@@ -635,7 +1109,7 @@
X ips_ha_t *ha;
X int i;
X
- DBG("ips_release");
+ METHOD_TRACE("ips_release", 1);
X
X for (i = 0; i < IPS_MAX_ADAPTERS && ips_sh[i] != sh; i++);
X
@@ -678,17 +1152,85 @@
X /* free extra memory */
X ips_free(ha);
X
+ /* Free I/O Region */
+ if (ha->io_addr)
+ release_region(ha->io_addr, ha->io_len);


+
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,17)

+ if (ha->mem_addr)
+ release_mem_region(ha->mem_addr, ha->mem_len);
+#endif
+
X /* free IRQ */
X free_irq(ha->irq, ha);
X
- /* unregister with SCSI sub system */
- scsi_unregister(sh);
+ ips_released_controllers++;
+
+ if (ips_num_controllers == ips_released_controllers)
+ unregister_reboot_notifier(&ips_notifier);
X
X return (FALSE);
X }


X
X /****************************************************************************/
X /* */

+/* Routine Name: ips_halt */


+/* */
+/* Routine Description: */
+/* */

+/* Perform cleanup when the system reboots */
+/* */
+/****************************************************************************/
+static int
+ips_halt(struct notifier_block *nb, ulong event, void *buf) {
+ ips_scb_t *scb;
+ ips_ha_t *ha;
+ int i;
+
+ if ((event != SYS_RESTART) && (event != SYS_HALT) &&
+ (event != SYS_POWER_OFF))
+ return (NOTIFY_DONE);
+
+ for (i = 0; i < ips_next_controller; i++) {
+ ha = (ips_ha_t *) ips_ha[i];
+
+ if (!ha)
+ continue;
+
+ if (!ha->active)
+ continue;
+
+ /* flush the cache on the controller */
+ scb = &ha->scbs[ha->max_cmds-1];
+
+ ips_init_scb(ha, scb);
+
+ scb->timeout = ips_cmd_timeout;
+ scb->cdb[0] = IPS_CMD_FLUSH;
+
+ scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
+ scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
+ scb->cmd.flush_cache.state = IPS_NORM_STATE;
+ scb->cmd.flush_cache.reserved = 0;
+ scb->cmd.flush_cache.reserved2 = 0;
+ scb->cmd.flush_cache.reserved3 = 0;
+ scb->cmd.flush_cache.reserved4 = 0;
+
+ printk("(%s%d) Flushing Cache.\n", ips_name, ha->host_num);
+
+ /* send command */
+ if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) == IPS_FAILURE)
+ printk("(%s%d) Incomplete Flush.\n", ips_name, ha->host_num);
+ else
+ printk("(%s%d) Flushing Complete.\n", ips_name, ha->host_num);
+ }
+
+ unregister_reboot_notifier(&ips_notifier);
+ return (NOTIFY_OK);
+}
+
+/****************************************************************************/
+/* */
X /* Routine Name: ips_eh_abort */


X /* */
X /* Routine Description: */

@@ -701,7 +1243,7 @@
X ips_ha_t *ha;
X ips_copp_wait_item_t *item;
X
- DBG("ips_eh_abort");
+ METHOD_TRACE("ips_eh_abort", 1);
X
X if (!SC)
X return (FAILED);
@@ -716,9 +1258,7 @@
X
X if (SC->serial_number != SC->serial_number_at_timeout) {
X /* HMM, looks like a bogus command */
-#if IPS_DEBUG >= 1
- printk(KERN_NOTICE "Abort called with bogus scsi command\n");
-#endif
+ DEBUG(1, "Abort called with bogus scsi command");
X
X return (FAILED);
X }
@@ -757,114 +1297,42 @@


X
X /****************************************************************************/
X /* */

-/* Routine Name: ips_abort */
+/* Routine Name: ips_eh_reset */


X /* */
X /* Routine Description: */

X /* */
-/* Abort a command */
+/* Reset the controller (with new eh error code) */
+/* */
+/* NOTE: this routine is called under the io_request_lock spinlock */
X /* */
X /****************************************************************************/
X int
-ips_abort(Scsi_Cmnd *SC) {
- ips_ha_t *ha;
+ips_eh_reset(Scsi_Cmnd *SC) {
+ int ret;
+ int i;
+ u32 cpu_flags;
+ ips_ha_t *ha;
+ ips_scb_t *scb;
X ips_copp_wait_item_t *item;
X
- DBG("ips_abort");
+ METHOD_TRACE("ips_eh_reset", 1);
X
- if (!SC)
- return (SCSI_ABORT_SNOOZE);
+#ifdef NO_IPS_RESET
+ return (FAILED);
+#else
X
- ha = (ips_ha_t *) SC->host->hostdata;
+ if (!SC) {
+ DEBUG(1, "Reset called with NULL scsi command");
X
- if (!ha)
- return (SCSI_ABORT_SNOOZE);
+ return (FAILED);
+ }
X
- if (!ha->active)
- return (SCSI_ABORT_SNOOZE);
+ ha = (ips_ha_t *) SC->host->hostdata;
X
- if (SC->serial_number != SC->serial_number_at_timeout) {
- /* HMM, looks like a bogus command */
-#if IPS_DEBUG >= 1
- printk(KERN_NOTICE "Abort called with bogus scsi command\n");
-#endif
+ if (!ha) {
+ DEBUG(1, "Reset called with NULL ha struct");
X
- return (SCSI_ABORT_NOT_RUNNING);
- }
-
- if (test_and_set_bit(IPS_IN_ABORT, &ha->flags))
- return (SCSI_ABORT_SNOOZE);
-
- /* See if the command is on the copp queue */
- IPS_QUEUE_LOCK(&ha->copp_waitlist);
- item = ha->copp_waitlist.head;
- while ((item) && (item->scsi_cmd != SC))
- item = item->next;
- IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
-
- if (item) {
- /* Found it */
- ips_removeq_copp(&ha->copp_waitlist, item);
- clear_bit(IPS_IN_ABORT, &ha->flags);
-
- return (SCSI_ABORT_PENDING);
- }
-
- /* See if the command is on the wait queue */
- if (ips_removeq_wait(&ha->scb_waitlist, SC)) {
- /* command not sent yet */
- clear_bit(IPS_IN_ABORT, &ha->flags);
-
- return (SCSI_ABORT_PENDING);
- } else {
- /* command must have already been sent */
- clear_bit(IPS_IN_ABORT, &ha->flags);
-
- return (SCSI_ABORT_SNOOZE);
- }
-}
-
-/****************************************************************************/
-/* */
-/* Routine Name: ips_eh_reset */
-/* */
-/* Routine Description: */
-/* */
-/* Reset the controller (with new eh error code) */
-/* */
-/* NOTE: this routine is called under the io_request_lock spinlock */
-/* */
-/****************************************************************************/
-int
-ips_eh_reset(Scsi_Cmnd *SC) {
- u32 cpu_flags;
- ips_ha_t *ha;
- ips_scb_t *scb;
- ips_copp_wait_item_t *item;
-
- DBG("ips_eh_reset");
-
-#ifdef NO_IPS_RESET
- return (FAILED);
-#else
-
- if (!SC) {
-
-#if IPS_DEBUG >= 1
- printk(KERN_NOTICE "Reset called with NULL scsi command\n");
-#endif
-
- return (FAILED);
- }
-
- ha = (ips_ha_t *) SC->host->hostdata;
-
- if (!ha) {
-
-#if IPS_DEBUG >= 1
- printk(KERN_NOTICE "Reset called with NULL ha struct\n");
-#endif
-
- return (FAILED);
+ return (FAILED);
X }
X
X if (!ha->active)
@@ -900,149 +1368,72 @@
X * command must have already been sent
X * reset the controller
X */
- if (!ips_reset_adapter(ha)) {
- clear_bit(IPS_IN_RESET, &ha->flags);
-
- return (FAILED);
- }
-
- if (!ips_clear_adapter(ha, IPS_INTR_IORL)) {
- clear_bit(IPS_IN_RESET, &ha->flags);
-
- return (FAILED);
- }
-
- /* FFDC */
- if (ha->subsys->param[3] & 0x300000) {
- struct timeval tv;
-
- do_gettimeofday(&tv);
- IPS_HA_LOCK(cpu_flags);
- ha->last_ffdc = tv.tv_sec;
- ha->reset_count++;
- IPS_HA_UNLOCK(cpu_flags);
- ips_ffdc_reset(ha, IPS_INTR_IORL);
- }
-
- /* Now fail all of the active commands */
-#if IPS_DEBUG >= 1
- printk(KERN_WARNING "(%s%d) Failing active commands\n",
+ printk(KERN_NOTICE "(%s%d) Resetting controller.\n",
X ips_name, ha->host_num);
-#endif
- while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
- scb->scsi_cmd->result = (DID_RESET << 16) | (SUGGEST_RETRY << 24);
- scb->scsi_cmd->scsi_done(scb->scsi_cmd);
- ips_freescb(ha, scb);
- }
-
- /* Reset the number of active IOCTLs */
- IPS_HA_LOCK(cpu_flags);
- ha->num_ioctl = 0;
- IPS_HA_UNLOCK(cpu_flags);
-
- clear_bit(IPS_IN_RESET, &ha->flags);
-
- if (!test_bit(IPS_IN_INTR, &ha->flags)) {
- /*
- * Only execute the next command when
- * we are not being called from the
- * interrupt handler. The interrupt
- * handler wants to do this and since
- * interrupts are turned off here....
- */
- ips_next(ha, IPS_INTR_IORL);
- }
-
- return (SUCCESS);
-
-#endif /* NO_IPS_RESET */
-
-}
-
-/****************************************************************************/
-/* */
-/* Routine Name: ips_reset */
-/* */
-/* Routine Description: */
-/* */
-/* Reset the controller */
-/* */
-/* NOTE: this routine is called under the io_request_lock spinlock */
-/* */
-/****************************************************************************/
-int
-ips_reset(Scsi_Cmnd *SC, unsigned int flags) {
- u32 cpu_flags;
- ips_ha_t *ha;
- ips_scb_t *scb;
- ips_copp_wait_item_t *item;
-
- DBG("ips_reset");
+ ret = (*ha->func.reset)(ha);
X
-#ifdef NO_IPS_RESET
- return (SCSI_RESET_SNOOZE);
-#else
+ if (!ret) {
+ Scsi_Cmnd *scsi_cmd;
X
- if (!SC) {
+ printk(KERN_NOTICE
+ "(%s%d) Controller reset failed - controller now offline.\n",
+ ips_name, ha->host_num);
X
-#if IPS_DEBUG >= 1
- printk(KERN_NOTICE "Reset called with NULL scsi command\n");
-#endif
+ /* Now fail all of the active commands */
+ DEBUG_VAR(1, "(%s%d) Failing active commands",
+ ips_name, ha->host_num);
X
- return (SCSI_RESET_SNOOZE);
- }
+ while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
+ scb->scsi_cmd->result = DID_ERROR << 16;
+ scb->scsi_cmd->scsi_done(scb->scsi_cmd);
+ ips_freescb(ha, scb);
+ }
X
- ha = (ips_ha_t *) SC->host->hostdata;
+ /* Now fail all of the pending commands */
+ DEBUG_VAR(1, "(%s%d) Failing pending commands",
+ ips_name, ha->host_num);
X
- if (!ha) {
+ while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) {
+ scsi_cmd->result = DID_ERROR;
+ scsi_cmd->scsi_done(scsi_cmd);
+ }
X
-#if IPS_DEBUG >= 1
- printk(KERN_NOTICE "Reset called with NULL ha struct\n");
-#endif
+ ha->active = FALSE;
+ clear_bit(IPS_IN_RESET, &ha->flags);
X
- return (SCSI_RESET_SNOOZE);
+ return (FAILED);
X }
X
- if (!ha->active)
- return (SCSI_RESET_SNOOZE);
-
- if (test_and_set_bit(IPS_IN_RESET, &ha->flags))
- return (SCSI_RESET_SNOOZE);
-
- /* See if the command is on the copp queue */
- IPS_QUEUE_LOCK(&ha->copp_waitlist);
- item = ha->copp_waitlist.head;
- while ((item) && (item->scsi_cmd != SC))
- item = item->next;
- IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
-
- if (item) {
- /* Found it */
- ips_removeq_copp(&ha->copp_waitlist, item);
- clear_bit(IPS_IN_RESET, &ha->flags);
+ if (!ips_clear_adapter(ha, IPS_INTR_IORL)) {
+ Scsi_Cmnd *scsi_cmd;
X
- return (SCSI_RESET_SNOOZE);
- }
+ printk(KERN_NOTICE
+ "(%s%d) Controller reset failed - controller now offline.\n",
+ ips_name, ha->host_num);
X
- /* See if the command is on the wait queue */
- if (ips_removeq_wait(&ha->scb_waitlist, SC)) {
- /* command not sent yet */
- clear_bit(IPS_IN_RESET, &ha->flags);
+ /* Now fail all of the active commands */
+ DEBUG_VAR(1, "(%s%d) Failing active commands",
+ ips_name, ha->host_num);
X
- return (SCSI_RESET_SNOOZE);
- }
+ while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
+ scb->scsi_cmd->result = DID_ERROR << 16;
+ scb->scsi_cmd->scsi_done(scb->scsi_cmd);
+ ips_freescb(ha, scb);
+ }
X
- /* reset the controller */
- if (!ips_reset_adapter(ha)) {
- clear_bit(IPS_IN_RESET, &ha->flags);
+ /* Now fail all of the pending commands */
+ DEBUG_VAR(1, "(%s%d) Failing pending commands",
+ ips_name, ha->host_num);
X
- return (SCSI_RESET_ERROR);
- }
+ while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) {
+ scsi_cmd->result = DID_ERROR << 16;
+ scsi_cmd->scsi_done(scsi_cmd);
+ }
X
- if (!ips_clear_adapter(ha, IPS_INTR_IORL)) {
+ ha->active = FALSE;
X clear_bit(IPS_IN_RESET, &ha->flags);
X
- return (SCSI_RESET_ERROR);
+ return (FAILED);
X }
X
X /* FFDC */
@@ -1058,16 +1449,19 @@
X }
X
X /* Now fail all of the active commands */
-#if IPS_DEBUG >= 1
- printk(KERN_WARNING "(%s%d) Failing active commands\n",
- ips_name, ha->host_num);
-#endif
+ DEBUG_VAR(1, "(%s%d) Failing active commands",
+ ips_name, ha->host_num);
+
X while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
X scb->scsi_cmd->result = (DID_RESET << 16) | (SUGGEST_RETRY << 24);
X scb->scsi_cmd->scsi_done(scb->scsi_cmd);
X ips_freescb(ha, scb);
X }
X
+ /* Reset DCDB active command bits */
+ for (i = 1; i < ha->nbus; i++)
+ ha->dcdb_active[i-1] = 0;
+
X /* Reset the number of active IOCTLs */
X IPS_HA_LOCK(cpu_flags);
X ha->num_ioctl = 0;
@@ -1086,7 +1480,7 @@
X ips_next(ha, IPS_INTR_IORL);
X }
X
- return (SCSI_RESET_SUCCESS);
+ return (SUCCESS);
X
X #endif /* NO_IPS_RESET */
X
@@ -1110,7 +1504,7 @@
X u32 cpu_flags;
X DECLARE_MUTEX_LOCKED(sem);
X
- DBG("ips_queue");
+ METHOD_TRACE("ips_queue", 1);
X
X ha = (ips_ha_t *) SC->host->hostdata;
X
@@ -1118,7 +1512,7 @@
X return (1);
X
X if (!ha->active)
- return (1);
+ return (DID_ERROR);
X
X #ifndef NO_IPS_CMDLINE
X if (ips_is_passthru(SC)) {
@@ -1151,24 +1545,28 @@
X
X SC->scsi_done = done;
X
-#if IPS_DEBUG >= 10
- printk(KERN_NOTICE "%s: ips_queue: cmd 0x%X (%d %d %d)\n",
- ips_name,
- SC->cmnd[0],
- SC->channel,
- SC->target,
- SC->lun);
-#if IPS_DEBUG >= 11
- MDELAY(2*IPS_ONE_SEC);
-#endif
-#endif
+ DEBUG_VAR(2, "(%s%d): ips_queue: cmd 0x%X (%d %d %d)",
+ ips_name,
+ ha->host_num,
+ SC->cmnd[0],
+ SC->channel,
+ SC->target,
+ SC->lun);
+
+ /* Check for command to initiator IDs */
+ if ((SC->channel > 0) && (SC->target == ha->ha_id[SC->channel])) {
+ SC->result = DID_NO_CONNECT << 16;
+ done(SC);


+
+ return (0);
+ }

X
X #ifndef NO_IPS_CMDLINE
X if (ips_is_passthru(SC)) {
X ips_copp_wait_item_t *scratch;
X
X /* allocate space for the scribble */
- scratch = kmalloc(sizeof(ips_copp_wait_item_t), GFP_KERNEL);
+ scratch = kmalloc(sizeof(ips_copp_wait_item_t), GFP_ATOMIC);
X
X if (!scratch) {
X SC->result = DID_ERROR << 16;
@@ -1224,10 +1622,8 @@
X datasize = *((u32 *) &SC->cmnd[8]);
X
X if (copy_to_user(user_area, kern_area, datasize) > 0) {
-#if IPS_DEBUG_PT >= 1
- printk(KERN_NOTICE "(%s%d) passthru failed - unable to copy out user data\n",
- ips_name, ha->host_num);
-#endif
+ DEBUG_VAR(1, "(%s%d) passthru failed - unable to copy out user data",
+ ips_name, ha->host_num);
X
X SC->result = DID_ERROR << 16;
X SC->scsi_done(SC);
@@ -1255,7 +1651,7 @@
X int sectors;
X int cylinders;
X
- DBG("ips_biosparam");
+ METHOD_TRACE("ips_biosparam", 1);
X
X ha = (ips_ha_t *) disk->device->host->hostdata;
X
@@ -1281,10 +1677,8 @@
X
X cylinders = disk->capacity / (heads * sectors);
X
-#if IPS_DEBUG >= 2
- printk(KERN_NOTICE "Geometry: heads: %d, sectors: %d, cylinders: %d\n",
- heads, sectors, cylinders);
-#endif
+ DEBUG_VAR(2, "Geometry: heads: %d, sectors: %d, cylinders: %d",
+ heads, sectors, cylinders);
X
X geom[0] = heads;
X geom[1] = sectors;
@@ -1295,6 +1689,40 @@


X
X /****************************************************************************/
X /* */

+/* Routine Name: ips_select_queue_depth */


+/* */
+/* Routine Description: */
+/* */

+/* Select queue depths for the devices on the contoller */
+/* */
+/****************************************************************************/
+static void
+ips_select_queue_depth(struct Scsi_Host *host, Scsi_Device *scsi_devs) {
+ Scsi_Device *device;
+ ips_ha_t *ha;
+ int count = 0;
+
+ ha = IPS_HA(host);
+
+ for (device = scsi_devs; device; device = device->next) {
+ if (device->host == host) {
+ if ((device->channel == 0) && (device->type == 0))
+ count++;
+ }
+ }
+
+ for (device = scsi_devs; device; device = device->next) {
+ if (device->host == host) {
+ if ((device->channel == 0) && (device->type == 0))
+ device->queue_depth = ha->max_cmds / count - 1;
+ else
+ device->queue_depth = 2;
+ }
+ }
+}
+
+/****************************************************************************/
+/* */
X /* Routine Name: do_ipsintr */


X /* */
X /* Routine Description: */

@@ -1307,7 +1735,7 @@
X ips_ha_t *ha;
X u32 cpu_flags;
X
- DBG("do_ipsintr");
+ METHOD_TRACE("do_ipsintr", 2);
X
X ha = (ips_ha_t *) dev_id;
X
@@ -1333,7 +1761,7 @@
X return;
X }
X
- ips_intr(ha);
+ (*ha->func.intr)(ha);
X
X clear_bit(IPS_IN_INTR, &ha->flags);
X
@@ -1345,7 +1773,7 @@


X
X /****************************************************************************/
X /* */

-/* Routine Name: ips_intr */
+/* Routine Name: ips_intr_copperhead */


X /* */
X /* Routine Description: */

X /* */
@@ -1355,13 +1783,14 @@
X /* */
X /****************************************************************************/
X void
-ips_intr(ips_ha_t *ha) {
+ips_intr_copperhead(ips_ha_t *ha) {
X ips_stat_t *sp;
X ips_scb_t *scb;
- int status;
+ IPS_STATUS cstatus;
+ int intrstatus;
X u32 cpu_flags;
X
- DBG("ips_intr");
+ METHOD_TRACE("ips_intr", 2);
X
X if (!ha)
X return;
@@ -1370,16 +1799,36 @@
X return;
X
X IPS_HA_LOCK(cpu_flags);
- while (ips_isintr(ha)) {
+
+ intrstatus = (*ha->func.isintr)(ha);
+
+ if (!intrstatus) {
+ /*
+ * Unexpected/Shared interrupt
+ */
+ IPS_HA_UNLOCK(cpu_flags);
+
+ return;
+ }
+
+ while (TRUE) {
X sp = &ha->sp;
X
- if ((status = ips_chkstatus(ha)) < 0) {
- /* unexpected interrupt - no ccb */
+ intrstatus = (*ha->func.isintr)(ha);
+
+ if (!intrstatus)
+ break;
+ else
+ cstatus.value = (*ha->func.statupd)(ha);
+
+ if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) {
X printk(KERN_WARNING "(%s%d) Spurious interrupt; no ccb.\n",
X ips_name, ha->host_num);
- continue ;
+
+ continue;
X }
X
+ ips_chkstatus(ha, &cstatus);
X scb = (ips_scb_t *) sp->scb_addr;
X
X /*
@@ -1389,32 +1838,108 @@
X IPS_HA_UNLOCK(cpu_flags);
X (*scb->callback) (ha, scb);
X IPS_HA_LOCK(cpu_flags);
- }
+ } /* end while */
X
X IPS_HA_UNLOCK(cpu_flags);
X }


X
X /****************************************************************************/
X /* */

-/* Routine Name: ips_info */
+/* Routine Name: ips_intr_morpheus */


X /* */
X /* Routine Description: */

X /* */
-/* Return info about the driver */
+/* Polling interrupt handler */
+/* */
+/* ASSUMES interrupts are disabled */
X /* */
X /****************************************************************************/
-const char *
-ips_info(struct Scsi_Host *SH) {
- static char buffer[256];
- char *bp;
- ips_ha_t *ha;
-
- DBG("ips_info");
+void
+ips_intr_morpheus(ips_ha_t *ha) {
+ ips_stat_t *sp;
+ ips_scb_t *scb;
+ IPS_STATUS cstatus;
+ int intrstatus;
+ u32 cpu_flags;
X
- ha = IPS_HA(SH);
+ METHOD_TRACE("ips_intr_morpheus", 2);
X
X if (!ha)
- return (NULL);
+ return;
+
+ if (!ha->active)
+ return;
+
+ IPS_HA_LOCK(cpu_flags);
+
+ intrstatus = (*ha->func.isintr)(ha);
+
+ if (!intrstatus) {
+ /*
+ * Unexpected/Shared interrupt
+ */
+ IPS_HA_UNLOCK(cpu_flags);
+
+ return;
+ }
+
+ while (TRUE) {
+ sp = &ha->sp;
+
+ intrstatus = (*ha->func.isintr)(ha);
+
+ if (!intrstatus)
+ break;
+ else
+ cstatus.value = (*ha->func.statupd)(ha);
+
+ if (cstatus.value == 0xffffffff)
+ /* No more to process */
+ break;
+
+ if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) {
+ printk(KERN_WARNING "(%s%d) Spurious interrupt; no ccb.\n",
+ ips_name, ha->host_num);


+
+ continue;
+ }
+

+ ips_chkstatus(ha, &cstatus);
+ scb = (ips_scb_t *) sp->scb_addr;
+
+ /*
+ * use the callback function to finish things up
+ * NOTE: interrupts are OFF for this
+ */
+ IPS_HA_UNLOCK(cpu_flags);
+ (*scb->callback) (ha, scb);
+ IPS_HA_LOCK(cpu_flags);
+ } /* end while */
+
+ IPS_HA_UNLOCK(cpu_flags);
+}
+
+/****************************************************************************/
+/* */
+/* Routine Name: ips_info */


+/* */
+/* Routine Description: */
+/* */

+/* Return info about the driver */
+/* */
+/****************************************************************************/
+const char *
+ips_info(struct Scsi_Host *SH) {
+ static char buffer[256];
+ char *bp;
+ ips_ha_t *ha;
+
+ METHOD_TRACE("ips_info", 1);
+
+ ha = IPS_HA(SH);
+
+ if (!ha)
+ return (NULL);
X
X bp = &buffer[0];
X memset(bp, 0, sizeof(buffer));
@@ -1449,10 +1974,10 @@
X int ret;
X ips_ha_t *ha = NULL;
X
- DBG("ips_proc_info");
+ METHOD_TRACE("ips_proc_info", 1);
X
X /* Find our host structure */
- for (i = 0; i < ips_num_controllers; i++) {
+ for (i = 0; i < ips_next_controller; i++) {
X if (ips_sh[i] && ips_sh[i]->host_no == hostno) {
X ha = (ips_ha_t *) ips_sh[i]->hostdata;
X
@@ -1494,7 +2019,7 @@
X /****************************************************************************/
X static int
X ips_is_passthru(Scsi_Cmnd *SC) {
- DBG("ips_is_passthru");
+ METHOD_TRACE("ips_is_passthru", 1);
X
X if (!SC)
X return (0);
@@ -1528,24 +2053,20 @@
X ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb) {
X ips_passthru_t *pt;
X
- DBG("ips_make_passthru");
+ METHOD_TRACE("ips_make_passthru", 1);
X
X if (!SC->request_bufflen || !SC->request_buffer) {
X /* no data */
-#if IPS_DEBUG_PT >= 1
- printk(KERN_NOTICE "(%s%d) No passthru structure\n",
- ips_name, ha->host_num);
-#endif
+ DEBUG_VAR(1, "(%s%d) No passthru structure",
+ ips_name, ha->host_num);
X
X return (IPS_FAILURE);
X }
X
X if (SC->request_bufflen < sizeof(ips_passthru_t)) {
X /* wrong size */
-#if IPS_DEBUG_PT >= 1
- printk(KERN_NOTICE "(%s%d) Passthru structure wrong size\n",
+ DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
X ips_name, ha->host_num);
-#endif
X
X return (IPS_FAILURE);
X }
@@ -1555,10 +2076,8 @@
X (((char *) SC->request_buffer)[2] != 'P') ||
X (((char *) SC->request_buffer)[3] != 'P')) {
X /* signature doesn't match */
-#if IPS_DEBUG_PT >= 1
- printk(KERN_NOTICE "(%s%d) Wrong signature on passthru structure.\n",
- ips_name, ha->host_num);
-#endif
+ DEBUG_VAR(1, "(%s%d) Wrong signature on passthru structure.",
+ ips_name, ha->host_num);
X
X return (IPS_FAILURE);
X }
@@ -1602,10 +2121,8 @@
X if (SC->cmnd[0] == IPS_IOCTL_COMMAND) {
X if (SC->request_bufflen < (sizeof(ips_passthru_t) + pt->CmdBSize)) {
X /* wrong size */
- #if IPS_DEBUG_PT >= 1
- printk(KERN_NOTICE "(%s%d) Passthru structure wrong size\n",
- ips_name, ha->host_num);
- #endif
+ DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
+ ips_name, ha->host_num);
X
X return (IPS_FAILURE);
X }
@@ -1617,10 +2134,8 @@
X } else if (SC->cmnd[0] == IPS_IOCTL_NEW_COMMAND) {
X if (SC->request_bufflen < (sizeof(ips_passthru_t))) {
X /* wrong size */
- #if IPS_DEBUG_PT >= 1
- printk(KERN_NOTICE "(%s%d) Passthru structure wrong size\n",
- ips_name, ha->host_num);
- #endif
+ DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
+ ips_name, ha->host_num);
X
X return (IPS_FAILURE);
X }
@@ -1639,14 +2154,23 @@
X return (IPS_FAILURE);
X
X /* don't flash the BIOS on future cards */
- if (ha->revision_id > IPS_REVID_TROMBONE64) {
-#if IPS_DEBUG_PT >= 1
- printk(KERN_NOTICE "(%s%d) flash bios failed - unsupported controller\n",
- ips_name, ha->host_num);
-#endif
+ if ((ha->device_id != IPS_COPPERHEAD_DEVICEID) ||
+ (ha->revision_id > IPS_REVID_TROMBONE64)) {
+ DEBUG_VAR(1, "(%s%d) flash bios failed - unsupported controller",
+ ips_name, ha->host_num);
+
X return (IPS_FAILURE);
X }
X
+ /*
+ * Check to make sure we have functions
+ * to handle the request
+ */
+ if ((!ha->func.programbios) ||
+ (!ha->func.erasebios) ||
+ (!ha->func.verifybios))
+ return (IPS_FAILURE);
+
X /* copy in the size/buffer ptr from the scsi command */
X memcpy(&pt->CmdBuffer, &SC->cmnd[4], 4);
X memcpy(&pt->CmdBSize, &SC->cmnd[8], 4);
@@ -1660,7 +2184,7 @@
X void *bigger_struct;
X
X /* try to allocate a bigger struct */
- bigger_struct = kmalloc(pt->CmdBSize, GFP_KERNEL|GFP_DMA);
+ bigger_struct = kmalloc(pt->CmdBSize, GFP_ATOMIC|GFP_DMA);
X if (bigger_struct) {
X /* free the old memory */
X kfree(ha->ioctl_data);
@@ -1674,37 +2198,29 @@
X
X /* copy in the buffer */
X if (copy_from_user(ha->ioctl_data, pt->CmdBuffer, pt->CmdBSize) > 0) {
-#if IPS_DEBUG_PT >= 1
- printk(KERN_NOTICE "(%s%d) flash bios failed - unable to copy user buffer\n",
- ips_name, ha->host_num);
-#endif
+ DEBUG_VAR(1, "(%s%d) flash bios failed - unable to copy user buffer",
+ ips_name, ha->host_num);
X
X return (IPS_FAILURE);
X }
X
- if (ips_erase_bios(ha)) {
-#if IPS_DEBUG_PT >= 1
- printk(KERN_NOTICE "(%s%d) flash bios failed - unable to erase flash\n",
- ips_name, ha->host_num);
-#endif
+ if ((*ha->func.erasebios)(ha)) {
+ DEBUG_VAR(1, "(%s%d) flash bios failed - unable to erase flash",
+ ips_name, ha->host_num);
X
X return (IPS_FAILURE);
X }
X
- if (ips_program_bios(ha, ha->ioctl_data, pt->CmdBSize)) {
-#if IPS_DEBUG_PT >= 1
- printk(KERN_NOTICE "(%s%d) flash bios failed - unable to program flash\n",
- ips_name, ha->host_num);
-#endif
+ if ((*ha->func.programbios)(ha, ha->ioctl_data, pt->CmdBSize)) {
+ DEBUG_VAR(1, "(%s%d) flash bios failed - unable to program flash",
+ ips_name, ha->host_num);
X
X return (IPS_FAILURE);
X }
X
- if (ips_verify_bios(ha, ha->ioctl_data, pt->CmdBSize)) {
-#if IPS_DEBUG_PT >= 1
- printk(KERN_NOTICE "(%s%d) flash bios failed - unable to verify flash\n",
- ips_name, ha->host_num);
-#endif
+ if ((*ha->func.verifybios)(ha, ha->ioctl_data, pt->CmdBSize)) {
+ DEBUG_VAR(1, "(%s%d) flash bios failed - unable to verify flash",
+ ips_name, ha->host_num);
X
X return (IPS_FAILURE);
X }
@@ -1728,7 +2244,7 @@
X ips_usrcmd(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb) {
X IPS_SG_LIST *sg_list;
X
- DBG("ips_usrcmd");
+ METHOD_TRACE("ips_usrcmd", 1);
X
X if ((!scb) || (!pt) || (!ha))
X return (0);
@@ -1811,7 +2327,7 @@
X char *kern_area;
X u32 datasize;
X
- DBG("ips_usrcmd");
+ METHOD_TRACE("ips_usrcmd", 1);
X
X if ((!scb) || (!pt) || (!ha))
X return (0);
@@ -1848,7 +2364,7 @@
X void *bigger_struct;
X
X /* try to allocate a bigger struct */
- bigger_struct = kmalloc(pt->CmdBSize, GFP_KERNEL|GFP_DMA);
+ bigger_struct = kmalloc(pt->CmdBSize, GFP_ATOMIC|GFP_DMA);
X if (bigger_struct) {
X /* free the old memory */
X kfree(ha->ioctl_data);
@@ -1869,10 +2385,8 @@
X datasize = *((u32 *) &scb->scsi_cmd->cmnd[8]);
X
X if (copy_from_user(kern_area, user_area, datasize) > 0) {
-#if IPS_DEBUG_PT >= 1
- printk(KERN_NOTICE "(%s%d) passthru failed - unable to copy in user data\n",
- ips_name, ha->host_num);
-#endif
+ DEBUG_VAR(1, "(%s%d) passthru failed - unable to copy in user data",
+ ips_name, ha->host_num);
X
X return (0);
X }
@@ -1923,12 +2437,11 @@
X ips_cleanup_passthru(ips_ha_t *ha, ips_scb_t *scb) {
X ips_passthru_t *pt;
X
- DBG("ips_cleanup_passthru");
+ METHOD_TRACE("ips_cleanup_passthru", 1);
X
X if ((!scb) || (!scb->scsi_cmd) || (!scb->scsi_cmd->request_buffer)) {
-#if IPS_DEBUG_PT >= 1
- printk(KERN_NOTICE "IPS couldn't cleanup\n");
-#endif
+ DEBUG_VAR(1, "(%s%d) couldn't cleanup after passthru",
+ ips_name, ha->host_num);
X
X return ;
X }
@@ -1962,12 +2475,13 @@
X ips_host_info(ips_ha_t *ha, char *ptr, off_t offset, int len) {
X IPS_INFOSTR info;
X
- DBG("ips_host_info");
+ METHOD_TRACE("ips_host_info", 1);
X
X info.buffer = ptr;
X info.length = len;
X info.offset = offset;
X info.pos = 0;
+ info.localpos = 0;
X
X copy_info(&info, "\nIBM ServeRAID General Information:\n\n");
X
@@ -1977,7 +2491,16 @@
X else
X copy_info(&info, "\tController Type : Unknown\n");
X
- copy_info(&info, "\tIO port address : 0x%lx\n", ha->io_addr);
+ if (ha->io_addr)
+ copy_info(&info, "\tIO region : 0x%lx (%d bytes)\n",
+ ha->io_addr, ha->io_len);
+
+ if (ha->mem_addr) {
+ copy_info(&info, "\tMemory region : 0x%lx (%d bytes)\n",
+ ha->mem_addr, ha->mem_len);
+ copy_info(&info, "\tShared memory address : 0x%lx\n", ha->mem_ptr);
+ }
+
X copy_info(&info, "\tIRQ number : %d\n", ha->irq);
X
X if (ha->nvram->signature == IPS_NVRAM_P5_SIG)
@@ -2017,7 +2540,7 @@
X
X copy_info(&info, "\n");
X
- return (info.pos > info.offset ? info.pos - info.offset : 0);
+ return (info.localpos);
X }
X
X /****************************************************************************/
@@ -2031,10 +2554,7 @@
X /****************************************************************************/
X static void
X copy_mem_info(IPS_INFOSTR *info, char *data, int len) {
- DBG("copy_mem_info");
-
- if (info->pos + len > info->length)
- len = info->length - info->pos;
+ METHOD_TRACE("copy_mem_info", 1);
X
X if (info->pos + len < info->offset) {
X info->pos += len;
@@ -2043,12 +2563,17 @@
X
X if (info->pos < info->offset) {
X data += (info->offset - info->pos);
- len -= (info->offset - info->pos);
+ len -= (info->offset - info->pos);
+ info->pos += (info->offset - info->pos);
X }
X
+ if (info->localpos + len > info->length)
+ len = info->length - info->localpos;
+
X if (len > 0) {
- memcpy(info->buffer + info->pos, data, len);
+ memcpy(info->buffer + info->localpos, data, len);
X info->pos += len;
+ info->localpos += len;
X }
X }
X
@@ -2064,10 +2589,10 @@
X static int
X copy_info(IPS_INFOSTR *info, char *fmt, ...) {
X va_list args;
- char buf[81];
+ char buf[128];
X int len;
X
- DBG("copy_info");
+ METHOD_TRACE("copy_info", 1);
X
X va_start(args, fmt);
X len = vsprintf(buf, fmt, args);
@@ -2091,57 +2616,32 @@
X /****************************************************************************/
X static int
X ips_hainit(ips_ha_t *ha) {


- int i;
+ int i;

+ struct timeval tv;
X
- DBG("ips_hainit");
+ METHOD_TRACE("ips_hainit", 1);
X
X if (!ha)
X return (0);
X
- /* initialize status queue */
- ips_statinit(ha);
+ if (ha->func.statinit)
+ (*ha->func.statinit)(ha);
+
+ if (ha->func.enableint)
+ (*ha->func.enableint)(ha);
X
+ /* Send FFDC */
X ha->reset_count = 1;
+ do_gettimeofday(&tv);
+ ha->last_ffdc = tv.tv_sec;
+ ips_ffdc_reset(ha, IPS_INTR_IORL);
X
- /* Setup HBA ID's */
X if (!ips_read_config(ha, IPS_INTR_IORL)) {
-
-#ifndef NO_IPS_RESET
-
- ha->reset_count++;
-
- /* Try to reset the controller and try again */
- if (!ips_reset_adapter(ha)) {
- printk(KERN_WARNING "(%s%d) unable to reset controller.\n",
- ips_name, ha->host_num);
-
- return (0);
- }
-
- if (!ips_clear_adapter(ha, IPS_INTR_IORL)) {
- printk(KERN_WARNING "(%s%d) unable to initialize controller.\n",
- ips_name, ha->host_num);
-
- return (0);
- }
-
-#endif
-
- if (!ips_read_config(ha, IPS_INTR_IORL)) {
- printk(KERN_WARNING "(%s%d) unable to read config from controller.\n",
- ips_name, ha->host_num);
-
- return (0);
- }
- } /* end if */
-
- /* write driver version */
- if (!ips_write_driver_status(ha, IPS_INTR_IORL)) {
- printk(KERN_WARNING "(%s%d) unable to write driver info to controller.\n",
+ printk(KERN_WARNING "(%s%d) unable to read config from controller.\n",
X ips_name, ha->host_num);


X
X return (0);
- }

+ } /* end if */
X
X if (!ips_read_adapter_status(ha, IPS_INTR_IORL)) {
X printk(KERN_WARNING "(%s%d) unable to read controller status.\n",
@@ -2157,19 +2657,18 @@
X return (0);
X }
X
- /* FFDC */
- if (ha->subsys->param[3] & 0x300000) {
- struct timeval tv;
+ /* write nvram user page 5 */
+ if (!ips_write_driver_status(ha, IPS_INTR_IORL)) {
+ printk(KERN_WARNING "(%s%d) unable to write driver info to controller.\n",
+ ips_name, ha->host_num);
X
- do_gettimeofday(&tv);
- ha->last_ffdc = tv.tv_sec;
- ips_ffdc_reset(ha, IPS_INTR_IORL);


+ return (0);
X }
X

X /* set limits on SID, LUN, BUS */
X ha->ntargets = IPS_MAX_TARGETS + 1;
X ha->nlun = 1;
- ha->nbus = (ha->enq->ucMaxPhysicalDevices / IPS_MAX_TARGETS);
+ ha->nbus = (ha->enq->ucMaxPhysicalDevices / IPS_MAX_TARGETS) + 1;
X
X switch (ha->conf->logical_drive[0].ucStripeSize) {
X case 4:
@@ -2240,13 +2739,14 @@
X ips_scb_t *scb;
X Scsi_Cmnd *SC;
X Scsi_Cmnd *p;
+ Scsi_Cmnd *q;
X ips_copp_wait_item_t *item;
X int ret;
X int intr_status;
X u32 cpu_flags;
X u32 cpu_flags2;
X
- DBG("ips_next");
+ METHOD_TRACE("ips_next", 1);
X
X if (!ha)
X return ;
@@ -2392,7 +2892,8 @@
X
X IPS_HA_UNLOCK(cpu_flags);
X
- SC = ips_removeq_wait(&ha->scb_waitlist, p);
+ q = p;
+ SC = ips_removeq_wait(&ha->scb_waitlist, q);
X
X SC->result = DID_OK;
X SC->host_scribble = NULL;
@@ -2419,28 +2920,41 @@
X
X sg = SC->request_buffer;
X
- for (i = 0; i < SC->use_sg; i++) {
- scb->sg_list[i].address = VIRT_TO_BUS(sg[i].address);
- scb->sg_list[i].length = sg[i].length;
+ if (SC->use_sg == 1) {
+ if (sg[0].length > ha->max_xfer) {
+ scb->breakup = 1;
+ scb->data_len = ha->max_xfer;
+ } else
+ scb->data_len = sg[0].length;
X
- if (scb->data_len + sg[i].length > ha->max_xfer) {
- /*
- * Data Breakup required
- */
- scb->breakup = i;
- break;
- }
+ scb->dcdb.transfer_length = scb->data_len;
+ scb->data_busaddr = VIRT_TO_BUS(sg[0].address);
+ scb->sg_len = 0;
+ } else {
X
- scb->data_len += sg[i].length;
- }
+ for (i = 0; i < SC->use_sg; i++) {
+ scb->sg_list[i].address = VIRT_TO_BUS(sg[i].address);
+ scb->sg_list[i].length = sg[i].length;
X
- if (!scb->breakup)
- scb->sg_len = SC->use_sg;
- else
- scb->sg_len = scb->breakup;
+ if (scb->data_len + sg[i].length > ha->max_xfer) {
+ /*
+ * Data Breakup required
+ */
+ scb->breakup = i;
+ break;
+ }
+
+ scb->data_len += sg[i].length;
+ }
+
+ if (!scb->breakup)
+ scb->sg_len = SC->use_sg;
+ else
+ scb->sg_len = scb->breakup;
X
- scb->dcdb.transfer_length = scb->data_len;
- scb->data_busaddr = VIRT_TO_BUS(scb->sg_list);
+ scb->dcdb.transfer_length = scb->data_len;
+ scb->data_busaddr = VIRT_TO_BUS(scb->sg_list);
+ }
X } else {
X if (SC->request_bufflen) {
X if (SC->request_bufflen > ha->max_xfer) {
@@ -2527,7 +3041,7 @@
X /****************************************************************************/
X static inline void
X ips_putq_scb_head(ips_scb_queue_t *queue, ips_scb_t *item) {
- DBG("ips_putq_scb_head");
+ METHOD_TRACE("ips_putq_scb_head", 1);
X
X if (!item)
X return ;
@@ -2558,7 +3072,7 @@
X /****************************************************************************/
X static inline void
X ips_putq_scb_tail(ips_scb_queue_t *queue, ips_scb_t *item) {
- DBG("ips_putq_scb_tail");
+ METHOD_TRACE("ips_putq_scb_tail", 1);
X
X if (!item)
X return ;
@@ -2595,7 +3109,7 @@
X ips_removeq_scb_head(ips_scb_queue_t *queue) {
X ips_scb_t *item;
X
- DBG("ips_removeq_scb_head");
+ METHOD_TRACE("ips_removeq_scb_head", 1);
X
X IPS_QUEUE_LOCK(queue);
X
@@ -2635,7 +3149,7 @@
X ips_removeq_scb(ips_scb_queue_t *queue, ips_scb_t *item) {
X ips_scb_t *p;
X
- DBG("ips_removeq_scb");
+ METHOD_TRACE("ips_removeq_scb", 1);
X
X if (!item)
X return (NULL);
@@ -2686,7 +3200,7 @@
X /****************************************************************************/
X static inline void
X ips_putq_wait_head(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
- DBG("ips_putq_wait_head");
+ METHOD_TRACE("ips_putq_wait_head", 1);
X
X if (!item)
X return ;
@@ -2717,7 +3231,7 @@
X /****************************************************************************/
X static inline void
X ips_putq_wait_tail(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
- DBG("ips_putq_wait_tail");
+ METHOD_TRACE("ips_putq_wait_tail", 1);
X
X if (!item)
X return ;
@@ -2754,7 +3268,7 @@
X ips_removeq_wait_head(ips_wait_queue_t *queue) {
X Scsi_Cmnd *item;
X
- DBG("ips_removeq_wait_head");
+ METHOD_TRACE("ips_removeq_wait_head", 1);
X
X IPS_QUEUE_LOCK(queue);
X
@@ -2794,7 +3308,7 @@
X ips_removeq_wait(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
X Scsi_Cmnd *p;
X
- DBG("ips_removeq_wait");
+ METHOD_TRACE("ips_removeq_wait", 1);
X
X if (!item)
X return (NULL);
@@ -2845,7 +3359,7 @@
X /****************************************************************************/
X static inline void
X ips_putq_copp_head(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
- DBG("ips_putq_copp_head");
+ METHOD_TRACE("ips_putq_copp_head", 1);
X
X if (!item)
X return ;
@@ -2876,7 +3390,7 @@
X /****************************************************************************/
X static inline void
X ips_putq_copp_tail(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
- DBG("ips_putq_copp_tail");
+ METHOD_TRACE("ips_putq_copp_tail", 1);
X
X if (!item)
X return ;
@@ -2913,7 +3427,7 @@
X ips_removeq_copp_head(ips_copp_queue_t *queue) {
X ips_copp_wait_item_t *item;
X
- DBG("ips_removeq_copp_head");
+ METHOD_TRACE("ips_removeq_copp_head", 1);
X
X IPS_QUEUE_LOCK(queue);
X
@@ -2953,7 +3467,7 @@
X ips_removeq_copp(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
X ips_copp_wait_item_t *p;
X
- DBG("ips_removeq_copp");
+ METHOD_TRACE("ips_removeq_copp", 1);
X
X if (!item)
X return (NULL);
@@ -3002,7 +3516,7 @@
X /****************************************************************************/
X static void
X ipsintr_blocking(ips_ha_t *ha, ips_scb_t *scb) {
- DBG("ipsintr_blocking");
+ METHOD_TRACE("ipsintr_blocking", 2);
X
X if ((ha->waitflag == TRUE) &&
X (ha->cmd_in_progress == scb->cdb[0])) {
@@ -3023,7 +3537,14 @@
X /****************************************************************************/
X static void
X ipsintr_done(ips_ha_t *ha, ips_scb_t *scb) {
- DBG("ipsintr_done");
+ METHOD_TRACE("ipsintr_done", 2);
+
+ if (!scb) {
+ printk(KERN_WARNING "(%s%d) Spurious interrupt; scb NULL.\n",
+ ips_name, ha->host_num);
+
+ return ;
+ }
X
X if (scb->scsi_cmd == NULL) {
X /* unexpected interrupt */
@@ -3050,7 +3571,7 @@
X int ret;
X u32 cpu_flags;
X
- DBG("ips_done");
+ METHOD_TRACE("ips_done", 1);
X
X if (!scb)
X return ;
@@ -3082,31 +3603,46 @@
X
X sg = scb->scsi_cmd->request_buffer;
X
- scb->data_len = 0;
-
- for (i = bk_save; i < scb->scsi_cmd->use_sg; i++) {
- scb->sg_list[i - bk_save].address = VIRT_TO_BUS(sg[i].address);
- scb->sg_list[i - bk_save].length = sg[i].length;
-
- if (scb->data_len + sg[i].length > ha->max_xfer) {
- /*
- * Data Breakup required
- */
- scb->breakup = i;
- break;
+ if (scb->scsi_cmd->use_sg == 1) {
+ if (sg[0].length - (bk_save * ha->max_xfer)) {
+ /* Further breakup required */
+ scb->data_len = ha->max_xfer;
+ scb->data_busaddr = VIRT_TO_BUS(sg[0].address + (bk_save * ha->max_xfer));
+ scb->breakup = bk_save + 1;
+ } else {
+ scb->data_len = sg[0].length - (bk_save * ha->max_xfer);
+ scb->data_busaddr = VIRT_TO_BUS(sg[0].address + (bk_save * ha->max_xfer));
X }
X
- scb->data_len += sg[i].length;
- }
+ scb->dcdb.transfer_length = scb->data_len;
+ scb->sg_len = 0;
+ } else {
+ scb->data_len = 0;
X
- if (!scb->breakup)
- scb->sg_len = scb->scsi_cmd->use_sg - bk_save;
- else
- scb->sg_len = scb->breakup - bk_save;
+ for (i = bk_save; i < scb->scsi_cmd->use_sg; i++) {
+ scb->sg_list[i - bk_save].address = VIRT_TO_BUS(sg[i].address);
+ scb->sg_list[i - bk_save].length = sg[i].length;
+
+ if (scb->data_len + sg[i].length > ha->max_xfer) {
+ /*
+ * Data Breakup required
+ */
+ scb->breakup = i;
+ break;
+ }
X
- scb->dcdb.transfer_length = scb->data_len;
- scb->data_busaddr = VIRT_TO_BUS(scb->sg_list);
- } else {
+ scb->data_len += sg[i].length;
+ }
+
+ if (!scb->breakup)
+ scb->sg_len = scb->scsi_cmd->use_sg - bk_save;
+ else
+ scb->sg_len = scb->breakup - bk_save;
+
+ scb->dcdb.transfer_length = scb->data_len;
+ scb->data_busaddr = VIRT_TO_BUS(scb->sg_list);
+ }
+ } else {
X /* Non S/G Request */
X if (scb->scsi_cmd->request_bufflen - (bk_save * ha->max_xfer)) {
X /* Further breakup required */
@@ -3185,31 +3721,29 @@
X /* */
X /****************************************************************************/
X static int
-ips_map_status(ips_scb_t *scb, ips_stat_t *sp) {
+ips_map_status(ips_ha_t *ha, ips_scb_t *scb, ips_stat_t *sp) {
X int errcode;
+ int device_error;
X
- DBG("ips_map_status");
+ METHOD_TRACE("ips_map_status", 1);
X
X if (scb->bus) {
-#if IPS_DEBUG >= 10
- printk(KERN_NOTICE "(%s) Physical device error: %x %x, Sense Key: %x, ASC: %x, ASCQ: %x\n",
- ips_name,
- scb->basic_status,
- scb->extended_status,
- scb->dcdb.sense_info[2] & 0xf,
- scb->dcdb.sense_info[12],
- scb->dcdb.sense_info[13]);
-#endif
-
- /* copy SCSI status and sense data for DCDB commands */
- memcpy(scb->scsi_cmd->sense_buffer, scb->dcdb.sense_info,
- sizeof(scb->scsi_cmd->sense_buffer));
- scb->scsi_cmd->result = scb->dcdb.scsi_status;
- } else
- scb->scsi_cmd->result = 0;
+ DEBUG_VAR(2, "(%s%d) Physical device error (%d %d %d): %x %x, Sense Key: %x, ASC: %x, ASCQ: %x",
+ ips_name,
+ ha->host_num,
+ scb->scsi_cmd->channel,
+ scb->scsi_cmd->target,
+ scb->scsi_cmd->lun,
+ scb->basic_status,
+ scb->extended_status,
+ scb->extended_status == IPS_ERR_CKCOND ? scb->dcdb.sense_info[2] & 0xf : 0,
+ scb->extended_status == IPS_ERR_CKCOND ? scb->dcdb.sense_info[12] : 0,
+ scb->extended_status == IPS_ERR_CKCOND ? scb->dcdb.sense_info[13] : 0);
+ }
X
X /* default driver error */
X errcode = DID_ERROR;
+ device_error = 0;
X
X switch (scb->basic_status & IPS_GSC_STATUS_MASK) {
X case IPS_CMD_TIMEOUT:
@@ -3224,25 +3758,19 @@
X break;
X
X case IPS_PHYS_DRV_ERROR:
- /*
- * For physical drive errors that
- * are not on a logical drive should
- * be DID_OK. The SCSI errcode will
- * show what the real error is.
- */
- if (scb->bus)
- errcode = DID_OK;
-
X switch (scb->extended_status) {
X case IPS_ERR_SEL_TO:
- if (scb->bus) {
- scb->scsi_cmd->result |= DID_TIME_OUT << 16;
+ if (scb->bus)
+ errcode = DID_NO_CONNECT;
X
- return (0);
- }
X break;
+
X case IPS_ERR_OU_RUN:
X if ((scb->bus) && (scb->dcdb.transfer_length < scb->data_len)) {
+ /* Underrun - set default to no error */
+ errcode = DID_OK;
+
+ /* Restrict access to physical DASD */
X if ((scb->scsi_cmd->cmnd[0] == INQUIRY) &&
X ((((char *) scb->scsi_cmd->buffer)[0] & 0x1f) == TYPE_DISK)) {
X /* underflow -- no error */
@@ -3250,23 +3778,16 @@
X errcode = DID_TIME_OUT;
X break;
X }
-
- /* normal underflow Occured */
- if (scb->dcdb.transfer_length >= scb->scsi_cmd->underflow) {
- scb->scsi_cmd->result |= DID_OK << 16;
-
- return (0);
- }
- }
+ } else
+ errcode = DID_ERROR;
X
X break;
+
X case IPS_ERR_RECOVERY:
X /* don't fail recovered errors */
- if (scb->bus) {
- scb->scsi_cmd->result |= DID_OK << 16;
+ if (scb->bus)
+ errcode = DID_OK;
X
- return (0);
- }
X break;
X
X case IPS_ERR_HOST_RESET:
@@ -3275,11 +3796,25 @@
X break;
X
X case IPS_ERR_CKCOND:
+ if (scb->bus) {
+ memcpy(scb->scsi_cmd->sense_buffer, scb->dcdb.sense_info,
+ sizeof(scb->scsi_cmd->sense_buffer));
+
+ device_error = 2; /* check condition */
+ }
+
+ errcode = DID_OK;
+
X break;
+
+ default:
+ errcode = DID_ERROR;
+ break;
+
X } /* end switch */
X } /* end switch */
X
- scb->scsi_cmd->result |= (errcode << 16);
+ scb->scsi_cmd->result = device_error | (errcode << 16);
X
X return (1);
X }
@@ -3297,7 +3832,7 @@
X ips_send(ips_ha_t *ha, ips_scb_t *scb, ips_scb_callback callback) {
X int ret;
X
- DBG("ips_send");
+ METHOD_TRACE("ips_send", 1);
X
X scb->callback = callback;
X
@@ -3319,7 +3854,7 @@
X ips_send_wait(ips_ha_t *ha, ips_scb_t *scb, int timeout, int intr) {
X int ret;
X
- DBG("ips_send_wait");
+ METHOD_TRACE("ips_send_wait", 1);
X
X ha->waitflag = TRUE;
X ha->cmd_in_progress = scb->cdb[0];


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 080'
echo 'File patch-2.4.0-test9 is continued in part 081'
echo "081" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part085

#!/bin/sh -x
# this is part 085 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 085; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ mask |= POLLOUT | POLLWRNORM;
+ }

+ }
+ spin_unlock_irqrestore(&s->lock, flags);

+ CS_DBGOUT(CS_FUNCTION | CS_WAVE_WRITE | CS_WAVE_READ, 4,

+ printk(KERN_INFO "cs4281: cs4281_poll()- 0x%.8x\n",mask) );
+ return mask;
+}
+
+
+static int cs4281_mmap(struct file *file, struct vm_area_struct *vma)


+{
+ struct cs4281_state *s = (struct cs4281_state *)file->private_data;

+ struct dmabuf *db;
+ int ret;
+ unsigned long size;
+
+ CS_DBGOUT(CS_FUNCTION | CS_PARMS | CS_OPEN, 4,
+ printk(KERN_INFO "cs4281: cs4281_mmap()+\n") );
+
+ VALIDATE_STATE(s);
+ if (vma->vm_flags & VM_WRITE) {
+ if ((ret = prog_dmabuf_dac(s)) != 0)
+ return ret;
+ db = &s->dma_dac;
+ } else if (vma->vm_flags & VM_READ) {
+ if ((ret = prog_dmabuf_adc(s)) != 0)
+ return ret;
+ db = &s->dma_adc;
+ } else
+ return -EINVAL;
+ if (vma->vm_pgoff != 0)
+ return -EINVAL;
+ size = vma->vm_end - vma->vm_start;
+ if (size > (PAGE_SIZE << db->buforder))
+ return -EINVAL;
+ if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot))
+ return -EAGAIN;
+ db->mapped = 1;
+
+ CS_DBGOUT(CS_FUNCTION | CS_PARMS | CS_OPEN, 4,
+ printk(KERN_INFO "cs4281: cs4281_mmap()- 0 size=%d\n",
+ (unsigned)size) );


+
+ return 0;
+}
+

+
+static int cs4281_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{


+ struct cs4281_state *s = (struct cs4281_state *)file->private_data;
+ unsigned long flags;

+ audio_buf_info abinfo;
+ count_info cinfo;
+ int val, mapped, ret;
+
+ CS_DBGOUT(CS_FUNCTION, 4,
+ printk(KERN_INFO "cs4281: cs4281_ioctl(): file=0x%.8x cmd=0x%.8x\n",
+ (unsigned)file,cmd) );
+ VALIDATE_STATE(s);
+ mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
+ ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
+ switch (cmd) {
+ case OSS_GETVERSION:
+ CS_DBGOUT(CS_FUNCTION | CS_PARMS, 4, printk(KERN_INFO
+ "cs4281: cs4281_ioctl(): SOUND_VERSION=0x%.8x\n", SOUND_VERSION) );


+ return put_user(SOUND_VERSION, (int *)arg);
+

+ case SNDCTL_DSP_SYNC:


+ if (file->f_mode & FMODE_WRITE)

+ return drain_dac(s, 0/*file->f_flags & O_NONBLOCK*/);
+ return 0;
+
+ case SNDCTL_DSP_SETDUPLEX:
+ return 0;
+
+ case SNDCTL_DSP_GETCAPS:
+ return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+
+ case SNDCTL_DSP_RESET:


+ if (file->f_mode & FMODE_WRITE) {

+ stop_dac(s);
+ synchronize_irq();
+ s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count =
+ s->dma_dac.total_bytes = s->dma_dac.blocks = 0;
+ }
+ if (file->f_mode & FMODE_READ) {
+ stop_adc(s);
+ synchronize_irq();
+ s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count =
+ s->dma_adc.total_bytes = s->dma_adc.blocks = 0;
+ }
+ prog_codec(s);
+ return 0;
+
+ case SNDCTL_DSP_SPEED:


+ if (get_user(val, (int *)arg))
+ return -EFAULT;

+ if (val >= 0) {
+ stop_adc(s);
+ stop_dac(s);
+ s->dma_adc.ready = s->dma_dac.ready = 0;


+ // program sampling rates

+ if (val > 48000)
+ val = 48000;
+ if (val < 6300)
+ val = 6300;
+ s->rate = val;
+ prog_codec(s);
+ }
+ return put_user(s->rate, (int *)arg);
+
+ case SNDCTL_DSP_STEREO:


+ if (get_user(val, (int *)arg))
+ return -EFAULT;

+ stop_adc(s);
+ stop_dac(s);
+ s->dma_adc.ready = s->dma_dac.ready = 0;
+ // program channels
+ s->channels = val ? 2 : 1;
+ prog_codec(s);
+ return 0;
+
+ case SNDCTL_DSP_CHANNELS:


+ if (get_user(val, (int *)arg))
+ return -EFAULT;

+ if (val != 0) {
+ stop_adc(s);
+ stop_dac(s);
+ s->dma_adc.ready = s->dma_dac.ready = 0;
+ // program channels
+ s->channels = val ? 2 : 1;
+ prog_codec(s);
+ }
+ return put_user(s->channels, (int *)arg);
+
+ case SNDCTL_DSP_GETFMTS: // Returns a mask
+ return put_user(AFMT_S16_LE|AFMT_U16_LE|AFMT_S8|AFMT_U8, (int *)arg);
+
+ case SNDCTL_DSP_SETFMT: // Selects ONE fmt


+ if (get_user(val, (int *)arg))
+ return -EFAULT;

+ if (val != AFMT_QUERY) {
+ stop_adc(s);
+ stop_dac(s);
+ s->dma_adc.ready = s->dma_dac.ready = 0;
+ // program format
+ if (val != AFMT_S16_LE && val != AFMT_U16_LE &&
+ val != AFMT_S8 && val != AFMT_U8)
+ val = AFMT_U8;
+ s->fmt = val;
+ prog_codec(s);
+ }
+ return put_user(s->fmt, (int *)arg);
+
+ case SNDCTL_DSP_POST:
+ return 0;
+
+ case SNDCTL_DSP_GETTRIGGER:
+ val = 0;
+ if (file->f_mode & s->ena & FMODE_READ)
+ val |= PCM_ENABLE_INPUT;
+ if (file->f_mode & s->ena & FMODE_WRITE)
+ val |= PCM_ENABLE_OUTPUT;


+ return put_user(val, (int *)arg);
+

+ case SNDCTL_DSP_SETTRIGGER:


+ if (get_user(val, (int *)arg))
+ return -EFAULT;

+ if (file->f_mode & FMODE_READ) {

+ if (val & PCM_ENABLE_INPUT) {


+ if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
+ return ret;

+ start_adc(s);
+ } else
+ stop_adc(s);


+ }
+ if (file->f_mode & FMODE_WRITE) {

+ if (val & PCM_ENABLE_OUTPUT) {


+ if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s)))
+ return ret;

+ start_dac(s);
+ } else
+ stop_dac(s);


+ }
+ return 0;
+

+ case SNDCTL_DSP_GETOSPACE:
+ if (!(file->f_mode & FMODE_WRITE))
+ return -EINVAL;
+ if (!(s->ena & FMODE_WRITE) && (val = prog_dmabuf_dac(s)) != 0)
+ return val;


+ spin_lock_irqsave(&s->lock, flags);
+ cs4281_update_ptr(s);

+ abinfo.fragsize = s->dma_dac.fragsize;
+ abinfo.bytes = s->dma_dac.dmasize - s->dma_dac.count;
+ abinfo.fragstotal = s->dma_dac.numfrag;
+ abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
+ spin_unlock_irqrestore(&s->lock, flags);
+ return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+
+ case SNDCTL_DSP_GETISPACE:
+ if (!(file->f_mode & FMODE_READ))
+ return -EINVAL;
+ if (!(s->ena & FMODE_READ) && (val = prog_dmabuf_adc(s)) != 0)
+ return val;


+ spin_lock_irqsave(&s->lock, flags);
+ cs4281_update_ptr(s);

+ abinfo.fragsize = s->dma_adc.fragsize;
+ abinfo.bytes = s->dma_adc.count;
+ abinfo.fragstotal = s->dma_adc.numfrag;
+ abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
+ spin_unlock_irqrestore(&s->lock, flags);
+ return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+
+ case SNDCTL_DSP_NONBLOCK:
+ file->f_flags |= O_NONBLOCK;
+ return 0;
+
+ case SNDCTL_DSP_GETODELAY:
+ if (!(file->f_mode & FMODE_WRITE))
+ return -EINVAL;


+ spin_lock_irqsave(&s->lock, flags);
+ cs4281_update_ptr(s);

+ val = s->dma_dac.count;
+ spin_unlock_irqrestore(&s->lock, flags);


+ return put_user(val, (int *)arg);
+

+ case SNDCTL_DSP_GETIPTR:
+ if (!(file->f_mode & FMODE_READ))
+ return -EINVAL;


+ spin_lock_irqsave(&s->lock, flags);
+ cs4281_update_ptr(s);

+ cinfo.bytes = s->dma_adc.total_bytes;
+ cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift;
+ cinfo.ptr = s->dma_adc.hwptr;
+ if (s->dma_adc.mapped)
+ s->dma_adc.count &= s->dma_adc.fragsize-1;
+ spin_unlock_irqrestore(&s->lock, flags);
+ return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+
+ case SNDCTL_DSP_GETOPTR:
+ if (!(file->f_mode & FMODE_WRITE))
+ return -EINVAL;


+ spin_lock_irqsave(&s->lock, flags);
+ cs4281_update_ptr(s);

+ cinfo.bytes = s->dma_dac.total_bytes;
+ if (s->dma_dac.mapped)
+ {
+ cinfo.blocks = (cinfo.bytes >> s->dma_dac.fragshift)
+ - s->dma_adc.blocks;
+ s->dma_dac.blocks = cinfo.bytes >> s->dma_dac.fragshift;
+ }
+ else
+ {
+ cinfo.blocks = s->dma_dac.count >> s->dma_dac.fragshift;
+ }
+ cinfo.ptr = s->dma_dac.hwptr;
+ if (s->dma_dac.mapped)
+ s->dma_dac.count &= s->dma_dac.fragsize-1;
+ spin_unlock_irqrestore(&s->lock, flags);
+ return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+
+ case SNDCTL_DSP_GETBLKSIZE:


+ if (file->f_mode & FMODE_WRITE) {

+ if ((val = prog_dmabuf_dac(s)))
+ return val;
+ return put_user(s->dma_dac.fragsize, (int *)arg);
+ }
+ if ((val = prog_dmabuf_adc(s)))
+ return val;
+ return put_user(s->dma_adc.fragsize, (int *)arg);
+
+ case SNDCTL_DSP_SETFRAGMENT:


+ if (get_user(val, (int *)arg))
+ return -EFAULT;

+ return 0; // Say OK, but do nothing.
+
+ case SNDCTL_DSP_SUBDIVIDE:
+ if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
+ (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))


+ return -EINVAL;
+ if (get_user(val, (int *)arg))
+ return -EFAULT;

+ if (val != 1 && val != 2 && val != 4)
+ return -EINVAL;


+ if (file->f_mode & FMODE_READ)

+ s->dma_adc.subdivision = val;


+ if (file->f_mode & FMODE_WRITE)

+ s->dma_dac.subdivision = val;
+ return 0;
+
+ case SOUND_PCM_READ_RATE:
+ return put_user(s->rate, (int *)arg);
+
+ case SOUND_PCM_READ_CHANNELS:
+ return put_user(s->channels, (int *)arg);
+
+ case SOUND_PCM_READ_BITS:
+ return put_user((s->fmt & (AFMT_S8|AFMT_U8)) ? 8 : 16, (int *)arg);
+
+ case SOUND_PCM_WRITE_FILTER:
+ case SNDCTL_DSP_SETSYNCRO:
+ case SOUND_PCM_READ_FILTER:


+ return -EINVAL;
+
+ }

+ return mixer_ioctl(s, cmd, arg);
+}
+
+
+static int cs4281_release(struct inode *inode, struct file *file)


+{
+ struct cs4281_state *s = (struct cs4281_state *)file->private_data;
+

+ CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2,
+ printk(KERN_INFO "cs4281: cs4281_release(): inode=0x%.8x file=0x%.8x\n",
+ (unsigned)inode,(unsigned)file) );
+
+ VALIDATE_STATE(s);
+


+ if (file->f_mode & FMODE_WRITE)

+ drain_dac(s, file->f_flags & O_NONBLOCK);
+ down(&s->open_sem);


+ if (file->f_mode & FMODE_WRITE) {

+ stop_dac(s);
+ dealloc_dmabuf(s,&s->dma_dac);
+ }
+ if (file->f_mode & FMODE_READ) {
+ stop_adc(s);
+ dealloc_dmabuf(s,&s->dma_adc);
+ }
+ s->open_mode &= ~(FMODE_READ | FMODE_WRITE);
+ up(&s->open_sem);
+ wake_up(&s->open_wait);


+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+

+static int cs4281_open(struct inode *inode, struct file *file)


+{
+ int minor = MINOR(inode->i_rdev);
+ struct cs4281_state *s = devs;
+

+ CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2,
+ printk(KERN_INFO "cs4281: cs4281_open(): inode=0x%.8x file=0x%.8x\n",
+ (unsigned)inode,(unsigned)file) );
+ while (s && ((s->dev_audio ^ minor) & ~0xf))


+ s = s->next;
+ if (!s)

+ {
+ CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2, printk(KERN_INFO
+ "cs4281: cs4281_open(): ERROR unable to find audio state struct\n") );
+ return -ENODEV;
+ }


+ VALIDATE_STATE(s);
+ file->private_data = s;
+

+ // wait for device to become free
+ down(&s->open_sem);
+ while (s->open_mode & (FMODE_READ | FMODE_WRITE)) {


+ if (file->f_flags & O_NONBLOCK) {

+ up(&s->open_sem);
+ return -EBUSY;
+ }
+ up(&s->open_sem);
+ interruptible_sleep_on(&s->open_wait);


+ if (signal_pending(current))
+ return -ERESTARTSYS;

+ down(&s->open_sem);
+ }
+ s->fmt = AFMT_U8;
+ s->channels = 1;
+ s->rate = 8000;
+ s->clkdiv = 96 | 0x80;
+ s->ena = s->endofbuffer = 0;
+ s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
+ s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;
+ s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
+ up(&s->open_sem);
+ MOD_INC_USE_COUNT;
+
+ if (prog_dmabuf_dac(s) || prog_dmabuf_adc(s)) {
+
+ printk(KERN_ERR "cs4281: Program dmabufs failed.\n");
+ cs4281_release(inode, file);
+
+ return -ENOMEM;
+ }
+ prog_codec(s);
+ CS_DBGOUT(CS_INIT | CS_FUNCTION | CS_OPEN, 2,
+ printk(KERN_INFO "cs4281: cs4281_open()- 0\n") );


+ return 0;
+}
+
+

+// ******************************************************************************************
+// Wave (audio) file operations struct.
+// ******************************************************************************************
+static /*const*/ struct file_operations cs4281_audio_fops = {
+ llseek: cs4281_llseek,
+ read: cs4281_read,
+ write: cs4281_write,
+ poll: cs4281_poll,
+ ioctl: cs4281_ioctl,
+ mmap: cs4281_mmap,
+ open: cs4281_open,
+ release: cs4281_release,


+};
+
+// ---------------------------------------------------------------------
+

+// hold spinlock for the following!
+static void cs4281_handle_midi(struct cs4281_state *s)
+{
+ unsigned char ch;
+ int wake;
+ unsigned temp1;
+
+ wake = 0;
+ while (!(readl(s->pBA0+ BA0_MIDSR) & 0x80)) {
+ ch = readl(s->pBA0+BA0_MIDRP);
+ if (s->midi.icnt < MIDIINBUF) {
+ s->midi.ibuf[s->midi.iwr] = ch;
+ s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF;
+ s->midi.icnt++;
+ }
+ wake = 1;
+ }
+ if (wake)
+ wake_up(&s->midi.iwait);
+ wake = 0;
+ while (!(readl(s->pBA0+ BA0_MIDSR) & 0x40) && s->midi.ocnt > 0) {
+ temp1 = ( s->midi.obuf[s->midi.ord] ) & 0x000000ff;
+ writel(temp1, s->pBA0+BA0_MIDWP);
+ s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF;
+ s->midi.ocnt--;
+ if (s->midi.ocnt < MIDIOUTBUF-16)
+ wake = 1;
+ }
+ if (wake)
+ wake_up(&s->midi.owait);
+}
+
+
+
+static void cs4281_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct cs4281_state *s = (struct cs4281_state *)dev_id;
+ unsigned int temp1;
+
+ // fastpath out, to ease interrupt sharing
+ temp1 = readl(s->pBA0+BA0_HISR); // Get Int Status reg.
+
+ CS_DBGOUT(CS_INTERRUPT, 6, printk(KERN_INFO
+ "cs4281: cs4281_interrupt() BA0_HISR=0x%.8x\n",temp1) );
+
+ if (!(temp1 & (HISR_DMA0 | HISR_DMA1 | HISR_MIDI))) { // If not DMA or MIDI int,
+ writel(HICR_IEV| HICR_CHGM, s->pBA0+BA0_HICR); // reenable interrupts
+ CS_DBGOUT(CS_INTERRUPT, 4, printk(KERN_INFO
+ "cs4281: cs4281_interrupt(): returning not cs4281 interrupt.\n") );
+ return; // and return.
+ }
+
+ if(temp1 & HISR_DMA0) // If play interrupt,
+ readl(s->pBA0+BA0_HDSR0); // clear the source.
+
+ if(temp1 & HISR_DMA1) // Same for play.
+ readl(s->pBA0+BA0_HDSR1);
+ writel(HICR_IEV| HICR_CHGM, s->pBA0+BA0_HICR); // Local EOI
+
+ spin_lock(&s->lock);
+ //
+ // ok, at this point we assume that the fifos have been filled
+ // with silence and so we now turn off the DMA engine.
+ // if FMODE_WRITE is set that means that some thread
+ // attempted to start_dac, which probably means that an open
+ // occurred, so do not stop the dac in this case.
+ //
+ if(s->endofbuffer && !(s->ena & FMODE_WRITE))
+ {
+ CS_DBGOUT(CS_INTERRUPT, 2, printk(KERN_INFO
+ "cs4281: cs4281_interrupt() stopping play DMA\n") );
+ writel(temp1|DCRn_MSK, s->pBA0+BA0_DCR0); // Stop Play DMA
+ s->endofbuffer = 0;
+ }
+ else
+ {
+ cs4281_update_ptr(s);
+ }
+ cs4281_handle_midi(s);
+ spin_unlock(&s->lock);
+}
+
+// **************************************************************************
+
+static void cs4281_midi_timer(unsigned long data)
+{
+ struct cs4281_state *s = (struct cs4281_state *)data;


+ unsigned long flags;
+

+ spin_lock_irqsave(&s->lock, flags);
+ cs4281_handle_midi(s);
+ spin_unlock_irqrestore(&s->lock, flags);
+ s->midi.timer.expires = jiffies+1;
+ add_timer(&s->midi.timer);


+}
+
+
+// ---------------------------------------------------------------------
+

+static ssize_t cs4281_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos)


+{
+ struct cs4281_state *s = (struct cs4281_state *)file->private_data;
+ ssize_t ret;
+ unsigned long flags;

+ unsigned ptr;
+ int cnt;
+


+ VALIDATE_STATE(s);
+ if (ppos != &file->f_pos)
+ return -ESPIPE;

+ if (!access_ok(VERIFY_WRITE, buffer, count))
+ return -EFAULT;
+ ret = 0;
+ while (count > 0) {
+ spin_lock_irqsave(&s->lock, flags);

+ ptr = s->midi.ird;
+ cnt = MIDIINBUF - ptr;
+ if (s->midi.icnt < cnt)
+ cnt = s->midi.icnt;


+ spin_unlock_irqrestore(&s->lock, flags);
+ if (cnt > count)
+ cnt = count;
+ if (cnt <= 0) {

+ if (file->f_flags & O_NONBLOCK)
+ return ret ? ret : -EAGAIN;

+ interruptible_sleep_on(&s->midi.iwait);


+ if (signal_pending(current))
+ return ret ? ret : -ERESTARTSYS;
+ continue;
+ }

+ if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt))


+ return ret ? ret : -EFAULT;

+ ptr = (ptr + cnt) % MIDIINBUF;
+ spin_lock_irqsave(&s->lock, flags);
+ s->midi.ird = ptr;
+ s->midi.icnt -= cnt;


+ spin_unlock_irqrestore(&s->lock, flags);
+ count -= cnt;
+ buffer += cnt;
+ ret += cnt;
+ }

+ return ret;
+}
+
+

+static ssize_t cs4281_midi_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)


+{
+ struct cs4281_state *s = (struct cs4281_state *)file->private_data;
+ ssize_t ret;
+ unsigned long flags;

+ unsigned ptr;
+ int cnt;
+


+ VALIDATE_STATE(s);
+ if (ppos != &file->f_pos)
+ return -ESPIPE;

+ if (!access_ok(VERIFY_READ, buffer, count))
+ return -EFAULT;
+ ret = 0;
+ while (count > 0) {
+ spin_lock_irqsave(&s->lock, flags);

+ ptr = s->midi.owr;
+ cnt = MIDIOUTBUF - ptr;
+ if (s->midi.ocnt + cnt > MIDIOUTBUF)
+ cnt = MIDIOUTBUF - s->midi.ocnt;


+ if (cnt <= 0)

+ cs4281_handle_midi(s);


+ spin_unlock_irqrestore(&s->lock, flags);
+ if (cnt > count)
+ cnt = count;
+ if (cnt <= 0) {

+ if (file->f_flags & O_NONBLOCK)
+ return ret ? ret : -EAGAIN;

+ interruptible_sleep_on(&s->midi.owait);


+ if (signal_pending(current))
+ return ret ? ret : -ERESTARTSYS;
+ continue;
+ }

+ if (copy_from_user(s->midi.obuf + ptr, buffer, cnt))


+ return ret ? ret : -EFAULT;

+ ptr = (ptr + cnt) % MIDIOUTBUF;
+ spin_lock_irqsave(&s->lock, flags);
+ s->midi.owr = ptr;
+ s->midi.ocnt += cnt;


+ spin_unlock_irqrestore(&s->lock, flags);
+ count -= cnt;
+ buffer += cnt;
+ ret += cnt;

+ spin_lock_irqsave(&s->lock, flags);
+ cs4281_handle_midi(s);


+ spin_unlock_irqrestore(&s->lock, flags);
+ }

+ return ret;
+}
+
+

+static unsigned int cs4281_midi_poll(struct file *file, struct poll_table_struct *wait)


+{
+ struct cs4281_state *s = (struct cs4281_state *)file->private_data;
+ unsigned long flags;
+ unsigned int mask = 0;
+

+ VALIDATE_STATE(s);
+ if (file->f_flags & FMODE_WRITE)
+ poll_wait(file, &s->midi.owait, wait);
+ if (file->f_flags & FMODE_READ)
+ poll_wait(file, &s->midi.iwait, wait);
+ spin_lock_irqsave(&s->lock, flags);
+ if (file->f_flags & FMODE_READ) {
+ if (s->midi.icnt > 0)


+ mask |= POLLIN | POLLRDNORM;
+ }

+ if (file->f_flags & FMODE_WRITE) {
+ if (s->midi.ocnt < MIDIOUTBUF)


+ mask |= POLLOUT | POLLWRNORM;
+ }

+ spin_unlock_irqrestore(&s->lock, flags);
+ return mask;
+}
+
+
+static int cs4281_midi_open(struct inode *inode, struct file *file)


+{
+ int minor = MINOR(inode->i_rdev);
+ struct cs4281_state *s = devs;

+ unsigned long flags,temp1;
+ while (s && s->dev_midi != minor)


+ s = s->next;
+ if (!s)
+ return -ENODEV;
+ VALIDATE_STATE(s);
+ file->private_data = s;

+ // wait for device to become free
+ down(&s->open_sem);
+ while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {


+ if (file->f_flags & O_NONBLOCK) {

+ up(&s->open_sem);
+ return -EBUSY;
+ }
+ up(&s->open_sem);
+ interruptible_sleep_on(&s->open_wait);


+ if (signal_pending(current))
+ return -ERESTARTSYS;

+ down(&s->open_sem);


+ }
+ spin_lock_irqsave(&s->lock, flags);

+ if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
+ s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
+ s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
+ writel(1, s->pBA0+BA0_MIDCR); // Reset the interface.
+ writel(0, s->pBA0+BA0_MIDCR); // Return to normal mode.
+ s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
+ writel(0x0000000f, s->pBA0+BA0_MIDCR); // Enable transmit, record, ints.
+ temp1 = readl(s->pBA0+BA0_HIMR);
+ writel(temp1 & 0xffbfffff, s->pBA0+BA0_HIMR); // Enable midi int. recognition.


+ writel(HICR_IEV | HICR_CHGM, s->pBA0+BA0_HICR); // Enable interrupts

+ init_timer(&s->midi.timer);
+ s->midi.timer.expires = jiffies+1;
+ s->midi.timer.data = (unsigned long)s;
+ s->midi.timer.function = cs4281_midi_timer;
+ add_timer(&s->midi.timer);
+ }
+ if (file->f_mode & FMODE_READ) {
+ s->midi.ird = s->midi.iwr = s->midi.icnt = 0;


+ }
+ if (file->f_mode & FMODE_WRITE) {

+ s->midi.ord = s->midi.owr = s->midi.ocnt = 0;


+ }
+ spin_unlock_irqrestore(&s->lock, flags);

+ s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
+ up(&s->open_sem);


+ MOD_INC_USE_COUNT;
+ return 0;
+}
+
+

+static int cs4281_midi_release(struct inode *inode, struct file *file)


+{
+ struct cs4281_state *s = (struct cs4281_state *)file->private_data;

+ DECLARE_WAITQUEUE(wait, current);
+ unsigned long flags;

+ unsigned count, tmo;
+
+ VALIDATE_STATE(s);
+


+ if (file->f_mode & FMODE_WRITE) {

+ current->state = TASK_INTERRUPTIBLE;

+ add_wait_queue(&s->midi.owait, &wait);


+ for (;;) {
+ spin_lock_irqsave(&s->lock, flags);

+ count = s->midi.ocnt;


+ spin_unlock_irqrestore(&s->lock, flags);
+ if (count <= 0)
+ break;
+ if (signal_pending(current))
+ break;

+ if (file->f_flags & O_NONBLOCK) {

+ remove_wait_queue(&s->midi.owait, &wait);


+ current->state = TASK_RUNNING;
+ return -EBUSY;
+ }

+ tmo = (count * HZ) / 3100;
+ if (!schedule_timeout(tmo ? : 1) && tmo)
+ printk(KERN_DEBUG "cs4281: midi timed out??\n");
+ }
+ remove_wait_queue(&s->midi.owait, &wait);


+ current->state = TASK_RUNNING;
+ }

+ down(&s->open_sem);
+ s->open_mode &= (~(file->f_mode << FMODE_MIDI_SHIFT)) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE);
+ spin_lock_irqsave(&s->lock, flags);
+ if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
+ writel(0, s->pBA0+BA0_MIDCR); // Disable Midi interrupts.
+ del_timer(&s->midi.timer);


+ }
+ spin_unlock_irqrestore(&s->lock, flags);

+ up(&s->open_sem);
+ wake_up(&s->open_wait);


+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+

+// ******************************************************************************************
+// Midi file operations struct.
+// ******************************************************************************************
+static /*const*/ struct file_operations cs4281_midi_fops = {
+ llseek: cs4281_llseek,
+ read: cs4281_midi_read,
+ write: cs4281_midi_write,
+ poll: cs4281_midi_poll,
+ open: cs4281_midi_open,
+ release: cs4281_midi_release,


+};
+
+
+// ---------------------------------------------------------------------
+

+// maximum number of devices
+#define NR_DEVICE 8 // Only eight devices supported currently.
+
+// ---------------------------------------------------------------------
+
+static struct initvol {
+ int mixch;
+ int vol;
+} initvol[] __initdata = {
+ { SOUND_MIXER_WRITE_VOLUME, 0x4040 },
+ { SOUND_MIXER_WRITE_PCM, 0x4040 },
+ { SOUND_MIXER_WRITE_SYNTH, 0x4040 },
+ { SOUND_MIXER_WRITE_CD, 0x4040 },
+ { SOUND_MIXER_WRITE_LINE, 0x4040 },
+ { SOUND_MIXER_WRITE_LINE1, 0x4040 },
+ { SOUND_MIXER_WRITE_RECLEV, 0x0000 },
+ { SOUND_MIXER_WRITE_SPEAKER, 0x4040 },
+ { SOUND_MIXER_WRITE_MIC, 0x0000 }
+};
+
+
+static int __devinit cs4281_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
+{
+ struct cs4281_state *s;
+ dma_addr_t dma_mask;
+ mm_segment_t fs;
+ int i, val, index = 0;
+ unsigned int temp1, temp2;
+
+ CS_DBGOUT(CS_INIT, 2, printk(KERN_INFO "cs4281: probe()+\n") );
+
+ if (!RSRCISMEMORYREGION(pcidev, 0) ||
+ !RSRCISMEMORYREGION(pcidev, 1))
+ {
+ CS_DBGOUT(CS_ERROR, 1,
+ printk(KERN_ERR "cs4281: probe()- Memory region not assigned\n") );
+ return -1;
+ }
+ if (pcidev->irq == 0) {
+ CS_DBGOUT(CS_ERROR, 1,
+ printk(KERN_ERR "cs4281: probe() IRQ not assigned\n") );
+ return -1;
+ }
+ if (!pci_dma_supported(pcidev, 0xffffffff)) {
+ CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
+ "cs4281: probe() architecture does not support 32bit PCI busmaster DMA\n") );
+ return -1;
+ }
+ dma_mask = 0xffffffff; /* this enables playback and recording */
+ if (!(s = kmalloc(sizeof(struct cs4281_state), GFP_KERNEL))) {
+ CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
+ "cs4281: probe() no memory for state struct.\n") );
+ return -1;
+ }
+ memset(s, 0, sizeof(struct cs4281_state));
+ init_waitqueue_head(&s->dma_adc.wait);
+ init_waitqueue_head(&s->dma_dac.wait);
+ init_waitqueue_head(&s->open_wait);
+ init_waitqueue_head(&s->midi.iwait);
+ init_waitqueue_head(&s->midi.owait);
+ init_MUTEX(&s->open_sem);
+ spin_lock_init(&s->lock);
+ s->pBA0phys = RSRCADDRESS(pcidev, 0);
+ s->pBA1phys = RSRCADDRESS(pcidev, 1);
+ s->pBA0 = ioremap_nocache(s->pBA0phys, 4096); // Convert phys
+ s->pBA1 = ioremap_nocache(s->pBA1phys, 65536); // to linear.
+ temp1 = readl(s->pBA0+ BA0_PCICFG00);
+ temp2 = readl(s->pBA0+ BA0_PCICFG04);
+
+ CS_DBGOUT(CS_INIT, 2,
+ printk(KERN_INFO "cs4281: probe() BA0=0x%.8x BA1=0x%.8x pBA0=0x%.8x pBA1=0x%.8x \n",
+ (unsigned)temp1,(unsigned)temp2,(unsigned)s->pBA0,(unsigned)s->pBA1) );
+
+ CS_DBGOUT(CS_INIT, 2,
+ printk(KERN_INFO "cs4281: probe() pBA0phys=0x%.8x pBA1phys=0x%.8x\n",
+ (unsigned)s->pBA0phys,(unsigned)s->pBA1phys) );
+
+ temp1 = cs4281_hw_init(s);
+ if(temp1){
+ CS_DBGOUT(CS_ERROR | CS_INIT, 1,
+ printk(KERN_ERR "cs4281: cs4281_hw_init() failed. Skipping part.\n") );
+ return -1;
+ }
+ s->magic = CS4281_MAGIC;
+ s->pcidev = pcidev;
+ s->irq = pcidev->irq;
+ if (pci_enable_device(pcidev))
+ {
+ CS_DBGOUT(CS_INIT | CS_ERROR, 1,
+ printk(KERN_ERR "cs4281: pci_enable_device() failed\n") );
+ goto err_irq;
+ }
+ if(request_irq(s->irq, cs4281_interrupt, SA_SHIRQ, "Crystal CS4281", s)){
+ CS_DBGOUT(CS_INIT | CS_ERROR, 1,
+ printk(KERN_ERR "cs4281: irq %u in use\n", s->irq) );
+ goto err_irq;
+ }
+ if ((s->dev_audio = register_sound_dsp(&cs4281_audio_fops, -1)) < 0)
+ {
+ CS_DBGOUT(CS_INIT | CS_ERROR, 1,
+ printk(KERN_ERR "cs4281: probe() register_sound_dsp() failed.\n") );
+ goto err_dev1;
+ }
+ if ((s->dev_mixer = register_sound_mixer(&cs4281_mixer_fops, -1)) < 0)
+ {
+ CS_DBGOUT(CS_INIT | CS_ERROR, 1,
+ printk(KERN_ERR "cs4281: probe() register_sound_mixer() failed.\n") );
+ goto err_dev2;
+ }
+ if ((s->dev_midi = register_sound_midi(&cs4281_midi_fops, -1)) < 0)
+ {
+ CS_DBGOUT(CS_INIT | CS_ERROR, 1,
+ printk(KERN_ERR "cs4281: probe() register_sound_midi() failed.\n") );
+ goto err_dev3;
+ }
+
+ pci_set_master(pcidev); // enable bus mastering
+
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+ val = SOUND_MASK_LINE;
+ mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
+ for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) {
+ val = initvol[i].vol;
+ mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val);
+ }
+ val = 1; // enable mic preamp
+ mixer_ioctl(s, SOUND_MIXER_PRIVATE1, (unsigned long)&val);
+ set_fs(fs);
+
+ // queue it for later freeing
+ s->next = devs;
+ pcidev->driver_data = s;
+ pcidev->dma_mask = dma_mask;
+ devs = s;
+ index++;
+ return 0;
+
+err_dev3:
+ unregister_sound_mixer(s->dev_mixer);
+err_dev2:
+ unregister_sound_dsp(s->dev_audio);
+err_dev1:
+ free_irq(s->irq, s);
+err_irq:
+ kfree(s);
+
+ if (!devs)
+ {
+ CS_DBGOUT(CS_INIT | CS_ERROR, 1,
+ printk(KERN_INFO "cs4281: probe()- no device allocated\n") );
+ return -ENODEV;


+ }
+ CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,

+ printk(KERN_INFO "cs4281: probe()- device allocated successfully\n") );
+ return 0;
+} // probe_cs4281


+
+
+// ---------------------------------------------------------------------
+

+static void __devinit cs4281_remove(struct pci_dev *dev)
+{
+ struct cs4281_state *s = (struct cs4281_state *)dev->driver_data;
+ // stop DMA controller
+ synchronize_irq();
+ free_irq(s->irq, s);
+ unregister_sound_dsp(s->dev_audio);
+ unregister_sound_mixer(s->dev_mixer);
+ unregister_sound_midi(s->dev_midi);
+ kfree(s);
+ dev->driver_data = NULL;
+ CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,
+ printk(KERN_INFO "cs4281: cs4281_remove(): remove successful\n") );
+}
+
+static struct pci_device_id id_table[] __devinitdata = {
+ { PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CRYSTAL_CS4281, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
+ { 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, id_table);
+
+static struct pci_driver cs4281_driver = {
+ name: "cs4281",
+ id_table: id_table,
+ probe: cs4281_probe,
+ remove: cs4281_remove
+};
+
+static int __init init_cs4281(void)
+{
+
+ CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO "cs4281: init_cs4281()+ \n") );
+ if (!pci_present()) /* No PCI bus in this machine! */


+ {
+ CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,

+ printk(KERN_INFO "cs4281: init_cs4281()- no pci bus found\n") );
+ return -ENODEV;
+ }
+ printk(KERN_INFO "cs4281: version v%d.%02d.%d time " __TIME__ " " __DATE__ "\n",
+ CS4281_MAJOR_VERSION, CS4281_MINOR_VERSION, CS4281_ARCH);
+ if (!pci_register_driver(&cs4281_driver)) {
+ pci_unregister_driver(&cs4281_driver);
+ CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,
+ printk(KERN_INFO "cs4281: init_cs4281()- unable to register pci device \n") );
+ return -ENODEV;
+ }
+ CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO "cs4281: init_cs4281()- 0\n") );


+ return 0;
+}
+
+

+// ---------------------------------------------------------------------
+
+
+MODULE_AUTHOR("gw boynton, we...@crystal.cirrus.com");
+MODULE_DESCRIPTION("Cirrus Logic CS4281 Driver");
+
+static void __exit cleanup_cs4281(void)
+{
+ pci_unregister_driver(&cs4281_driver);
+ CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,
+ printk(KERN_INFO "cs4281: cleanup_cs4281() finished\n") );
+}
+
+// ---------------------------------------------------------------------
+
+module_init(init_cs4281);
+module_exit(cleanup_cs4281);
+
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/cs4281_hwdefs.h linux/drivers/sound/cs4281_hwdefs.h
--- v2.4.0-test8/linux/drivers/sound/cs4281_hwdefs.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/sound/cs4281_hwdefs.h Sat Sep 23 20:23:09 2000
@@ -0,0 +1,1234 @@
+//****************************************************************************
+//
+// HWDEFS.H - Definitions of the registers and data structures used by the
+// CS4281
+//
+// Copyright (c) 1999 Crystal Semiconductor Corp.
+//
+//****************************************************************************
+
+#ifndef _H_HWDEFS
+#define _H_HWDEFS
+
+//****************************************************************************
+//
+// The following define the offsets of the registers located in the PCI
+// configuration space of the CS4281 part.
+//
+//****************************************************************************
+#define PCICONFIG_DEVID_VENID 0x00000000L
+#define PCICONFIG_STATUS_COMMAND 0x00000004L
+#define PCICONFIG_CLASS_REVISION 0x00000008L
+#define PCICONFIG_LATENCY_TIMER 0x0000000CL
+#define PCICONFIG_BA0 0x00000010L
+#define PCICONFIG_BA1 0x00000014L
+#define PCICONFIG_SUBSYSID_SUBSYSVENID 0x0000002CL
+#define PCICONFIG_INTERRUPT 0x0000003CL
+
+//****************************************************************************
+//
+// The following define the offsets of the registers accessed via base address
+// register zero on the CS4281 part.
+//
+//****************************************************************************
+#define BA0_HISR 0x00000000L
+#define BA0_HICR 0x00000008L
+#define BA0_HIMR 0x0000000CL
+#define BA0_IIER 0x00000010L
+#define BA0_HDSR0 0x000000F0L
+#define BA0_HDSR1 0x000000F4L
+#define BA0_HDSR2 0x000000F8L
+#define BA0_HDSR3 0x000000FCL
+#define BA0_DCA0 0x00000110L
+#define BA0_DCC0 0x00000114L
+#define BA0_DBA0 0x00000118L
+#define BA0_DBC0 0x0000011CL
+#define BA0_DCA1 0x00000120L
+#define BA0_DCC1 0x00000124L
+#define BA0_DBA1 0x00000128L
+#define BA0_DBC1 0x0000012CL
+#define BA0_DCA2 0x00000130L
+#define BA0_DCC2 0x00000134L
+#define BA0_DBA2 0x00000138L
+#define BA0_DBC2 0x0000013CL
+#define BA0_DCA3 0x00000140L
+#define BA0_DCC3 0x00000144L
+#define BA0_DBA3 0x00000148L
+#define BA0_DBC3 0x0000014CL
+#define BA0_DMR0 0x00000150L
+#define BA0_DCR0 0x00000154L
+#define BA0_DMR1 0x00000158L
+#define BA0_DCR1 0x0000015CL
+#define BA0_DMR2 0x00000160L
+#define BA0_DCR2 0x00000164L
+#define BA0_DMR3 0x00000168L
+#define BA0_DCR3 0x0000016CL
+#define BA0_DLMR 0x00000170L
+#define BA0_DLSR 0x00000174L
+#define BA0_FCR0 0x00000180L
+#define BA0_FCR1 0x00000184L
+#define BA0_FCR2 0x00000188L
+#define BA0_FCR3 0x0000018CL
+#define BA0_FPDR0 0x00000190L
+#define BA0_FPDR1 0x00000194L
+#define BA0_FPDR2 0x00000198L
+#define BA0_FPDR3 0x0000019CL
+#define BA0_FCHS 0x0000020CL
+#define BA0_FSIC0 0x00000210L
+#define BA0_FSIC1 0x00000214L
+#define BA0_FSIC2 0x00000218L
+#define BA0_FSIC3 0x0000021CL
+#define BA0_PCICFG00 0x00000300L
+#define BA0_PCICFG04 0x00000304L
+#define BA0_PCICFG08 0x00000308L
+#define BA0_PCICFG0C 0x0000030CL
+#define BA0_PCICFG10 0x00000310L
+#define BA0_PCICFG14 0x00000314L
+#define BA0_PCICFG18 0x00000318L
+#define BA0_PCICFG1C 0x0000031CL
+#define BA0_PCICFG20 0x00000320L
+#define BA0_PCICFG24 0x00000324L
+#define BA0_PCICFG28 0x00000328L
+#define BA0_PCICFG2C 0x0000032CL
+#define BA0_PCICFG30 0x00000330L
+#define BA0_PCICFG34 0x00000334L
+#define BA0_PCICFG38 0x00000338L
+#define BA0_PCICFG3C 0x0000033CL
+#define BA0_PCICFG40 0x00000340L
+#define BA0_PMCS 0x00000344L
+#define BA0_CWPR 0x000003E0L
+#define BA0_EPPMC 0x000003E4L
+#define BA0_GPIOR 0x000003E8L
+#define BA0_SPMC 0x000003ECL
+#define BA0_CFLR 0x000003F0L
+#define BA0_IISR 0x000003F4L
+#define BA0_TMS 0x000003F8L
+#define BA0_SSVID 0x000003FCL
+#define BA0_CLKCR1 0x00000400L
+#define BA0_FRR 0x00000410L
+#define BA0_SLT12O 0x0000041CL
+#define BA0_SERMC 0x00000420L
+#define BA0_SERC1 0x00000428L
+#define BA0_SERC2 0x0000042CL
+#define BA0_SLT12M 0x0000045CL
+#define BA0_ACCTL 0x00000460L
+#define BA0_ACSTS 0x00000464L
+#define BA0_ACOSV 0x00000468L
+#define BA0_ACCAD 0x0000046CL
+#define BA0_ACCDA 0x00000470L
+#define BA0_ACISV 0x00000474L
+#define BA0_ACSAD 0x00000478L
+#define BA0_ACSDA 0x0000047CL
+#define BA0_JSPT 0x00000480L
+#define BA0_JSCTL 0x00000484L
+#define BA0_MIDCR 0x00000490L
+#define BA0_MIDCMD 0x00000494L
+#define BA0_MIDSR 0x00000494L
+#define BA0_MIDWP 0x00000498L
+#define BA0_MIDRP 0x0000049CL
+#define BA0_AODSD1 0x000004A8L
+#define BA0_AODSD2 0x000004ACL
+#define BA0_CFGI 0x000004B0L
+#define BA0_SLT12M2 0x000004DCL
+#define BA0_ACSTS2 0x000004E4L
+#define BA0_ACISV2 0x000004F4L
+#define BA0_ACSAD2 0x000004F8L
+#define BA0_ACSDA2 0x000004FCL
+#define BA0_IOTGP 0x00000500L
+#define BA0_IOTSB 0x00000504L
+#define BA0_IOTFM 0x00000508L
+#define BA0_IOTDMA 0x0000050CL
+#define BA0_IOTAC0 0x00000500L
+#define BA0_IOTAC1 0x00000504L
+#define BA0_IOTAC2 0x00000508L
+#define BA0_IOTAC3 0x0000050CL
+#define BA0_IOTPCP 0x0000052CL
+#define BA0_IOTCC 0x00000530L
+#define BA0_IOTCR 0x0000058CL
+#define BA0_PCPRR 0x00000600L
+#define BA0_PCPGR 0x00000604L
+#define BA0_PCPCR 0x00000608L
+#define BA0_PCPCIEN 0x00000608L
+#define BA0_SBMAR 0x00000700L
+#define BA0_SBMDR 0x00000704L
+#define BA0_SBRR 0x00000708L
+#define BA0_SBRDP 0x0000070CL
+#define BA0_SBWDP 0x00000710L
+#define BA0_SBWBS 0x00000710L
+#define BA0_SBRBS 0x00000714L
+#define BA0_FMSR 0x00000730L
+#define BA0_B0AP 0x00000730L
+#define BA0_FMDP 0x00000734L
+#define BA0_B1AP 0x00000738L
+#define BA0_B1DP 0x0000073CL
+#define BA0_SSPM 0x00000740L
+#define BA0_DACSR 0x00000744L
+#define BA0_ADCSR 0x00000748L
+#define BA0_SSCR 0x0000074CL
+#define BA0_FMLVC 0x00000754L
+#define BA0_FMRVC 0x00000758L
+#define BA0_SRCSA 0x0000075CL
+#define BA0_PPLVC 0x00000760L
+#define BA0_PPRVC 0x00000764L
+#define BA0_PASR 0x00000768L
+#define BA0_CASR 0x0000076CL
+
+//****************************************************************************
+//
+// The following define the offsets of the AC97 shadow registers, which appear
+// as a virtual extension to the base address register zero memory range.
+//
+//****************************************************************************
+#define AC97_REG_OFFSET_MASK 0x0000007EL
+#define AC97_CODEC_NUMBER_MASK 0x00003000L
+
+#define BA0_AC97_RESET 0x00001000L
+#define BA0_AC97_MASTER_VOLUME 0x00001002L
+#define BA0_AC97_HEADPHONE_VOLUME 0x00001004L
+#define BA0_AC97_MASTER_VOLUME_MONO 0x00001006L
+#define BA0_AC97_MASTER_TONE 0x00001008L
+#define BA0_AC97_PC_BEEP_VOLUME 0x0000100AL
+#define BA0_AC97_PHONE_VOLUME 0x0000100CL
+#define BA0_AC97_MIC_VOLUME 0x0000100EL
+#define BA0_AC97_LINE_IN_VOLUME 0x00001010L
+#define BA0_AC97_CD_VOLUME 0x00001012L
+#define BA0_AC97_VIDEO_VOLUME 0x00001014L
+#define BA0_AC97_AUX_VOLUME 0x00001016L
+#define BA0_AC97_PCM_OUT_VOLUME 0x00001018L
+#define BA0_AC97_RECORD_SELECT 0x0000101AL
+#define BA0_AC97_RECORD_GAIN 0x0000101CL
+#define BA0_AC97_RECORD_GAIN_MIC 0x0000101EL
+#define BA0_AC97_GENERAL_PURPOSE 0x00001020L
+#define BA0_AC97_3D_CONTROL 0x00001022L
+#define BA0_AC97_MODEM_RATE 0x00001024L
+#define BA0_AC97_POWERDOWN 0x00001026L
+#define BA0_AC97_EXT_AUDIO_ID 0x00001028L
+#define BA0_AC97_EXT_AUDIO_POWER 0x0000102AL
+#define BA0_AC97_PCM_FRONT_DAC_RATE 0x0000102CL
+#define BA0_AC97_PCM_SURR_DAC_RATE 0x0000102EL
+#define BA0_AC97_PCM_LFE_DAC_RATE 0x00001030L
+#define BA0_AC97_PCM_LR_ADC_RATE 0x00001032L
+#define BA0_AC97_MIC_ADC_RATE 0x00001034L
+#define BA0_AC97_6CH_VOL_C_LFE 0x00001036L
+#define BA0_AC97_6CH_VOL_SURROUND 0x00001038L
+#define BA0_AC97_RESERVED_3A 0x0000103AL
+#define BA0_AC97_EXT_MODEM_ID 0x0000103CL
+#define BA0_AC97_EXT_MODEM_POWER 0x0000103EL
+#define BA0_AC97_LINE1_CODEC_RATE 0x00001040L
+#define BA0_AC97_LINE2_CODEC_RATE 0x00001042L
+#define BA0_AC97_HANDSET_CODEC_RATE 0x00001044L
+#define BA0_AC97_LINE1_CODEC_LEVEL 0x00001046L
+#define BA0_AC97_LINE2_CODEC_LEVEL 0x00001048L
+#define BA0_AC97_HANDSET_CODEC_LEVEL 0x0000104AL
+#define BA0_AC97_GPIO_PIN_CONFIG 0x0000104CL
+#define BA0_AC97_GPIO_PIN_TYPE 0x0000104EL
+#define BA0_AC97_GPIO_PIN_STICKY 0x00001050L
+#define BA0_AC97_GPIO_PIN_WAKEUP 0x00001052L
+#define BA0_AC97_GPIO_PIN_STATUS 0x00001054L
+#define BA0_AC97_MISC_MODEM_AFE_STAT 0x00001056L
+#define BA0_AC97_RESERVED_58 0x00001058L
+#define BA0_AC97_CRYSTAL_REV_N_FAB_ID 0x0000105AL
+#define BA0_AC97_TEST_AND_MISC_CTRL 0x0000105CL
+#define BA0_AC97_AC_MODE 0x0000105EL
+#define BA0_AC97_MISC_CRYSTAL_CONTROL 0x00001060L
+#define BA0_AC97_LINE1_HYPRID_CTRL 0x00001062L
+#define BA0_AC97_VENDOR_RESERVED_64 0x00001064L
+#define BA0_AC97_VENDOR_RESERVED_66 0x00001066L
+#define BA0_AC97_SPDIF_CONTROL 0x00001068L
+#define BA0_AC97_VENDOR_RESERVED_6A 0x0000106AL
+#define BA0_AC97_VENDOR_RESERVED_6C 0x0000106CL
+#define BA0_AC97_VENDOR_RESERVED_6E 0x0000106EL
+#define BA0_AC97_VENDOR_RESERVED_70 0x00001070L
+#define BA0_AC97_VENDOR_RESERVED_72 0x00001072L
+#define BA0_AC97_VENDOR_RESERVED_74 0x00001074L
+#define BA0_AC97_CAL_ADDRESS 0x00001076L
+#define BA0_AC97_CAL_DATA 0x00001078L
+#define BA0_AC97_VENDOR_RESERVED_7A 0x0000107AL
+#define BA0_AC97_VENDOR_ID1 0x0000107CL
+#define BA0_AC97_VENDOR_ID2 0x0000107EL
+
+//****************************************************************************
+//
+// The following define the offsets of the registers and memories accessed via
+// base address register one on the CS4281 part.
+//
+//****************************************************************************
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PCI device ID/vendor ID
+// register.
+//
+//****************************************************************************
+#define PDV_VENID_MASK 0x0000FFFFL
+#define PDV_DEVID_MASK 0xFFFF0000L
+#define PDV_VENID_SHIFT 0L
+#define PDV_DEVID_SHIFT 16L
+#define VENID_CIRRUS_LOGIC 0x1013L
+#define DEVID_CS4281 0x6005L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PCI status and command
+// register.
+//
+//****************************************************************************
+#define PSC_IO_SPACE_ENABLE 0x00000001L
+#define PSC_MEMORY_SPACE_ENABLE 0x00000002L
+#define PSC_BUS_MASTER_ENABLE 0x00000004L
+#define PSC_SPECIAL_CYCLES 0x00000008L
+#define PSC_MWI_ENABLE 0x00000010L
+#define PSC_VGA_PALETTE_SNOOP 0x00000020L
+#define PSC_PARITY_RESPONSE 0x00000040L
+#define PSC_WAIT_CONTROL 0x00000080L
+#define PSC_SERR_ENABLE 0x00000100L
+#define PSC_FAST_B2B_ENABLE 0x00000200L
+#define PSC_UDF_MASK 0x007F0000L
+#define PSC_FAST_B2B_CAPABLE 0x00800000L
+#define PSC_PARITY_ERROR_DETECTED 0x01000000L
+#define PSC_DEVSEL_TIMING_MASK 0x06000000L
+#define PSC_TARGET_ABORT_SIGNALLED 0x08000000L
+#define PSC_RECEIVED_TARGET_ABORT 0x10000000L
+#define PSC_RECEIVED_MASTER_ABORT 0x20000000L
+#define PSC_SIGNALLED_SERR 0x40000000L
+#define PSC_DETECTED_PARITY_ERROR 0x80000000L
+#define PSC_UDF_SHIFT 16L
+#define PSC_DEVSEL_TIMING_SHIFT 25L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PCI class/revision ID
+// register.
+//
+//****************************************************************************
+#define PCR_REVID_MASK 0x000000FFL
+#define PCR_INTERFACE_MASK 0x0000FF00L
+#define PCR_SUBCLASS_MASK 0x00FF0000L
+#define PCR_CLASS_MASK 0xFF000000L
+#define PCR_REVID_SHIFT 0L
+#define PCR_INTERFACE_SHIFT 8L
+#define PCR_SUBCLASS_SHIFT 16L
+#define PCR_CLASS_SHIFT 24L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PCI latency timer register.
+//
+//****************************************************************************
+#define PLT_CACHE_LINE_SIZE_MASK 0x000000FFL
+#define PLT_LATENCY_TIMER_MASK 0x0000FF00L
+#define PLT_HEADER_TYPE_MASK 0x00FF0000L
+#define PLT_BIST_MASK 0xFF000000L
+#define PLT_CACHE_LINE_SIZE_SHIFT 0L
+#define PLT_LATENCY_TIMER_SHIFT 8L
+#define PLT_HEADER_TYPE_SHIFT 16L
+#define PLT_BIST_SHIFT 24L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PCI base address registers.
+//
+//****************************************************************************
+#define PBAR_MEMORY_SPACE_INDICATOR 0x00000001L
+#define PBAR_LOCATION_TYPE_MASK 0x00000006L
+#define PBAR_NOT_PREFETCHABLE 0x00000008L
+#define PBAR_ADDRESS_MASK 0xFFFFFFF0L
+#define PBAR_LOCATION_TYPE_SHIFT 1L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PCI subsystem ID/subsystem
+// vendor ID register.
+//
+//****************************************************************************
+#define PSS_SUBSYSTEM_VENDOR_ID_MASK 0x0000FFFFL
+#define PSS_SUBSYSTEM_ID_MASK 0xFFFF0000L
+#define PSS_SUBSYSTEM_VENDOR_ID_SHIFT 0L
+#define PSS_SUBSYSTEM_ID_SHIFT 16L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PCI interrupt register.
+//
+//****************************************************************************
+#define PI_LINE_MASK 0x000000FFL
+#define PI_PIN_MASK 0x0000FF00L
+#define PI_MIN_GRANT_MASK 0x00FF0000L
+#define PI_MAX_LATENCY_MASK 0xFF000000L
+#define PI_LINE_SHIFT 0L
+#define PI_PIN_SHIFT 8L
+#define PI_MIN_GRANT_SHIFT 16L
+#define PI_MAX_LATENCY_SHIFT 24L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the host interrupt status
+// register.
+//
+//****************************************************************************
+#define HISR_HVOLMASK 0x00000003L
+#define HISR_VDNI 0x00000001L
+#define HISR_VUPI 0x00000002L
+#define HISR_GP1I 0x00000004L
+#define HISR_GP3I 0x00000008L
+#define HISR_GPSI 0x00000010L
+#define HISR_GPPI 0x00000020L
+#define HISR_DMAI 0x00040000L
+#define HISR_FIFOI 0x00100000L
+#define HISR_HVOL 0x00200000L
+#define HISR_MIDI 0x00400000L
+#define HISR_SBINT 0x00800000L
+#define HISR_INTENA 0x80000000L
+#define HISR_DMA_MASK 0x00000F00L
+#define HISR_FIFO_MASK 0x0000F000L
+#define HISR_DMA_SHIFT 8L
+#define HISR_FIFO_SHIFT 12L
+#define HISR_FIFO0 0x00001000L
+#define HISR_FIFO1 0x00002000L
+#define HISR_FIFO2 0x00004000L
+#define HISR_FIFO3 0x00008000L
+#define HISR_DMA0 0x00000100L
+#define HISR_DMA1 0x00000200L
+#define HISR_DMA2 0x00000400L
+#define HISR_DMA3 0x00000800L
+#define HISR_RESERVED 0x40000000L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the host interrupt control
+// register.
+//
+//****************************************************************************
+#define HICR_IEV 0x00000001L
+#define HICR_CHGM 0x00000002L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the DMA Mode Register n
+// (DMRn)
+//
+//****************************************************************************
+#define DMRn_TR_MASK 0x0000000CL
+#define DMRn_TR_SHIFT 2L
+#define DMRn_AUTO 0x00000010L
+#define DMRn_TR_READ 0x00000008L
+#define DMRn_TR_WRITE 0x00000004L
+#define DMRn_TYPE_MASK 0x000000C0L
+#define DMRn_TYPE_SHIFT 6L
+#define DMRn_SIZE8 0x00010000L
+#define DMRn_MONO 0x00020000L
+#define DMRn_BEND 0x00040000L
+#define DMRn_USIGN 0x00080000L
+#define DMRn_SIZE20 0x00100000L
+#define DMRn_SWAPC 0x00400000L
+#define DMRn_CBC 0x01000000L
+#define DMRn_TBC 0x02000000L
+#define DMRn_POLL 0x10000000L
+#define DMRn_DMA 0x20000000L
+#define DMRn_FSEL_MASK 0xC0000000L
+#define DMRn_FSEL_SHIFT 30L
+#define DMRn_FSEL0 0x00000000L
+#define DMRn_FSEL1 0x40000000L
+#define DMRn_FSEL2 0x80000000L
+#define DMRn_FSEL3 0xC0000000L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the DMA Command Register n
+// (DCRn)
+//
+//****************************************************************************
+#define DCRn_HTCIE 0x00020000L
+#define DCRn_TCIE 0x00010000L
+#define DCRn_MSK 0x00000001L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the FIFO Control
+// register n.(FCRn)
+//
+//****************************************************************************
+#define FCRn_OF_MASK 0x0000007FL
+#define FCRn_OF_SHIFT 0L
+#define FCRn_SZ_MASK 0x00007F00L
+#define FCRn_SZ_SHIFT 8L
+#define FCRn_LS_MASK 0x001F0000L
+#define FCRn_LS_SHIFT 16L
+#define FCRn_RS_MASK 0x1F000000L
+#define FCRn_RS_SHIFT 24L
+#define FCRn_FEN 0x80000000L
+#define FCRn_PSH 0x20000000L
+#define FCRn_DACZ 0x40000000L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the serial port Power Management
+// control register.(SPMC)
+//
+//****************************************************************************
+#define SPMC_RSTN 0x00000001L
+#define SPMC_ASYN 0x00000002L
+#define SPMC_WUP1 0x00000004L
+#define SPMC_WUP2 0x00000008L
+#define SPMC_ASDI2E 0x00000100L
+#define SPMC_ESSPD 0x00000200L
+#define SPMC_GISPEN 0x00004000L
+#define SPMC_GIPPEN 0x00008000L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the Configuration Load register.
+// (CFLR)
+//
+//****************************************************************************
+#define CFLR_CLOCK_SOURCE_MASK 0x00000003L
+#define CFLR_CLOCK_SOURCE_AC97 0x00000001L
+
+#define CFLR_CB0_MASK 0x000000FFL
+#define CFLR_CB1_MASK 0x0000FF00L
+#define CFLR_CB2_MASK 0x00FF0000L
+#define CFLR_CB3_MASK 0xFF000000L
+#define CFLR_CB0_SHIFT 0L
+#define CFLR_CB1_SHIFT 8L
+#define CFLR_CB2_SHIFT 16L
+#define CFLR_CB3_SHIFT 24L
+
+#define IOTCR_DMA0 0x00000000L
+#define IOTCR_DMA1 0x00000400L
+#define IOTCR_DMA2 0x00000800L
+#define IOTCR_DMA3 0x00000C00L
+#define IOTCR_CCLS 0x00000100L
+#define IOTCR_PCPCI 0x00000200L
+#define IOTCR_DDMA 0x00000300L
+
+#define SBWBS_WBB 0x00000080L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the SRC Slot Assignment Register
+// (SRCSA)
+//
+//****************************************************************************
+#define SRCSA_PLSS_MASK 0x0000001FL
+#define SRCSA_PLSS_SHIFT 0L
+#define SRCSA_PRSS_MASK 0x00001F00L
+#define SRCSA_PRSS_SHIFT 8L
+#define SRCSA_CLSS_MASK 0x001F0000L
+#define SRCSA_CLSS_SHIFT 16L
+#define SRCSA_CRSS_MASK 0x1F000000L
+#define SRCSA_CRSS_SHIFT 24L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the Sound System Power Management
+// register.(SSPM)
+//
+//****************************************************************************
+#define SSPM_FPDN 0x00000080L
+#define SSPM_MIXEN 0x00000040L
+#define SSPM_CSRCEN 0x00000020L
+#define SSPM_PSRCEN 0x00000010L
+#define SSPM_JSEN 0x00000008L
+#define SSPM_ACLEN 0x00000004L
+#define SSPM_FMEN 0x00000002L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the Sound System Control
+// Register. (SSCR)
+//


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 085'
echo 'File patch-2.4.0-test9 is continued in part 086'
echo "086" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part081

#!/bin/sh -x
# this is part 081 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 081; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

@@ -3347,7 +3882,7 @@
X ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) {
X int ret;
X
- DBG("ips_send_cmd");
+ METHOD_TRACE("ips_send_cmd", 1);
X
X ret = IPS_SUCCESS;
X
@@ -3576,7 +4111,7 @@
X memcpy(scb->dcdb.scsi_cdb, scb->scsi_cmd->cmnd, scb->scsi_cmd->cmd_len);
X }
X
- return (ips_issue(ha, scb));
+ return ((*ha->func.issue)(ha, scb));
X }
X
X /****************************************************************************/
@@ -3588,60 +4123,57 @@
X /* Check the status of commands to logical drives */


X /* */
X /****************************************************************************/

-static int
-ips_chkstatus(ips_ha_t *ha) {
+static void
+ips_chkstatus(ips_ha_t *ha, IPS_STATUS *pstatus) {
X ips_scb_t *scb;
- ips_stat_t *sp = &ha->sp;
+ ips_stat_t *sp;
X u8 basic_status;
X u8 ext_status;
- int command_id;
X int errcode;
- int ret;
-
- DBG("ips_chkstatus");
-
- command_id = ips_statupd(ha);
X
- if (command_id > (IPS_MAX_CMDS-1)) {
- printk(KERN_NOTICE "(%s%d) invalid command id received: %d\n",
- ips_name, ha->host_num, command_id);
+ METHOD_TRACE("ips_chkstatus", 1);
X
- return (-1);
- }
+ scb = &ha->scbs[pstatus->fields.command_id];
+ scb->basic_status = basic_status = pstatus->fields.basic_status & IPS_BASIC_STATUS_MASK;
+ scb->extended_status = ext_status = pstatus->fields.extended_status;
X
- scb = &ha->scbs[command_id];
- sp->scb_addr = (u32) scb;


+ sp = &ha->sp;

X sp->residue_len = 0;
- scb->basic_status = basic_status = ha->adapt->p_status_tail->basic_status & IPS_BASIC_STATUS_MASK;
- scb->extended_status = ext_status = ha->adapt->p_status_tail->extended_status;
+ sp->scb_addr = (u32) scb;
X
X /* Remove the item from the active queue */
X ips_removeq_scb(&ha->scb_activelist, scb);
X
X if (!scb->scsi_cmd)
X /* internal commands are handled in do_ipsintr */
- return (0);
+ return ;
+
+ DEBUG_VAR(2, "(%s%d) ips_chkstatus: cmd 0x%X id %d (%d %d %d)",


+ ips_name,
+ ha->host_num,

+ scb->cdb[0],
+ scb->cmd.basic_io.command_id,
+ scb->bus,
+ scb->target_id,
+ scb->lun);
X
X #ifndef NO_IPS_CMDLINE
X if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd)))
X /* passthru - just returns the raw result */
- return (0);
+ return ;
X #endif
X
X errcode = DID_OK;
- ret = 0;
X
X if (((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_SUCCESS) ||
X ((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_RECOVERED_ERROR)) {
X
X if (scb->bus == 0) {
-#if IPS_DEBUG >= 1
X if ((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_RECOVERED_ERROR) {
- printk(KERN_NOTICE "(%s%d) Recovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x\n",
- ips_name, ha->host_num,
- scb->cmd.basic_io.op_code, basic_status, ext_status);
+ DEBUG_VAR(1, "(%s%d) Recovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x",
+ ips_name, ha->host_num,
+ scb->cmd.basic_io.op_code, basic_status, ext_status);
X }
-#endif
X
X switch (scb->scsi_cmd->cmnd[0]) {
X case ALLOW_MEDIUM_REMOVAL:
@@ -3650,7 +4182,6 @@
X case WRITE_FILEMARKS:
X case SPACE:
X errcode = DID_ERROR;
- ret = 1;
X break;
X
X case START_STOP:
@@ -3659,7 +4190,6 @@
X case TEST_UNIT_READY:
X if (!ips_online(ha, scb)) {
X errcode = DID_TIME_OUT;
- ret = 1;
X }
X break;
X
@@ -3668,7 +4198,6 @@
X ips_inquiry(ha, scb);
X } else {
X errcode = DID_TIME_OUT;
- ret = 1;
X }
X break;
X
@@ -3687,7 +4216,6 @@
X case MODE_SENSE:
X if (!ips_online(ha, scb) || !ips_msense(ha, scb)) {
X errcode = DID_ERROR;
- ret = 1;
X }
X break;
X
@@ -3696,7 +4224,6 @@
X ips_rdcap(ha, scb);
X else {
X errcode = DID_TIME_OUT;
- ret = 1;
X }
X break;
X
@@ -3706,7 +4233,6 @@
X
X case FORMAT_UNIT:
X errcode = DID_ERROR;
- ret = 1;
X break;
X
X case SEEK_10:
@@ -3718,7 +4244,6 @@
X
X default:
X errcode = DID_ERROR;
- ret = 1;


X } /* end switch */
X

X scb->scsi_cmd->result = errcode << 16;
@@ -3728,23 +4253,17 @@


X ((((char *) scb->scsi_cmd->buffer)[0] & 0x1f) == TYPE_DISK)) {
X

X scb->scsi_cmd->result = DID_TIME_OUT << 16;
-
- ret = 1;
X }
X } /* else */
X } else { /* recovered error / success */
-#if IPS_DEBUG >= 1
X if (scb->bus == 0) {
- printk(KERN_NOTICE "(%s%d) Unrecovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x\n",
- ips_name, ha->host_num,
- scb->cmd.basic_io.op_code, basic_status, ext_status);
+ DEBUG_VAR(1, "(%s%d) Unrecovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x",
+ ips_name, ha->host_num,
+ scb->cmd.basic_io.op_code, basic_status, ext_status);
X }
-#endif
X
- ret = ips_map_status(scb, sp);
+ ips_map_status(ha, scb, sp);
X } /* else */
-
- return (ret);
X }
X
X /****************************************************************************/
@@ -3758,7 +4277,7 @@


X /****************************************************************************/
X static int

X ips_online(ips_ha_t *ha, ips_scb_t *scb) {
- DBG("ips_online");
+ METHOD_TRACE("ips_online", 1);
X
X if (scb->target_id >= IPS_MAX_LD)
X return (0);
@@ -3792,7 +4311,7 @@
X ips_inquiry(ips_ha_t *ha, ips_scb_t *scb) {
X IPS_INQ_DATA inq;
X
- DBG("ips_inquiry");
+ METHOD_TRACE("ips_inquiry", 1);
X
X memset(&inq, 0, sizeof(IPS_INQ_DATA));
X
@@ -3823,7 +4342,7 @@
X ips_rdcap(ips_ha_t *ha, ips_scb_t *scb) {
X IPS_CAPACITY *cap;
X
- DBG("ips_rdcap");
+ METHOD_TRACE("ips_rdcap", 1);
X
X if (scb->scsi_cmd->bufflen < 8)
X return (0);
@@ -3852,7 +4371,7 @@
X u32 cylinders;
X ips_mdata_t mdata;
X
- DBG("ips_msense");
+ METHOD_TRACE("ips_msense", 1);
X
X if (ha->enq->ulDriveSize[scb->target_id] > 0x400000 &&
X (ha->enq->ucMiscFlag & 0x8) == 0) {
@@ -3930,7 +4449,7 @@
X ips_reqsen(ips_ha_t *ha, ips_scb_t *scb) {
X char *sp;
X
- DBG("ips_reqsen");
+ METHOD_TRACE("ips_reqsen", 1);
X
X sp = (char *) scb->scsi_cmd->sense_buffer;
X memset(sp, 0, sizeof(scb->scsi_cmd->sense_buffer));
@@ -3956,7 +4475,7 @@
X ips_free(ips_ha_t *ha) {
X int i;
X
- DBG("ips_free");
+ METHOD_TRACE("ips_free", 1);
X
X if (ha) {
X if (ha->enq) {
@@ -4004,6 +4523,14 @@
X kfree(ha->scbs);
X ha->scbs = NULL;
X } /* end if */
+
+ /* free memory mapped (if applicable) */
+ if (ha->mem_ptr) {
+ iounmap(ha->ioremap_ptr);
+ ha->ioremap_ptr = NULL;
+ ha->mem_ptr = NULL;
+ ha->mem_addr = 0;
+ }
X }
X }
X
@@ -4021,10 +4548,10 @@
X ips_scb_t *scb_p;
X int i;
X
- DBG("ips_allocatescbs");
+ METHOD_TRACE("ips_allocatescbs", 1);
X
X /* Allocate memory for the CCBs */
- ha->scbs = (ips_scb_t *) kmalloc(ha->max_cmds * sizeof(ips_scb_t), GFP_KERNEL|GFP_DMA);
+ ha->scbs = (ips_scb_t *) kmalloc(ha->max_cmds * sizeof(ips_scb_t), GFP_ATOMIC|GFP_DMA);
X
X memset(ha->scbs, 0, ha->max_cmds * sizeof(ips_scb_t));
X
@@ -4032,7 +4559,7 @@
X scb_p = &ha->scbs[i];
X
X /* allocate S/G list */
- scb_p->sg_list = (IPS_SG_LIST *) kmalloc(sizeof(IPS_SG_LIST) * IPS_MAX_SG, GFP_KERNEL|GFP_DMA);
+ scb_p->sg_list = (IPS_SG_LIST *) kmalloc(sizeof(IPS_SG_LIST) * IPS_MAX_SG, GFP_ATOMIC|GFP_DMA);
X
X if (! scb_p->sg_list)
X return (0);
@@ -4061,7 +4588,7 @@
X ips_init_scb(ips_ha_t *ha, ips_scb_t *scb) {
X IPS_SG_LIST *sg_list;
X
- DBG("ips_init_scb");
+ METHOD_TRACE("ips_init_scb", 1);
X
X if (scb == NULL)
X return ;
@@ -4102,7 +4629,7 @@
X ips_scb_t *scb;
X u32 cpu_flags;
X
- DBG("ips_getscb");
+ METHOD_TRACE("ips_getscb", 1);
X
X IPS_SCB_LOCK(cpu_flags);
X if ((scb = ha->scb_freelist) == NULL) {
@@ -4136,7 +4663,7 @@
X ips_freescb(ips_ha_t *ha, ips_scb_t *scb) {
X u32 cpu_flags;
X
- DBG("ips_freescb");
+ METHOD_TRACE("ips_freescb", 1);
X
X /* check to make sure this is not our "special" scb */
X if (IPS_COMMAND_ID(ha, scb) < (ha->max_cmds - 1)) {
@@ -4149,7 +4676,7 @@


X
X /****************************************************************************/
X /* */

-/* Routine Name: ips_reset_adapter */
+/* Routine Name: ips_isinit_copperhead */


X /* */
X /* Routine Description: */
X /* */

@@ -4157,21 +4684,402 @@


X /* */
X /****************************************************************************/
X static int

-ips_reset_adapter(ips_ha_t *ha) {
- u8 Isr;
- u8 Cbsp;
- u8 PostByte[IPS_MAX_POST_BYTES];
+ips_isinit_copperhead(ips_ha_t *ha) {
+ u8 scpr;
+ u8 isr;
+
+ METHOD_TRACE("ips_isinit_copperhead", 1);
+
+ isr = inb(ha->io_addr + IPS_REG_HISR);
+ scpr = inb(ha->io_addr + IPS_REG_SCPR);
+
+ if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0))
+ return (0);
+ else
+ return (1);


+}
+
+/****************************************************************************/
+/* */

+/* Routine Name: ips_isinit_copperhead_memio */


+/* */
+/* Routine Description: */
+/* */

+/* Reset the controller */


+/* */
+/****************************************************************************/
+static int

+ips_isinit_copperhead_memio(ips_ha_t *ha) {
+ u8 isr;
+ u8 scpr;
+
+ METHOD_TRACE("ips_is_init_copperhead_memio", 1);
+
+ isr = readb(ha->mem_ptr + IPS_REG_HISR);
+ scpr = readb(ha->mem_ptr + IPS_REG_SCPR);
+
+ if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0))
+ return (0);
+ else
+ return (1);


+}
+
+/****************************************************************************/
+/* */

+/* Routine Name: ips_isinit_morpheus */


+/* */
+/* Routine Description: */
+/* */

+/* Reset the controller */


+/* */
+/****************************************************************************/
+static int

+ips_isinit_morpheus(ips_ha_t *ha) {
+ u32 post;
+ u32 bits;
+
+ METHOD_TRACE("ips_is_init_morpheus", 1);
+
+ post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
+ bits = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
+
+ if (post == 0)
+ return (0);
+ else if (bits & 0x3)
+ return (0);
+ else
+ return (1);


+}
+
+/****************************************************************************/
+/* */

+/* Routine Name: ips_enable_int_copperhead */


+/* */
+/* Routine Description: */

+/* Turn on interrupts */


+/* */
+/****************************************************************************/
+static void

+ips_enable_int_copperhead(ips_ha_t *ha) {
+ METHOD_TRACE("ips_enable_int_copperhead", 1);
+
+ outb(ha->io_addr + IPS_REG_HISR, IPS_BIT_EI);


+}
+
+/****************************************************************************/
+/* */

+/* Routine Name: ips_enable_int_copperhead_memio */


+/* */
+/* Routine Description: */

+/* Turn on interrupts */


+/* */
+/****************************************************************************/
+static void

+ips_enable_int_copperhead_memio(ips_ha_t *ha) {
+ METHOD_TRACE("ips_enable_int_copperhead_memio", 1);
+
+ writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR);


+}
+
+/****************************************************************************/
+/* */

+/* Routine Name: ips_enable_int_morpheus */


+/* */
+/* Routine Description: */

+/* Turn on interrupts */


+/* */
+/****************************************************************************/
+static void

+ips_enable_int_morpheus(ips_ha_t *ha) {
+ u32 Oimr;
+
+ METHOD_TRACE("ips_enable_int_morpheus", 1);
+
+ Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
+ Oimr &= ~0x08;
+ writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);


+}
+
+/****************************************************************************/
+/* */

+/* Routine Name: ips_init_copperhead */


+/* */
+/* Routine Description: */
+/* */

+/* Initialize a copperhead controller */


+/* */
+/****************************************************************************/
+static int

+ips_init_copperhead(ips_ha_t *ha) {
+ u8 Isr;
+ u8 Cbsp;
+ u8 PostByte[IPS_MAX_POST_BYTES];
+ u8 ConfigByte[IPS_MAX_CONFIG_BYTES];


+ int i, j;
+

+ METHOD_TRACE("ips_init_copperhead", 1);
+
+ for (i = 0; i < IPS_MAX_POST_BYTES; i++) {
+ for (j = 0; j < 45; j++) {
+ Isr = inb(ha->io_addr + IPS_REG_HISR);
+ if (Isr & IPS_BIT_GHI)
+ break;
+
+ MDELAY(IPS_ONE_SEC);
+ }
+
+ if (j >= 45)
+ /* error occured */
+ return (0);
+
+ PostByte[i] = inb(ha->io_addr + IPS_REG_ISPR);
+ outb(Isr, ha->io_addr + IPS_REG_HISR);
+ }
+
+ if (PostByte[0] < IPS_GOOD_POST_STATUS) {
+ printk(KERN_WARNING "(%s%d) reset controller fails (post status %x %x).\n",
+ ips_name, ha->host_num, PostByte[0], PostByte[1]);


+
+ return (0);
+ }

+
+ for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) {
+ for (j = 0; j < 240; j++) {
+ Isr = inb(ha->io_addr + IPS_REG_HISR);
+ if (Isr & IPS_BIT_GHI)
+ break;
+
+ MDELAY(IPS_ONE_SEC); /* 100 msec */
+ }
+
+ if (j >= 240)
+ /* error occured */
+ return (0);
+
+ ConfigByte[i] = inb(ha->io_addr + IPS_REG_ISPR);
+ outb(Isr, ha->io_addr + IPS_REG_HISR);
+ }
+
+ for (i = 0; i < 240; i++) {
+ Cbsp = inb(ha->io_addr + IPS_REG_CBSP);
+
+ if ((Cbsp & IPS_BIT_OP) == 0)
+ break;
+
+ MDELAY(IPS_ONE_SEC);
+ }
+
+ if (i >= 240)
+ /* reset failed */
+ return (0);
+
+ /* setup CCCR */
+ outw(0x1010, ha->io_addr + IPS_REG_CCCR);
+
+ /* Enable busmastering */
+ outb(IPS_BIT_EBM, ha->io_addr + IPS_REG_SCPR);
+
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ /* fix for anaconda64 */
+ outl(0, ha->io_addr + IPS_REG_NDAE);
+
+ /* Enable interrupts */
+ outb(IPS_BIT_EI, ha->io_addr + IPS_REG_HISR);
+
+ return (1);


+}
+
+/****************************************************************************/
+/* */

+/* Routine Name: ips_init_copperhead_memio */


+/* */
+/* Routine Description: */
+/* */

+/* Initialize a copperhead controller with memory mapped I/O */


+/* */
+/****************************************************************************/
+static int

+ips_init_copperhead_memio(ips_ha_t *ha) {
+ u8 Isr;
+ u8 Cbsp;
+ u8 PostByte[IPS_MAX_POST_BYTES];
X u8 ConfigByte[IPS_MAX_CONFIG_BYTES];
X int i, j;
+
+ METHOD_TRACE("ips_init_copperhead_memio", 1);
+
+ for (i = 0; i < IPS_MAX_POST_BYTES; i++) {
+ for (j = 0; j < 45; j++) {
+ Isr = readb(ha->mem_ptr + IPS_REG_HISR);
+ if (Isr & IPS_BIT_GHI)
+ break;
+
+ MDELAY(IPS_ONE_SEC);
+ }
+
+ if (j >= 45)
+ /* error occured */
+ return (0);
+
+ PostByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR);
+ writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
+ }
+
+ if (PostByte[0] < IPS_GOOD_POST_STATUS) {
+ printk(KERN_WARNING "(%s%d) reset controller fails (post status %x %x).\n",
+ ips_name, ha->host_num, PostByte[0], PostByte[1]);


+
+ return (0);
+ }

+
+ for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) {
+ for (j = 0; j < 240; j++) {
+ Isr = readb(ha->mem_ptr + IPS_REG_HISR);
+ if (Isr & IPS_BIT_GHI)
+ break;
+
+ MDELAY(IPS_ONE_SEC); /* 100 msec */
+ }
+
+ if (j >= 240)
+ /* error occured */
+ return (0);
+
+ ConfigByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR);
+ writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
+ }
+
+ for (i = 0; i < 240; i++) {
+ Cbsp = readb(ha->mem_ptr + IPS_REG_CBSP);
+
+ if ((Cbsp & IPS_BIT_OP) == 0)
+ break;
+
+ MDELAY(IPS_ONE_SEC);
+ }
+
+ if (i >= 240)
+ /* error occured */
+ return (0);
+
+ /* setup CCCR */
+ writel(0x1010, ha->mem_ptr + IPS_REG_CCCR);
+
+ /* Enable busmastering */
+ writeb(IPS_BIT_EBM, ha->mem_ptr + IPS_REG_SCPR);
+
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ /* fix for anaconda64 */
+ writel(0, ha->mem_ptr + IPS_REG_NDAE);
+
+ /* Enable interrupts */
+ writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR);
+
+ /* if we get here then everything went OK */
+ return (1);


+}
+
+/****************************************************************************/
+/* */

+/* Routine Name: ips_init_morpheus */


+/* */
+/* Routine Description: */
+/* */

+/* Initialize a morpheus controller */


+/* */
+/****************************************************************************/
+static int

+ips_init_morpheus(ips_ha_t *ha) {
+ u32 Post;
+ u32 Config;
+ u32 Isr;
+ u32 Oimr;
+ int i;
+
+ METHOD_TRACE("ips_init_morpheus", 1);
+
+ /* Wait up to 45 secs for Post */
+ for (i = 0; i < 45; i++) {
+ Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
+
+ if (Isr & IPS_BIT_I960_MSG0I)
+ break;
+
+ MDELAY(IPS_ONE_SEC);
+ }
+
+ if (i >= 45) {
+ /* error occured */
+ printk(KERN_WARNING "(%s%d) timeout waiting for post.\n",


+ ips_name, ha->host_num);
+

+ return (0);
+ }
+
+ Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
+
+ /* Clear the interrupt bit */
+ Isr = (u32) IPS_BIT_I960_MSG0I;
+ writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
+
+ if (Post < (IPS_GOOD_POST_STATUS << 8)) {
+ printk(KERN_WARNING "(%s%d) reset controller fails (post status %x).\n",
+ ips_name, ha->host_num, Post);


+
+ return (0);
+ }

+
+ /* Wait up to 240 secs for config bytes */
+ for (i = 0; i < 240; i++) {
+ Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
+
+ if (Isr & IPS_BIT_I960_MSG1I)
+ break;
+
+ MDELAY(IPS_ONE_SEC); /* 100 msec */
+ }
+
+ if (i >= 240) {
+ /* error occured */
+ printk(KERN_WARNING "(%s%d) timeout waiting for config.\n",


+ ips_name, ha->host_num);
+

+ return (0);
+ }
+
+ Config = readl(ha->mem_ptr + IPS_REG_I960_MSG1);
+
+ /* Clear interrupt bit */
+ Isr = (u32) IPS_BIT_I960_MSG1I;
+ writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
+
+ /* Turn on the interrupts */
+ Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
+ Oimr &= ~0x8;
+ writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
+
+ /* if we get here then everything went OK */
+ return (1);


+}
+
+/****************************************************************************/
+/* */

+/* Routine Name: ips_reset_copperhead */


+/* */
+/* Routine Description: */
+/* */

+/* Reset the controller */


+/* */
+/****************************************************************************/
+static int

+ips_reset_copperhead(ips_ha_t *ha) {
X int reset_counter;
X u32 cpu_flags;
X
- DBG("ips_reset_adapter");
+ METHOD_TRACE("ips_reset_copperhead", 1);


X
-#if IPS_DEBUG >= 1

- printk(KERN_WARNING "ips_reset_adapter: io addr: %x, irq: %d\n",
- ha->io_addr, ha->irq);
-#endif
+ DEBUG_VAR(1, "(%s%d) ips_reset_copperhead: io addr: %x, irq: %d",
+ ips_name, ha->host_num, ha->io_addr, ha->irq);
X
X IPS_HA_LOCK(cpu_flags);
X
@@ -4185,109 +5093,107 @@
X outb(0, ha->io_addr + IPS_REG_SCPR);
X MDELAY(IPS_ONE_SEC);
X
- for (i = 0; i < IPS_MAX_POST_BYTES; i++) {
- for (j = 0; j < 45; j++) {
- Isr = inb(ha->io_addr + IPS_REG_HISR);
- if (Isr & IPS_BIT_GHI)
- break;
-
- MDELAY(IPS_ONE_SEC);
- }
-
- if (j >= 45) {
- /* error occured */
- if (reset_counter < 2)
- continue;
- else {
- /* reset failed */
- IPS_HA_UNLOCK(cpu_flags);


-
- return (0);
- }
- }

+ if ((*ha->func.init)(ha))
+ break;
+ else if (reset_counter >= 2) {
+ IPS_HA_UNLOCK(cpu_flags);
X
- PostByte[i] = inb(ha->io_addr + IPS_REG_ISPR);
- outb(Isr, ha->io_addr + IPS_REG_HISR);
+ return (0);
X }
+ }
X
- if (PostByte[0] < IPS_GOOD_POST_STATUS) {
- printk("(%s%d) reset controller fails (post status %x %x).\n",
- ips_name, ha->host_num, PostByte[0], PostByte[1]);
+ IPS_HA_UNLOCK(cpu_flags);
X
- IPS_HA_UNLOCK(cpu_flags);
+ return (1);
+}


X
- return (0);
- }

+/****************************************************************************/
+/* */
+/* Routine Name: ips_reset_copperhead_memio */


+/* */
+/* Routine Description: */
+/* */

+/* Reset the controller */


+/* */
+/****************************************************************************/
+static int

+ips_reset_copperhead_memio(ips_ha_t *ha) {
+ int reset_counter;
+ u32 cpu_flags;
X
- for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) {
- for (j = 0; j < 240; j++) {
- Isr = inb(ha->io_addr + IPS_REG_HISR);
- if (Isr & IPS_BIT_GHI)
- break;
+ METHOD_TRACE("ips_reset_copperhead_memio", 1);
X
- MDELAY(IPS_ONE_SEC); /* 100 msec */
- }
+ DEBUG_VAR(1, "(%s%d) ips_reset_copperhead_memio: mem addr: %x, irq: %d",
+ ips_name, ha->host_num, ha->mem_addr, ha->irq);
X
- if (j >= 240) {
- /* error occured */
- if (reset_counter < 2)
- continue;
- else {
- /* reset failed */
- IPS_HA_UNLOCK(cpu_flags);
+ IPS_HA_LOCK(cpu_flags);


X
- return (0);
- }

- }
+ reset_counter = 0;
X
- ConfigByte[i] = inb(ha->io_addr + IPS_REG_ISPR);
- outb(Isr, ha->io_addr + IPS_REG_HISR);
- }
+ while (reset_counter < 2) {
+ reset_counter++;
X
- if (ConfigByte[0] == 0 && ConfigByte[1] == 2) {
- printk("(%s%d) reset controller fails (status %x %x).\n",
- ips_name, ha->host_num, ConfigByte[0], ConfigByte[1]);
+ writeb(IPS_BIT_RST, ha->mem_ptr + IPS_REG_SCPR);
+ MDELAY(IPS_ONE_SEC);
+ writeb(0, ha->mem_ptr + IPS_REG_SCPR);
+ MDELAY(IPS_ONE_SEC);
X
+ if ((*ha->func.init)(ha))
+ break;
+ else if (reset_counter >= 2) {
X IPS_HA_UNLOCK(cpu_flags);


X
X return (0);
X }

+ }
X
- for (i = 0; i < 240; i++) {
- Cbsp = inb(ha->io_addr + IPS_REG_CBSP);
+ IPS_HA_UNLOCK(cpu_flags);
X
- if ((Cbsp & IPS_BIT_OP) == 0)
- break;
+ return (1);
+}
X
- MDELAY(IPS_ONE_SEC);
- }
+/****************************************************************************/
+/* */
+/* Routine Name: ips_reset_morpheus */


+/* */
+/* Routine Description: */
+/* */

+/* Reset the controller */


+/* */
+/****************************************************************************/
+static int

+ips_reset_morpheus(ips_ha_t *ha) {
+ int reset_counter;
+ u8 junk;
+ u32 cpu_flags;
X
- if (i >= 240) {
- /* error occured */
- if (reset_counter < 2)
- continue;
- else {
- /* reset failed */
- IPS_HA_UNLOCK(cpu_flags);
+ METHOD_TRACE("ips_reset_morpheus", 1);


X
- return (0);
- }

- }
+ DEBUG_VAR(1, "(%s%d) ips_reset_morpheus: mem addr: %x, irq: %d",
+ ips_name, ha->host_num, ha->mem_addr, ha->irq);
X
- /* setup CCCR */
- outw(0x1010, ha->io_addr + IPS_REG_CCCR);
+ IPS_HA_LOCK(cpu_flags);
X
- /* Enable busmastering */
- outb(IPS_BIT_EBM, ha->io_addr + IPS_REG_SCPR);
+ reset_counter = 0;
X
- /* setup status queues */
- ips_statinit(ha);
+ while (reset_counter < 2) {
+ reset_counter++;
X
- /* Enable interrupts */
- outb(IPS_BIT_EI, ha->io_addr + IPS_REG_HISR);
+ writel(0x80000000, ha->mem_ptr + IPS_REG_I960_IDR);
X
- /* if we get here then everything went OK */
- break;
+ /* Delay for 300 msec */
+ MDELAY(300 * IPS_ONE_MSEC);
+
+ /* Do a PCI config read to wait for adapter */
+ pci_read_config_byte(ha->pcidev, 4, &junk);
+
+ if ((*ha->func.init)(ha))
+ break;
+ else if (reset_counter >= 2) {
+ IPS_HA_UNLOCK(cpu_flags);
+
+ return (0);
+ }
X }
X
X IPS_HA_UNLOCK(cpu_flags);
@@ -4308,7 +5214,7 @@
X ips_statinit(ips_ha_t *ha) {
X u32 phys_status_start;
X
- DBG("ips_statinit");
+ METHOD_TRACE("ips_statinit", 1);
X
X ha->adapt->p_status_start = ha->adapt->status;
X ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS;
@@ -4326,18 +5232,45 @@


X
X /****************************************************************************/
X /* */

-/* Routine Name: ips_statupd */
+/* Routine Name: ips_statinit_memio */


X /* */
X /* Routine Description: */
X /* */

-/* Remove an element from the status queue */
+/* Initialize the status queues on the controller */


X /* */
X /****************************************************************************/

-static int
-ips_statupd(ips_ha_t *ha) {
- int command_id;
+static void
+ips_statinit_memio(ips_ha_t *ha) {
+ u32 phys_status_start;
+
+ METHOD_TRACE("ips_statinit_memio", 1);
+
+ ha->adapt->p_status_start = ha->adapt->status;
+ ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS;
+ ha->adapt->p_status_tail = ha->adapt->status;
+
+ phys_status_start = VIRT_TO_BUS(ha->adapt->status);
+ writel(phys_status_start, ha->mem_ptr + IPS_REG_SQSR);
+ writel(phys_status_start + IPS_STATUS_Q_SIZE, ha->mem_ptr + IPS_REG_SQER);
+ writel(phys_status_start + IPS_STATUS_SIZE, ha->mem_ptr + IPS_REG_SQHR);
+ writel(phys_status_start, ha->mem_ptr + IPS_REG_SQTR);
+
+ ha->adapt->hw_status_start = phys_status_start;
+ ha->adapt->hw_status_tail = phys_status_start;
+}
X
- DBG("ips_statupd");
+/****************************************************************************/
+/* */
+/* Routine Name: ips_statupd_copperhead */


+/* */
+/* Routine Description: */
+/* */

+/* Remove an element from the status queue */
+/* */
+/****************************************************************************/
+static u32
+ips_statupd_copperhead(ips_ha_t *ha) {
+ METHOD_TRACE("ips_statupd_copperhead", 1);
X
X if (ha->adapt->p_status_tail != ha->adapt->p_status_end) {
X ha->adapt->p_status_tail++;
@@ -4349,47 +5282,87 @@
X
X outl(ha->adapt->hw_status_tail, ha->io_addr + IPS_REG_SQTR);
X
- command_id = ha->adapt->p_status_tail->command_id;
+ return (ha->adapt->p_status_tail->value);


+}
+
+/****************************************************************************/
+/* */

+/* Routine Name: ips_statupd_copperhead_memio */


+/* */
+/* Routine Description: */
+/* */

+/* Remove an element from the status queue */
+/* */
+/****************************************************************************/
+static u32
+ips_statupd_copperhead_memio(ips_ha_t *ha) {
+ METHOD_TRACE("ips_statupd_copperhead_memio", 1);
+
+ if (ha->adapt->p_status_tail != ha->adapt->p_status_end) {
+ ha->adapt->p_status_tail++;
+ ha->adapt->hw_status_tail += sizeof(IPS_STATUS);
+ } else {
+ ha->adapt->p_status_tail = ha->adapt->p_status_start;
+ ha->adapt->hw_status_tail = ha->adapt->hw_status_start;
+ }
X
- return (command_id);
+ writel(ha->adapt->hw_status_tail, ha->mem_ptr + IPS_REG_SQTR);
+
+ return (ha->adapt->p_status_tail->value);


X }
X
X /****************************************************************************/
X /* */

-/* Routine Name: ips_issue */
+/* Routine Name: ips_statupd_morpheus */


X /* */
X /* Routine Description: */
X /* */

-/* Send a command down to the controller */
+/* Remove an element from the status queue */
X /* */
-/* ASSUMED to be called from within a lock */
+/****************************************************************************/
+static u32
+ips_statupd_morpheus(ips_ha_t *ha) {
+ u32 val;
+
+ METHOD_TRACE("ips_statupd_morpheus", 1);
+
+ val = readl(ha->mem_ptr + IPS_REG_I2O_OUTMSGQ);
+
+ return (val);


+}
+
+/****************************************************************************/
+/* */

+/* Routine Name: ips_issue_copperhead */


+/* */
+/* Routine Description: */
+/* */

+/* Send a command down to the controller */


X /* */
X /****************************************************************************/

X static int
-ips_issue(ips_ha_t *ha, ips_scb_t *scb) {
+ips_issue_copperhead(ips_ha_t *ha, ips_scb_t *scb) {
X u32 TimeOut;
X u16 val;
X u32 cpu_flags;
X
- DBG("ips_issue");
+ METHOD_TRACE("ips_issue_copperhead", 1);


X
-#if IPS_DEBUG >= 10

- if (scb->scsi_cmd)
- printk(KERN_NOTICE "%s: ips_issue: cmd 0x%X id %d (%d %d %d)\n",
- ips_name,
- scb->cdb[0],
- scb->cmd.basic_io.command_id,
- scb->bus,
- scb->target_id,
- scb->lun);
- else
- printk(KERN_NOTICE "%s: ips_issue: logical cmd id %d\n",
- ips_name,
- scb->cmd.basic_io.command_id);
-#if IPS_DEBUG >= 11
- MDELAY(IPS_ONE_SEC);
-#endif
-#endif
+ if (scb->scsi_cmd) {
+ DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",


+ ips_name,
+ ha->host_num,

+ scb->cdb[0],
+ scb->cmd.basic_io.command_id,
+ scb->bus,
+ scb->target_id,
+ scb->lun);
+ } else {
+ DEBUG_VAR(2, KERN_NOTICE "(%s%d) ips_issue: logical cmd id %d",


+ ips_name,
+ ha->host_num,

+ scb->cmd.basic_io.command_id);
+ }
X
X IPS_HA_LOCK(cpu_flags);
X
@@ -4416,14 +5389,189 @@
X outl(scb->scb_busaddr, ha->io_addr + IPS_REG_CCSAR);
X outw(IPS_BIT_START_CMD, ha->io_addr + IPS_REG_CCCR);
X
- IPS_HA_UNLOCK(cpu_flags);
+ IPS_HA_UNLOCK(cpu_flags);
+
+ return (IPS_SUCCESS);


+}
+
+/****************************************************************************/
+/* */

+/* Routine Name: ips_issue_copperhead_memio */


+/* */
+/* Routine Description: */
+/* */

+/* Send a command down to the controller */


+/* */
+/****************************************************************************/
+static int

+ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) {
+ u32 TimeOut;
+ u32 val;
+ u32 cpu_flags;
+
+ METHOD_TRACE("ips_issue_copperhead_memio", 1);
+
+ if (scb->scsi_cmd) {
+ DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",


+ ips_name,
+ ha->host_num,

+ scb->cdb[0],
+ scb->cmd.basic_io.command_id,
+ scb->bus,
+ scb->target_id,
+ scb->lun);
+ } else {
+ DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d",


+ ips_name,
+ ha->host_num,

+ scb->cmd.basic_io.command_id);
+ }
+
+ IPS_HA_LOCK(cpu_flags);
+
+ TimeOut = 0;
+
+ while ((val = readl(ha->mem_ptr + IPS_REG_CCCR)) & IPS_BIT_SEM) {
+ UDELAY(1000);
+
+ if (++TimeOut >= IPS_SEM_TIMEOUT) {
+ if (!(val & IPS_BIT_START_STOP))
+ break;
+
+ printk(KERN_WARNING "(%s%d) ips_issue val [0x%x].\n",
+ ips_name, ha->host_num, val);
+ printk(KERN_WARNING "(%s%d) ips_issue semaphore chk timeout.\n",


+ ips_name, ha->host_num);
+

+ IPS_HA_UNLOCK(cpu_flags);
+
+ return (IPS_FAILURE);


+ } /* end if */

+ } /* end while */
+

+ writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_CCSAR);
+ writel(IPS_BIT_START_CMD, ha->mem_ptr + IPS_REG_CCCR);
+
+ IPS_HA_UNLOCK(cpu_flags);
+
+ return (IPS_SUCCESS);


+}
+
+/****************************************************************************/
+/* */

+/* Routine Name: ips_issue_i2o */


+/* */
+/* Routine Description: */
+/* */

+/* Send a command down to the controller */


+/* */
+/****************************************************************************/
+static int

+ips_issue_i2o(ips_ha_t *ha, ips_scb_t *scb) {
+ u32 cpu_flags;
+
+ METHOD_TRACE("ips_issue_i2o", 1);
+
+ if (scb->scsi_cmd) {
+ DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",


+ ips_name,
+ ha->host_num,

+ scb->cdb[0],
+ scb->cmd.basic_io.command_id,
+ scb->bus,
+ scb->target_id,
+ scb->lun);
+ } else {
+ DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d",


+ ips_name,
+ ha->host_num,

+ scb->cmd.basic_io.command_id);
+ }
+
+ IPS_HA_LOCK(cpu_flags);
+
+ outl(scb->scb_busaddr, ha->io_addr + IPS_REG_I2O_INMSGQ);
+
+ IPS_HA_UNLOCK(cpu_flags);
+
+ return (IPS_SUCCESS);


+}
+
+/****************************************************************************/
+/* */

+/* Routine Name: ips_issue_i2o_memio */


+/* */
+/* Routine Description: */
+/* */

+/* Send a command down to the controller */


+/* */
+/****************************************************************************/
+static int

+ips_issue_i2o_memio(ips_ha_t *ha, ips_scb_t *scb) {
+ u32 cpu_flags;
+
+ METHOD_TRACE("ips_issue_i2o_memio", 1);
+
+ if (scb->scsi_cmd) {
+ DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",


+ ips_name,
+ ha->host_num,

+ scb->cdb[0],
+ scb->cmd.basic_io.command_id,
+ scb->bus,
+ scb->target_id,
+ scb->lun);
+ } else {
+ DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d",


+ ips_name,
+ ha->host_num,

+ scb->cmd.basic_io.command_id);
+ }
+
+ IPS_HA_LOCK(cpu_flags);
+
+ writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_I2O_INMSGQ);
+
+ IPS_HA_UNLOCK(cpu_flags);
+
+ return (IPS_SUCCESS);


+}
+
+/****************************************************************************/
+/* */

+/* Routine Name: ips_isintr_copperhead */


+/* */
+/* Routine Description: */
+/* */

+/* Test to see if an interrupt is for us */


+/* */
+/****************************************************************************/
+static int

+ips_isintr_copperhead(ips_ha_t *ha) {
+ u8 Isr;
+
+ METHOD_TRACE("ips_isintr_copperhead", 2);
+
+ Isr = inb(ha->io_addr + IPS_REG_HISR);
+
+ if (Isr == 0xFF)
+ /* ?!?! Nothing really there */
+ return (0);
+
+ if (Isr & IPS_BIT_SCE)
+ return (1);
+ else if (Isr & (IPS_BIT_SQO | IPS_BIT_GHI)) {
+ /* status queue overflow or GHI */
+ /* just clear the interrupt */
+ outb(Isr, ha->io_addr + IPS_REG_HISR);
+ }
X
- return (IPS_SUCCESS);


+ return (0);
X }
X

X /****************************************************************************/
X /* */

-/* Routine Name: ips_isintr */
+/* Routine Name: ips_isintr_copperhead_memio */


X /* */
X /* Routine Description: */
X /* */

@@ -4431,12 +5579,12 @@


X /* */
X /****************************************************************************/
X static int

-ips_isintr(ips_ha_t *ha) {
+ips_isintr_copperhead_memio(ips_ha_t *ha) {
X u8 Isr;
X
- DBG("ips_isintr");
+ METHOD_TRACE("ips_isintr_memio", 2);
X
- Isr = inb(ha->io_addr + IPS_REG_HISR);
+ Isr = readb(ha->mem_ptr + IPS_REG_HISR);
X
X if (Isr == 0xFF)
X /* ?!?! Nothing really there */
@@ -4447,7 +5595,7 @@
X else if (Isr & (IPS_BIT_SQO | IPS_BIT_GHI)) {
X /* status queue overflow or GHI */
X /* just clear the interrupt */
- outb(Isr, ha->io_addr + IPS_REG_HISR);
+ writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
X }
X
X return (0);
@@ -4455,6 +5603,29 @@


X
X /****************************************************************************/
X /* */

+/* Routine Name: ips_isintr_morpheus */


+/* */
+/* Routine Description: */
+/* */

+/* Test to see if an interrupt is for us */


+/* */
+/****************************************************************************/
+static int

+ips_isintr_morpheus(ips_ha_t *ha) {
+ u32 Isr;
+
+ METHOD_TRACE("ips_isintr_morpheus", 2);
+
+ Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
+
+ if (Isr & IPS_BIT_I2O_OPQI)
+ return (1);
+ else
+ return (0);


+}
+
+/****************************************************************************/
+/* */

X /* Routine Name: ips_wait */


X /* */
X /* Routine Description: */

@@ -4467,7 +5638,7 @@
X int ret;
X u8 done;
X
- DBG("ips_wait");
+ METHOD_TRACE("ips_wait", 1);
X
X ret = IPS_FAILURE;
X done = FALSE;
@@ -4502,7 +5673,7 @@
X while (test_and_set_bit(IPS_IN_INTR, &ha->flags))
X UDELAY(1000);


X
- ips_intr(ha);
+ (*ha->func.intr)(ha);
X
X clear_bit(IPS_IN_INTR, &ha->flags);

X } else if (intr == IPS_INTR_HAL) {
@@ -4528,7 +5699,7 @@
X while (test_and_set_bit(IPS_IN_INTR, &ha->flags))
X UDELAY(1000);


X
- ips_intr(ha);
+ (*ha->func.intr)(ha);
X
X clear_bit(IPS_IN_INTR, &ha->flags);
X

@@ -4553,7 +5724,7 @@


X /****************************************************************************/
X static int

X ips_write_driver_status(ips_ha_t *ha, int intr) {
- DBG("ips_write_driver_status");
+ METHOD_TRACE("ips_write_driver_status", 1);
X
X if (!ips_readwrite_page5(ha, FALSE, intr)) {
X printk(KERN_WARNING "(%s%d) unable to read NVRAM page 5.\n",
@@ -4565,21 +5736,18 @@
X /* check to make sure the page has a valid */
X /* signature */
X if (ha->nvram->signature != IPS_NVRAM_P5_SIG) {
-#if IPS_DEBUG >= 1
- printk("(%s%d) NVRAM page 5 has an invalid signature: %X.\n",
- ips_name, ha->host_num, ha->nvram->signature);
-#endif
+ DEBUG_VAR(1, "(%s%d) NVRAM page 5 has an invalid signature: %X.",
+ ips_name, ha->host_num, ha->nvram->signature);
+


X return (1);
X }
X

-#if IPS_DEBUG >= 2
- printk("(%s%d) Ad Type: %d, Ad Slot: %d, BIOS: %c%c%c%c %c%c%c%c.\n",
- ips_name, ha->host_num, ha->nvram->adapter_type, ha->nvram->adapter_slot,
- ha->nvram->bios_high[0], ha->nvram->bios_high[1],
- ha->nvram->bios_high[2], ha->nvram->bios_high[3],
- ha->nvram->bios_low[0], ha->nvram->bios_low[1],
- ha->nvram->bios_low[2], ha->nvram->bios_low[3]);
-#endif
+ DEBUG_VAR(2, "(%s%d) Ad Type: %d, Ad Slot: %d, BIOS: %c%c%c%c %c%c%c%c.",
+ ips_name, ha->host_num, ha->nvram->adapter_type, ha->nvram->adapter_slot,
+ ha->nvram->bios_high[0], ha->nvram->bios_high[1],
+ ha->nvram->bios_high[2], ha->nvram->bios_high[3],
+ ha->nvram->bios_low[0], ha->nvram->bios_low[1],
+ ha->nvram->bios_low[2], ha->nvram->bios_low[3]);
X
X /* save controller type */
X ha->ad_type = ha->nvram->adapter_type;
@@ -4614,7 +5782,7 @@
X ips_scb_t *scb;
X int ret;
X
- DBG("ips_read_adapter_status");
+ METHOD_TRACE("ips_read_adapter_status", 1);
X
X scb = &ha->scbs[ha->max_cmds-1];
X
@@ -4633,8 +5801,9 @@
X scb->cmd.basic_io.reserved = 0;
X
X /* send command */
- ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr);
- if ((ret == IPS_FAILURE) || (ret == IPS_SUCCESS_IMM))
+ if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) ||
+ (ret == IPS_SUCCESS_IMM) ||
+ ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
X return (0);
X
X return (1);
@@ -4654,7 +5823,7 @@
X ips_scb_t *scb;
X int ret;
X
- DBG("ips_read_subsystem_parameters");
+ METHOD_TRACE("ips_read_subsystem_parameters", 1);
X
X scb = &ha->scbs[ha->max_cmds-1];
X
@@ -4673,8 +5842,9 @@
X scb->cmd.basic_io.reserved = 0;
X
X /* send command */
- ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr);
- if ((ret == IPS_FAILURE) || (ret == IPS_SUCCESS_IMM))
+ if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) ||
+ (ret == IPS_SUCCESS_IMM) ||
+ ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
X return (0);
X
X return (1);
@@ -4695,7 +5865,7 @@
X int i;
X int ret;
X
- DBG("ips_read_config");
+ METHOD_TRACE("ips_read_config", 1);
X
X /* set defaults for initiator IDs */
X ha->conf->init_id[0] = IPS_ADAPTER_ID;
@@ -4745,7 +5915,7 @@
X ips_scb_t *scb;
X int ret;
X
- DBG("ips_readwrite_page5");
+ METHOD_TRACE("ips_readwrite_page5", 1);
X
X scb = &ha->scbs[ha->max_cmds-1];
X
@@ -4789,7 +5959,7 @@
X ips_scb_t *scb;
X int ret;
X
- DBG("ips_clear_adapter");
+ METHOD_TRACE("ips_clear_adapter", 1);
X
X scb = &ha->scbs[ha->max_cmds-1];
X
@@ -4807,8 +5977,9 @@
X scb->cmd.config_sync.reserved3 = 0;
X
X /* issue command */
- ret = ips_send_wait(ha, scb, ips_reset_timeout, intr);
- if ((ret == IPS_FAILURE) || (ret == IPS_SUCCESS_IMM))
+ if (((ret = ips_send_wait(ha, scb, ips_reset_timeout, intr)) == IPS_FAILURE) ||
+ (ret == IPS_SUCCESS_IMM) ||
+ ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
X return (0);
X
X /* send unlock stripe command */
@@ -4826,8 +5997,9 @@
X scb->cmd.unlock_stripe.reserved3 = 0;
X
X /* issue command */
- ret = ips_send_wait(ha, scb, ips_reset_timeout, intr);
- if ((ret == IPS_FAILURE) || (ret == IPS_SUCCESS_IMM))
+ if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) ||
+ (ret == IPS_SUCCESS_IMM) ||
+ ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
X return (0);
X
X return (1);
@@ -4846,7 +6018,7 @@
X ips_ffdc_reset(ips_ha_t *ha, int intr) {
X ips_scb_t *scb;
X
- DBG("ips_ffdc_reset");
+ METHOD_TRACE("ips_ffdc_reset", 1);
X
X scb = &ha->scbs[ha->max_cmds-1];
X
@@ -4879,12 +6051,10 @@
X ips_ffdc_time(ips_ha_t *ha, int intr) {
X ips_scb_t *scb;
X
- DBG("ips_ffdc_time");
+ METHOD_TRACE("ips_ffdc_time", 1);


X
-#if IPS_DEBUG >= 1

- printk(KERN_NOTICE "(%s%d) Sending time update.\n",


- ips_name, ha->host_num);
-#endif

+ DEBUG_VAR(1, "(%s%d) Sending time update.",


+ ips_name, ha->host_num);
X

X scb = &ha->scbs[ha->max_cmds-1];
X
@@ -4933,6 +6103,8 @@
X {30, 30},
X {31, 31} };
X
+ METHOD_TRACE("ips_fix_ffdc_time", 1);
+
X days = current_time / IPS_SECS_DAY;
X rem = current_time % IPS_SECS_DAY;
X
@@ -4981,6 +6153,8 @@
X int timeout;
X u8 status;
X
+ METHOD_TRACE("ips_erase_bios", 1);
+
X /* Clear the status register */
X outl(0, ha->io_addr + IPS_REG_FLAP);
X if (ha->revision_id == IPS_REVID_TROMBONE64)
@@ -5077,6 +6251,115 @@


X
X /****************************************************************************/
X /* */

+/* Routine Name: ips_erase_bios_memio */


+/* */
+/* Routine Description: */

+/* Erase the BIOS on the adapter */


+/* */
+/****************************************************************************/
+static int

+ips_erase_bios_memio(ips_ha_t *ha) {
+ int timeout;
+ u8 status;
+
+ METHOD_TRACE("ips_erase_bios_memio", 1);
+
+ /* Clear the status register */
+ writel(0, ha->mem_ptr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ UDELAY(5); /* 5 us */
+
+ writeb(0x50, ha->mem_ptr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ UDELAY(5); /* 5 us */
+
+ /* Erase Setup */
+ writeb(0x20, ha->mem_ptr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ UDELAY(5); /* 5 us */
+
+ /* Erase Confirm */
+ writeb(0xD0, ha->mem_ptr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ UDELAY(5); /* 5 us */
+
+ /* Erase Status */
+ writeb(0x70, ha->mem_ptr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ UDELAY(5); /* 5 us */
+
+ timeout = 80000; /* 80 seconds */
+
+ while (timeout > 0) {
+ if (ha->revision_id == IPS_REVID_TROMBONE64) {
+ writel(0, ha->mem_ptr + IPS_REG_FLAP);
+ UDELAY(5); /* 5 us */
+ }
+
+ status = readb(ha->mem_ptr + IPS_REG_FLDP);
+
+ if (status & 0x80)
+ break;
+
+ MDELAY(1);
+ timeout--;
+ }
+
+ /* check for timeout */
+ if (timeout <= 0) {
+ /* timeout */
+
+ /* try to suspend the erase */
+ writeb(0xB0, ha->mem_ptr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ UDELAY(5); /* 5 us */
+
+ /* wait for 10 seconds */
+ timeout = 10000;
+ while (timeout > 0) {
+ if (ha->revision_id == IPS_REVID_TROMBONE64) {
+ writel(0, ha->mem_ptr + IPS_REG_FLAP);
+ UDELAY(5); /* 5 us */
+ }
+
+ status = readb(ha->mem_ptr + IPS_REG_FLDP);
+
+ if (status & 0xC0)
+ break;
+
+ MDELAY(1);
+ timeout--;
+ }
+
+ return (1);
+ }
+
+ /* check for valid VPP */
+ if (status & 0x08)
+ /* VPP failure */
+ return (1);
+
+ /* check for succesful flash */
+ if (status & 0x30)
+ /* sequence error */
+ return (1);
+
+ /* Otherwise, we were successful */
+ /* clear status */
+ writeb(0x50, ha->mem_ptr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ UDELAY(5); /* 5 us */
+
+ /* enable reads */
+ writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ UDELAY(5); /* 5 us */


+
+ return (0);
+}

+
+/****************************************************************************/
+/* */
X /* Routine Name: ips_program_bios */


X /* */
X /* Routine Description: */

@@ -5089,6 +6372,8 @@
X int timeout;
X u8 status;
X
+ METHOD_TRACE("ips_program_bios", 1);
+
X for (i = 0; i < buffersize; i++) {
X /* write a byte */
X outl(i, ha->io_addr + IPS_REG_FLAP);
@@ -5162,6 +6447,93 @@


X
X /****************************************************************************/
X /* */

+/* Routine Name: ips_program_bios_memio */


+/* */
+/* Routine Description: */

+/* Program the BIOS on the adapter */


+/* */
+/****************************************************************************/
+static int

+ips_program_bios_memio(ips_ha_t *ha, char *buffer, int buffersize) {
+ int i;
+ int timeout;
+ u8 status;
+
+ METHOD_TRACE("ips_program_bios_memio", 1);
+
+ for (i = 0; i < buffersize; i++) {
+ /* write a byte */
+ writel(i, ha->mem_ptr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ UDELAY(5); /* 5 us */
+
+ writeb(0x40, ha->mem_ptr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ UDELAY(5); /* 5 us */
+
+ writeb(buffer[i], ha->mem_ptr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ UDELAY(5); /* 5 us */
+
+ /* wait up to one second */


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 081'
echo 'File patch-2.4.0-test9 is continued in part 082'
echo "082" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part087

#!/bin/sh -x
# this is part 087 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 087; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

- printk(KERN_WARNING "opl3: I/O port 0x%x already in use\n", io);
- return 0;
- }
X if (!opl3_detect(io, NULL))
X {
X return -ENODEV;
X }
- me = opl3_init(io, NULL, THIS_MODULE);
- request_region(io, 4, devc->fm_info.name);
X
+ me = opl3_init(io, NULL, THIS_MODULE);
X }
X
X return 0;
@@ -1212,8 +1221,11 @@
X {
X if (devc && io != -1)
X {
- if(devc->base)
+ if (devc->base) {
X release_region(devc->base,4);
+ if (devc->is_opl4)
+ release_region(devc->base - 8, 2);
+ }
X kfree(devc);
X devc = NULL;
X sound_unload_synthdev(me);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/opl3sa.c linux/drivers/sound/opl3sa.c
--- v2.4.0-test8/linux/drivers/sound/opl3sa.c Fri Aug 11 08:26:43 2000
+++ linux/drivers/sound/opl3sa.c Wed Sep 27 13:53:56 2000
@@ -14,6 +14,7 @@
X * Changes:
X * Alan Cox Modularisation


X * Christoph Hellwig Adapted to module_init/module_exit

+ * Arnaldo C. de Melo got rid of attach_uart401
X *

X * FIXME:
X * Check for install of mpu etc is wrong, should check result of the mss stuff
@@ -176,12 +177,6 @@
X }
X
X
-static void __init attach_opl3sa_mpu(struct address_info *hw_config)
-{
- hw_config->name = "OPL3-SA (MPU401)";
- attach_uart401(hw_config, THIS_MODULE);
-}
-
X static int __init probe_opl3sa_mpu(struct address_info *hw_config)
X {
X unsigned char conf;
@@ -197,11 +192,6 @@
X DDB(printk("OPL3-SA: MPU mode already initialized\n"));
X return 0;
X }
- if (check_region(hw_config->io_base, 4))
- {
- printk(KERN_ERR "OPL3-SA: MPU I/O port conflict (%x)\n", hw_config->io_base);
- return 0;
- }
X if (hw_config->irq > 10)
X {
X printk(KERN_ERR "OPL3-SA: Bad MPU IRQ %d\n", hw_config->irq);
@@ -236,8 +226,9 @@
X opl3sa_write(0x03, conf);
X
X mpu_initialized = 1;
+ hw_config->name = "OPL3-SA (MPU401)";
X
- return probe_uart401(hw_config);
+ return probe_uart401(hw_config, THIS_MODULE);
X }
X
X static void __exit unload_opl3sa_wss(struct address_info *hw_config)
@@ -310,9 +301,6 @@
X found_mpu=probe_opl3sa_mpu(&cfg_mpu);
X
X attach_opl3sa_wss(&cfg);
- if(found_mpu)
- attach_opl3sa_mpu(&cfg_mpu);
-


X return 0;
X }
X

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/pss.c linux/drivers/sound/pss.c
--- v2.4.0-test8/linux/drivers/sound/pss.c Fri Aug 11 08:26:43 2000
+++ linux/drivers/sound/pss.c Mon Sep 18 15:02:02 2000
@@ -24,8 +24,32 @@
X * To probe_pss_mss added test for initialize AD1848
X * 98-05-28: Vladimir Michl <vladimi...@upol.cz>
X * Fixed computation of mixer volumes
+ * 04-05-1999: Anthony Barbachan <barb...@xmen.cis.fordham.edu>
+ * Added code that allows the user to enable his cdrom and/or
+ * joystick through the module parameters pss_cdrom_port and
+ * pss_enable_joystick. pss_cdrom_port takes a port address as its
+ * argument. pss_enable_joystick takes either a 0 or a non-0 as its
+ * argument.
+ * 04-06-1999: Anthony Barbachan <barb...@xmen.cis.fordham.edu>
+ * Separated some code into new functions for easier reuse.
+ * Cleaned up and streamlined new code. Added code to allow a user
+ * to only use this driver for enabling non-sound components
+ * through the new module parameter pss_no_sound (flag). Added
+ * code that would allow a user to decide whether the driver should
+ * reset the configured hardware settings for the PSS board through
+ * the module parameter pss_keep_settings (flag). This flag will
+ * allow a user to free up resources in use by this card if needbe,
+ * furthermore it allows him to use this driver to just enable the
+ * emulations and then be unloaded as it is no longer needed. Both
+ * new settings are only available to this driver if compiled as a
+ * module. The default settings of all new parameters are set to
+ * load the driver as it did in previous versions.
+ * 04-07-1999: Anthony Barbachan <barb...@xmen.cis.fordham.edu>
+ * Added module parameter pss_firmware to allow the user to tell
+ * the driver where the fireware file is located. The default
+ * setting is the previous hardcoded setting "/etc/sound/pss_synth".
X * 00-03-03: Christoph Hellwig <chhe...@gmx.net>
- * Adapted to module_init/module_exit
+ * Adapted to module_init/module_exit
X */
X
X
@@ -84,6 +108,7 @@
X #define NO_WSS_MIXER -1
X
X #include "coproc.h"
+
X #include "pss_boot.h"
X
X /* If compiled into kernel, it enable or disable pss mixer */
@@ -116,6 +141,8 @@
X
X static int pss_initialized = 0;
X static int nonstandard_microcode = 0;
+static int pss_cdrom_port = -1; /* Parameter for the PSS cdrom port */
+static int pss_enable_joystick = 0;/* Parameter for enabling the joystick */
X
X static void pss_write(pss_confdata *devc, int data)
X {
@@ -574,6 +601,49 @@
X ioctl: pss_mixer_ioctl
X };
X
+void disable_all_emulations(void)
+{
+ outw(0x0000, REG(CONF_PSS)); /* 0x0400 enables joystick */
+ outw(0x0000, REG(CONF_WSS));
+ outw(0x0000, REG(CONF_SB));
+ outw(0x0000, REG(CONF_MIDI));
+ outw(0x0000, REG(CONF_CDROM));
+}
+
+void configure_nonsound_components(void)
+{
+ /* Configure Joystick port */
+
+ if(pss_enable_joystick)
+ {
+ outw(0x0400, REG(CONF_PSS)); /* 0x0400 enables joystick */
+ printk(KERN_INFO "PSS: joystick enabled.\n");
+ }
+ else
+ {
+ printk(KERN_INFO "PSS: joystick port not enabled.\n");
+ }
+
+ /* Configure CDROM port */
+
+ if(pss_cdrom_port == -1) /* If cdrom port enablation wasn't requested */
+ {
+ printk(KERN_INFO "PSS: CDROM port not enabled.\n");
+ }
+ else if(check_region(pss_cdrom_port, 2))
+ {
+ printk(KERN_ERR "PSS: CDROM I/O port conflict.\n");
+ }
+ else if(!set_io_base(devc, CONF_CDROM, pss_cdrom_port))
+ {
+ printk(KERN_ERR "PSS: CDROM I/O port could not be set.\n");
+ }
+ else /* CDROM port successfully configured */
+ {
+ printk(KERN_INFO "PSS: CDROM I/O port set to 0x%x.\n", pss_cdrom_port);
+ }
+}
+
X void attach_pss(struct address_info *hw_config)
X {
X unsigned short id;
@@ -594,13 +664,10 @@
X id = inw(REG(PSS_ID)) & 0x00ff;
X
X /*
- * Disable all emulations. Will be enabled later (if required).
+ * Disable all emulations. Will be enabled later (if required).
X */
- outw(0x0000, REG(CONF_PSS)); /* 0x0400 enables joystick */
- outw(0x0000, REG(CONF_WSS));
- outw(0x0000, REG(CONF_SB));
- outw(0x0000, REG(CONF_MIDI));
- outw(0x0000, REG(CONF_CDROM));
+
+ disable_all_emulations();
X
X #if YOU_REALLY_WANT_TO_ALLOCATE_THESE_RESOURCES
X if (sound_alloc_dma(hw_config->dma, "PSS"))
@@ -620,6 +687,7 @@
X }
X #endif
X
+ configure_nonsound_components();
X pss_initialized = 1;
X sprintf(tmp, "ECHO-PSS Rev. %d", id);
X conf_printf(tmp, hw_config);
@@ -1028,6 +1096,9 @@
X static int mss_dma __initdata = -1;
X static int mpu_io __initdata = -1;
X static int mpu_irq __initdata = -1;
+static int pss_no_sound __initdata = 0; /* Just configure non-sound components */
+static int pss_keep_settings = 1; /* Keep hardware settings at module exit */
+static char *pss_firmware = "/etc/sound/pss_synth";
X
X MODULE_PARM(pss_io, "i");
X MODULE_PARM_DESC(pss_io, "Set i/o base of PSS card (probably 0x220 or 0x240)");
@@ -1041,6 +1112,16 @@
X MODULE_PARM_DESC(mpu_io, "Set MIDI i/o base (0x330 or other. Address must be on 4 location boundaries and must be from 0x100 to 0xFFC)");
X MODULE_PARM(mpu_irq, "i");
X MODULE_PARM_DESC(mpu_irq, "Set MIDI IRQ (3, 5, 7, 9, 10, 11, 12)");
+MODULE_PARM(pss_cdrom_port, "i");
+MODULE_PARM_DESC(pss_cdrom_port, "Set the PSS CDROM port i/o base (0x340 or other)");
+MODULE_PARM(pss_enable_joystick, "i");
+MODULE_PARM_DESC(pss_enable_joystick, "Enables the PSS joystick port (1 to enable, 0 to disable)");
+MODULE_PARM(pss_no_sound, "i");
+MODULE_PARM_DESC(pss_no_sound, "Configure sound compoents (0 - no, 1 - yes)");
+MODULE_PARM(pss_keep_settings, "i");
+MODULE_PARM_DESC(pss_keep_settings, "Keep hardware setting at driver unloading (0 - no, 1 - yes)");
+MODULE_PARM(pss_firmware, "s");
+MODULE_PARM_DESC(pss_firmware, "Location of the firmware file (default - /etc/sound/pss_synth)");
X MODULE_PARM(pss_mixer, "b");
X MODULE_PARM_DESC(pss_mixer, "Enable (1) or disable (0) PSS mixer (controlling of output volume, bass, treble, synth volume). The mixer is not available on all PSS cards.");
X MODULE_AUTHOR("Hannu Savolainen, Vladimir Michl");
@@ -1055,6 +1136,19 @@
X
X static int __init init_pss(void)
X {
+
+ if(pss_no_sound) /* If configuring only nonsound components */
+ {
+ cfg.io_base = pss_io;
+ if(!probe_pss(&cfg))
+ return -ENODEV;
+ printk(KERN_INFO "ECHO-PSS Rev. %d\n", inw(REG(PSS_ID)) & 0x00ff);
+ printk(KERN_INFO "PSS: loading in no sound mode.\n");
+ disable_all_emulations();
+ configure_nonsound_components();


+ return 0;
+ }
+

X cfg.io_base = pss_io;
X
X cfg2.io_base = mss_io;
@@ -1071,7 +1165,7 @@
X
X if (!pss_synth) {
X fw_load = 1;
- pss_synthLen = mod_firmware_load("/etc/sound/pss_synth", (void *) &pss_synth);
+ pss_synthLen = mod_firmware_load(pss_firmware, (void *) &pss_synth);
X }
X if (!probe_pss(&cfg))
X return -ENODEV;
@@ -1093,13 +1187,22 @@
X
X static void __exit cleanup_pss(void)
X {
- if (fw_load && pss_synth)
- vfree(pss_synth);
- if (pssmss)
- unload_pss_mss(&cfg2);
- if (pssmpu)
- unload_pss_mpu(&cfg_mpu);
- unload_pss(&cfg);
+ if(!pss_no_sound)
+ {
+ if(fw_load && pss_synth)
+ vfree(pss_synth);
+ if(pssmss)
+ unload_pss_mss(&cfg2);
+ if(pssmpu)
+ unload_pss_mpu(&cfg_mpu);
+ unload_pss(&cfg);
+ }
+
+ if(!pss_keep_settings) /* Keep hardware settings if asked */
+ {
+ disable_all_emulations();
+ printk(KERN_INFO "Resetting PSS sound card configurations.\n");
+ }
X }
X
X module_init(init_pss);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/sb.h linux/drivers/sound/sb.h
--- v2.4.0-test8/linux/drivers/sound/sb.h Fri Aug 11 08:26:43 2000
+++ linux/drivers/sound/sb.h Wed Sep 27 13:53:56 2000
@@ -178,8 +178,7 @@
X /* From sb_common.c */
X void sb_dsp_disable_midi(int port);
X void sb_dsp_disable_recording(int port);
-void attach_sbmpu (struct address_info *hw_config, struct module *owner);
-int probe_sbmpu (struct address_info *hw_config);
+int probe_sbmpu (struct address_info *hw_config, struct module *owner);
X void unload_sbmpu (struct address_info *hw_config);
X
X void unload_sb16(struct address_info *hw_info);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/sb_card.c linux/drivers/sound/sb_card.c
--- v2.4.0-test8/linux/drivers/sound/sb_card.c Mon Aug 21 09:44:05 2000
+++ linux/drivers/sound/sb_card.c Wed Sep 27 13:53:56 2000
@@ -47,6 +47,9 @@
X *
X * 12-08-2000 Added Creative SB32 PnP (CTL009F).
X * Kasatenko Ivan Alex. <skyw...@rnc.ru>
+ *
+ * 21-09-2000 Got rid of attach_sbmpu
+ * Arnaldo Carvalho de Melo <ac...@conectiva.com.br>


X */
X
X #include <linux/config.h>

@@ -524,7 +527,7 @@
X return(NULL);
X
X /* Cards with separate OPL3 device (ALS, CMI, etc.)
- * This is just to activate the device... */
+ * This is just to activate the device so the OPL module can use it */
X if(sb_isapnp_list[slot].opl_vendor || sb_isapnp_list[slot].opl_function) {
X if((opl_dev[card] = isapnp_find_dev(bus, sb_isapnp_list[slot].opl_vendor, sb_isapnp_list[slot].opl_function, NULL))) {
X int ret = opl_dev[card]->prepare(opl_dev[card]);
@@ -607,7 +610,7 @@


X return 0;
X }
X

-int __init sb_isapnp_probe(struct address_info *hw_config, struct address_info *mpu_config, int card)
+static int __init sb_isapnp_probe(struct address_info *hw_config, struct address_info *mpu_config, int card)
X {
X static int first = 1;
X int i;
@@ -647,7 +650,7 @@
X
X static int __init init_sb(void)
X {
- int card, max = multiple ? SB_CARDS_MAX : 1;
+ int card, max = (multiple && isapnp) ? SB_CARDS_MAX : 1;
X
X printk(KERN_INFO "Soundblaster audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");
X
@@ -658,9 +661,15 @@
X * single driver! */
X if(isapnp && (sb_isapnp_probe(&cfg[card], &cfg_mpu[card], card) < 0) ) {
X if(!sb_cards_num) {
+ /* Found no ISAPnP cards, so check for a non-pnp
+ * card and set the detection loop for 1 cycle
+ */
X printk(KERN_NOTICE "sb: No ISAPnP cards found, trying standard ones...\n");
X isapnp = 0;
+ max = 1;
X } else
+ /* found all the ISAPnP cards so exit the
+ * detection loop. */
X break;
X }
X #endif
@@ -674,8 +683,21 @@
X
X cfg[card].card_subtype = type;
X
- if (!probe_sb(&cfg[card]))
- return -ENODEV;
+ if (!probe_sb(&cfg[card])) {
+ /* if one or more cards already registered, don't
+ * return an error but print a warning. Note, this
+ * should never really happen unless the hardware
+ * or ISAPnP screwed up. */
+ if (sb_cards_num) {
+ printk(KERN_WARNING "sb.c: There was a " \
+ "problem probing one of your SoundBlaster " \
+ "ISAPnP soundcards. Continuing.\n");
+ card--;
+ sb_cards_num--;
+ continue;
+ } else
+ return -ENODEV;
+ }
X attach_sb_card(&cfg[card]);
X
X if(cfg[card].slots[0]==-1)
@@ -683,10 +705,8 @@
X
X if (!isapnp)
X cfg_mpu[card].io_base = mpu_io;
- if (probe_sbmpu(&cfg_mpu[card]))
+ if (probe_sbmpu(&cfg_mpu[card], THIS_MODULE))
X sbmpu[card] = 1;
- if (sbmpu[card])
- attach_sbmpu(&cfg_mpu[card], THIS_MODULE);
X }
X
X if(isapnp)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/sb_common.c linux/drivers/sound/sb_common.c
--- v2.4.0-test8/linux/drivers/sound/sb_common.c Fri Aug 11 08:26:43 2000
+++ linux/drivers/sound/sb_common.c Wed Sep 27 13:53:56 2000
@@ -19,6 +19,8 @@
X * 2000/01/18 - separated sb_card and sb_common -
X * Jeff Garzik <jga...@mandrakesoft.com>
X *
+ * 2000/09/18 - got rid of attach_uart401
+ * Arnaldo Carvalho de Melo <ac...@conectiva.com.br>


X */
X
X #include <linux/config.h>

@@ -1190,24 +1192,10 @@


X return 1;
X }
X

-void attach_sbmpu(struct address_info *hw_config, struct module *owner)
-{
- if (last_sb->model == MDL_ESS) {
-#if defined(CONFIG_SOUND_MPU401)
- attach_mpu401(hw_config, owner);
- if (last_sb->irq == -hw_config->irq) {
- last_sb->midi_irq_cookie=(void *)hw_config->slots[1];
- }
-#endif
- return;
- }
- attach_uart401(hw_config, THIS_MODULE);
- last_sb->midi_irq_cookie=midi_devs[hw_config->slots[4]]->devc;
-}
-
-int probe_sbmpu(struct address_info *hw_config)
+int probe_sbmpu(struct address_info *hw_config, struct module *owner)
X {
X sb_devc *devc = last_devc;
+ int ret;
X
X if (last_devc == NULL)
X return 0;
@@ -1239,15 +1227,15 @@
X return 0;
X hw_config->name = "ESS1xxx MPU";
X devc->midi_irq_cookie = -1;
- return probe_mpu401(hw_config);
+ if (!probe_mpu401(hw_config))
+ return 0;
+ attach_mpu401(hw_config, owner);
+ if (last_sb->irq == -hw_config->irq)
+ last_sb->midi_irq_cookie=(void *)hw_config->slots[1];
+ return 1;
X }
X #endif
X
- if (check_region(hw_config->io_base, 4))
- {
- printk(KERN_ERR "sbmpu: I/O port conflict (%x)\n", hw_config->io_base);
- return 0;
- }
X switch (devc->model)
X {
X case MDL_SB16:
@@ -1277,7 +1265,11 @@
X default:
X return 0;
X }
- return probe_uart401(hw_config);
+
+ ret = probe_uart401(hw_config, owner);
+ if (ret)
+ last_sb->midi_irq_cookie=midi_devs[hw_config->slots[4]]->devc;


+ return ret;
X }
X

X void unload_sbmpu(struct address_info *hw_config)
@@ -1296,7 +1288,6 @@
X EXPORT_SYMBOL(sb_dsp_unload);
X EXPORT_SYMBOL(sb_dsp_disable_midi);
X EXPORT_SYMBOL(sb_be_quiet);
-EXPORT_SYMBOL(attach_sbmpu);
X EXPORT_SYMBOL(probe_sbmpu);
X EXPORT_SYMBOL(unload_sbmpu);
X EXPORT_SYMBOL(smw_free);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/sequencer.c linux/drivers/sound/sequencer.c
--- v2.4.0-test8/linux/drivers/sound/sequencer.c Fri Aug 11 08:26:44 2000
+++ linux/drivers/sound/sequencer.c Mon Sep 25 12:32:54 2000
@@ -18,9 +18,6 @@
X
X #define SEQUENCER_C
X #include "sound_config.h"
-#include "softoss.h"
-
-int (*softsynthp) (int cmd, int parm1, int parm2, unsigned long parm3) = NULL;
X
X #include "midi_ctrl.h"
X
@@ -170,10 +167,7 @@
X if (data == 0xfe) /* Ignore active sensing */
X return;
X
- if (softsynthp != NULL)
- tstamp = softsynthp(SSYN_GETTIME, 0, 0, 0);
- else
- tstamp = jiffies - seq_time;
+ tstamp = jiffies - seq_time;
X
X if (tstamp != prev_input_time)
X {
@@ -195,8 +189,6 @@
X
X if (seq_mode == SEQ_2)
X this_time = tmr->get_time(tmr_no);
- else if (softsynthp != NULL)
- this_time = softsynthp(SSYN_GETTIME, 0, 0, 0);
X else
X this_time = jiffies - seq_time;
X
@@ -659,10 +651,7 @@
X prev_event_time = time;
X
X seq_playing = 1;
- if (softsynthp != NULL)
- softsynthp(SSYN_REQUEST, time, 0, 0);
- else
- request_sound_timer(time);
+ request_sound_timer(time);
X
X if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
X wake_up(&seq_sleeper);
@@ -671,13 +660,7 @@
X break;
X
X case TMR_START:
- if (softsynthp != NULL)
- {
- softsynthp(SSYN_START, 0, 0, 0);
- seq_time = 0;
- }
- else
- seq_time = jiffies;
+ seq_time = jiffies;
X prev_input_time = 0;
X prev_event_time = 0;
X break;
@@ -785,10 +768,7 @@
X time = *delay;
X prev_event_time = time;
X
- if (softsynthp != NULL)
- softsynthp(SSYN_REQUEST, time, 0, 0);
- else
- request_sound_timer(time);
+ request_sound_timer(time);
X
X if ((SEQ_MAX_QUEUE - qlen) >= output_threshold)
X wake_up(&seq_sleeper);
@@ -809,14 +789,9 @@
X case SEQ_SYNCTIMER: /*
X * Reset timer
X */
- if (softsynthp != NULL)
- seq_time = 0;
- else
- seq_time = jiffies;
+ seq_time = jiffies;
X prev_input_time = 0;
X prev_event_time = 0;
- if (softsynthp != NULL)
- softsynthp(SSYN_START, 0, 0, 0);
X break;
X
X case SEQ_MIDIPUTC: /*
@@ -838,10 +813,7 @@
X */
X
X seq_playing = 1;
- if (softsynthp != NULL)
- softsynthp(SSYN_REQUEST, -1, 0, 0);
- else
- request_sound_timer(-1);
+ request_sound_timer(-1);
X return 2;
X }
X else
@@ -1085,15 +1057,10 @@
X }
X }
X
- if (softsynthp != NULL)
- seq_time = 0;
- else
- seq_time = jiffies;
+ seq_time = jiffies;
X
X prev_input_time = 0;
X prev_event_time = 0;
- if (softsynthp != NULL)
- softsynthp(SSYN_START, 0, 0, 0);
X
X if (seq_mode == SEQ_1 && (mode == OPEN_READ || mode == OPEN_READWRITE))
X {
@@ -1280,10 +1247,7 @@
X int chn;
X unsigned long flags;
X
- if (softsynthp != NULL)
- softsynthp(SSYN_STOP, 0, 0, 0);
- else
- sound_stop_timer();
+ sound_stop_timer();
X
X seq_time = jiffies;
X prev_input_time = 0;
@@ -1449,10 +1413,7 @@
X case SNDCTL_SEQ_GETTIME:
X if (seq_mode == SEQ_2)
X return tmr->ioctl(tmr_no, cmd, arg);
- if (softsynthp != NULL)
- val = softsynthp(SSYN_GETTIME, 0, 0, 0);
- else
- val = jiffies - seq_time;
+ val = jiffies - seq_time;
X break;
X
X case SNDCTL_SEQ_CTRLRATE:
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/sequencer_syms.c linux/drivers/sound/sequencer_syms.c
--- v2.4.0-test8/linux/drivers/sound/sequencer_syms.c Thu Feb 24 22:12:57 2000
+++ linux/drivers/sound/sequencer_syms.c Mon Sep 25 12:32:54 2000
@@ -23,10 +23,6 @@
X EXPORT_SYMBOL(sound_timer_syncinterval);
X EXPORT_SYMBOL(reprogram_timer);
X
-#include "softoss.h"
-
-EXPORT_SYMBOL(softsynthp);
-
X /* Tuning */
X
X #define _SEQUENCER_C_
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/softoss.c linux/drivers/sound/softoss.c
--- v2.4.0-test8/linux/drivers/sound/softoss.c Fri Aug 11 08:26:44 2000
+++ linux/drivers/sound/softoss.c Wed Dec 31 16:00:00 1969
@@ -1,1532 +0,0 @@
-/*
- * sound/softoss.c
- *
- * Software based MIDI synthsesizer driver.
- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- *
- *
- * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
- * Christoph Hellwig : adapted to module_init/module_exit
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/module.h>
-
-/*
- * When POLLED_MODE is defined, the resampling loop is run using a timer
- * callback routine. Normally the resampling loop is executed inside
- * audio buffer interrupt handler which doesn't work with single mode DMA.
- */
-#define SOFTSYN_MAIN
-#undef POLLED_MODE
-#define HANDLE_LFO
-
-#define ENVELOPE_SCALE 8
-#define NO_SAMPLE 0xffff
-
-#include "sound_config.h"
-#include "softoss.h"
-#include <linux/ultrasound.h>
-
-int softsynth_disabled = 0;
-
-static volatile int intr_pending = 0;
-
-#ifdef POLLED_MODE
-
-static struct timer_list poll_timer = {
- NULL, NULL, 0, 0, softsyn_poll
-};
-
-#else
-#endif
-
-#ifdef HANDLE_LFO
-/*
- * LFO table. Playback at 128 Hz gives 1 Hz LFO frequency.
- */
-static int tremolo_table[128] =
-{
- 0, 39, 158, 355, 630, 982, 1411, 1915,
- 2494, 3146, 3869, 4662, 5522, 6448, 7438, 8489,
- 9598, 10762, 11980, 13248, 14563, 15922, 17321, 18758,
- 20228, 21729, 23256, 24806, 26375, 27960, 29556, 31160,
- 32768, 34376, 35980, 37576, 39161, 40730, 42280, 43807,
- 45308, 46778, 48215, 49614, 50973, 52288, 53556, 54774,
- 55938, 57047, 58098, 59088, 60014, 60874, 61667, 62390,
- 63042, 63621, 64125, 64554, 64906, 65181, 65378, 65497,
- 65536, 65497, 65378, 65181, 64906, 64554, 64125, 63621,
- 63042, 62390, 61667, 60874, 60014, 59087, 58098, 57047,
- 55938, 54774, 53556, 52288, 50973, 49614, 48215, 46778,
- 45308, 43807, 42280, 40730, 39161, 37576, 35980, 34376,
- 32768, 31160, 29556, 27960, 26375, 24806, 23256, 21729,
- 20228, 18758, 17321, 15922, 14563, 13248, 11980, 10762,
- 9598, 8489, 7438, 6448, 5522, 4662, 3869, 3146,
- 2494, 1915, 1411, 982, 630, 355, 158, 39
-};
-
-static int vibrato_table[128] =
-{
- 0, 1608, 3212, 4808, 6393, 7962, 9512, 11039,
- 12540, 14010, 15447, 16846, 18205, 19520, 20788, 22006,
- 23170, 24279, 25330, 26320, 27246, 28106, 28899, 29622,
- 30274, 30853, 31357, 31786, 32138, 32413, 32610, 32729,
- 32768, 32729, 32610, 32413, 32138, 31786, 31357, 30853,
- 30274, 29622, 28899, 28106, 27246, 26320, 25330, 24279,
- 23170, 22006, 20788, 19520, 18205, 16846, 15447, 14010,
- 12540, 11039, 9512, 7962, 6393, 4808, 3212, 1608,
- 0, -1608, -3212, -4808, -6393, -7962, -9512, -11039,
- -12540, -14010, -15447, -16846, -18205, -19520, -20788, -22006,
- -23170, -24279, -25330, -26320, -27246, -28106, -28899, -29622,
- -30274, -30853, -31357, -31786, -32138, -32413, -32610, -32729,
- -32768, -32729, -32610, -32413, -32138, -31786, -31357, -30853,
- -30274, -29622, -28899, -28106, -27246, -26320, -25330, -24279,
- -23170, -22006, -20788, -19520, -18205, -16846, -15447, -14010,
- -12540, -11039, -9512, -7962, -6393, -4808, -3212, -1608
-};
-
-#endif
-
-static unsigned long last_resample_jiffies;
-static unsigned long resample_counter;
-
-extern int *sound_osp;
-
-static volatile int is_running = 0;
-static int softsynth_loaded = 0;
-
-static struct synth_info softsyn_info = {
- "SoftOSS", 0, SYNTH_TYPE_SAMPLE, SAMPLE_TYPE_GUS, 0, 16, 0, MAX_PATCH
-};
-
-static struct softsyn_devc sdev_info = {
- 0
-};
-
-softsyn_devc *devc = &sdev_info; /* used in softoss_rs.c */
-
-static struct voice_alloc_info *voice_alloc;
-
-static int softsyn_open(int synthdev, int mode);
-static void init_voice(softsyn_devc * devc, int voice);
-static void compute_step(int voice);
-
-static volatile int tmr_running = 0;
-static int voice_limit = 24;
-
-
-static void set_max_voices(int nr)


-{
- int i;
-

- if (nr < 4)
- nr = 4;
-
- if (nr > voice_limit)
- nr = voice_limit;
-
- voice_alloc->max_voice = devc->maxvoice = nr;
- devc->afterscale = 5;
-
- for (i = 31; i > 0; i--)
- if (nr & (1 << i))
- {
- devc->afterscale = i + 1;
- return;
- }
-}
-
-static void update_vibrato(int voice)
-{
- voice_info *v = &softoss_voices[voice];
-
-#ifdef HANDLE_LFO
- int x;
-
- x = vibrato_table[v->vibrato_phase >> 8];
- v->vibrato_phase = (v->vibrato_phase + v->vibrato_step) & 0x7fff;
-
- x = (x * v->vibrato_depth) >> 15;
- v->vibrato_level = (x * 600) >> 8;
-
- compute_step(voice);
-#else
- v->vibrato_level = 0;
-#endif
-}
-
-#ifdef HANDLE_LFO
-static void update_tremolo(int voice)
-{
- voice_info *v = &softoss_voices[voice];
- int x;
-
- x = tremolo_table[v->tremolo_phase >> 8];
- v->tremolo_phase = (v->tremolo_phase + v->tremolo_step) & 0x7fff;
-
- v->tremolo_level = (x * v->tremolo_depth) >> 20;
-}
-#endif
-
-static void start_vibrato(int voice)
-{
- voice_info *v = &softoss_voices[voice];
- int rate;
-
- if (!v->vibrato_depth)
- return;
-
- rate = v->vibrato_rate * 6 * 128;
- v->vibrato_step = (rate * devc->control_rate) / devc->speed;
-
- devc->vibratomap |= (1 << voice); /* Enable vibrato */
-}
-
-static void start_tremolo(int voice)
-{
- voice_info *v = &softoss_voices[voice];
- int rate;
-
- if (!v->tremolo_depth)
- return;
-
- rate = v->tremolo_rate * 6 * 128;
- v->tremolo_step = (rate * devc->control_rate) / devc->speed;
-
- devc->tremolomap |= (1 << voice); /* Enable tremolo */
-}
-
-static void update_volume(int voice)
-{
- voice_info *v = &softoss_voices[voice];
- unsigned int vol;
-
- /*
- * Compute plain volume
- */
-
- vol = (v->velocity * v->expression_vol * v->main_vol) >> 12;
-
-#ifdef HANDLE_LFO
- /*
- * Handle LFO
- */
-
- if (devc->tremolomap & (1 << voice))
- {
- int t;
-
- t = 32768 - v->tremolo_level;
- vol = (vol * t) >> 15;
- update_tremolo(voice);
- }
-#endif
- /*
- * Envelope
- */
-
- if (v->mode & WAVE_ENVELOPES && !v->percussive_voice)
- vol = (vol * (v->envelope_vol >> 16)) >> 19;
- else
- vol >>= 4;
-
- /*
- * Handle panning
- */
-
- if (v->panning < 0) /* Pan left */
- v->rightvol = (vol * (128 + v->panning)) / 128;
- else
- v->rightvol = vol;
-
- if (v->panning > 0) /* Pan right */
- v->leftvol = (vol * (128 - v->panning)) / 128;
- else
- v->leftvol = vol;
-}
-
-static void step_envelope(int voice, int do_release, int velocity)
-{
- voice_info *v = &softoss_voices[voice];
- int r, rate, time, dif;
- unsigned int vol;


- unsigned long flags;
-

- save_flags(flags);
- cli();
-
- if (!voice_active[voice] || v->sample == NULL)
- {
- restore_flags(flags);
- return;
- }
- if (!do_release)
- {
- if (v->mode & WAVE_SUSTAIN_ON && v->envelope_phase == 2)
- {
- /* Stop envelope until note off */
- v->envelope_volstep = 0;
- v->envelope_time = 0x7fffffff;
- if (v->mode & WAVE_VIBRATO)
- start_vibrato(voice);
- if (v->mode & WAVE_TREMOLO)
- start_tremolo(voice);
- restore_flags(flags);
- return;
- }
- }
- if (do_release)
- v->envelope_phase = 3;
- else
- v->envelope_phase++;
-
- if (v->envelope_phase >= 5) /* Finished */
- {
- init_voice(devc, voice);
- restore_flags(flags);
- return;
- }
- vol = v->envelope_target = v->sample->env_offset[v->envelope_phase] << 22;
-
-
- rate = v->sample->env_rate[v->envelope_phase];
- r = 3 - ((rate >> 6) & 0x3);
- r *= 3;
- r = (int) (rate & 0x3f) << r;
- rate = (((r * 44100) / devc->speed) * devc->control_rate) << 8;
-
- if (rate < (1 << 20)) /* Avoid infinitely "releasing" voices */
- rate = 1 << 20;
-
- dif = (v->envelope_vol - vol);
- if (dif < 0)
- dif *= -1;
- if (dif < rate * 2) /* Too close */
- {
- step_envelope(voice, 0, 60);
- restore_flags(flags);
- return;
- }
-
- if (vol > v->envelope_vol)
- {
- v->envelope_volstep = rate;
- time = (vol - v->envelope_vol) / rate;
- }
- else
- {
- v->envelope_volstep = -rate;
- time = (v->envelope_vol - vol) / rate;
- }
-
- time--;
- if (time <= 0)
- time = 1;
- v->envelope_time = time;
- restore_flags(flags);
-}
-
-static void step_envelope_lfo(int voice)
-{
- voice_info *v = &softoss_voices[voice];
-
- /*
- * Update pitch (vibrato) LFO
- */
-
- if (devc->vibratomap & (1 << voice))
- update_vibrato(voice);
-
- /*
- * Update envelope
- */
-
- if (v->mode & WAVE_ENVELOPES)
- {
- v->envelope_vol += v->envelope_volstep;
- /* Overshoot protection */
- if (v->envelope_vol < 0)
- {
- v->envelope_vol = v->envelope_target;
- v->envelope_volstep = 0;
- }
- if (v->envelope_time-- <= 0)
- {
- v->envelope_vol = v->envelope_target;
- step_envelope(voice, 0, 60);
- }
- }
-}
-
-static void compute_step(int voice)
-{
- voice_info *v = &softoss_voices[voice];
-
- /*
- * Since the pitch bender may have been set before playing the note, we
- * have to calculate the bending now.
- */
-
- v->current_freq = compute_finetune(v->orig_freq,
- v->bender,
- v->bender_range,
- v->vibrato_level);
- v->step = (((v->current_freq << 9) + (devc->speed >> 1)) / devc->speed);
-
- if (v->mode & WAVE_LOOP_BACK)
- v->step *= -1; /* Reversed playback */
-}
-
-static void init_voice(softsyn_devc * devc, int voice)
-{
- voice_info *v = &softoss_voices[voice];


- unsigned long flags;
-

- save_flags(flags);
- cli();
- voice_active[voice] = 0;
- devc->vibratomap &= ~(1 << voice);
- devc->tremolomap &= ~(1 << voice);
- v->mode = 0;
- v->wave = NULL;
- v->sample = NULL;
- v->ptr = 0;
- v->step = 0;
- v->startloop = 0;
- v->startbackloop = 0;
- v->endloop = 0;
- v->looplen = 0;
- v->bender = 0;
- v->bender_range = 200;
- v->panning = 0;
- v->main_vol = 127;
- v->expression_vol = 127;
- v->patch_vol = 127;
- v->percussive_voice = 0;
- v->sustain_mode = 0;
- v->envelope_phase = 1;
- v->envelope_vol = 1 << 24;
- v->envelope_volstep = 256;
- v->envelope_time = 0;
- v->vibrato_phase = 0;
- v->vibrato_step = 0;
- v->vibrato_level = 0;
- v->vibrato_rate = 0;
- v->vibrato_depth = 0;
- v->tremolo_phase = 0;
- v->tremolo_step = 0;
- v->tremolo_level = 0;
- v->tremolo_rate = 0;
- v->tremolo_depth = 0;
- voice_alloc->map[voice] = 0;
- voice_alloc->alloc_times[voice] = 0;
- restore_flags(flags);
-}
-
-static void reset_samples(softsyn_devc * devc)


-{
- int i;
-

- for (i = 0; i < MAX_VOICE; i++)
- voice_active[i] = 0;
- for (i = 0; i < devc->maxvoice; i++)
- {
- init_voice(devc, i);
- softoss_voices[i].instr = 0;
- }
-
- devc->ram_used = 0;
-
- for (i = 0; i < MAX_PATCH; i++)
- devc->programs[i] = NO_SAMPLE;
-
- for (i = 0; i < devc->nrsamples; i++)
- {
- vfree(devc->samples[i]);
- vfree(devc->wave[i]);
- devc->samples[i] = NULL;
- devc->wave[i] = NULL;
- }
- devc->nrsamples = 0;
-}
-
-static void init_engine(softsyn_devc * devc)
-{
- int i, fz, srate, sz = devc->channels;
-
- set_max_voices(devc->default_max_voices);
- voice_alloc->timestamp = 0;
-
- if (devc->bits == 16)
- sz *= 2;
-
- fz = devc->fragsize / sz; /* Samples per fragment */
- devc->samples_per_fragment = fz;
-
- devc->usecs = 0;
- devc->usecs_per_frag = (1000000 * fz) / devc->speed;
-
- for (i = 0; i < devc->maxvoice; i++)
- {
- init_voice(devc, i);
- softoss_voices[i].instr = 0;
- }
- devc->engine_state = ES_STOPPED;
-
- /*
- * Initialize delay
- */
-
- for (i = 0; i < DELAY_SIZE; i++)
- left_delay[i] = right_delay[i] = 0;
- delayp = 0;
- srate = (devc->speed / 10000); /* 1 to 4 */
- if (srate <= 0)
- srate = 1;
- devc->delay_size = (DELAY_SIZE * srate) / 4;
- if (devc->delay_size == 0 || devc->delay_size > DELAY_SIZE)
- devc->delay_size = DELAY_SIZE;
-}
-
-void softsyn_control_loop(void)
-{
- int voice;
-
- /*
- * Recompute envlope, LFO, etc.
- */
- for (voice = 0; voice < devc->maxvoice; voice++)
- {
- if (voice_active[voice])
- {
- update_volume(voice);
- step_envelope_lfo(voice);
- }
- else
- voice_alloc->map[voice] = 0;
- }
-}
-
-static void start_engine(softsyn_devc * devc);
-
-static void do_resample(int dummy)
-{
- struct dma_buffparms *dmap = audio_devs[devc->audiodev]->dmap_out;
- struct voice_info *vinfo;
- unsigned long flags, jif;
-
- int voice, loops;
- short *buf;
-
- if (softsynth_disabled)
- return;
-
- save_flags(flags);
- cli();
-
- if (is_running)
- {
- printk(KERN_WARNING "SoftOSS: Playback overrun\n");
- restore_flags(flags);
- return;
- }
- jif = jiffies;
- if (jif == last_resample_jiffies)
- {
- if (resample_counter++ > 50)
- {
- for (voice = 0; voice < devc->maxvoice; voice++)
- init_voice(devc, voice);
- voice_limit--;
- resample_counter = 0;
- printk(KERN_WARNING "SoftOSS: CPU overload. Limiting # of voices to %d\n", voice_limit);
-
- if (voice_limit < 10)
- {
- voice_limit = 10;
- devc->speed = (devc->speed * 2) / 3;
-
- printk(KERN_WARNING "SoftOSS: Dropping sampling rate and stopping the device.\n");
- softsynth_disabled = 1;
- }
- }
- }
- else
- {
- last_resample_jiffies = jif;
- resample_counter = 0;
- }
-
- /* is_running = 1; */
-
- if (dmap->qlen > devc->max_playahead)
- {
- printk(KERN_WARNING "SoftOSS: audio buffers full\n");
- is_running = 0;
- restore_flags(flags);
- return;
- }
- /*
- * First verify that all active voices are valid (do this just once per block).
- */
-
- for (voice = 0; voice < devc->maxvoice; voice++)
- {
- if (voice_active[voice])
- {
- int ptr;
-
- vinfo = &softoss_voices[voice];
- ptr = vinfo->ptr >> 9;
-
- if (vinfo->wave == NULL || ptr < 0 || ptr > vinfo->sample->len)
- init_voice(devc, voice);
- else if (!(vinfo->mode & WAVE_LOOPING) && (vinfo->ptr + vinfo->step) > vinfo->endloop)
- voice_active[voice] = 0;
- }
- }
-
- /*
- * Start the resampling process
- */
-
- loops = devc->samples_per_fragment;
- buf = (short *) (dmap->raw_buf + (dmap->qtail * dmap->fragment_size));
-
- softsynth_resample_loop(buf, loops); /* In Xsoftsynth_rs.c */
-
- dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
- dmap->qlen++;
- dmap->user_counter += dmap->fragment_size;
-
- devc->usecs += devc->usecs_per_frag;
-
- if (tmr_running)
- sound_timer_interrupt();
- /*
- * Execute timer
- */
-
- if (!tmr_running)
- {
- if (devc->usecs >= devc->next_event_usecs)
- {
- devc->next_event_usecs = ~0;
- sequencer_timer(0);
- }
- }
-
- is_running = 0;
- restore_flags(flags);
-}
-
-static void delayed_resample(int dummy)
-{
- struct dma_buffparms *dmap = audio_devs[devc->audiodev]->dmap_out;
- int n = 0;
-
- if (is_running)
- return;
-
- while (devc->engine_state != ES_STOPPED && dmap->qlen < devc->max_playahead && n++ < 2)
- do_resample(0);
- intr_pending = 0;
-}
-
-#ifdef POLLED_MODE
-static void softsyn_poll(unsigned long dummy)
-{
- delayed_resample(0);
-
- if (devc->engine_state != ES_STOPPED)
- {
- poll_timer.expires = jiffies+1;
- add_timer(&poll_timer);
- }
-}
-
-#else
-static void softsyn_callback(int dev, int parm)
-{
- delayed_resample(0);
-}
-#endif
-
-static void start_engine(softsyn_devc * devc)
-{
- struct dma_buffparms *dmap;
- int trig, n;
- mm_segment_t fs;
-
- if (!devc->audio_opened)
- if (softsyn_open(devc->synthdev, 0) < 0)
- return;
-
- if (devc->audiodev >= num_audiodevs)
- return;
-
- dmap = audio_devs[devc->audiodev]->dmap_out;
-
- devc->usecs = 0;
- devc->next_event_usecs = ~0;
- devc->control_rate = 64;
- devc->control_counter = 0;
-
- if (devc->engine_state == ES_STOPPED)
- {
- n = trig = 0;
- fs = get_fs();
- set_fs(get_ds());
- dma_ioctl(devc->audiodev, SNDCTL_DSP_SETTRIGGER, (caddr_t)&trig);
-#ifdef POLLED_MODE
- poll_timer.expires = jiffies+1;
- add_timer(&poll_timer);
- /* Start polling */
-#else
- dmap->audio_callback = softsyn_callback;
- dmap->qhead = dmap->qtail = dmap->qlen = 0;
-#endif
- while (dmap->qlen < devc->max_playahead && n++ < 2)
- do_resample(0);
- devc->engine_state = ES_STARTED;
- last_resample_jiffies = jiffies;
- resample_counter = 0;
- trig = PCM_ENABLE_OUTPUT;
- if (dma_ioctl(devc->audiodev, SNDCTL_DSP_SETTRIGGER, (caddr_t)&trig) < 0)
- printk(KERN_ERR "SoftOSS: Trigger failed\n");
- set_fs(fs);
- }
-}
-
-static void stop_engine(softsyn_devc * devc)
-{
-}
-
-static void request_engine(softsyn_devc * devc, int ticks)
-{
- if (ticks < 0) /* Relative time */
- devc->next_event_usecs = devc->usecs - ticks * (1000000 / HZ);
- else
- devc->next_event_usecs = ticks * (1000000 / HZ);
-}
-
-/*
- * Softsync hook serves mode1 (timing) calls made by sequencer.c
- */
-
-static int softsynth_hook(int cmd, int parm1, int parm2, unsigned long parm3)
-{
- switch (cmd)
- {
- case SSYN_START:
- start_engine(devc);
- break;
-
- case SSYN_STOP:
- stop_engine(devc);
- break;
-
- case SSYN_REQUEST:
- request_engine(devc, parm1);
- break;
-
- case SSYN_GETTIME:
- return devc->usecs / (1000000 / HZ);
- break;
-
- default:
- printk(KERN_WARNING "SoftOSS: Unknown request %d\n", cmd);
- }


- return 0;
-}
-

-static int softsyn_ioctl(int dev, unsigned int cmd, caddr_t arg)
-{
- switch (cmd)
- {
- case SNDCTL_SYNTH_INFO:
- softsyn_info.nr_voices = devc->maxvoice;
- if (copy_to_user(arg, &softsyn_info, sizeof(softsyn_info)))
- return -EFAULT;
- return 0;
-
- case SNDCTL_SEQ_RESETSAMPLES:
- stop_engine(devc);
- reset_samples(devc);
- return 0;
-
- case SNDCTL_SYNTH_MEMAVL:
- return devc->ram_size - devc->ram_used;
-
- default:
- return -EINVAL;
- }
-}
-
-static int softsyn_kill_note(int devno, int voice, int note, int velocity)
-{
- if (voice < 0 || voice > devc->maxvoice)
- return 0;
- voice_alloc->map[voice] = 0xffff; /* Releasing */
-
- if (softoss_voices[voice].sustain_mode & 1) /* Sustain controller on */
- {
- softoss_voices[voice].sustain_mode = 3; /* Note off pending */
- return 0;
- }
- if (velocity > 127 || softoss_voices[voice].mode & WAVE_FAST_RELEASE)
- {
- init_voice(devc, voice); /* Mark it inactive */
- return 0;
- }
- if (softoss_voices[voice].mode & WAVE_ENVELOPES)
- step_envelope(voice, 1, velocity); /* Enter sustain phase */
- else
- init_voice(devc, voice); /* Mark it inactive */


- return 0;
-}
-

-static int softsyn_set_instr(int dev, int voice, int instr)
-{
- if (voice < 0 || voice > devc->maxvoice)
- return 0;
-
- if (instr < 0 || instr > MAX_PATCH)
- {
- printk(KERN_ERR "SoftOSS: Invalid instrument number %d\n", instr);
- return 0;
- }
- softoss_voices[voice].instr = instr;


- return 0;
-}
-

-static int softsyn_start_note(int dev, int voice, int note, int volume)
-{
- int instr = 0;
- int best_sample, best_delta, delta_freq, selected;
- unsigned long note_freq, freq, base_note, flags;
- voice_info *v = &softoss_voices[voice];
-
- struct patch_info *sample;
-
- if (voice < 0 || voice > devc->maxvoice)
- return 0;
-
- if (volume == 0) /* Actually note off */
- softsyn_kill_note(dev, voice, note, volume);
-
- save_flags(flags);
- cli();
-
- if (note == 255)
- { /* Just volume update */
- v->velocity = volume;
- if (voice_active[voice])
- update_volume(voice);
- restore_flags(flags);
- return 0;
- }
- voice_active[voice] = 0; /* Stop the voice for a while */
- devc->vibratomap &= ~(1 << voice);
- devc->tremolomap &= ~(1 << voice);
-
- instr = v->instr;
- if (instr < 0 || instr > MAX_PATCH || devc->programs[instr] == NO_SAMPLE)
- {
- printk(KERN_WARNING "SoftOSS: Undefined MIDI instrument %d\n", instr);
- restore_flags(flags);
- return 0;
- }
- instr = devc->programs[instr];
-
- if (instr < 0 || instr >= devc->nrsamples)
- {
- printk(KERN_WARNING "SoftOSS: Corrupted MIDI instrument %d (%d)\n", v->instr, instr);
- restore_flags(flags);
- return 0;
- }
- note_freq = note_to_freq(note);
-
- selected = -1;
-
- best_sample = instr;
- best_delta = 1000000;
-
- while (instr != NO_SAMPLE && instr >= 0 && selected == -1)
- {
- delta_freq = note_freq - devc->samples[instr]->base_note;
-
- if (delta_freq < 0)
- delta_freq = -delta_freq;
- if (delta_freq < best_delta)
- {
- best_sample = instr;
- best_delta = delta_freq;
- }
- if (devc->samples[instr]->low_note <= note_freq &&
- note_freq <= devc->samples[instr]->high_note)
- {
- selected = instr;
- }
- else instr = devc->samples[instr]->key; /* Link to next sample */
-
- if (instr < 0 || instr >= devc->nrsamples)
- instr = NO_SAMPLE;
- }
-
- if (selected == -1)
- instr = best_sample;
- else
- instr = selected;
-
- if (instr < 0 || instr == NO_SAMPLE || instr > devc->nrsamples)
- {
- printk(KERN_WARNING "SoftOSS: Unresolved MIDI instrument %d\n", v->instr);
- restore_flags(flags);
- return 0;
- }
- sample = devc->samples[instr];
- v->sample = sample;
-
- if (v->percussive_voice) /* No key tracking */
- v->orig_freq = sample->base_freq; /* Fixed pitch */
- else
- {
- base_note = sample->base_note / 100;
- note_freq /= 100;
-
- freq = sample->base_freq * note_freq / base_note;
- v->orig_freq = freq;
- }
-
- if (!(sample->mode & WAVE_LOOPING))
- sample->loop_end = sample->len;
-
- v->wave = devc->wave[instr];
- if (volume < 0)
- volume = 0;
- else if (volume > 127)
- volume = 127;
- v->ptr = 0;
- v->startloop = sample->loop_start * 512;
- v->startbackloop = 0;
- v->endloop = sample->loop_end * 512;
- v->looplen = (sample->loop_end - sample->loop_start) * 512;
- v->leftvol = 64;
- v->rightvol = 64;
- v->patch_vol = sample->volume;
- v->velocity = volume;
- v->mode = sample->mode;
- v->vibrato_phase = 0;
- v->vibrato_step = 0;
- v->vibrato_level = 0;
- v->vibrato_rate = 0;
- v->vibrato_depth = 0;
- v->tremolo_phase = 0;
- v->tremolo_step = 0;
- v->tremolo_level = 0;
- v->tremolo_rate = 0;
- v->tremolo_depth = 0;
-
- if (!(v->mode & WAVE_LOOPING))
- v->mode &= ~(WAVE_BIDIR_LOOP | WAVE_LOOP_BACK);
- else if (v->mode & WAVE_LOOP_BACK)
- {
- v->ptr = sample->len;
- v->startbackloop = v->startloop;
- }
- if (v->mode & WAVE_VIBRATO)
- {
- v->vibrato_rate = sample->vibrato_rate;
- v->vibrato_depth = sample->vibrato_depth;
- }
- if (v->mode & WAVE_TREMOLO)
- {
- v->tremolo_rate = sample->tremolo_rate;
- v->tremolo_depth = sample->tremolo_depth;
- }
- if (v->mode & WAVE_ENVELOPES)
- {
- v->envelope_phase = -1;
- v->envelope_vol = 0;
- step_envelope(voice, 0, 60);
- }
- update_volume(voice);
- compute_step(voice);
-
- voice_active[voice] = 1; /* Mark it active */
- restore_flags(flags);


- return 0;
-}
-

-static int softsyn_open(int synthdev, int mode)
-{
- int err;
- extern int softoss_dev;
- int frags = 0x7fff0007; /* fragment size of 128 bytes */
- mm_segment_t fs;
-
- if (devc->audio_opened) /* Already opened */
- return 0;
-
- softsynth_disabled = 0;
- devc->finfo.f_mode = FMODE_WRITE;
- devc->finfo.f_flags = 0;
-
- if (softoss_dev >= num_audiodevs)
- softoss_dev = num_audiodevs - 1;
-
- if (softoss_dev < 0)
- softoss_dev = 0;
- if (softoss_dev >= num_audiodevs)
- return -ENXIO;
- devc->audiodev = softoss_dev;
-
- if (!(audio_devs[devc->audiodev]->format_mask & AFMT_S16_LE))
- {
-/* printk(KERN_ERR "SoftOSS: The audio device doesn't support 16 bits\n"); */
- return -ENXIO;
- }
- if ((err = audio_open((devc->audiodev << 4) | SND_DEV_DSP16, &devc->finfo)) < 0)
- return err;
-
- devc->speed = audio_devs[devc->audiodev]->d->set_speed(
- devc->audiodev, devc->speed);
- devc->channels = audio_devs[devc->audiodev]->d->set_channels(
- devc->audiodev, devc->channels);
- devc->bits = audio_devs[devc->audiodev]->d->set_bits(
- devc->audiodev, devc->bits);
-
-
- DDB(printk("SoftOSS: Using audio dev %d, speed %d, bits %d, channels %d\n", devc->audiodev, devc->speed, devc->bits, devc->channels));
- fs = get_fs();
- set_fs(get_ds());
- dma_ioctl(devc->audiodev, SNDCTL_DSP_SETFRAGMENT, (caddr_t) & frags);
- dma_ioctl(devc->audiodev, SNDCTL_DSP_GETBLKSIZE, (caddr_t) & devc->fragsize);
- set_fs(fs);
-
- if (devc->bits != 16 || devc->channels != 2)
- {
- audio_release((devc->audiodev << 4) | SND_DEV_DSP16, &devc->finfo);
-/* printk("SoftOSS: A 16 bit stereo sound card is required\n");*/
- return -EINVAL;
- }
- if (devc->max_playahead >= audio_devs[devc->audiodev]->dmap_out->nbufs)
- devc->max_playahead = audio_devs[devc->audiodev]->dmap_out->nbufs;
-
- DDB(printk("SoftOSS: Using %d fragments of %d bytes\n", devc->max_playahead, devc->fragsize));
-
- init_engine(devc);
- devc->audio_opened = 1;
- devc->sequencer_mode = mode;


- return 0;
-}
-

-static void softsyn_close(int synthdev)
-{
- mm_segment_t fs;
-
- devc->engine_state = ES_STOPPED;
-#ifdef POLLED_MODE
- del_timer(&poll_timer);
-#endif
- fs = get_fs();
- set_fs(get_ds());
- dma_ioctl(devc->audiodev, SNDCTL_DSP_RESET, 0);
- set_fs(fs);
- if (devc->audio_opened)
- audio_release((devc->audiodev << 4) | SND_DEV_DSP16, &devc->finfo);
- devc->audio_opened = 0;
-}
-
-static void softsyn_hw_control(int dev, unsigned char *event_rec)
-{
- int voice, cmd;
- unsigned short p1, p2;
- unsigned int plong;
-
- cmd = event_rec[2];
- voice = event_rec[3];
- p1 = *(unsigned short *) &event_rec[4];
- p2 = *(unsigned short *) &event_rec[6];
- plong = *(unsigned int *) &event_rec[4];
-
- switch (cmd)
- {
-
- case _GUS_NUMVOICES:
- set_max_voices(p1);
- break;
-
- default:;
- }
-}
-
-static int softsyn_load_patch(int dev, int format, const char *addr,
- int offs, int count, int pmgr_flag)
-{
- struct patch_info *patch = NULL;
-
- int i, p, instr;
- long sizeof_patch;
- int memlen, adj;
- unsigned short data;
- short *wave = NULL;
-
- sizeof_patch = (long) &patch->data[0] - (long) patch; /* Header size */
-
- if (format != GUS_PATCH)
- {
-/* printk(KERN_ERR "SoftOSS: Invalid patch format (key) 0x%x\n", format);*/
- return -EINVAL;
- }
- if (count < sizeof_patch)
- {
-/* printk(KERN_ERR "SoftOSS: Patch header too short\n");*/
- return -EINVAL;
- }
- count -= sizeof_patch;
-
- if (devc->nrsamples >= MAX_SAMPLE)
- {
-/* printk(KERN_ERR "SoftOSS: Sample table full\n");*/
- return -ENOBUFS;
- }
-
- /*
- * Copy the header from user space but ignore the first bytes which have
- * been transferred already.
- */
-
- patch = vmalloc(sizeof(*patch));
-
- if (patch == NULL)
- {
-/* printk(KERN_ERR "SoftOSS: Out of memory\n");*/
- return -ENOMEM;
- }
- if(copy_from_user(&((char *) patch)[offs], &(addr)[offs], sizeof_patch - offs))
- return -EFAULT;
-
- if (patch->mode & WAVE_ROM)
- {
- vfree(patch);
- return -EINVAL;
- }
- instr = patch->instr_no;
-
- if (instr < 0 || instr > MAX_PATCH)
- {
-/* printk(KERN_ERR "SoftOSS: Invalid patch number %d\n", instr);*/
- vfree(patch);
- return -EINVAL;
- }
- if (count < patch->len)
- {
-/* printk(KERN_ERR "SoftOSS: Patch record too short (%d<%d)\n", count, (int) patch->len);*/
- patch->len = count;
- }
- if (patch->len <= 0 || patch->len > (devc->ram_size - devc->ram_used))
- {
-/* printk(KERN_ERR "SoftOSS: Invalid sample length %d\n", (int) patch->len); */
- vfree(patch);
- return -EINVAL;
- }
- if (patch->mode & WAVE_LOOPING)
- {
- if (patch->loop_start < 0 || patch->loop_start >= patch->len)
- {
-/* printk(KERN_ERR "SoftOSS: Invalid loop start %d\n", patch->loop_start);*/
- vfree(patch);
- return -EINVAL;
- }
- if (patch->loop_end < patch->loop_start || patch->loop_end > patch->len)
- {
-/* printk(KERN_ERR "SoftOSS: Invalid loop start or end point (%d, %d)\n", patch->loop_start, patch->loop_end);*/
- vfree(patch);
- return -EINVAL;
- }
- }
- /*
- * Next load the wave data to memory
- */
-
- memlen = patch->len;
- adj = 1;
-
- if (!(patch->mode & WAVE_16_BITS))
- memlen *= 2;
- else
- adj = 2;
-
- wave = vmalloc(memlen);
-
- if (wave == NULL)
- {
-/* printk(KERN_ERR "SoftOSS: Can't allocate %d bytes of mem for a sample\n", memlen);*/
- vfree(patch);
- return -ENOMEM;
- }
- p = 0;
- for (i = 0; i < memlen / 2; i++) /* Handle words */
- {
- unsigned char tmp;
- data = 0;
- if (patch->mode & WAVE_16_BITS)
- {
- get_user(*(unsigned char *) &tmp, (unsigned char *) &((addr)[sizeof_patch + p++])); /* Get lsb */
- data = tmp;
- get_user(*(unsigned char *) &tmp, (unsigned char *) &((addr)[sizeof_patch + p++])); /* Get msb */
- if (patch->mode & WAVE_UNSIGNED)
- tmp ^= 0x80; /* Convert to signed */
- data |= (tmp << 8);
- }
- else
- {
- get_user(*(unsigned char *) &tmp, (unsigned char *) &((addr)[sizeof_patch + p++]));
- if (patch->mode & WAVE_UNSIGNED)
- tmp ^= 0x80; /* Convert to signed */
- data = (tmp << 8); /* Convert to 16 bits */
- }
- wave[i] = (short) data;
- }
-
- devc->ram_used += patch->len;
-
- /*
- * Convert pointers to 16 bit indexes
- */
- patch->len /= adj;
- patch->loop_start /= adj;
- patch->loop_end /= adj;
-
- /*
- * Finally link the loaded patch to the chain
- */
-
- patch->key = devc->programs[instr];
- devc->programs[instr] = devc->nrsamples;
- devc->wave[devc->nrsamples] = (short *) wave;
- devc->samples[devc->nrsamples++] = patch;
-


- return 0;
-}
-

-static void softsyn_panning(int dev, int voice, int pan)
-{
- if (voice < 0 || voice > devc->maxvoice)
- return;
-
- if (pan < -128)
- pan = -128;
- if (pan > 127)
- pan = 127;
-
- softoss_voices[voice].panning = pan;
- if (voice_active[voice])
- update_volume(voice);
-}
-
-static void softsyn_volume_method(int dev, int mode)
-{
-}
-
-static void softsyn_aftertouch(int dev, int voice, int pressure)
-{
- if (voice < 0 || voice > devc->maxvoice)
- return;
-
- if (voice_active[voice])
- update_volume(voice);
-}
-
-static void softsyn_controller(int dev, int voice, int ctrl_num, int value)
-{


- unsigned long flags;
-

- if (voice < 0 || voice > devc->maxvoice)
- return;
- save_flags(flags);
- cli();
-
- switch (ctrl_num)
- {
- case CTRL_PITCH_BENDER:
- softoss_voices[voice].bender = value;
- if (voice_active[voice])
- compute_step(voice); /* Update pitch */
- break;
-
-
- case CTRL_PITCH_BENDER_RANGE:
- softoss_voices[voice].bender_range = value;
- break;
-
- case CTL_EXPRESSION:
- value /= 128;
- case CTRL_EXPRESSION:
- softoss_voices[voice].expression_vol = value;
- if (voice_active[voice])
- update_volume(voice);
- break;
-
- case CTL_PAN:
- softsyn_panning(dev, voice, (value * 2) - 128);
- break;
-
- case CTL_MAIN_VOLUME:
- value = (value * 100) / 16383;
-
- case CTRL_MAIN_VOLUME:
- softoss_voices[voice].main_vol = value;
- if (voice_active[voice])
- update_volume(voice);
- break;
-
- default:
- break;
- }
- restore_flags(flags);
-}
-
-static void softsyn_bender(int dev, int voice, int value)
-{
- if (voice < 0 || voice > devc->maxvoice)
- return;
-
- softoss_voices[voice].bender = value - 8192;
- if (voice_active[voice])
- compute_step(voice); /* Update pitch */
-}
-
-static int softsyn_alloc_voice(int dev, int chn, int note, struct voice_alloc_info *alloc)
-{
- int i, p, best = -1, best_time = 0x7fffffff;
-
- p = alloc->ptr;
-
- /*
- * First look for a completely stopped voice
- */
-
- for (i = 0; i < alloc->max_voice; i++)
- {
- if (alloc->map[p] == 0)
- {
- alloc->ptr = p;
- voice_active[p] = 0;
- return p;
- }
- if (alloc->alloc_times[p] < best_time)
- {
- best = p;
- best_time = alloc->alloc_times[p];
- }
- p = (p + 1) % alloc->max_voice;
- }
-
- /*
- * Then look for a releasing voice
- */
-
- for (i = 0; i < alloc->max_voice; i++)
- {
- if (alloc->map[p] == 0xffff)
- {
- alloc->ptr = p;
- voice_active[p] = 0;
- return p;
- }
- p = (p + 1) % alloc->max_voice;
- }
-
- if (best >= 0)
- p = best;
-
- alloc->ptr = p;
- voice_active[p] = 0;
- return p;
-}
-
-static void softsyn_setup_voice(int dev, int voice, int chn)
-{


- unsigned long flags;
-

- struct channel_info *info = &synth_devs[dev]->chn_info[chn];
-
- save_flags(flags);
- cli();
-
- /* init_voice(devc, voice); */
- softsyn_set_instr(dev, voice, info->pgm_num);
-
- softoss_voices[voice].expression_vol = info->controllers[CTL_EXPRESSION]; /* Just MSB */
- softoss_voices[voice].main_vol = (info->controllers[CTL_MAIN_VOLUME] * 100) / (unsigned) 128;
- softsyn_panning(dev, voice, (info->controllers[CTL_PAN] * 2) - 128);
- softoss_voices[voice].bender = 0; /* info->bender_value; */
- softoss_voices[voice].bender_range = info->bender_range;
-
- if (chn == 9)
- softoss_voices[voice].percussive_voice = 1;
- restore_flags(flags);
-}
-
-static void softsyn_reset(int devno)
-{
- int i;


- unsigned long flags;
-

- save_flags(flags);
- cli();
-
- for (i = 0; i < devc->maxvoice; i++)
- init_voice(devc, i);
- restore_flags(flags);
-}
-
-static struct synth_operations softsyn_operations =
-{
- owner: THIS_MODULE,
- id: "SoftOSS",
- info: &softsyn_info,
- midi_dev: 0,
- synth_type: SYNTH_TYPE_SAMPLE,
- synth_subtype: 0,
- open: softsyn_open,
- close: softsyn_close,
- ioctl: softsyn_ioctl,
- kill_note: softsyn_kill_note,
- start_note: softsyn_start_note,
- set_instr: softsyn_set_instr,
- reset: softsyn_reset,
- hw_control: softsyn_hw_control,
- load_patch: softsyn_load_patch,
- aftertouch: softsyn_aftertouch,
- controller: softsyn_controller,
- panning: softsyn_panning,
- volume_method: softsyn_volume_method,
- bender: softsyn_bender,
- alloc_voice: softsyn_alloc_voice,
- setup_voice: softsyn_setup_voice
-};
-
-/*
- * Timer stuff (for /dev/music).
- */
-
-static unsigned int soft_tmr_start(int dev, unsigned int usecs)
-{
- tmr_running = 1;
- start_engine(devc);
- return devc->usecs_per_frag;
-}
-
-static void soft_tmr_disable(int dev)
-{
- stop_engine(devc);
- tmr_running = 0;
-}
-
-static void soft_tmr_restart(int dev)
-{
- tmr_running = 1;
-}
-
-static struct sound_lowlev_timer soft_tmr =
-{
- 0,
- 9999,
- soft_tmr_start,
- soft_tmr_disable,
- soft_tmr_restart
-};
-
-static int __init probe_softsyn(struct address_info *hw_config)


-{
- int i;
-

- if (softsynth_loaded)
- return 0;
-
- devc->ram_size = 8 * 1024 * 1024;
- devc->ram_used = 0;
- devc->nrsamples = 0;
- for (i = 0; i < MAX_PATCH; i++)
- {
- devc->programs[i] = NO_SAMPLE;
- devc->wave[i] = NULL;
- }
-
- devc->maxvoice = DEFAULT_VOICES;
-
- devc->audiodev = 0;
- devc->audio_opened = 0;
- devc->channels = 2;
- devc->bits = 16;
- devc->max_playahead = 32;
-
-#ifdef CONFIG_SOFTOSS_RATE
- devc->speed = CONFIG_SOFTOSS_RATE;
-#else
- devc->speed = 32000;
-#endif
-
-#ifdef CONFIG_SOFTOSS_VOICES
- devc->default_max_voices = CONFIG_SOFTOSS_VOICES;
-#else
- devc->default_max_voices = 32;
-#endif
- softsynth_loaded = 1;


- return 1;
-}
-

-static void __init attach_softsyn_card(struct address_info *hw_config)
-{
- voice_alloc = &softsyn_operations.alloc;
- synth_devs[devc->synthdev = num_synths++] = &softsyn_operations;
- sequencer_init();
- sound_timer_init(&soft_tmr, "SoftOSS");
- devc->timerdev = num_sound_timers;
- softsynthp = softsynth_hook;
-
-#ifndef POLLED_MODE
-#endif
-}
-
-static void __exit unload_softsyn(struct address_info *hw_config)
-{
- if (!softsynth_loaded)
- return;
- softsynthp = NULL;
- softsynth_loaded = 0;
- reset_samples(devc);
-}
-
-static struct address_info cfg;
-
-static int __init init_softoss(void)
-{
- printk(KERN_INFO "SoftOSS driver Copyright (C) by Hannu Savolainen 1993-1997\n");
- if (!probe_softsyn(&cfg))
- return -ENODEV;
- attach_softsyn_card(&cfg);
-


- return 0;
-}
-

-static void __exit cleanup_softoss(void)
-{
- unload_softsyn(&cfg);
- sound_unload_synthdev(devc->synthdev);
- sound_unload_timerdev(devc->timerdev);
-}
-
-module_init(init_softoss);
-module_exit(cleanup_softoss);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/softoss.h linux/drivers/sound/softoss.h
--- v2.4.0-test8/linux/drivers/sound/softoss.h Thu Feb 19 14:46:15 1998
+++ linux/drivers/sound/softoss.h Wed Dec 31 16:00:00 1969
@@ -1,161 +0,0 @@
-/*
- * softoss.h - Definitions for Software MIDI Synthesizer.
- */
-/*
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.
- */
-
-
-/*
- * Sequencer mode1 timer calls made by sequencer.c
- */
-extern int (*softsynthp) (int cmd, int parm1, int parm2, unsigned long parm3);
-
-#define SSYN_START 1
-#define SSYN_REQUEST 2 /* parm1 = time */
-#define SSYN_STOP 3
-#define SSYN_GETTIME 4 /* Returns number of ticks since reset */
-
-#define MAX_PATCH 256
-#define MAX_SAMPLE 512
-#define MAX_VOICE 32
-#define DEFAULT_VOICES 16
-
-typedef struct voice_info
-{
-/*
- * Don't change anything in the beginning of this struct. These fields are used
- * by the resampling loop which may have been written in assembly for some
- * architectures. Any change may make the resampling code incompatible
- */
- int instr;
- short *wave;
- struct patch_info *sample;
-
- unsigned int ptr; int step; /* Pointer to the wave data and pointer increment */
-
- int mode;
- int startloop, startbackloop, endloop, looplen;
-
- unsigned int leftvol, rightvol;
-/***** Don't change anything above this */
-
- volatile unsigned long orig_freq, current_freq;
- volatile int bender, bender_range, panning;
- volatile int main_vol, expression_vol, patch_vol, velocity;
-
-/* Envelope parameters */
-
- int envelope_phase;
- volatile int envelope_vol;
- volatile int envelope_volstep;
- int envelope_time; /* Number of remaining envelope steps */
- unsigned int envelope_target;
- int percussive_voice;
- int sustain_mode; /* 0=off, 1=sustain on, 2=sustain on+key released */
-
-/* Vibrato */
- int vibrato_rate;
- int vibrato_depth;
- int vibrato_phase;
- int vibrato_step;
- int vibrato_level;
-
-/* Tremolo */
- int tremolo_rate;
- int tremolo_depth;
- int tremolo_phase;
- int tremolo_step;
- int tremolo_level;
-} voice_info;
-
-extern voice_info softoss_voices[MAX_VOICE]; /* Voice spesific info */
-
-typedef struct softsyn_devc
-{
-/*
- * Don't change anything in the beginning of this struct. These fields are used
- * by the resampling loop which may have been written in assembly for some
- * architectures. Any change may make the resampling code incompatible
- */
- int maxvoice; /* # of voices to be processed */
- int afterscale;
- int delay_size;
- int control_rate, control_counter;
-/***** Don't change anything above this */
-
- int ram_size;
- int ram_used;
-
- int synthdev;
- int timerdev;
- int sequencer_mode;
-/*
- * Audio parameters
- */
-
- int audiodev;
- int audio_opened;
- int speed;
- int channels;
- int bits;
- int default_max_voices;
- int max_playahead;
- struct file finfo;
- int fragsize;
- int samples_per_fragment;
-
-/*
- * Sample storage
- */
- int nrsamples;
- struct patch_info *samples[MAX_SAMPLE];
- short *wave[MAX_SAMPLE];
-
-/*
- * Programs
- */
- int programs[MAX_PATCH];
-
-/*
- * Timer parameters
- */
- volatile unsigned long usecs;
- volatile unsigned long usecs_per_frag;
- volatile unsigned long next_event_usecs;


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 087'
echo 'File patch-2.4.0-test9 is continued in part 088'
echo "088" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part082

#!/bin/sh -x
# this is part 082 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 082; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ timeout = 1000;


+ while (timeout > 0) {
+ if (ha->revision_id == IPS_REVID_TROMBONE64) {
+ writel(0, ha->mem_ptr + IPS_REG_FLAP);
+ UDELAY(5); /* 5 us */
+ }
+
+ status = readb(ha->mem_ptr + IPS_REG_FLDP);
+
+ if (status & 0x80)
+ break;
+
+ MDELAY(1);
+ timeout--;
+ }
+

+ if (timeout == 0) {
+ /* timeout error */


+ writel(0, ha->mem_ptr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ UDELAY(5); /* 5 us */
+

+ writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ UDELAY(5); /* 5 us */
+

+ return (1);
+ }
+

+ /* check the status */
+ if (status & 0x18) {
+ /* programming error */


+ writel(0, ha->mem_ptr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ UDELAY(5); /* 5 us */
+

+ writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ UDELAY(5); /* 5 us */
+

+ return (1);
+ }
+ } /* end for */
+
+ /* Enable reading */


+ writel(0, ha->mem_ptr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ UDELAY(5); /* 5 us */
+

+ writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ UDELAY(5); /* 5 us */
+
+ return (0);
+}
+
+/****************************************************************************/
+/* */

X /* Routine Name: ips_verify_bios */


X /* */
X /* Routine Description: */

@@ -5173,6 +6545,8 @@
X u8 checksum;
X int i;
X
+ METHOD_TRACE("ips_verify_bios", 1);
+
X /* test 1st byte */


X outl(0, ha->io_addr + IPS_REG_FLAP);
X if (ha->revision_id == IPS_REVID_TROMBONE64)

@@ -5205,13 +6579,56 @@


X return (0);
X }
X

-#if defined (MODULE)
+/****************************************************************************/
+/* */
+/* Routine Name: ips_verify_bios_memio */


+/* */
+/* Routine Description: */

+/* Verify the BIOS on the adapter */


+/* */
+/****************************************************************************/
+static int

+ips_verify_bios_memio(ips_ha_t *ha, char *buffer, int buffersize) {
+ u8 checksum;
+ int i;
+
+ METHOD_TRACE("ips_verify_bios_memio", 1);
+
+ /* test 1st byte */


+ writel(0, ha->mem_ptr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ UDELAY(5); /* 5 us */

X
-Scsi_Host_Template driver_template = IPS;
+ if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55)
+ return (1);
X
- #include "scsi_module.c"
+ writel(1, ha->mem_ptr + IPS_REG_FLAP);


+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ UDELAY(5); /* 5 us */

+ if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA)
+ return (1);
+
+ checksum = 0xff;
+ for (i = 2; i < buffersize; i++) {
+


+ writel(i, ha->mem_ptr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ UDELAY(5); /* 5 us */
+

+ checksum = (u8) checksum + readb(ha->mem_ptr + IPS_REG_FLDP);
+ }
+
+ if (checksum != 0)
+ /* failure */
+ return (1);
+ else
+ /* success */


+ return (0);
+}
+

+static Scsi_Host_Template driver_template = IPS;
+#include "scsi_module.c"
X
-#endif
X
X
X /*
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/ips.h linux/drivers/scsi/ips.h
--- v2.4.0-test8/linux/drivers/scsi/ips.h Fri Sep 8 12:54:34 2000
+++ linux/drivers/scsi/ips.h Thu Sep 21 13:22:05 2000
@@ -1,5 +1,5 @@
X /*****************************************************************************/
-/* ips.h -- driver for the IBM ServeRAID adapter */
+/* ips.h -- driver for the IBM ServeRAID controller */
X /* */
X /* Written By: Keith Mitchell, IBM Corporation */
X /* */
@@ -53,8 +53,6 @@
X /* Prototypes */
X extern int ips_detect(Scsi_Host_Template *);
X extern int ips_release(struct Scsi_Host *);
- extern int ips_abort(Scsi_Cmnd *);
- extern int ips_reset(Scsi_Cmnd *, unsigned int);
X extern int ips_eh_abort(Scsi_Cmnd *);
X extern int ips_eh_reset(Scsi_Cmnd *);
X extern int ips_queue(Scsi_Cmnd *, void (*) (Scsi_Cmnd *));
@@ -71,7 +69,21 @@
X
X #define IPS_HA(x) ((ips_ha_t *) x->hostdata)
X #define IPS_COMMAND_ID(ha, scb) (int) (scb - ha->scbs)
-
+ #define IPS_IS_TROMBONE(ha) (((ha->device_id == IPS_COPPERHEAD_DEVICEID) && \
+ (ha->revision_id >= IPS_REVID_TROMBONE32) && \
+ (ha->revision_id <= IPS_REVID_TROMBONE64)) ? 1 : 0)
+ #define IPS_IS_CLARINET(ha) (((ha->device_id == IPS_COPPERHEAD_DEVICEID) && \
+ (ha->revision_id >= IPS_REVID_CLARINETP1) && \
+ (ha->revision_id <= IPS_REVID_CLARINETP3)) ? 1 : 0)
+ #define IPS_IS_MORPHEUS(ha) (ha->device_id == IPS_MORPHEUS_DEVICEID)
+ #define IPS_USE_I2O_DELIVER(ha) ((IPS_IS_MORPHEUS(ha) || \
+ (IPS_IS_TROMBONE(ha) && \
+ (ips_force_i2o))) ? 1 : 0)
+ #define IPS_USE_I2O_STATUS(ha) (IPS_IS_MORPHEUS(ha))
+ #define IPS_USE_MEMIO(ha) ((IPS_IS_MORPHEUS(ha) || \
+ ((IPS_IS_TROMBONE(ha) || IPS_IS_CLARINET(ha)) && \
+ (ips_force_memio))) ? 1 : 0)
+
X #ifndef VIRT_TO_BUS
X #define VIRT_TO_BUS(x) (unsigned int)virt_to_bus((void *) x)
X #endif
@@ -79,7 +91,7 @@
X #ifndef UDELAY
X #define UDELAY udelay
X #endif
-
+
X #ifndef MDELAY
X #define MDELAY mdelay
X #endif
@@ -87,15 +99,15 @@
X #ifndef verify_area_20
X #define verify_area_20(t,a,sz) (0) /* success */
X #endif
-
+
X #ifndef PUT_USER
X #define PUT_USER put_user
X #endif
-
+
X #ifndef __PUT_USER
X #define __PUT_USER __put_user
X #endif
-
+
X #ifndef GET_USER
X #define GET_USER get_user
X #endif
@@ -129,6 +141,14 @@
X #define IPS_REG_CBSP 0x07 /* CBSP register */
X #define IPS_REG_FLAP 0x18 /* Flash address port */
X #define IPS_REG_FLDP 0x1C /* Flash data port */
+ #define IPS_REG_NDAE 0x38 /* Anaconda 64 NDAE Register */
+ #define IPS_REG_I2O_INMSGQ 0x40 /* I2O Inbound Message Queue */
+ #define IPS_REG_I2O_OUTMSGQ 0x44 /* I2O Outbound Message Queue */
+ #define IPS_REG_I2O_HIR 0x30 /* I2O Interrupt Status */
+ #define IPS_REG_I960_IDR 0x20 /* i960 Inbound Doorbell */
+ #define IPS_REG_I960_MSG0 0x18 /* i960 Outbound Reg 0 */
+ #define IPS_REG_I960_MSG1 0x1C /* i960 Outbound Reg 1 */
+ #define IPS_REG_I960_OIMR 0x34 /* i960 Oubound Int Mask Reg */
X
X /*
X * Adapter register bit equates
@@ -144,6 +164,9 @@
X #define IPS_BIT_EBM 0x02 /* SCPR Enable Bus Master */
X #define IPS_BIT_EI 0x80 /* HISR Enable Interrupts */
X #define IPS_BIT_OP 0x01 /* OP bit in CBSP */
+ #define IPS_BIT_I2O_OPQI 0x08 /* General Host Interrupt */
+ #define IPS_BIT_I960_MSG0I 0x01 /* Message Register 0 Interrupt*/
+ #define IPS_BIT_I960_MSG1I 0x02 /* Message Register 1 Interrupt*/
X
X /*
X * Adapter Command ID Equates
@@ -194,13 +217,15 @@
X #define IPS_INTR_HAL 2
X #define IPS_ADAPTER_ID 0xF
X #define IPS_VENDORID 0x1014
- #define IPS_DEVICEID 0x002E
+ #define IPS_COPPERHEAD_DEVICEID 0x002E
+ #define IPS_MORPHEUS_DEVICEID 0x01BD
X #define IPS_IOCTL_SIZE 8192
X #define IPS_STATUS_SIZE 4
X #define IPS_STATUS_Q_SIZE (IPS_MAX_CMDS+1) * IPS_STATUS_SIZE
+ #define IPS_MEMMAP_SIZE 128
X #define IPS_ONE_MSEC 1
X #define IPS_ONE_SEC 1000
-
+
X /*
X * Geometry Settings
X */
@@ -328,6 +353,37 @@
X /*
X * Scsi_Host Template
X */
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27)
+ #define IPS { \
+ next : NULL, \
+ module : NULL, \
+ proc_info : NULL, \
+ proc_dir : NULL, \
+ name : NULL, \
+ detect : ips_detect, \
+ release : ips_release, \
+ info : ips_info, \
+ command : NULL, \
+ queuecommand : ips_queue, \
+ eh_strategy_handler : NULL, \
+ eh_abort_handler : ips_eh_abort, \
+ eh_device_reset_handler : NULL, \
+ eh_bus_reset_handler : NULL, \
+ eh_host_reset_handler : ips_eh_reset, \
+ abort : NULL, \
+ reset : NULL, \
+ slave_attach : NULL, \
+ bios_param : ips_biosparam, \
+ can_queue : 0, \
+ this_id: -1, \
+ sg_tablesize : IPS_MAX_SG, \
+ cmd_per_lun: 16, \


+ present : 0, \
+ unchecked_isa_dma : 0, \

+ use_clustering : ENABLE_CLUSTERING, \
+ use_new_eh_code : 1 \
+}
+#else
X #define IPS { \
X next : NULL, \
X module : NULL, \
@@ -343,8 +399,8 @@
X eh_device_reset_handler : NULL, \
X eh_bus_reset_handler : NULL, \
X eh_host_reset_handler : ips_eh_reset, \
- abort : ips_abort, \
- reset : ips_reset, \
+ abort : NULL, \
+ reset : NULL, \
X slave_attach : NULL, \
X bios_param : ips_biosparam, \
X can_queue : 0, \
@@ -355,7 +411,8 @@
X unchecked_isa_dma : 0, \
X use_clustering : ENABLE_CLUSTERING, \
X use_new_eh_code : 1 \
- }
+}
+#endif
X
X /*
X * IBM PCI Raid Command Formats
@@ -523,11 +580,15 @@
X u8 reserved2[3];
X } IPS_DCDB_TABLE, *PIPS_DCDB_TABLE;
X
-typedef struct {
- volatile u8 reserved;
- volatile u8 command_id;
- volatile u8 basic_status;
- volatile u8 extended_status;
+typedef union {
+ struct {
+ volatile u8 reserved;
+ volatile u8 command_id;
+ volatile u8 basic_status;
+ volatile u8 extended_status;
+ } fields;
+
+ volatile u32 value;
X } IPS_STATUS, *PIPS_STATUS;
X
X typedef struct {
@@ -602,7 +663,7 @@
X u8 ucCompression;
X u8 ucNvramType;
X u32 ulNvramSize;
-} IPS_HARDWARE, *PIPS_HARDWARE;
+} IPS_HARDWARE, *PIPS_HARDWARE;
X
X typedef struct {
X u8 ucLogDriveCount;
@@ -769,8 +830,15 @@
X int length;
X int offset;
X int pos;
+ int localpos;
X } IPS_INFOSTR;
X
+typedef struct {
+ char *option_name;
+ int *option_flag;
+ int option_value;
+} IPS_OPTION;
+
X /*
X * Status Info
X */
@@ -815,6 +883,24 @@
X spinlock_t lock;
X } ips_copp_queue_t;
X
+/* forward decl for host structure */
+struct ips_ha;
+
+typedef struct {
+ int (*reset)(struct ips_ha *);
+ int (*issue)(struct ips_ha *, struct ips_scb *);
+ int (*isinit)(struct ips_ha *);
+ int (*isintr)(struct ips_ha *);
+ int (*init)(struct ips_ha *);
+ int (*erasebios)(struct ips_ha *);
+ int (*programbios)(struct ips_ha *, char *, int);
+ int (*verifybios)(struct ips_ha *, char *, int);
+ u32 (*statupd)(struct ips_ha *);
+ void (*statinit)(struct ips_ha *);
+ void (*intr)(struct ips_ha *);
+ void (*enableint)(struct ips_ha *);
+} ips_hw_func_t;
+
X typedef struct ips_ha {
X u8 ha_id[IPS_MAX_CHANNELS+1];
X u32 dcdb_active[IPS_MAX_CHANNELS];
@@ -849,12 +935,18 @@
X u16 reset_count; /* number of resets */
X u32 last_ffdc; /* last time we sent ffdc info*/
X u8 revision_id; /* Revision level */
-
- #if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,0)
+ u16 device_id; /* PCI device ID */
+ u8 reserved;
+ u32 mem_addr; /* Memory mapped address */
+ u32 io_len; /* Size of IO Address */
+ u32 mem_len; /* Size of memory address */
+ char *mem_ptr; /* Memory mapped Ptr */
+ char *ioremap_ptr; /* ioremapped memory pointer */
+ ips_hw_func_t func; /* hw function pointers */
+ struct pci_dev *pcidev; /* PCI device handle */
X spinlock_t scb_lock;
X spinlock_t copp_lock;
X spinlock_t ips_lock;
- #endif
X } ips_ha_t;
X
X typedef void (*ips_scb_callback) (ips_ha_t *, struct ips_scb *);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/mac53c94.c linux/drivers/scsi/mac53c94.c
--- v2.4.0-test8/linux/drivers/scsi/mac53c94.c Thu Nov 11 16:57:30 1999
+++ linux/drivers/scsi/mac53c94.c Tue Sep 19 08:31:53 2000
@@ -47,6 +47,7 @@
X Scsi_Cmnd *current_req; /* req we're currently working on */
X enum fsc_phase phase; /* what we're currently trying to do */
X struct dbdma_cmd *dma_cmds; /* space for dbdma commands, aligned */
+ void *dma_cmd_space;
X };
X
X static struct fsc_state *all_53c94s;
@@ -113,6 +114,7 @@
X DBDMA_ALIGN(dma_cmd_space);
X memset(state->dma_cmds, 0, (host->sg_tablesize + 1)
X * sizeof(struct dbdma_cmd));
+ state->dma_cmd_space = dma_cmd_space;
X
X *prev_statep = state;
X prev_statep = &state->next;
@@ -130,6 +132,22 @@
X }
X
X int
+mac53c94_release(struct Scsi_Host *host)
+{
+ struct fsc_state *fp = (struct fsc_state *) host->hostdata;
+
+ if (fp == 0)
+ return 0;
+ if (fp->regs)
+ iounmap((void *) fp->regs);
+ if (fp->dma)
+ iounmap((void *) fp->dma);
+ kfree(fp->dma_cmd_space);
+ free_irq(fp->intr, fp);


+ return 0;
+}
+

+int
X mac53c94_queue(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
X {
X unsigned long flags;
@@ -537,3 +555,7 @@


X return 0;
X }
X }

+
+static Scsi_Host_Template driver_template = SCSI_MAC53C94;
+
+#include "scsi_module.c"
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/mac53c94.h linux/drivers/scsi/mac53c94.h
--- v2.4.0-test8/linux/drivers/scsi/mac53c94.h Thu Nov 11 16:57:30 1999
+++ linux/drivers/scsi/mac53c94.h Tue Sep 19 08:31:53 2000
@@ -8,6 +8,7 @@
X #define _MAC53C94_H
X
X int mac53c94_detect(Scsi_Host_Template *);
+int mac53c94_release(struct Scsi_Host *);
X int mac53c94_command(Scsi_Cmnd *);
X int mac53c94_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
X int mac53c94_abort(Scsi_Cmnd *);
@@ -17,6 +18,7 @@
X proc_name: "53c94", \
X name: "53C94", \
X detect: mac53c94_detect, \
+ release: mac53c94_release, \
X command: mac53c94_command, \
X queuecommand: mac53c94_queue, \
X abort: mac53c94_abort, \
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/mac_scsi.c linux/drivers/scsi/mac_scsi.c
--- v2.4.0-test8/linux/drivers/scsi/mac_scsi.c Mon Jun 19 17:59:41 2000
+++ linux/drivers/scsi/mac_scsi.c Mon Sep 18 13:36:25 2000
@@ -662,9 +662,6 @@


X
X
X
-#ifdef MODULE
-

-Scsi_Host_Template driver_template = MAC_NCR5380;
+static Scsi_Host_Template driver_template = MAC_NCR5380;


X
X #include "scsi_module.c"
-#endif

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/mca_53c9x.c linux/drivers/scsi/mca_53c9x.c
--- v2.4.0-test8/linux/drivers/scsi/mca_53c9x.c Tue Sep 7 10:14:37 1999
+++ linux/drivers/scsi/mca_53c9x.c Mon Sep 18 13:36:25 2000
@@ -419,10 +419,8 @@
X outb(inb(PS2_SYS_CTR) & 0x3f, PS2_SYS_CTR);
X }
X
-#ifdef MODULE
-Scsi_Host_Template driver_template = MCA_53C9X;
+static Scsi_Host_Template driver_template = MCA_53C9X;


X #include "scsi_module.c"
-#endif
X
X /*

X * OK, here's the goods I promised. The NCR 86C01 is an MCA interface chip
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/megaraid.c linux/drivers/scsi/megaraid.c
--- v2.4.0-test8/linux/drivers/scsi/megaraid.c Mon Jun 19 13:42:40 2000
+++ linux/drivers/scsi/megaraid.c Mon Sep 18 13:36:25 2000
@@ -2032,8 +2032,6 @@
X
X __setup("megaraid=", megaraid_setup);
X
-#ifdef MODULE
-Scsi_Host_Template driver_template = MEGARAID;
+static Scsi_Host_Template driver_template = MEGARAID;


X
X #include "scsi_module.c"
-#endif

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/mesh.c linux/drivers/scsi/mesh.c
--- v2.4.0-test8/linux/drivers/scsi/mesh.c Mon Feb 14 13:37:25 2000
+++ linux/drivers/scsi/mesh.c Tue Sep 19 08:31:53 2000
@@ -149,6 +149,8 @@
X struct dbdma_cmd *dma_cmds; /* space for dbdma commands, aligned */
X int clk_freq;
X struct mesh_target tgts[8];
+ void *dma_cmd_space;
+ struct device_node *ofnode;
X #ifndef MESH_NEW_STYLE_EH
X Scsi_Cmnd *completed_q;
X Scsi_Cmnd *completed_qtail;
@@ -262,6 +264,7 @@
X panic("no mesh state");
X memset(ms, 0, sizeof(*ms));
X ms->host = mesh_host;
+ ms->ofnode = mesh;
X ms->mesh = (volatile struct mesh_regs *)
X ioremap(mesh->addrs[0].address, 0x1000);
X ms->dma = (volatile struct dbdma_regs *)
@@ -278,6 +281,7 @@
X ms->dma_cmds = (struct dbdma_cmd *) DBDMA_ALIGN(dma_cmd_space);
X memset(ms->dma_cmds, 0, (mesh_host->sg_tablesize + 1)
X * sizeof(struct dbdma_cmd));
+ ms->dma_cmd_space = dma_cmd_space;
X
X ms->current_req = 0;
X for (tgt = 0; tgt < 8; ++tgt) {
@@ -324,6 +328,23 @@
X }
X
X int
+mesh_release(struct Scsi_Host *host)
+{
+ struct mesh_state *ms = (struct mesh_state *) host->hostdata;
+
+ if (ms == 0)
+ return 0;
+ if (ms->mesh)
+ iounmap((void *) ms->mesh);
+ if (ms->dma)
+ iounmap((void *) ms->dma);
+ kfree(ms->dma_cmd_space);
+ free_irq(ms->meshintr, ms);
+ feature_clear(ms->ofnode, FEATURE_MESH_enable);


+ return 0;
+}
+

+int
X mesh_queue(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
X {
X unsigned long flags;
@@ -1910,3 +1931,7 @@
X } while (i != ms->log_ix);
X }
X #endif /* MESH_DBG */
+
+static Scsi_Host_Template driver_template = SCSI_MESH;
+
+#include "scsi_module.c"
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/mesh.h linux/drivers/scsi/mesh.h
--- v2.4.0-test8/linux/drivers/scsi/mesh.h Thu Nov 11 16:57:30 1999
+++ linux/drivers/scsi/mesh.h Tue Sep 19 08:31:53 2000
@@ -8,6 +8,7 @@
X #define _MESH_H
X
X int mesh_detect(Scsi_Host_Template *);
+int mesh_release(struct Scsi_Host *);
X int mesh_command(Scsi_Cmnd *);
X int mesh_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
X int mesh_abort(Scsi_Cmnd *);
@@ -17,6 +18,7 @@
X proc_name: "mesh", \
X name: "MESH", \
X detect: mesh_detect, \
+ release: mesh_release, \
X command: mesh_command, \
X queuecommand: mesh_queue, \
X abort: mesh_abort, \
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/mvme16x.h linux/drivers/scsi/mvme16x.h
--- v2.4.0-test8/linux/drivers/scsi/mvme16x.h Fri Sep 8 12:54:34 2000
+++ linux/drivers/scsi/mvme16x.h Mon Sep 18 14:09:49 2000


@@ -23,7 +23,6 @@
X #define CAN_QUEUE 24

X #endif
X
-#if defined(HOSTS_C) || defined(MODULE)

X #include <scsi/scsicam.h>
X
X #define MVME16x_SCSI {name: "MVME16x NCR53c710 SCSI", \


@@ -37,5 +36,5 @@
X sg_tablesize: 63, \
X cmd_per_lun: 3, \
X use_clustering: DISABLE_CLUSTERING }
-#endif
+

X #endif /* MVME16x_SCSI_H */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c
--- v2.4.0-test8/linux/drivers/scsi/ncr53c8xx.c Mon Jun 19 17:59:41 2000
+++ linux/drivers/scsi/ncr53c8xx.c Mon Sep 18 13:36:25 2000
@@ -9513,7 +9513,5 @@
X ** Module stuff
X */
X
-#ifdef MODULE
-Scsi_Host_Template driver_template = NCR53C8XX;
+static Scsi_Host_Template driver_template = NCR53C8XX;
X #include "scsi_module.c"
-#endif
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/ncr53c8xx.h linux/drivers/scsi/ncr53c8xx.h
--- v2.4.0-test8/linux/drivers/scsi/ncr53c8xx.h Fri Sep 8 12:54:35 2000
+++ linux/drivers/scsi/ncr53c8xx.h Mon Sep 18 14:09:49 2000
@@ -50,8 +50,6 @@
X ** Used by hosts.c and ncr53c8xx.c with module configuration.
X */


X
-#if defined(HOSTS_C) || defined(MODULE)
-

X #include <scsi/scsicam.h>
X
X int ncr53c8xx_abort(Scsi_Cmnd *);
@@ -95,7 +93,5 @@
X 0, 0, DISABLE_CLUSTERING}
X
X #endif /* LINUX_VERSION_CODE */


-
-#endif /* defined(HOSTS_C) || defined(MODULE) */
X

X #endif /* NCR53C8XX_H */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/oktagon_esp.c linux/drivers/scsi/oktagon_esp.c
--- v2.4.0-test8/linux/drivers/scsi/oktagon_esp.c Wed Jan 26 12:45:20 2000
+++ linux/drivers/scsi/oktagon_esp.c Mon Sep 18 13:36:25 2000
@@ -570,17 +570,14 @@
X sp->SCp.ptr = sp->SCp.buffer->address;


X }
X
-#ifdef MODULE
X

X #define HOSTS_C
X
X #include "oktagon_esp.h"
X
-Scsi_Host_Template driver_template = SCSI_OKTAGON_ESP;
+static Scsi_Host_Template driver_template = SCSI_OKTAGON_ESP;


X
X #include "scsi_module.c"
-
-#endif
X

X int oktagon_esp_release(struct Scsi_Host *instance)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/pas16.c linux/drivers/scsi/pas16.c
--- v2.4.0-test8/linux/drivers/scsi/pas16.c Thu Nov 11 16:57:30 1999
+++ linux/drivers/scsi/pas16.c Mon Sep 18 13:36:25 2000
@@ -597,12 +597,12 @@
X
X #include "NCR5380.c"


X
-#ifdef MODULE
X /* Eventually this will go into an include file, but this will be later */

-Scsi_Host_Template driver_template = MV_PAS16;
+static Scsi_Host_Template driver_template = MV_PAS16;


X
X #include "scsi_module.c"
X

+#ifdef MODULE
X MODULE_PARM(pas16_addr, "h");
X MODULE_PARM(pas16_irq, "i");
X #endif
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/pas16.h linux/drivers/scsi/pas16.h
--- v2.4.0-test8/linux/drivers/scsi/pas16.h Sat Apr 11 11:13:25 1998
+++ linux/drivers/scsi/pas16.h Mon Sep 18 14:10:10 2000
@@ -140,8 +140,6 @@


X * macros when this is being used solely for the host stub.
X */

X
-#if defined(HOSTS_C) || defined(MODULE)
-

X #define MV_PAS16 { \
X name: "Pro Audio Spectrum-16 SCSI", \
X detect: pas16_detect, \
@@ -155,7 +153,6 @@


X cmd_per_lun: CMD_PER_LUN , \
X use_clustering: DISABLE_CLUSTERING}

X
-#endif
X #ifndef HOSTS_C
X
X #define NCR5380_implementation_fields \
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/pci2000.c linux/drivers/scsi/pci2000.c
--- v2.4.0-test8/linux/drivers/scsi/pci2000.c Mon Jun 19 13:42:40 2000
+++ linux/drivers/scsi/pci2000.c Mon Sep 18 13:36:25 2000
@@ -855,9 +855,7 @@


X }
X
X
-#ifdef MODULE

X /* Eventually this will go into an include file, but this will be later */

-Scsi_Host_Template driver_template = PCI2000;
+static Scsi_Host_Template driver_template = PCI2000;


X
X #include "scsi_module.c"
-#endif

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/pci2220i.c linux/drivers/scsi/pci2220i.c
--- v2.4.0-test8/linux/drivers/scsi/pci2220i.c Mon Jun 19 13:42:40 2000
+++ linux/drivers/scsi/pci2220i.c Mon Sep 18 13:36:25 2000
@@ -2509,7 +2509,7 @@
X init_timer (&padapter->reconTimer);
X padapter->reconTimer.function = ReconTimerExpiry;
X padapter->reconTimer.data = (unsigned long)padapter;
- printk("\nPCI-%sI EIDE CONTROLLER: at I/O = %lX/%lX IRQ = %ld\n", str, padapter->basePort, padapter->regBase, irq);
+ printk("\nPCI-%sI EIDE CONTROLLER: at I/O = %lX/%lX IRQ = %d\n", str, padapter->basePort, padapter->regBase, irq);
X printk("Version %s, Compiled %s %s\n\n", PCI2220I_VERSION, __DATE__, __TIME__);
X }
X /****************************************************************
@@ -2920,9 +2920,7 @@


X }
X
X
-#ifdef MODULE

X /* Eventually this will go into an include file, but this will be later */

-Scsi_Host_Template driver_template = PCI2220I;
+static Scsi_Host_Template driver_template = PCI2220I;


X
X #include "scsi_module.c"
-#endif

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/pluto.c linux/drivers/scsi/pluto.c
--- v2.4.0-test8/linux/drivers/scsi/pluto.c Fri Jul 14 12:20:22 2000
+++ linux/drivers/scsi/pluto.c Mon Sep 18 13:36:25 2000
@@ -331,11 +331,8 @@


X return 0;
X }
X

-#ifdef MODULE
-
-Scsi_Host_Template driver_template = PLUTO;
+static Scsi_Host_Template driver_template = PLUTO;


X
X #include "scsi_module.c"
X
X EXPORT_NO_SYMBOLS;
-#endif /* MODULE */

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/ppa.c linux/drivers/scsi/ppa.c
--- v2.4.0-test8/linux/drivers/scsi/ppa.c Mon Jul 24 18:59:27 2000
+++ linux/drivers/scsi/ppa.c Mon Sep 18 13:36:25 2000
@@ -99,10 +99,8 @@


X * Parallel port probing routines *
X ***************************************************************************/
X
-#ifdef MODULE

-Scsi_Host_Template driver_template = PPA;
+static Scsi_Host_Template driver_template = PPA;


X #include "scsi_module.c"
-#endif
X
X /*

X * Start of Chipset kludges
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/psi240i.c linux/drivers/scsi/psi240i.c
--- v2.4.0-test8/linux/drivers/scsi/psi240i.c Thu Nov 11 16:57:30 1999
+++ linux/drivers/scsi/psi240i.c Mon Sep 18 13:36:25 2000
@@ -713,10 +713,8 @@


X }
X
X
-#ifdef MODULE

X /* Eventually this will go into an include file, but this will be later */

-Scsi_Host_Template driver_template = PSI240I;
+static Scsi_Host_Template driver_template = PSI240I;


X
X #include "scsi_module.c"
-#endif

X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/qla1280.c linux/drivers/scsi/qla1280.c
--- v2.4.0-test8/linux/drivers/scsi/qla1280.c Mon Jun 19 13:42:40 2000
+++ linux/drivers/scsi/qla1280.c Mon Sep 18 13:36:25 2000
@@ -6163,11 +6163,9 @@
X /*
X * Declarations for load module
X */
-#ifdef MODULE
-Scsi_Host_Template driver_template = QLA1280_LINUX_TEMPLATE;
+static Scsi_Host_Template driver_template = QLA1280_LINUX_TEMPLATE;


X
X #include "scsi_module.c"
-#endif
X

X /************************************************************************
X * qla1280_check_for_dead_scsi_bus *
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/qlogicfas.c linux/drivers/scsi/qlogicfas.c
--- v2.4.0-test8/linux/drivers/scsi/qlogicfas.c Tue Feb 15 08:53:46 2000
+++ linux/drivers/scsi/qlogicfas.c Mon Sep 18 13:36:25 2000
@@ -643,8 +643,10 @@
X ip[0] = 0xff;
X ip[1] = 0x3f;
X ip[2] = disk->capacity / (ip[0] * ip[1]);
+#if 0
X if (ip[2] > 1023)
X ip[2] = 1023;
+#endif


X }
X return 0;
X }

@@ -674,10 +676,7 @@
X return qinfo;


X }
X
-#ifdef MODULE
X /* Eventually this will go into an include file, but this will be later */

-Scsi_Host_Template driver_template = QLOGICFAS;
-
+static Scsi_Host_Template driver_template = QLOGICFAS;
X #include "scsi_module.c"
-#endif
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/qlogicfc.c linux/drivers/scsi/qlogicfc.c
--- v2.4.0-test8/linux/drivers/scsi/qlogicfc.c Fri Aug 11 14:30:35 2000
+++ linux/drivers/scsi/qlogicfc.c Mon Sep 18 13:36:25 2000
@@ -2226,10 +2226,6 @@
X #endif /* DEBUG_ISP2x00 */


X
X
-#ifdef MODULE
-

-Scsi_Host_Template driver_template = QLOGICFC;
+static Scsi_Host_Template driver_template = QLOGICFC;


X
X #include "scsi_module.c"
-
-#endif

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/qlogicisp.c linux/drivers/scsi/qlogicisp.c
--- v2.4.0-test8/linux/drivers/scsi/qlogicisp.c Mon Jun 19 13:42:41 2000
+++ linux/drivers/scsi/qlogicisp.c Mon Sep 18 13:36:25 2000
@@ -1989,8 +1989,6 @@
X #endif /* DEBUG_ISP1020 */
X
X
-#ifdef MODULE
-Scsi_Host_Template driver_template = QLOGICISP;
+static Scsi_Host_Template driver_template = QLOGICISP;
X
X #include "scsi_module.c"
-#endif /* MODULE */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/qlogicpti.c linux/drivers/scsi/qlogicpti.c
--- v2.4.0-test8/linux/drivers/scsi/qlogicpti.c Mon Aug 28 12:00:08 2000
+++ linux/drivers/scsi/qlogicpti.c Mon Sep 18 13:36:25 2000
@@ -1526,10 +1526,8 @@
X return return_status;
X }
X
-#ifdef MODULE
-Scsi_Host_Template driver_template = QLOGICPTI;
+static Scsi_Host_Template driver_template = QLOGICPTI;


X
X #include "scsi_module.c"
X
X EXPORT_NO_SYMBOLS;
-#endif /* MODULE */

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- v2.4.0-test8/linux/drivers/scsi/scsi.c Mon Jul 31 11:00:06 2000
+++ linux/drivers/scsi/scsi.c Wed Sep 27 14:10:54 2000
@@ -36,6 +36,9 @@
X * out_of_space hacks, D. Gilbert (dpg) 990608
X */
X
+#define REVISION "Revision: 1.00"
+#define VERSION "Id: scsi.c 1.00 2000/09/26"
+
X #include <linux/config.h>
X #include <linux/module.h>
X
@@ -384,7 +387,7 @@
X * return NULL.
X */
X SCpnt = NULL;
- break;
+ goto busy;
X }
X }
X /*
@@ -402,6 +405,7 @@
X if (SCpnt) {
X break;
X }
+ busy:
X /*
X * If we have been asked to wait for a free block, then
X * wait here.
@@ -495,30 +499,7 @@
X return SCpnt;
X }
X
-/*
- * Function: scsi_release_command
- *
- * Purpose: Release a command block.
- *
- * Arguments: SCpnt - command block we are releasing.
- *
- * Notes: The command block can no longer be used by the caller once
- * this funciton is called. This is in effect the inverse
- * of scsi_allocate_device. Note that we also must perform
- * a couple of additional tasks. We must first wake up any
- * processes that might have blocked waiting for a command
- * block, and secondly we must hit the queue handler function
- * to make sure that the device is busy.
- *
- * The idea is that a lot of the mid-level internals gunk
- * gets hidden in this function. Upper level drivers don't
- * have any chickens to wave in the air to get things to
- * work reliably.
- *
- * This function is deprecated, and drivers should be
- * rewritten to use Scsi_Request instead of Scsi_Cmnd.
- */
-void scsi_release_command(Scsi_Cmnd * SCpnt)
+inline void __scsi_release_command(Scsi_Cmnd * SCpnt)
X {
X unsigned long flags;
X Scsi_Device * SDpnt;
@@ -562,6 +543,43 @@
X * they wake up.
X */
X wake_up(&SDpnt->scpnt_wait);
+}
+
+/*
+ * Function: scsi_release_command
+ *
+ * Purpose: Release a command block.
+ *
+ * Arguments: SCpnt - command block we are releasing.
+ *
+ * Notes: The command block can no longer be used by the caller once
+ * this funciton is called. This is in effect the inverse
+ * of scsi_allocate_device. Note that we also must perform
+ * a couple of additional tasks. We must first wake up any
+ * processes that might have blocked waiting for a command
+ * block, and secondly we must hit the queue handler function
+ * to make sure that the device is busy. Note - there is an
+ * option to not do this - there were instances where we could
+ * recurse too deeply and blow the stack if this happened
+ * when we were indirectly called from the request function
+ * itself.
+ *
+ * The idea is that a lot of the mid-level internals gunk
+ * gets hidden in this function. Upper level drivers don't
+ * have any chickens to wave in the air to get things to
+ * work reliably.
+ *
+ * This function is deprecated, and drivers should be
+ * rewritten to use Scsi_Request instead of Scsi_Cmnd.
+ */
+void scsi_release_command(Scsi_Cmnd * SCpnt)
+{
+ request_queue_t *q;
+ Scsi_Device * SDpnt;
+
+ SDpnt = SCpnt->device;
+
+ __scsi_release_command(SCpnt);
X
X /*
X * Finally, hit the queue request function to make sure that
@@ -569,12 +587,8 @@
X * This won't block - if the device cannot take any more, life
X * will go on.
X */
- {
- request_queue_t *q;
-
- q = &SDpnt->request_queue;
- scsi_queue_next_request(q, NULL);
- }
+ q = &SDpnt->request_queue;
+ scsi_queue_next_request(q, NULL);
X }
X
X /*
@@ -1361,13 +1375,8 @@
X SCpnt->done(SCpnt);
X }
X
-#if defined(CONFIG_MODULES) || defined(CONFIG_BLK_DEV_IDESCSI) || defined(CONFIG_USB_STORAGE)
X static int scsi_register_host(Scsi_Host_Template *);
X static void scsi_unregister_host(Scsi_Host_Template *);
-#endif
-
-
-int scsi_loadable_module_flag; /* Set after we scan builtin drivers */
X
X /*
X * Function: scsi_release_commandblocks()
@@ -1432,10 +1441,9 @@
X kmalloc(sizeof(Scsi_Cmnd),
X GFP_ATOMIC |
X (host->unchecked_isa_dma ? GFP_DMA : 0));
- memset(SCpnt, 0, sizeof(Scsi_Cmnd));
X if (NULL == SCpnt)
X break; /* If not, the next line will oops ... */
- memset(&SCpnt->eh_timeout, 0, sizeof(SCpnt->eh_timeout));
+ memset(SCpnt, 0, sizeof(Scsi_Cmnd));
X SCpnt->host = host;
X SCpnt->device = SDpnt;
X SCpnt->target = SDpnt->id;
@@ -1499,120 +1507,6 @@
X }
X }
X
-#ifndef MODULE /* { */
-
-char scsi_host_no_table[20][10] __initdata = {};
-int scsi_host_no_set __initdata = 0;
-
-/*
- * scsi_dev_init() is our initialization routine, which in turn calls host
- * initialization, bus scanning, and sd/st initialization routines.
- * This is only used at boot time.
- */
-int __init scsi_dev_init(void)
-{
- Scsi_Device *SDpnt;
- struct Scsi_Host *shpnt;
- struct Scsi_Device_Template *sdtpnt;
- struct proc_dir_entry *generic;
-#ifdef FOO_ON_YOU
- return;
-#endif
-
- /* Initialize list of host_no if kernel parameter set */
- if (scsi_host_no_set) {
- int i;
- for (i = 0;i < sizeof(scsi_host_no_table)/sizeof(scsi_host_no_table[0]);i++)
- scsi_host_no_insert(scsi_host_no_table[i], i);
- }
-
- /* Yes we're here... */
-
- scsi_devfs_handle = devfs_mk_dir (NULL, "scsi", NULL);
- /*
- * This makes /proc/scsi and /proc/scsi/scsi visible.
- */
-#ifdef CONFIG_PROC_FS
- proc_scsi = proc_mkdir("scsi", 0);
- if (!proc_scsi) {
- printk (KERN_ERR "cannot init /proc/scsi\n");


- return -ENOMEM;
- }
-

- generic = create_proc_info_entry ("scsi/scsi", 0, 0, scsi_proc_info);
- if (!generic) {
- printk (KERN_ERR "cannot init /proc/scsi/scsi\n");
- remove_proc_entry("scsi", 0);
- return -ENOMEM;
- }
- generic->write_proc = proc_scsi_gen_write;
-#endif
-
- /* Init a few things so we can "malloc" memory. */
- scsi_loadable_module_flag = 0;
-
- /* initialize all hosts */
- scsi_init();
-
- /*
- * This is where the processing takes place for most everything
- * when commands are completed. Until we do this, we will not be able
- * to queue any commands.
- */
- init_bh(SCSI_BH, scsi_bottom_half_handler);
-
- for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next) {
- scan_scsis(shpnt, 0, 0, 0, 0); /* scan for scsi devices */
- if (shpnt->select_queue_depths != NULL)
- (shpnt->select_queue_depths) (shpnt, shpnt->host_queue);
- }
-
- printk("scsi : detected ");
- for (sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next)
- if (sdtpnt->dev_noticed && sdtpnt->name)
- printk("%d SCSI %s%s ", sdtpnt->dev_noticed, sdtpnt->name,
- (sdtpnt->dev_noticed != 1) ? "s" : "");
- printk("total.\n");
-
- for (sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next)
- if (sdtpnt->init && sdtpnt->dev_noticed)
- (*sdtpnt->init) ();
-
- for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next) {
- for (SDpnt = shpnt->host_queue; SDpnt; SDpnt = SDpnt->next) {
- /* SDpnt->scsi_request_fn = NULL; */
- for (sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next)
- if (sdtpnt->attach)
- (*sdtpnt->attach) (SDpnt);
- if (SDpnt->attached) {
- scsi_build_commandblocks(SDpnt);
- if (0 == SDpnt->has_cmdblocks) {
- printk("scsi_dev_init: DANGER, no command blocks\n");
- /* What to do now ?? */
- }
- }


- }
- }
-
- /*

- * This should build the DMA pool.
- */
- scsi_resize_dma_pool();
-
- /*
- * OK, now we finish the initialization by doing spin-up, read
- * capacity, etc, etc
- */
- for (sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next)
- if (sdtpnt->finish && sdtpnt->nr_dev)
- (*sdtpnt->finish) ();
-
- scsi_loadable_module_flag = 1;


-
- return 0;
-}

-#endif /* MODULE */ /* } */
-
X #ifdef CONFIG_PROC_FS
X static int scsi_proc_info(char *buffer, char **start, off_t offset, int length)
X {
@@ -1908,15 +1802,8 @@
X #endif
X
X /*
- * Some host adapters that are plugging into other subsystems register
- * their hosts through the modules entrypoints, and don't use the big
- * list in hosts.c.
- */
-#if defined(CONFIG_MODULES) || defined(CONFIG_BLK_DEV_IDESCSI) || defined(CONFIG_USB_STORAGE) || defined(CONFIG_USB_MICROTEK) /* a big #ifdef block... */
-
-/*
- * This entry point should be called by a loadable module if it is trying
- * add a low level scsi driver to the system.
+ * This entry point should be called by a driver if it is trying
+ * to add a low level scsi driver to the system.
X */
X static int scsi_register_host(Scsi_Host_Template * tpnt)
X {
@@ -1957,8 +1844,8 @@
X return 1;
X }
X /*
- * The low-level driver failed to register a driver. We


- * can do this now.

+ * The low-level driver failed to register a driver.
+ * We can do this now.
X */
X scsi_register(tpnt, 0);
X }
@@ -2004,9 +1891,6 @@
X }
X }
X
- printk("scsi : %d host%s.\n", next_scsi_host,


- (next_scsi_host == 1) ? "" : "s");
-

X /* The next step is to call scan_scsis here. This generates the
X * Scsi_Devices entries
X */
@@ -2084,15 +1968,13 @@
X static void scsi_unregister_host(Scsi_Host_Template * tpnt)
X {
X int online_status;
- int pcount;
+ int pcount0, pcount;
X Scsi_Cmnd *SCpnt;
X Scsi_Device *SDpnt;
X Scsi_Device *SDpnt1;
X struct Scsi_Device_Template *sdtpnt;
X struct Scsi_Host *sh1;
X struct Scsi_Host *shpnt;
- Scsi_Host_Template *SHT;
- Scsi_Host_Template *SHTp;
X char name[10]; /* host_no>=10^9? I don't think so. */
X
X /*
@@ -2226,9 +2108,10 @@
X /* Next we go through and remove the instances of the individual hosts
X * that were detected */
X
+ pcount0 = next_scsi_host;
X for (shpnt = scsi_hostlist; shpnt; shpnt = sh1) {
X sh1 = shpnt->next;
- if (shpnt->hostt != tpnt || !shpnt->loaded_as_module)
+ if (shpnt->hostt != tpnt)
X continue;
X pcount = next_scsi_host;
X /* Remove the /proc/scsi directory entry */
@@ -2242,7 +2125,7 @@
X * written host adapters.
X */
X if (shpnt->irq)
- free_irq(shpnt->irq, NULL);
+ free_irq(shpnt->irq, NULL);
X if (shpnt->dma_channel != 0xff)
X free_dma(shpnt->dma_channel);
X if (shpnt->io_port && shpnt->n_io_port)
@@ -2261,8 +2144,9 @@
X if (!scsi_hosts)
X scsi_resize_dma_pool();
X
- printk("scsi : %d host%s.\n", next_scsi_host,


- (next_scsi_host == 1) ? "" : "s");

+ if (pcount0 != next_scsi_host)
+ printk("scsi : %d host%s left.\n", next_scsi_host,
+ (next_scsi_host == 1) ? "" : "s");
X
X #if defined(USE_STATIC_SCSI_MEMORY)
X printk("SCSI memory: total %ldKb, used %ldKb, free %ldKb.\n",
@@ -2271,24 +2155,21 @@
X (scsi_memory_upper_value - scsi_init_memory_start) / 1024);
X #endif
X
- /* There were some hosts that were loaded at boot time, so we cannot
- do any more than this */
- if (tpnt->present)
- return;
+ /* Remove it from the linked list and /proc */
+ if (tpnt->present) {
+ Scsi_Host_Template **SHTp = &scsi_hosts;
+ Scsi_Host_Template *SHT;
X
- /* OK, this is the very last step. Remove this host adapter from the
- linked list. */
- for (SHTp = NULL, SHT = scsi_hosts; SHT; SHTp = SHT, SHT = SHT->next)
- if (SHT == tpnt) {
- if (SHTp)
- SHTp->next = SHT->next;
- else
- scsi_hosts = SHT->next;
- SHT->next = NULL;
- break;
+ while ((SHT = *SHTp) != NULL) {
+ if (SHT == tpnt) {
+ *SHTp = SHT->next;
+ break;
+ }
+ SHTp = &SHT->next;
X }
- /* Rebuild the /proc/scsi directory entries */
- remove_proc_entry(tpnt->proc_name, proc_scsi);
+ /* Rebuild the /proc/scsi directory entries */
+ remove_proc_entry(tpnt->proc_name, proc_scsi);
+ }
X MOD_DEC_USE_COUNT;
X }
X
@@ -2421,6 +2302,10 @@
X }
X
X
+/* This function should be called by drivers which needs to register
+ * with the midlevel scsi system. As of 2.4.0-test9pre3 this is our
+ * main device/hosts register function /mathiasen
+ */
X int scsi_register_module(int module_type, void *ptr)
X {
X switch (module_type) {
@@ -2448,6 +2333,8 @@
X }
X }
X
+/* Reverse the actions taken above
+ */
X void scsi_unregister_module(int module_type, void *ptr)
X {
X switch (module_type) {
@@ -2466,8 +2353,6 @@
X return;
X }
X
-#endif /* CONFIG_MODULES */
-
X #ifdef CONFIG_PROC_FS
X /*
X * Function: scsi_dump_status
@@ -2574,17 +2459,11 @@
X }
X #endif /* CONFIG_PROC_FS */
X
-static int scsi_host_no_init (char *str)
+static int __init scsi_host_no_init (char *str)
X {
X static int next_no = 0;
X char *temp;
X
-#ifndef MODULE
- int len;
- scsi_host_no_set = 1;
- memset(scsi_host_no_table, 0, sizeof(scsi_host_no_table));
-#endif /* MODULE */
-
X while (str) {
X temp = str;
X while (*temp && (*temp != ':') && (*temp != ','))
@@ -2593,35 +2472,34 @@
X temp = NULL;
X else
X *temp++ = 0;
-#ifdef MODULE
X scsi_host_no_insert(str, next_no);
-#else
- if (next_no < sizeof(scsi_host_no_table)/sizeof(scsi_host_no_table[0])) {
- if ((len = strlen(str)) >= sizeof(scsi_host_no_table[0]))
- len = sizeof(scsi_host_no_table[0])-1;
- strncpy(scsi_host_no_table[next_no], str, len);
- scsi_host_no_table[next_no][len] = 0;


- }
-#endif /* MODULE */

X str = temp;
X next_no++;
X }


X return 1;
X }
X

-#ifndef MODULE
-__setup("scsihosts=", scsi_host_no_init);
-#endif
-
-#ifdef MODULE
X static char *scsihosts;
X
X MODULE_PARM(scsihosts, "s");
+MODULE_DESCRIPTION("SCSI core");
+
+#ifndef MODULE
+int __init scsi_setup(char *str)
+{
+ scsihosts = str;


+ return 1;
+}
+

+__setup("scsihosts=", scsi_setup);
+#endif
X
-int init_module(void)
+static int __init init_scsi(void)
X {
X struct proc_dir_entry *generic;
X
+ printk(KERN_INFO "SCSI subsystem driver " REVISION "\n");
+
X if( scsi_init_minimal_dma_pool() != 0 )
X {
X return 1;
@@ -2645,10 +2523,10 @@
X generic->write_proc = proc_scsi_gen_write;
X #endif
X
- scsi_loadable_module_flag = 1;
-
X scsi_devfs_handle = devfs_mk_dir (NULL, "scsi", NULL);
- scsi_host_no_init (scsihosts);
+ if (scsihosts)
+ printk("scsi: host order: %s\n", scsihosts);
+ scsi_host_no_init (scsihosts);
X /*
X * This is where the processing takes place for most everything
X * when commands are completed.
@@ -2658,7 +2536,7 @@


X return 0;
X }
X

-void cleanup_module(void)
+static void __exit exit_scsi(void)
X {
X Scsi_Host_Name *shn, *shn2 = NULL;
X
@@ -2688,7 +2566,8 @@
X
X }


X
-#endif /* MODULE */

+module_init(init_scsi);
+module_exit(exit_scsi);
X
X /*
X * Function: scsi_get_host_dev()
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/scsi.h linux/drivers/scsi/scsi.h
--- v2.4.0-test8/linux/drivers/scsi/scsi.h Fri Sep 8 12:54:34 2000
+++ linux/drivers/scsi/scsi.h Mon Oct 2 12:08:35 2000
@@ -492,6 +492,7 @@
X extern void scsi_finish_command(Scsi_Cmnd *);
X extern int scsi_retry_command(Scsi_Cmnd *);
X extern Scsi_Cmnd *scsi_allocate_device(Scsi_Device *, int, int);
+extern void __scsi_release_command(Scsi_Cmnd *);
X extern void scsi_release_command(Scsi_Cmnd *);
X extern void scsi_do_cmd(Scsi_Cmnd *, const void *cmnd,
X void *buffer, unsigned bufflen,
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/scsi_debug.c linux/drivers/scsi/scsi_debug.c
--- v2.4.0-test8/linux/drivers/scsi/scsi_debug.c Mon Mar 13 22:15:03 2000
+++ linux/drivers/scsi/scsi_debug.c Mon Sep 18 13:36:25 2000
@@ -767,12 +767,10 @@
X }
X #endif
X

-#ifdef MODULE
X /* Eventually this will go into an include file, but this will be later */

-Scsi_Host_Template driver_template = SCSI_DEBUG;
+static Scsi_Host_Template driver_template = SCSI_DEBUG;


X
X #include "scsi_module.c"
-#endif
X

X /*
X * Overrides for Emacs so that we almost follow Linus's tabbing style.

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/scsi_error.c linux/drivers/scsi/scsi_error.c
--- v2.4.0-test8/linux/drivers/scsi/scsi_error.c Mon Aug 21 07:37:13 2000
+++ linux/drivers/scsi/scsi_error.c Mon Sep 18 14:57:01 2000
@@ -1861,6 +1861,9 @@
X * Flush resources
X */
X
+ exit_files(current);
+ current->files = init_task.files;
+ atomic_inc(&current->files->count);
X daemonize();
X
X /*
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/scsi_lib.c linux/drivers/scsi/scsi_lib.c
--- v2.4.0-test8/linux/drivers/scsi/scsi_lib.c Wed Jul 5 13:18:05 2000
+++ linux/drivers/scsi/scsi_lib.c Sun Sep 17 10:09:29 2000
@@ -381,6 +381,8 @@
X * uptodate - 1 if I/O indicates success, 0 for I/O error.
X * sectors - number of sectors we want to mark.
X * requeue - indicates whether we should requeue leftovers.
+ * frequeue - indicates that if we release the command block
+ * that the queue request function should be called.
X *
X * Lock status: Assumed that lock is not held upon entry.
X *
@@ -395,10 +397,12 @@
X static Scsi_Cmnd *__scsi_end_request(Scsi_Cmnd * SCpnt,
X int uptodate,
X int sectors,
- int requeue)
+ int requeue,
+ int frequeue)
X {
X struct request *req;
X struct buffer_head *bh;
+ Scsi_Device * SDpnt;
X
X ASSERT_LOCK(&io_request_lock, 0);
X
@@ -458,11 +462,20 @@
X }
X add_blkdev_randomness(MAJOR(req->rq_dev));
X
+ SDpnt = SCpnt->device;
+
X /*
X * This will goose the queue request function at the end, so we don't
X * need to worry about launching another command.
X */
- scsi_release_command(SCpnt);
+ __scsi_release_command(SCpnt);
+
+ if( frequeue ) {
+ request_queue_t *q;
+
+ q = &SDpnt->request_queue;
+ scsi_queue_next_request(q, NULL);
+ }


X return NULL;
X }
X

@@ -488,7 +501,7 @@
X */
X Scsi_Cmnd *scsi_end_request(Scsi_Cmnd * SCpnt, int uptodate, int sectors)
X {
- return __scsi_end_request(SCpnt, uptodate, sectors, 1);
+ return __scsi_end_request(SCpnt, uptodate, sectors, 1, 1);
X }
X
X /*
@@ -648,7 +661,8 @@
X SCpnt = __scsi_end_request(SCpnt,
X 1,
X good_sectors,
- result == 0);
+ result == 0,
+ 1);
X
X /*
X * If the command completed without error, then either finish off the
@@ -718,8 +732,8 @@
X }
X break;
X case NOT_READY:
- printk(KERN_INFO "Device %x not ready.\n",
- SCpnt->request.rq_dev);
+ printk(KERN_INFO "Device %s not ready.\n",
+ kdevname(SCpnt->request.rq_dev));
X SCpnt = scsi_end_request(SCpnt, 0, this_count);
X return;
X break;
@@ -962,6 +976,7 @@
X }
X
X } else {
+ SRpnt = NULL;
X STpnt = scsi_get_request_dev(req);
X if (!STpnt) {
X panic("Unable to find device associated with request");
@@ -1010,7 +1025,7 @@
X */
X blkdev_dequeue_request(req);
X
- if (req != &SCpnt->request) {
+ if (req != &SCpnt->request && req != &SRpnt->sr_request ) {
X memcpy(&SCpnt->request, req, sizeof(struct request));
X
X /*
@@ -1048,8 +1063,12 @@
X * get those allocated here.
X */
X if (!SDpnt->scsi_init_io_fn(SCpnt)) {
- scsi_end_request(SCpnt, 0,
- SCpnt->request.nr_sectors);
+ SCpnt = __scsi_end_request(SCpnt, 0,
+ SCpnt->request.nr_sectors, 0, 0);
+ if( SCpnt != NULL )
+ {
+ panic("Should not have leftover blocks\n");
+ }
X spin_lock_irq(&io_request_lock);
X SHpnt->host_busy--;
X SDpnt->device_busy--;
@@ -1060,8 +1079,12 @@
X */
X if (!STpnt->init_command(SCpnt)) {
X scsi_release_buffers(SCpnt);
- scsi_end_request(SCpnt, 0,
- SCpnt->request.nr_sectors);
+ SCpnt = __scsi_end_request(SCpnt, 0,
+ SCpnt->request.nr_sectors, 0, 0);
+ if( SCpnt != NULL )
+ {
+ panic("Should not have leftover blocks\n");
+ }
X spin_lock_irq(&io_request_lock);
X SHpnt->host_busy--;
X SDpnt->device_busy--;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/scsi_module.c linux/drivers/scsi/scsi_module.c
--- v2.4.0-test8/linux/drivers/scsi/scsi_module.c Sat Sep 4 10:48:46 1999
+++ linux/drivers/scsi/scsi_module.c Wed Sep 20 13:11:53 2000
@@ -30,22 +30,26 @@
X */
X
X #include <linux/module.h>
+#include <linux/init.h>
X
-int init_module(void)
+static int __init init_this_scsi_driver(void)
X {
- driver_template.module = &__this_module;
+ driver_template.module = THIS_MODULE;
X scsi_register_module(MODULE_SCSI_HA, &driver_template);
X if (driver_template.present)
X return 0;
X
X scsi_unregister_module(MODULE_SCSI_HA, &driver_template);
- return -1;
+ return -ENODEV;
X }
X
-void cleanup_module(void)
+static void __exit exit_this_scsi_driver(void)
X {
X scsi_unregister_module(MODULE_SCSI_HA, &driver_template);
X }
+
+module_init(init_this_scsi_driver);
+module_exit(exit_this_scsi_driver);
X
X /*


X * Overrides for Emacs so that we almost follow Linus's tabbing style.

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/scsi_queue.c linux/drivers/scsi/scsi_queue.c
--- v2.4.0-test8/linux/drivers/scsi/scsi_queue.c Thu Jan 20 15:15:22 2000
+++ linux/drivers/scsi/scsi_queue.c Sun Sep 17 10:09:29 2000
@@ -118,7 +118,7 @@
X * If a host is inactive and cannot queue any commands, I don't see
X * how things could possibly work anyways.
X */
- if (cmd->device->device_blocked == 0) {
+ if (cmd->device->device_busy == 0) {
X if (scsi_retry_command(cmd) == 0) {
X return 0;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/scsi_scan.c linux/drivers/scsi/scsi_scan.c
--- v2.4.0-test8/linux/drivers/scsi/scsi_scan.c Tue Sep 5 14:08:55 2000
+++ linux/drivers/scsi/scsi_scan.c Tue Sep 19 08:01:34 2000
@@ -127,12 +127,14 @@
X {"REGAL", "CDC-4X", "*", BLIST_MAX5LUN | BLIST_SINGLELUN},
X {"NAKAMICH", "MJ-4.8S", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
X {"NAKAMICH", "MJ-5.16S", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
- {"PIONEER", "CD-ROM DRM-600", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
- {"PIONEER", "CD-ROM DRM-602X", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
- {"PIONEER", "CD-ROM DRM-604X", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
+ {"PIONEER", "CD-ROM DRM-600", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
+ {"PIONEER", "CD-ROM DRM-602X", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
+ {"PIONEER", "CD-ROM DRM-604X", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
X {"EMULEX", "MD21/S2 ESDI", "*", BLIST_SINGLELUN},
X {"CANON", "IPUBJD", "*", BLIST_SPARSELUN},
X {"nCipher", "Fastness Crypto", "*", BLIST_FORCELUN},
+ {"DEC","HSG80","*", BLIST_FORCELUN},
+ {"COMPAQ","LOGICAL VOLUME","*", BLIST_FORCELUN},
X {"NEC", "PD-1 ODX654P", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
X {"MATSHITA", "PD-1", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
X {"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN},
@@ -142,6 +144,8 @@
X {"DGC", "DISK", "*", BLIST_SPARSELUN}, // Dell PV 650F (no tgt @ LUN 0)
X {"DELL", "PV530F", "*", BLIST_SPARSELUN}, // Dell PV 530F
X {"SONY", "TSL", "*", BLIST_FORCELUN}, // DDS3 & DDS4 autoloaders
+ {"DELL", "PERCRAID", "*", BLIST_FORCELUN},
+ {"HP", "NetRAID-4M", "*", BLIST_FORCELUN},
X
X /*
X * Must be at end of list...
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/scsi_syms.c linux/drivers/scsi/scsi_syms.c
--- v2.4.0-test8/linux/drivers/scsi/scsi_syms.c Mon Mar 13 22:15:03 2000
+++ linux/drivers/scsi/scsi_syms.c Wed Sep 20 13:11:53 2000
@@ -6,8 +6,6 @@
X #include <linux/config.h>
X #include <linux/module.h>
X
-#ifdef CONFIG_MODULES
-
X #include <linux/sched.h>
X #include <linux/timer.h>
X #include <linux/string.h>
@@ -93,4 +91,3 @@
X EXPORT_SYMBOL(scsi_devicelist);
X EXPORT_SYMBOL(scsi_device_types);
X
-#endif /* CONFIG_MODULES */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/sd.c linux/drivers/scsi/sd.c
--- v2.4.0-test8/linux/drivers/scsi/sd.c Thu Sep 7 08:56:00 2000
+++ linux/drivers/scsi/sd.c Sun Oct 1 20:35:16 2000
@@ -80,7 +80,7 @@
X
X struct hd_struct *sd;
X
-static Scsi_Disk *rscsi_disks = NULL;
+static Scsi_Disk *rscsi_disks;
X static int *sd_sizes;
X static int *sd_blocksizes;
X static int *sd_hardsizes; /* Hardware sector size */
@@ -96,10 +96,30 @@
X static int sd_attach(Scsi_Device *);
X static int sd_detect(Scsi_Device *);
X static void sd_detach(Scsi_Device *);
-static void rw_intr(Scsi_Cmnd * SCpnt);
-
X static int sd_init_command(Scsi_Cmnd *);
X
+static struct Scsi_Device_Template sd_template = {
+ name:"disk",
+ tag:"sd",
+ scsi_type:TYPE_DISK,
+ major:SCSI_DISK0_MAJOR,
+ /*
+ * Secondary range of majors that this driver handles.
+ */
+ min_major:SCSI_DISK1_MAJOR,
+ max_major:SCSI_DISK7_MAJOR,
+ blk:1,
+ detect:sd_detect,
+ init:sd_init,
+ finish:sd_finish,
+ attach:sd_attach,
+ detach:sd_detach,
+ init_command:sd_init_command,
+};
+
+
+static void rw_intr(Scsi_Cmnd * SCpnt);
+
X #if defined(CONFIG_PPC)
X /*
X * Moved from arch/ppc/pmac_setup.c. This is where it really belongs.
@@ -243,25 +263,6 @@
X }
X }
X
-struct Scsi_Device_Template sd_template = {
- name:"disk",
- tag:"sd",
- scsi_type:TYPE_DISK,
- major:SCSI_DISK0_MAJOR,
- /*
- * Secondary range of majors that this driver handles.
- */
- min_major:SCSI_DISK1_MAJOR,
- max_major:SCSI_DISK7_MAJOR,
- blk:1,
- detect:sd_detect,
- init:sd_init,
- finish:sd_finish,
- attach:sd_attach,
- detach:sd_detach,
- init_command:sd_init_command,
-};
-
X static request_queue_t *sd_find_queue(kdev_t dev)
X {
X Scsi_Disk *dpnt;
@@ -720,13 +721,14 @@
X sd_devname(i, nbuff);
X
X /*
- * If the device is offline, don't try and read capacity or any of the other
- * nicities.
+ * If the device is offline, don't try and read capacity or any
+ * of the other niceties.
X */
- if (rscsi_disks[i].device->online == FALSE) {
+ if (rscsi_disks[i].device->online == FALSE)
X return i;
- }
- /* We need to retry the READ_CAPACITY because a UNIT_ATTENTION is
+
+ /*
+ * We need to retry the READ_CAPACITY because a UNIT_ATTENTION is
X * considered a fatal error, and many devices report such an error
X * just after a scsi bus reset.
X */
@@ -807,7 +809,8 @@
X } while(time1);
X printk(".");
X }
- } while (the_result && spintime && time_after(spintime_value + 100 * HZ, jiffies));
+ } while (the_result && spintime &&
+ time_after(spintime_value + 100 * HZ, jiffies));
X if (spintime) {
X if (the_result)
X printk("not responding...\n");
@@ -836,15 +839,16 @@
X /*
X * The SCSI standard says:
X * "READ CAPACITY is necessary for self configuring software"
- * While not mandatory, support of READ CAPACITY is strongly encouraged.
+ * While not mandatory, support of READ CAPACITY is strongly
+ * encouraged.
X * We used to die if we couldn't successfully do a READ CAPACITY.
X * But, now we go on about our way. The side effects of this are
X *
- * 1. We can't know block size with certainty. I have said "512 bytes
- * is it" as this is most common.
+ * 1. We can't know block size with certainty. I have said
+ * "512 bytes is it" as this is most common.
X *
- * 2. Recovery from when some one attempts to read past the end of the
- * raw device will be slower.
+ * 2. Recovery from when someone attempts to read past the
+ * end of the raw device will be slower.
X */
X
X if (the_result) {
@@ -867,15 +871,15 @@
X rscsi_disks[i].capacity = 0x1fffff;
X sector_size = 512;
X
- /* Set dirty bit for removable devices if not ready - sometimes drives
- * will not report this properly. */
+ /* Set dirty bit for removable devices if not ready -
+ * sometimes drives will not report this properly. */
X if (rscsi_disks[i].device->removable &&
X SRpnt->sr_sense_buffer[2] == NOT_READY)
X rscsi_disks[i].device->changed = 1;
X
X } else {
X /*
- * FLOPTICAL , if read_capa is ok , drive is assumed to be ready
+ * FLOPTICAL, if read_capa is ok, drive is assumed to be ready
X */
X rscsi_disks[i].ready = 1;
X
@@ -889,7 +893,8 @@
X
X if (sector_size == 0) {
X sector_size = 512;
- printk("%s : sector size 0 reported, assuming 512.\n", nbuff);
+ printk("%s : sector size 0 reported, assuming 512.\n",
+ nbuff);
X }
X if (sector_size != 512 &&
X sector_size != 1024 &&
@@ -924,31 +929,30 @@


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 082'
echo 'File patch-2.4.0-test9 is continued in part 083'
echo "083" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part083

#!/bin/sh -x
# this is part 083 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 083; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

X * So I have created this table. See ll_rw_blk.c
X * Jacques Gelinas (Jac...@solucorp.qc.ca)
X */
- int m, mb;
- int sz_quot, sz_rem;
+ int m;
X int hard_sector = sector_size;
+ int sz = rscsi_disks[i].capacity * (hard_sector/256);
+
X /* There are 16 minors allocated for each major device */
X for (m = i << 4; m < ((i + 1) << 4); m++) {
X sd_hardsizes[m] = hard_sector;
X }
- mb = rscsi_disks[i].capacity / 1024 * hard_sector / 1024;
- /* sz = div(m/100, 10); this seems to not be in the libr */
- m = (mb + 50) / 100;
- sz_quot = m / 10;
- sz_rem = m - (10 * sz_quot);
- printk("SCSI device %s: hdwr sector= %d bytes."
- " Sectors= %d [%d MB] [%d.%1d GB]\n",
- nbuff, hard_sector, rscsi_disks[i].capacity,
- mb, sz_quot, sz_rem);
+
+ printk("SCSI device %s: "
+ "%d %d-byte hdwr sectors (%d MB)\n",
+ nbuff, rscsi_disks[i].capacity,
+ hard_sector, (sz/2 - sz/1250 + 974)/1950);
X }
+
+ /* Rescale capacity to 512-byte units */
X if (sector_size == 4096)
X rscsi_disks[i].capacity <<= 3;
X if (sector_size == 2048)
- rscsi_disks[i].capacity <<= 2; /* Change into 512 byte sectors */
+ rscsi_disks[i].capacity <<= 2;
X if (sector_size == 1024)
- rscsi_disks[i].capacity <<= 1; /* Change into 512 byte sectors */
+ rscsi_disks[i].capacity <<= 1;
X if (sector_size == 256)
- rscsi_disks[i].capacity >>= 1; /* Change into 512 byte sectors */
+ rscsi_disks[i].capacity >>= 1;
X }
X
X
@@ -1014,7 +1018,7 @@
X * their size, and reads partition table entries for them.
X */
X
-static int sd_registered = 0;
+static int sd_registered;
X
X static int sd_init()
X {
@@ -1030,7 +1034,7 @@
X sd_template.dev_max = N_SD_MAJORS * SCSI_DISKS_PER_MAJOR;
X
X if (!sd_registered) {
- for (i = 0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) {
+ for (i = 0; i < N_USED_SD_MAJORS; i++) {
X if (devfs_register_blkdev(SD_MAJOR(i), "sd", &sd_fops)) {
X printk("Unable to get major %d for SCSI disk\n", SD_MAJOR(i));
X return 1;
@@ -1142,7 +1146,7 @@
X struct gendisk *gendisk;
X int i;
X
- for (i = 0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) {
+ for (i = 0; i < N_USED_SD_MAJORS; i++) {
X blk_dev[SD_MAJOR(i)].queue = sd_find_queue;
X }
X for (gendisk = gendisk_head; gendisk != NULL; gendisk = gendisk->next)
@@ -1335,12 +1339,13 @@
X return;
X }
X
-int init_sd(void)
+static int __init init_sd(void)
X {
X sd_template.module = THIS_MODULE;
X return scsi_register_module(MODULE_SCSI_DEV, &sd_template);
X }
-void exit_sd(void)
+
+static void __exit exit_sd(void)
X {
X struct gendisk **prev_sdgd_link;
X struct gendisk *sdgd;
@@ -1349,7 +1354,7 @@
X
X scsi_unregister_module(MODULE_SCSI_DEV, &sd_template);
X
- for (i = 0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++)
+ for (i = 0; i < N_USED_SD_MAJORS; i++)
X devfs_unregister_blkdev(SD_MAJOR(i), "sd");
X
X sd_registered--;
@@ -1378,7 +1383,7 @@
X removed > N_USED_SD_MAJORS ? "total" : "just", removed);
X
X }
- for (i = 0; i <= (sd_template.dev_max - 1) / SCSI_DISKS_PER_MAJOR; i++) {
+ for (i = 0; i < N_USED_SD_MAJORS; i++) {
X blk_size[SD_MAJOR(i)] = NULL;
X hardsect_size[SD_MAJOR(i)] = NULL;
X read_ahead[SD_MAJOR(i)] = 0;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/seagate.c linux/drivers/scsi/seagate.c
--- v2.4.0-test8/linux/drivers/scsi/seagate.c Fri Jul 7 15:55:24 2000
+++ linux/drivers/scsi/seagate.c Mon Sep 18 13:36:25 2000
@@ -5,7 +5,8 @@
X *
X * Note : TMC-880 boards don't work because they have two bits in
X * the status register flipped, I'll fix this "RSN"
- * [why do I have strong feeling that above message is from 1993? :-) pa...@ucw.cz]
+ * [why do I have strong feeling that above message is from 1993? :-)
+ * pa...@ucw.cz]
X *
X * This card does all the I/O via memory mapped I/O, so there is no need
X * to check or allocate a region of the I/O address space.
@@ -18,6 +19,13 @@
X *
X * 1998-jul-29 - created DPRINTK macros and made it work under
X * linux 2.1.112, simplified some #defines etc. <pa...@ucw.cz>
+ *
+ * Aug 2000 - aeb - deleted seagate_st0x_biosparam(). It would try to
+ * read the physical disk geometry, a bad mistake. Of course it doesnt
+ * matter much what geometry one invents, but on large disks it
+ * returned 256 (or more) heads, causing all kind of failures.
+ * Of course this means that people might see a different geometry now,
+ * so boot parameters may be necessary in some cases.
X */
X
X /*
@@ -1702,127 +1710,7 @@
X }
X
X
-int seagate_st0x_biosparam (Disk * disk, kdev_t dev, int *ip)
-{
- unsigned char buf[256 + sizeof (Scsi_Ioctl_Command)],
- cmd[6], *data, *page;
- Scsi_Ioctl_Command *sic = (Scsi_Ioctl_Command *) buf;
- int result, formatted_sectors, total_sectors;
- int cylinders, heads, sectors;
- int capacity;
-
-/*
- * Only SCSI-I CCS drives and later implement the necessary mode sense
- * pages.
- */
-
- if (disk->device->scsi_level < 2)
- return -1;
-
- data = sic->data;
-
- cmd[0] = MODE_SENSE;
- cmd[1] = (disk->device->lun << 5) & 0xe5;
- cmd[2] = 0x04; /* Read page 4, rigid disk geometry
- page current values */
- cmd[3] = 0;
- cmd[4] = 255;
- cmd[5] = 0;
-
-/*
- * We are transferring 0 bytes in the out direction, and expect to get back
- * 24 bytes for each mode page.
- */
- sic->inlen = 0;
- sic->outlen = 256;
-
- memcpy (data, cmd, 6);
-
- if (!(result = kernel_scsi_ioctl (disk->device, SCSI_IOCTL_SEND_COMMAND,
- sic)))
- {
-/*
- * The mode page lies beyond the MODE SENSE header, with length 4, and
- * the BLOCK DESCRIPTOR, with length header[3].
- */
- page = data + 4 + data[3];
- heads = (int) page[5];
- cylinders = (page[2] << 16) | (page[3] << 8) | page[4];
-
- cmd[2] = 0x03; /* Read page 3, format page current
- values */
- memcpy (data, cmd, 6);
-
- if (!(result = kernel_scsi_ioctl (disk->device, SCSI_IOCTL_SEND_COMMAND,
- sic)))
- {
- page = data + 4 + data[3];
- sectors = (page[10] << 8) | page[11];
-/*
- * Get the total number of formatted sectors from the block descriptor,
- * so we can tell how many are being used for alternates.
- */
- formatted_sectors = (data[4 + 1] << 16) | (data[4 + 2] << 8)
- | data[4 + 3];
-
- total_sectors = (heads * cylinders * sectors);
-
-/*
- * Adjust the real geometry by subtracting
- * (spare sectors / (heads * tracks)) cylinders from the number of cylinders.
- *
- * It appears that the CE cylinder CAN be a partial cylinder.
- */
-
- printk ("scsi%d : heads = %d cylinders = %d sectors = %d total = %d formatted = %d\n",
- hostno, heads, cylinders, sectors, total_sectors,
- formatted_sectors);
-
- if (!heads || !sectors || !cylinders)
- result = -1;
- else
- cylinders -= ((total_sectors - formatted_sectors) / (heads * sectors));
-
-/*
- * Now, we need to do a sanity check on the geometry to see if it is
- * BIOS compatible. The maximum BIOS geometry is 1024 cylinders *
- * 256 heads * 64 sectors.
- */
-
- if ((cylinders > 1024) || (sectors > 64))
- {
- /* The Seagate's seem to have some mapping. Multiply
- heads*sectors*cyl to get capacity. Then start rounding down.
- */
- capacity = heads * sectors * cylinders;
-
- /* Old MFM Drives use this, so does the Seagate */
- sectors = 17;
- heads = 2;
- capacity = capacity / sectors;
- while (cylinders > 1024)
- {
- heads *= 2; /* For some reason, they go in
- multiples */
- cylinders = capacity / heads;
- }
- }
- ip[0] = heads;
- ip[1] = sectors;
- ip[2] = cylinders;
-/*
- * There should be an alternate mapping for things the seagate doesn't
- * understand, but I couldn't say what it is with reasonable certainty.
- */
- }
- }
-
- return result;
-}
-


-#ifdef MODULE
X /* Eventually this will go into an include file, but this will be later */

-Scsi_Host_Template driver_template = SEAGATE_ST0X;
+static Scsi_Host_Template driver_template = SEAGATE_ST0X;


X
X #include "scsi_module.c"
-#endif

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/seagate.h linux/drivers/scsi/seagate.h
--- v2.4.0-test8/linux/drivers/scsi/seagate.h Tue Jan 25 13:01:14 2000
+++ linux/drivers/scsi/seagate.h Sun Sep 17 09:51:57 2000
@@ -20,16 +20,12 @@
X const char *seagate_st0x_info(struct Scsi_Host *);
X int seagate_st0x_reset(Scsi_Cmnd *, unsigned int);
X
-#include <linux/kdev_t.h>
-int seagate_st0x_biosparam(Disk *, kdev_t, int*);
-
X #define SEAGATE_ST0X { detect: seagate_st0x_detect, \
X info: seagate_st0x_info, \
X command: seagate_st0x_command, \
X queuecommand: seagate_st0x_queue_command, \
X abort: seagate_st0x_abort, \
X reset: seagate_st0x_reset, \
- bios_param: seagate_st0x_biosparam, \
X can_queue: 1, \
X this_id: 7, \
X sg_tablesize: SG_ALL, \
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/sg.c linux/drivers/scsi/sg.c
--- v2.4.0-test8/linux/drivers/scsi/sg.c Sun Aug 6 11:43:17 2000
+++ linux/drivers/scsi/sg.c Tue Oct 3 09:24:40 2000
@@ -17,8 +17,11 @@
X * any later version.
X *
X */
- static char * sg_version_str = "Version: 3.1.16 (20000716)";
- static int sg_version_num = 30116; /* 2 digits for each component */
+#include <linux/config.h>
+#ifdef CONFIG_PROC_FS
+ static char * sg_version_str = "Version: 3.1.17 (20001002)";
+#endif
+ static int sg_version_num = 30117; /* 2 digits for each component */
X /*
X * D. P. Gilbert (dgil...@interlog.com, do...@triode.net.au), notes:
X * - scsi logging is available via SCSI_LOG_TIMEOUT macros. First
@@ -38,7 +41,6 @@
X * # cat /proc/scsi/sg/debug
X *
X */
-#include <linux/config.h>
X #include <linux/module.h>
X
X #include <linux/fs.h>
@@ -67,10 +69,8 @@
X #ifdef CONFIG_PROC_FS
X #include <linux/proc_fs.h>
X static int sg_proc_init(void);
-#ifdef MODULE
X static void sg_proc_cleanup(void);
X #endif
-#endif
X
X #ifndef LINUX_VERSION_CODE
X #include <linux/version.h>
@@ -112,12 +112,12 @@
X static int sg_detect(Scsi_Device *);
X static void sg_detach(Scsi_Device *);
X
-static Scsi_Cmnd * dummy_cmdp = 0; /* only used for sizeof */
+static Scsi_Request * dummy_cmdp = 0; /* only used for sizeof */
X
X static rwlock_t sg_dev_arr_lock = RW_LOCK_UNLOCKED; /* Also used to lock
X file descriptor list for device */
X
-struct Scsi_Device_Template sg_template =
+static struct Scsi_Device_Template sg_template =
X {
X tag:"sg",
X scsi_type:0xff,
@@ -148,12 +148,12 @@
X
X typedef struct sg_request /* SG_MAX_QUEUE requests outstanding per file */
X {
- Scsi_Cmnd * my_cmdp; /* != 0 when request with lower levels */
+ Scsi_Request * my_cmdp; /* != 0 when request with lower levels */
X struct sg_request * nextrp; /* NULL -> tail request (slist) */
X struct sg_fd * parentfp; /* NULL -> not in use */
X Sg_scatter_hold data; /* hold buffer, perhaps scatter list */
X sg_io_hdr_t header; /* scsi command+info, see <scsi/sg.h> */
- unsigned char sense_b[sizeof(dummy_cmdp->sense_buffer)];
+ unsigned char sense_b[sizeof(dummy_cmdp->sr_sense_buffer)];
X char res_used; /* 1 -> using reserve buffer, 0 -> not ... */
X char orphan; /* 1 -> drop on sight, 0 -> normal */
X char sg_io_owned; /* 1 -> packet belongs to SG_IO */
@@ -230,15 +230,17 @@
X static int sg_remove_request(Sg_fd * sfp, Sg_request * srp);
X static int sg_res_in_use(Sg_fd * sfp);
X static int sg_dio_in_use(Sg_fd * sfp);
-static void sg_clr_scpnt(Scsi_Cmnd * SCpnt);
-static void sg_shorten_timeout(Scsi_Cmnd * scpnt);
+static void sg_clr_srpnt(Scsi_Request * SRpnt);
+static void sg_shorten_timeout(Scsi_Request * srpnt);
X static int sg_ms_to_jif(unsigned int msecs);
X static unsigned sg_jif_to_ms(int jifs);
X static int sg_allow_access(unsigned char opcode, char dev_type);
-static int sg_last_dev(void);
X static int sg_build_dir(Sg_request * srp, Sg_fd * sfp, int dxfer_len);
X static void sg_unmap_and(Sg_scatter_hold * schp, int free_also);
X static Sg_device * sg_get_dev(int dev);
+#ifdef CONFIG_PROC_FS
+static int sg_last_dev(void);
+#endif
X
X static Sg_device ** sg_dev_arr = NULL;
X
@@ -267,7 +269,8 @@
X * else try and use this device. Also, if error recovery fails, it
X * may try and take the device offline, in which case all further
X * access to the device is prohibited. */
- if(! scsi_block_when_processing_errors(sdp->device))
+ if (! ((flags & O_NONBLOCK) ||
+ scsi_block_when_processing_errors(sdp->device)))
X return -ENXIO;
X
X SCSI_LOG_TIMEOUT(3, printk("sg_open: dev=%d, flags=0x%x\n", dev, flags));
@@ -275,7 +278,7 @@
X if (flags & O_EXCL) {
X if (O_RDONLY == (flags & O_ACCMODE))
X return -EACCES; /* Can't lock it with read only access */
- if (sdp->headfp && (filp->f_flags & O_NONBLOCK))
+ if (sdp->headfp && (flags & O_NONBLOCK))
X return -EBUSY;
X res = 0; /* following is a macro that beats race condition */
X __wait_event_interruptible(sdp->o_excl_wait,
@@ -285,7 +288,7 @@
X return res; /* -ERESTARTSYS because signal hit process */
X }
X else if (sdp->exclude) { /* some other fd has an exclusive lock on dev */
- if (filp->f_flags & O_NONBLOCK)
+ if (flags & O_NONBLOCK)
X return -EBUSY;
X res = 0; /* following is a macro that beats race condition */
X __wait_event_interruptible(sdp->o_excl_wait, (! sdp->exclude), res);
@@ -349,9 +352,6 @@
X return -ENXIO;
X SCSI_LOG_TIMEOUT(3, printk("sg_read: dev=%d, count=%d\n",
X MINOR(sdp->i_rdev), (int)count));
-
- if(! scsi_block_when_processing_errors(sdp->device))
- return -ENXIO;
X if (ppos != &filp->f_pos)
X ; /* FIXME: Hmm. Seek to the right place, or fail? */
X if ((k = verify_area(VERIFY_WRITE, buf, count)))
@@ -447,20 +447,16 @@
X static ssize_t sg_new_read(Sg_fd * sfp, char * buf, size_t count,
X Sg_request * srp)
X {
- Sg_device * sdp = sfp->parentdp;
X sg_io_hdr_t * hp = &srp->header;
X int k, len;
X
- if(! scsi_block_when_processing_errors(sdp->device) )
- return -ENXIO;
X if (count < size_sg_io_hdr)
X return -EINVAL;
-
X hp->sb_len_wr = 0;
X if ((hp->mx_sb_len > 0) && hp->sbp) {
X if ((CHECK_CONDITION & hp->masked_status) ||
X (DRIVER_SENSE & hp->driver_status)) {
- int sb_len = sizeof(dummy_cmdp->sense_buffer);
+ int sb_len = sizeof(dummy_cmdp->sr_sense_buffer);
X sb_len = (hp->mx_sb_len > sb_len) ? sb_len : hp->mx_sb_len;
X len = 8 + (int)srp->sense_b[7]; /* Additional sense length field */
X len = (len > sb_len) ? sb_len : len;
@@ -492,14 +488,15 @@
X Sg_request * srp;
X struct sg_header old_hdr;
X sg_io_hdr_t * hp;
- unsigned char cmnd[sizeof(dummy_cmdp->cmnd)];
+ unsigned char cmnd[sizeof(dummy_cmdp->sr_cmnd)];
X
X if ((! (sfp = (Sg_fd *)filp->private_data)) || (! (sdp = sfp->parentdp)))
X return -ENXIO;
X SCSI_LOG_TIMEOUT(3, printk("sg_write: dev=%d, count=%d\n",
X MINOR(sdp->i_rdev), (int)count));
X
- if(! scsi_block_when_processing_errors(sdp->device) )
+ if (! ((filp->f_flags & O_NONBLOCK) ||
+ scsi_block_when_processing_errors(sdp->device)))
X return -ENXIO;
X if (ppos != &filp->f_pos)
X ; /* FIXME: Hmm. Seek to the right place, or fail? */
@@ -581,7 +578,7 @@
X int k;
X Sg_request * srp;
X sg_io_hdr_t * hp;
- unsigned char cmnd[sizeof(dummy_cmdp->cmnd)];
+ unsigned char cmnd[sizeof(dummy_cmdp->sr_cmnd)];
X int timeout;
X
X if (count < size_sg_io_hdr)
@@ -625,7 +622,7 @@
X unsigned char * cmnd, int timeout, int blocking)
X {
X int k;
- Scsi_Cmnd * SCpnt;
+ Scsi_Request * SRpnt;
X Sg_device * sdp = sfp->parentdp;
X sg_io_hdr_t * hp = &srp->header;
X
@@ -652,38 +649,34 @@
X return k;
X }
X /* SCSI_LOG_TIMEOUT(7, printk("sg_write: allocating device\n")); */
- SCpnt = scsi_allocate_device(sdp->device, blocking, TRUE);
- if (! SCpnt) {
- sg_finish_rem_req(srp);
- return (signal_pending(current)) ? -EINTR : -EAGAIN;
- /* No available command blocks, or, interrupted while waiting */
- }
+ SRpnt = scsi_allocate_request(sdp->device);
+
X /* SCSI_LOG_TIMEOUT(7, printk("sg_write: device allocated\n")); */
- srp->my_cmdp = SCpnt;
- SCpnt->request.rq_dev = sdp->i_rdev;
- SCpnt->request.rq_status = RQ_ACTIVE;
- SCpnt->sense_buffer[0] = 0;
- SCpnt->cmd_len = hp->cmd_len;
+ srp->my_cmdp = SRpnt;
+ SRpnt->sr_request.rq_dev = sdp->i_rdev;
+ SRpnt->sr_request.rq_status = RQ_ACTIVE;
+ SRpnt->sr_sense_buffer[0] = 0;
+ SRpnt->sr_cmd_len = hp->cmd_len;
X /* Set the LUN field in the command structure, overriding user input */
X if (! (hp->flags & SG_FLAG_LUN_INHIBIT))
X cmnd[1] = (cmnd[1] & 0x1f) | (sdp->device->lun << 5);
X
X /* SCSI_LOG_TIMEOUT(7, printk("sg_write: do cmd\n")); */
- SCpnt->use_sg = srp->data.k_use_sg;
- SCpnt->sglist_len = srp->data.sglist_len;
- SCpnt->bufflen = srp->data.bufflen;
- SCpnt->underflow = 0;
- SCpnt->buffer = srp->data.buffer;
+ SRpnt->sr_use_sg = srp->data.k_use_sg;
+ SRpnt->sr_sglist_len = srp->data.sglist_len;
+ SRpnt->sr_bufflen = srp->data.bufflen;
+ SRpnt->sr_underflow = 0;
+ SRpnt->sr_buffer = srp->data.buffer;
X switch (hp->dxfer_direction) {
X case SG_DXFER_TO_FROM_DEV:
X case SG_DXFER_FROM_DEV:
- SCpnt->sc_data_direction = SCSI_DATA_READ; break;
+ SRpnt->sr_data_direction = SCSI_DATA_READ; break;
X case SG_DXFER_TO_DEV:
- SCpnt->sc_data_direction = SCSI_DATA_WRITE; break;
+ SRpnt->sr_data_direction = SCSI_DATA_WRITE; break;
X case SG_DXFER_UNKNOWN:
- SCpnt->sc_data_direction = SCSI_DATA_UNKNOWN; break;
+ SRpnt->sr_data_direction = SCSI_DATA_UNKNOWN; break;
X default:
- SCpnt->sc_data_direction = SCSI_DATA_NONE; break;
+ SRpnt->sr_data_direction = SCSI_DATA_NONE; break;
X }
X srp->data.k_use_sg = 0;
X srp->data.sglist_len = 0;
@@ -692,10 +685,10 @@
X hp->duration = jiffies; /* unit jiffies now, millisecs after done */
X /* Now send everything of to mid-level. The next time we hear about this
X packet is when sg_cmd_done_bh() is called (i.e. a callback). */
- scsi_do_cmd(SCpnt, (void *)cmnd,
- (void *)SCpnt->buffer, hp->dxfer_len,
+ scsi_do_req(SRpnt, (void *)cmnd,
+ (void *)SRpnt->sr_buffer, hp->dxfer_len,
X sg_cmd_done_bh, timeout, SG_DEFAULT_RETRIES);
- /* dxfer_len overwrites SCpnt->bufflen, hence need for b_malloc_len */
+ /* dxfer_len overwrites SRpnt->sr_bufflen, hence need for b_malloc_len */


X return 0;
X }
X

@@ -712,8 +705,6 @@
X return -ENXIO;
X SCSI_LOG_TIMEOUT(3, printk("sg_ioctl: dev=%d, cmd=0x%x\n",
X MINOR(sdp->i_rdev), (int)cmd_in));
- if(! scsi_block_when_processing_errors(sdp->device) )
- return -ENXIO;
X read_only = (O_RDWR != (filp->f_flags & O_ACCMODE));
X
X switch(cmd_in)
@@ -885,7 +876,11 @@
X case SG_EMULATED_HOST:
X return put_user(sdp->device->host->hostt->emulated, (int *)arg);
X case SG_SCSI_RESET:
- if (! scsi_block_when_processing_errors(sdp->device))
+ if (filp->f_flags & O_NONBLOCK) {
+ if (sdp->device->host->in_recovery)
+ return -EBUSY;
+ }
+ else if (! scsi_block_when_processing_errors(sdp->device))
X return -EBUSY;
X result = get_user(val, (int *)arg);
X if (result) return result;
@@ -989,7 +984,8 @@
X * mid level when a command is completed (or has failed). */
X static void sg_cmd_done_bh(Scsi_Cmnd * SCpnt)
X {
- int dev = MINOR(SCpnt->request.rq_dev);
+ Scsi_Request * SRpnt = SCpnt->sc_request;
+ int dev = MINOR(SRpnt->sr_request.rq_dev);
X Sg_device * sdp = NULL;
X Sg_fd * sfp;
X Sg_request * srp = NULL;
@@ -1002,15 +998,15 @@
X if (NULL == sdp) {
X read_unlock(&sg_dev_arr_lock);
X SCSI_LOG_TIMEOUT(1, printk("sg...bh: bad args dev=%d\n", dev));
- scsi_release_command(SCpnt);
- SCpnt = NULL;
+ scsi_release_request(SRpnt);
+ SRpnt = NULL;
X return;
X }
X sfp = sdp->headfp;
X while (sfp) {
X read_lock(&sfp->rq_list_lock);
X for (srp = sfp->headrp; srp; srp = srp->nextrp) {
- if (SCpnt == srp->my_cmdp)
+ if (SRpnt == srp->my_cmdp)
X break;
X }
X read_unlock(&sfp->rq_list_lock);
@@ -1021,41 +1017,41 @@
X read_unlock(&sg_dev_arr_lock);
X if (! srp) {
X SCSI_LOG_TIMEOUT(1, printk("sg...bh: req missing, dev=%d\n", dev));
- scsi_release_command(SCpnt);
- SCpnt = NULL;
+ scsi_release_request(SRpnt);
+ SRpnt = NULL;
X return;
X }
X /* First transfer ownership of data buffers to sg_device object. */
- srp->data.k_use_sg = SCpnt->use_sg;
- srp->data.sglist_len = SCpnt->sglist_len;
- srp->data.bufflen = SCpnt->bufflen;
- srp->data.buffer = SCpnt->buffer;
- sg_clr_scpnt(SCpnt);
+ srp->data.k_use_sg = SRpnt->sr_use_sg;
+ srp->data.sglist_len = SRpnt->sr_sglist_len;
+ srp->data.bufflen = SRpnt->sr_bufflen;
+ srp->data.buffer = SRpnt->sr_buffer;
+ sg_clr_srpnt(SRpnt);
X srp->my_cmdp = NULL;
X srp->done = 1;
X
X SCSI_LOG_TIMEOUT(4, printk("sg...bh: dev=%d, pack_id=%d, res=0x%x\n",
- dev, srp->header.pack_id, (int)SCpnt->result));
+ dev, srp->header.pack_id, (int)SRpnt->sr_result));
X srp->header.resid = SCpnt->resid;
X /* sg_unmap_and(&srp->data, 0); */ /* unmap locked pages a.s.a.p. */
X /* N.B. unit of duration changes here from jiffies to millisecs */
X srp->header.duration = sg_jif_to_ms(jiffies - (int)srp->header.duration);
- if (0 != SCpnt->result) {
- memcpy(srp->sense_b, SCpnt->sense_buffer, sizeof(srp->sense_b));
- srp->header.status = 0xff & SCpnt->result;
- srp->header.masked_status = status_byte(SCpnt->result);
- srp->header.msg_status = msg_byte(SCpnt->result);
- srp->header.host_status = host_byte(SCpnt->result);
- srp->header.driver_status = driver_byte(SCpnt->result);
+ if (0 != SRpnt->sr_result) {
+ memcpy(srp->sense_b, SRpnt->sr_sense_buffer, sizeof(srp->sense_b));
+ srp->header.status = 0xff & SRpnt->sr_result;
+ srp->header.masked_status = status_byte(SRpnt->sr_result);
+ srp->header.msg_status = msg_byte(SRpnt->sr_result);
+ srp->header.host_status = host_byte(SRpnt->sr_result);
+ srp->header.driver_status = driver_byte(SRpnt->sr_result);
X if ((sdp->sgdebug > 0) &&
X ((CHECK_CONDITION == srp->header.masked_status) ||
X (COMMAND_TERMINATED == srp->header.masked_status)))
- print_sense("sg_cmd_done_bh", SCpnt);
+ print_req_sense("sg_cmd_done_bh", SRpnt);
X
X /* Following if statement is a patch supplied by Eric Youngdale */
- if (driver_byte(SCpnt->result) != 0
- && (SCpnt->sense_buffer[0] & 0x7f) == 0x70
- && (SCpnt->sense_buffer[2] & 0xf) == UNIT_ATTENTION
+ if (driver_byte(SRpnt->sr_result) != 0
+ && (SRpnt->sr_sense_buffer[0] & 0x7f) == 0x70
+ && (SRpnt->sr_sense_buffer[2] & 0xf) == UNIT_ATTENTION
X && sdp->device->removable) {
X /* Detected disc change. Set the bit - this may be used if */
X /* there are filesystems using this device. */
@@ -1064,8 +1060,8 @@
X }
X /* Rely on write phase to clean out srp status values, so no "else" */
X
- scsi_release_command(SCpnt);
- SCpnt = NULL;
+ scsi_release_request(SRpnt);
+ SRpnt = NULL;
X if (sfp->closed) { /* whoops this fd already released, cleanup */
X SCSI_LOG_TIMEOUT(1,
X printk("sg...bh: already closed, freeing ...\n"));
@@ -1300,19 +1296,19 @@
X return;
X }
X
-#ifdef MODULE
-
+MODULE_AUTHOR("Douglas Gilbert");
+MODULE_DESCRIPTION("SCSI generic (sg) driver");
X MODULE_PARM(def_reserved_size, "i");
X MODULE_PARM_DESC(def_reserved_size, "size of buffer reserved for each fd");
X
-int init_module(void) {
+static int __init init_sg(void) {
X if (def_reserved_size >= 0)
X sg_big_buff = def_reserved_size;
- sg_template.module = &__this_module;
+ sg_template.module = THIS_MODULE;
X return scsi_register_module(MODULE_SCSI_DEV, &sg_template);


X }
X
-void cleanup_module( void)

+static void __exit exit_sg( void)
X {
X #ifdef CONFIG_PROC_FS
X sg_proc_cleanup();
@@ -1327,7 +1323,6 @@
X }
X sg_template.dev_max = 0;


X }
-#endif /* MODULE */

X
X
X #if 0
@@ -1336,7 +1331,7 @@
X #endif
X
X /* Can't see clean way to abort a command so shorten timeout to 1 jiffy */
-static void sg_shorten_timeout(Scsi_Cmnd * scpnt)
+static void sg_shorten_timeout(Scsi_Request * srpnt)
X {
X #if 0 /* scsi_syms.c is very miserly about exported functions */
X scsi_delete_timer(scpnt);
@@ -1975,6 +1970,7 @@
X return resp;
X }
X
+#ifdef CONFIG_PROC_FS
X static Sg_request * sg_get_nth_request(Sg_fd * sfp, int nth)
X {
X Sg_request * resp;
@@ -1988,6 +1984,7 @@
X read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
X return resp;
X }
+#endif
X
X /* always adds to end of list */
X static Sg_request * sg_add_request(Sg_fd * sfp)
@@ -2067,6 +2064,7 @@
X return res;
X }
X
+#ifdef CONFIG_PROC_FS
X static Sg_fd * sg_get_nth_sfp(Sg_device * sdp, int nth)
X {
X Sg_fd * resp;
@@ -2080,6 +2078,7 @@
X read_unlock_irqrestore(&sg_dev_arr_lock, iflags);
X return resp;
X }
+#endif
X
X static Sg_fd * sg_add_sfp(Sg_device * sdp, int dev)
X {
@@ -2366,14 +2365,14 @@
X sg_low_free(buff, size, mem_src);
X }
X
-static void sg_clr_scpnt(Scsi_Cmnd * SCpnt)
+static void sg_clr_srpnt(Scsi_Request * SRpnt)
X {
- SCpnt->use_sg = 0;
- SCpnt->sglist_len = 0;
- SCpnt->bufflen = 0;
- SCpnt->buffer = NULL;
- SCpnt->underflow = 0;
- SCpnt->request.rq_dev = MKDEV(0, 0); /* "sg" _disowns_ command blk */
+ SRpnt->sr_use_sg = 0;
+ SRpnt->sr_sglist_len = 0;
+ SRpnt->sr_bufflen = 0;
+ SRpnt->sr_buffer = NULL;
+ SRpnt->sr_underflow = 0;
+ SRpnt->sr_request.rq_dev = MKDEV(0, 0); /* "sg" _disowns_ command blk */
X }
X
X static int sg_ms_to_jif(unsigned int msecs)
@@ -2413,6 +2412,7 @@
X }
X
X
+#ifdef CONFIG_PROC_FS
X static int sg_last_dev()
X {
X int k;
@@ -2424,6 +2424,7 @@
X read_unlock_irqrestore(&sg_dev_arr_lock, iflags);
X return k + 1; /* origin 1 */
X }
+#endif
X
X static Sg_device * sg_get_dev(int dev)
X {
@@ -2543,7 +2544,6 @@


X return 0;
X }
X
-#ifdef MODULE

X static void sg_proc_cleanup()
X {
X int k;
@@ -2555,7 +2555,6 @@
X remove_proc_entry(sg_proc_leaf_names[k], sg_proc_sgp);
X remove_proc_entry(sg_proc_sg_dirname, proc_scsi);
X }
-#endif
X
X static int sg_proc_dressz_read(char * buffer, char ** start, off_t offset,
X int size, int * eof, void * data)
@@ -2642,8 +2641,8 @@
X /* stop indenting so far ... */
X PRINT_PROC(srp->res_used ? " rb>> " :
X ((SG_INFO_DIRECT_IO_MASK & hp->info) ? " dio>> " : " "));
- blen = srp->my_cmdp ? srp->my_cmdp->bufflen : srp->data.bufflen;
- usg = srp->my_cmdp ? srp->my_cmdp->use_sg : srp->data.k_use_sg;
+ blen = srp->my_cmdp ? srp->my_cmdp->sr_bufflen : srp->data.bufflen;
+ usg = srp->my_cmdp ? srp->my_cmdp->sr_use_sg : srp->data.k_use_sg;
X PRINT_PROC(srp->done ? ((1 == srp->done) ? "rcv:" : "fin:")
X : (srp->my_cmdp ? "act:" : "prior:"));
X PRINT_PROC(" id=%d blen=%d", srp->header.pack_id, blen);
@@ -2785,3 +2784,7 @@
X return 1;
X }
X #endif /* CONFIG_PROC_FS */
+
+
+module_init(init_sg);
+module_exit(exit_sg);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/sgiwd93.c linux/drivers/scsi/sgiwd93.c
--- v2.4.0-test8/linux/drivers/scsi/sgiwd93.c Tue Jul 11 11:17:45 2000
+++ linux/drivers/scsi/sgiwd93.c Mon Sep 18 13:36:25 2000
@@ -317,17 +317,13 @@
X return 1; /* Found one. */


X }
X
-#ifdef MODULE
-

X #define HOSTS_C
X
X #include "sgiwd93.h"
X
-Scsi_Host_Template driver_template = SGIWD93_SCSI;
+static Scsi_Host_Template driver_template = SGIWD93_SCSI;


X
X #include "scsi_module.c"
-
-#endif
X

X int sgiwd93_release(struct Scsi_Host *instance)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/sim710.c linux/drivers/scsi/sim710.c
--- v2.4.0-test8/linux/drivers/scsi/sim710.c Fri Nov 19 11:30:54 1999
+++ linux/drivers/scsi/sim710.c Mon Sep 18 13:36:25 2000
@@ -1603,7 +1603,8 @@


X return 1;
X }
X

-Scsi_Host_Template driver_template = SIM710_SCSI;
+#endif
+
+static Scsi_Host_Template driver_template = SIM710_SCSI;


X
X #include "scsi_module.c"
-#endif

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/sim710.h linux/drivers/scsi/sim710.h
--- v2.4.0-test8/linux/drivers/scsi/sim710.h Fri Sep 8 12:54:34 2000
+++ linux/drivers/scsi/sim710.h Mon Sep 18 14:10:10 2000
@@ -21,7 +21,6 @@
X #define sim710_release NULL


X #endif
X
-#if defined(HOSTS_C) || defined(MODULE)
X #include <scsi/scsicam.h>
X

X #define SIM710_SCSI { proc_name: "sim710", \
@@ -40,8 +39,6 @@
X cmd_per_lun: 1, \
X use_clustering: DISABLE_CLUSTERING, \
X use_new_eh_code: 1}


-
-#endif
X
X #ifndef HOSTS_C

X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/sr.c linux/drivers/scsi/sr.c
--- v2.4.0-test8/linux/drivers/scsi/sr.c Thu Sep 7 08:32:01 2000
+++ linux/drivers/scsi/sr.c Sun Oct 1 20:35:16 2000
@@ -71,7 +71,7 @@
X
X static int sr_init_command(Scsi_Cmnd *);
X
-struct Scsi_Device_Template sr_template =
+static struct Scsi_Device_Template sr_template =
X {
X name:"cdrom",
X tag:"sr",
@@ -696,7 +696,7 @@
X return cgc->stat;
X }
X
-static int sr_registered = 0;
+static int sr_registered;
X
X static int sr_init()
X {
@@ -849,13 +849,13 @@
X return;
X }
X
-int init_sr(void)
+static int __init init_sr(void)
X {
X sr_template.module = THIS_MODULE;
X return scsi_register_module(MODULE_SCSI_DEV, &sr_template);
X }
X
-void exit_sr(void)
+static void __exit exit_sr(void)
X {
X scsi_unregister_module(MODULE_SCSI_DEV, &sr_template);
X devfs_unregister_blkdev(MAJOR_NR, "sr");
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/st.c linux/drivers/scsi/st.c
--- v2.4.0-test8/linux/drivers/scsi/st.c Wed Sep 6 12:53:14 2000
+++ linux/drivers/scsi/st.c Fri Sep 22 14:37:37 2000
@@ -155,7 +155,7 @@
X static int st_detect(Scsi_Device *);
X static void st_detach(Scsi_Device *);
X
-struct Scsi_Device_Template st_template =
+static struct Scsi_Device_Template st_template =
X {
X name:"tape",
X tag:"st",
@@ -173,6 +173,47 @@
X static int update_partition(Scsi_Tape *);
X
X static int st_int_ioctl(Scsi_Tape *, unsigned int, unsigned long);
+
+
+/* #include "osst_detect.h" */
+#ifndef SIGS_FROM_OSST
+#define SIGS_FROM_OSST \
+ {"OnStream", "SC-", "", "osst"}, \
+ {"OnStream", "DI-", "", "osst"}, \
+ {"OnStream", "DP-", "", "osst"}, \
+ {"OnStream", "USB", "", "osst"}, \
+ {"OnStream", "FW-", "", "osst"}
+#endif
+
+struct st_reject_data {
+ char *vendor;
+ char *model;
+ char *rev;
+ char *driver_hint; /* Name of the correct driver, NULL if unknown */
+};
+
+static struct st_reject_data reject_list[] = {
+ /* {"XXX", "Yy-", "", NULL}, example */
+ SIGS_FROM_OSST,
+ {NULL, }};
+
+/* If the device signature is on the list of incompatible drives, the
+ function returns a pointer to the name of the correct driver (if known) */
+static char * st_incompatible(Scsi_Device* SDp)
+{
+ struct st_reject_data *rp;
+
+ for (rp=&(reject_list[0]); rp->vendor != NULL; rp++)
+ if (!strncmp(rp->vendor, SDp->vendor, strlen(rp->vendor)) &&
+ !strncmp(rp->model, SDp->model, strlen(rp->model)) &&
+ !strncmp(rp->rev, SDp->rev, strlen(rp->rev))) {
+ if (rp->driver_hint)
+ return rp->driver_hint;
+ else
+ return "unknown";
+ }
+ return NULL;
+}
X
X
X /* Convert the result to success code */
@@ -3460,9 +3501,17 @@
X ST_partstat *STps;
X int i, mode, target_nbr;
X unsigned long flags = 0;
+ char *stp;
X
X if (SDp->type != TYPE_TAPE)
X return 1;
+ if ((stp = st_incompatible(SDp))) {
+ printk(KERN_INFO
+ "st: Found incompatible tape at scsi%d, channel %d, id %d, lun %d\n",
+ SDp->host->host_no, SDp->channel, SDp->id, SDp->lun);
+ printk(KERN_INFO "st: The suggested driver is %s.\n", stp);
+ return 1;
+ }
X
X write_lock_irqsave(&st_dev_arr_lock, flags);
X if (st_template.nr_dev >= st_template.dev_max) {
@@ -3626,7 +3675,7 @@
X
X static int st_detect(Scsi_Device * SDp)
X {
- if (SDp->type != TYPE_TAPE)
+ if (SDp->type != TYPE_TAPE || st_incompatible(SDp))
X return 0;
X
X printk(KERN_WARNING
@@ -3700,17 +3749,15 @@


X }
X
X
-#ifdef MODULE
-

-int __init init_module(void)
+static int __init init_st(void)
X {
X validate_options();
X
- st_template.module = &__this_module;
+ st_template.module = THIS_MODULE;
X return scsi_register_module(MODULE_SCSI_DEV, &st_template);
X }
X
-void cleanup_module(void)
+static void __exit exit_st(void)


X {
X int i;
X

@@ -3736,4 +3783,6 @@
X st_template.dev_max = 0;
X printk(KERN_INFO "st: Unloaded.\n");


X }
-#endif /* MODULE */
+

+module_init(init_st);
+module_exit(exit_st);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/sun3_scsi.c linux/drivers/scsi/sun3_scsi.c
--- v2.4.0-test8/linux/drivers/scsi/sun3_scsi.c Sat Feb 26 20:33:03 2000
+++ linux/drivers/scsi/sun3_scsi.c Mon Sep 18 13:36:25 2000
@@ -529,10 +529,7 @@
X
X #include "sun3_NCR5380.c"
X
-#ifdef MODULE
-
-Scsi_Host_Template driver_template = SUN3_NCR5380;
+static Scsi_Host_Template driver_template = SUN3_NCR5380;


X
X #include "scsi_module.c"
-#endif
X

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/sym53c416.c linux/drivers/scsi/sym53c416.c
--- v2.4.0-test8/linux/drivers/scsi/sym53c416.c Thu Nov 11 16:57:30 1999
+++ linux/drivers/scsi/sym53c416.c Mon Sep 18 13:36:25 2000
@@ -813,7 +813,8 @@
X MODULE_PARM(sym53c416_2, "1-2i");
X MODULE_PARM(sym53c416_3, "1-2i");
X
-Scsi_Host_Template driver_template = SYM53C416;
+#endif
+
+static Scsi_Host_Template driver_template = SYM53C416;


X
X #include "scsi_module.c"
-#endif

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/sym53c8xx.c linux/drivers/scsi/sym53c8xx.c
--- v2.4.0-test8/linux/drivers/scsi/sym53c8xx.c Mon Jun 19 17:59:42 2000
+++ linux/drivers/scsi/sym53c8xx.c Tue Sep 19 08:31:53 2000
@@ -107,6 +107,7 @@
X
X #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
X

+#include <linux/config.h>
X #ifdef MODULE
X #include <linux/module.h>

X #endif
@@ -698,6 +699,9 @@
X #elif defined(__alpha__)
X # define pcivtobus(p) ((p) & 0xfffffffful)
X # define memcpy_to_pci(a, b, c) memcpy_toio((a), (b), (c))
+#elif defined(CONFIG_PPC)
+# define pcivtobus(p) phys_to_bus(p)
+# define memcpy_to_pci(a, b, c) memcpy_toio((a), (b), (c))
X #else /* others */
X # define pcivtobus(p) (p)
X # define memcpy_to_pci(a, b, c) memcpy_toio((a), (b), (c))
@@ -15059,7 +15063,5 @@


X ** Module stuff
X */
X
-#ifdef MODULE

-Scsi_Host_Template driver_template = SYM53C8XX;
+static Scsi_Host_Template driver_template = SYM53C8XX;
X #include "scsi_module.c"
-#endif
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/sym53c8xx.h linux/drivers/scsi/sym53c8xx.h
--- v2.4.0-test8/linux/drivers/scsi/sym53c8xx.h Fri Sep 8 12:54:35 2000
+++ linux/drivers/scsi/sym53c8xx.h Mon Oct 2 11:03:13 2000
@@ -65,8 +65,6 @@
X ** Used by hosts.c and sym53c8xx.c with module configuration.


X */
X
-#if defined(HOSTS_C) || defined(MODULE)
-
X #include <scsi/scsicam.h>
X

X int sym53c8xx_abort(Scsi_Cmnd *);
@@ -110,7 +108,5 @@


X 0, 0, DISABLE_CLUSTERING}
X
X #endif /* LINUX_VERSION_CODE */
-
-#endif /* defined(HOSTS_C) || defined(MODULE) */
X

X #endif /* SYM53C8XX_H */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/sym53c8xx_comm.h linux/drivers/scsi/sym53c8xx_comm.h
--- v2.4.0-test8/linux/drivers/scsi/sym53c8xx_comm.h Mon Jun 19 17:59:42 2000
+++ linux/drivers/scsi/sym53c8xx_comm.h Mon Sep 18 15:05:20 2000
@@ -498,7 +498,8 @@
X # define memcpy_to_pci(a, b, c) memcpy_toio((a), (b), (c))
X #endif
X
-#ifndef SCSI_NCR_PCI_MEM_NOT_SUPPORTED
+#if (defined(SCSI_NCR_NVRAM_SUPPORT) && !defined(NCR_IOMAPPED)) || \
+ (defined(__i386__) && !defined(SCSI_NCR_PCI_MEM_NOT_SUPPORTED))
X static u_long __init remap_pci_mem(u_long base, u_long size)
X {
X u_long page_base = ((u_long) base) & PAGE_MASK;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/t128.c linux/drivers/scsi/t128.c
--- v2.4.0-test8/linux/drivers/scsi/t128.c Fri Nov 19 11:30:54 1999
+++ linux/drivers/scsi/t128.c Mon Sep 18 13:36:25 2000
@@ -393,9 +393,7 @@


X
X #include "NCR5380.c"
X
-#ifdef MODULE
X /* Eventually this will go into an include file, but this will be later */

-Scsi_Host_Template driver_template = TRANTOR_T128;
+static Scsi_Host_Template driver_template = TRANTOR_T128;


X
X #include "scsi_module.c"
-#endif

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/t128.h linux/drivers/scsi/t128.h
--- v2.4.0-test8/linux/drivers/scsi/t128.h Fri Nov 19 11:30:54 1999
+++ linux/drivers/scsi/t128.h Mon Sep 18 14:10:10 2000
@@ -117,8 +117,6 @@


X * macros when this is being used solely for the host stub.
X */
X
-#if defined(HOSTS_C) || defined(MODULE)
-

X #define TRANTOR_T128 { \
X name: "Trantor T128/T128F/T228", \
X detect: t128_detect, \
@@ -131,8 +129,6 @@


X sg_tablesize: SG_ALL, \
X cmd_per_lun: CMD_PER_LUN, \
X use_clustering: DISABLE_CLUSTERING}
-
-#endif
X
X #ifndef HOSTS_C

X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/tmscsim.c linux/drivers/scsi/tmscsim.c
--- v2.4.0-test8/linux/drivers/scsi/tmscsim.c Thu Jul 6 19:27:48 2000
+++ linux/drivers/scsi/tmscsim.c Mon Sep 18 14:26:56 2000
@@ -2588,6 +2588,7 @@
X return( 1 );
X }
X
-Scsi_Host_Template driver_template = DC390_T;
+#endif
+
+static Scsi_Host_Template driver_template = DC390_T;
X #include "scsi_module.c"
-#endif /* def MODULE */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/u14-34f.c linux/drivers/scsi/u14-34f.c
--- v2.4.0-test8/linux/drivers/scsi/u14-34f.c Tue Mar 21 14:43:39 2000
+++ linux/drivers/scsi/u14-34f.c Mon Sep 18 13:36:25 2000
@@ -1964,12 +1964,11 @@


X return FALSE;
X }
X
-#if defined(MODULE)

-Scsi_Host_Template driver_template = ULTRASTOR_14_34F;
+static Scsi_Host_Template driver_template = ULTRASTOR_14_34F;


X
X #include "scsi_module.c"
X

-#else
+#ifndef MODULE
X
X #if LINUX_VERSION_CODE < LinuxVersionCode(2,3,18)

X void u14_34f_setup(char *str, int *ints) {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/ultrastor.c linux/drivers/scsi/ultrastor.c
--- v2.4.0-test8/linux/drivers/scsi/ultrastor.c Thu Nov 11 16:57:31 1999
+++ linux/drivers/scsi/ultrastor.c Mon Sep 18 13:36:25 2000
@@ -1161,9 +1161,7 @@
X spin_unlock_irqrestore(&io_request_lock, flags);


X }
X
-#ifdef MODULE
X /* Eventually this will go into an include file, but this will be later */

-Scsi_Host_Template driver_template = ULTRASTOR_14F;
+static Scsi_Host_Template driver_template = ULTRASTOR_14F;


X
X #include "scsi_module.c"
-#endif

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/scsi/wd7000.c linux/drivers/scsi/wd7000.c
--- v2.4.0-test8/linux/drivers/scsi/wd7000.c Thu Dec 16 13:57:05 1999
+++ linux/drivers/scsi/wd7000.c Mon Sep 18 13:36:25 2000
@@ -1778,9 +1778,7 @@


X return (0);
X }
X

-#ifdef MODULE
X /* Eventually this will go into an include file, but this will be later */

-Scsi_Host_Template driver_template = WD7000;
+static Scsi_Host_Template driver_template = WD7000;


X
X #include "scsi_module.c"
-#endif

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/Config.in linux/drivers/sound/Config.in
--- v2.4.0-test8/linux/drivers/sound/Config.in Tue Aug 22 11:31:05 2000
+++ linux/drivers/sound/Config.in Mon Sep 25 12:32:54 2000
@@ -16,6 +16,7 @@
X fi
X dep_tristate ' Creative SBLive! (EMU10K1)' CONFIG_SOUND_EMU10K1 $CONFIG_SOUND
X dep_tristate ' Crystal SoundFusion (CS4280/461x)' CONFIG_SOUND_FUSION $CONFIG_SOUND
+dep_tristate ' Crystal Sound CS4281' CONFIG_SOUND_CS4281 $CONFIG_SOUND
X dep_tristate ' Ensoniq AudioPCI (ES1370)' CONFIG_SOUND_ES1370 $CONFIG_SOUND
X dep_tristate ' Creative Ensoniq AudioPCI 97 (ES1371)' CONFIG_SOUND_ES1371 $CONFIG_SOUND
X dep_tristate ' ESS Technology Solo1' CONFIG_SOUND_ESSSOLO1 $CONFIG_SOUND
@@ -127,12 +128,6 @@


X fi
X fi
X

- dep_tristate ' SoftOSS software wave table engine' CONFIG_SOUND_SOFTOSS $CONFIG_SOUND_OSS
- if [ "$CONFIG_SOUND_SOFTOSS" = "y" ]; then
- int 'Sampling rate for SoftOSS 8000 to 48000' CONFIG_SOFTOSS_RATE 22050
- int 'Max # of concurrent voices for SoftOSS 4 to 32' CONFIG_SOFTOSS_VOICES 32
- fi
-
X dep_tristate ' 100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support' CONFIG_SOUND_SB $CONFIG_SOUND_OSS
X dep_tristate ' AWE32 synth' CONFIG_SOUND_AWE32_SYNTH $CONFIG_SOUND_OSS
X dep_tristate ' Full support for Turtle Beach WaveFront (Tropez Plus, Tropez, Maui) synth/soundcards' CONFIG_SOUND_WAVEFRONT $CONFIG_SOUND_OSS m
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/Makefile linux/drivers/sound/Makefile
--- v2.4.0-test8/linux/drivers/sound/Makefile Tue Aug 22 11:31:05 2000
+++ linux/drivers/sound/Makefile Mon Sep 25 12:32:54 2000
@@ -43,7 +43,6 @@
X obj-$(CONFIG_SOUND_PSS) += pss.o ad1848.o mpu401.o
X obj-$(CONFIG_SOUND_TRIX) += trix.o ad1848.o sb_lib.o uart401.o
X obj-$(CONFIG_SOUND_OPL3SA1) += opl3sa.o ad1848.o uart401.o
-obj-$(CONFIG_SOUND_SOFTOSS) += softoss2.o
X obj-$(CONFIG_SOUND_SSCAPE) += sscape.o ad1848.o mpu401.o
X obj-$(CONFIG_SOUND_MAD16) += mad16.o ad1848.o sb_lib.o uart401.o
X obj-$(CONFIG_SOUND_CS4232) += cs4232.o uart401.o
@@ -79,6 +78,7 @@
X obj-$(CONFIG_SOUND_ES1371) += es1371.o ac97_codec.o
X obj-$(CONFIG_SOUND_ESSSOLO1) += esssolo1.o
X obj-$(CONFIG_SOUND_FUSION) += cs46xx.o ac97_codec.o
+obj-$(CONFIG_SOUND_CS4281) += cs4281.o
X obj-$(CONFIG_SOUND_MAESTRO) += maestro.o
X obj-$(CONFIG_SOUND_TRIDENT) += trident.o ac97_codec.o
X
@@ -104,7 +104,7 @@
X
X # Declare multi-part drivers.
X
-list-multi := sound.o gus.o pas2.o sb.o sb_lib.o softoss2.o vidc_mod.o \
+list-multi := sound.o gus.o pas2.o sb.o sb_lib.o vidc_mod.o \
X soundcore.o wavefront.o
X
X sound-objs := \
@@ -119,7 +119,6 @@
X pas2-objs := pas2_card.o pas2_midi.o pas2_mixer.o pas2_pcm.o
X sb-objs := sb_card.o
X sb_lib-objs := sb_common.o sb_audio.o sb_midi.o sb_mixer.o sb_ess.o
-softoss2-objs := softoss.o softoss_rs.o
X vidc_mod-objs := vidc.o vidc_fill.o
X wavefront-objs := wavfront.o wf_midi.o yss225.o
X
@@ -180,9 +179,6 @@
X
X sb_lib.o: $(sb_lib-objs)
X $(LD) -r -o $@ $(sb_lib-objs)
-
-softoss2.o: $(softoss2-objs)
- $(LD) -r -o $@ $(softoss2-objs)
X
X vidc_mod.o: $(vidc_mod-objs)
X $(LD) -r -o $@ $(vidc_mod-objs)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/ac97_codec.c linux/drivers/sound/ac97_codec.c
--- v2.4.0-test8/linux/drivers/sound/ac97_codec.c Tue Aug 29 14:09:15 2000
+++ linux/drivers/sound/ac97_codec.c Sun Oct 1 20:20:20 2000
@@ -35,6 +35,7 @@
X #include <linux/string.h>
X #include <linux/errno.h>
X #include <linux/bitops.h>
+#include <linux/delay.h>
X #include <linux/ac97_codec.h>
X #include <asm/uaccess.h>
X
@@ -48,6 +49,7 @@
X static int ac97_init_mixer(struct ac97_codec *codec);
X
X static int sigmatel_init(struct ac97_codec *codec);
+static int enable_eapd(struct ac97_codec *codec);
X
X #define arraysize(x) (sizeof(x)/sizeof((x)[0]))
X
@@ -58,11 +60,14 @@
X } ac97_codec_ids[] = {
X {0x414B4D00, "Asahi Kasei AK4540" , NULL},
X {0x41445340, "Analog Devices AD1881" , NULL},
+ {0x41445360, "Analog Devices AD1885" , enable_eapd},
X {0x43525900, "Cirrus Logic CS4297" , NULL},
X {0x43525903, "Cirrus Logic CS4297" , NULL},
X {0x43525913, "Cirrus Logic CS4297A" , NULL},
X {0x43525923, "Cirrus Logic CS4298" , NULL},
+ {0x4352592B, "Cirrus Logic CS4294" , NULL},
X {0x43525931, "Cirrus Logic CS4299" , NULL},
+ {0x43525934, "Cirrus Logic CS4299" , NULL},
X {0x4e534331, "National Semiconductor LM4549" , NULL},
X {0x53494c22, "Silicon Laboratory Si3036" , NULL},
X {0x53494c23, "Silicon Laboratory Si3038" , NULL},
@@ -71,8 +76,10 @@
X {0x83847605, "SigmaTel STAC9704" , NULL},
X {0x83847608, "SigmaTel STAC9708" , NULL},
X {0x83847609, "SigmaTel STAC9721/23" , sigmatel_init},
+ {0x54524103, "TriTech TR?????" , NULL},
X {0x54524106, "TriTech TR28026" , NULL},
X {0x54524108, "TriTech TR28028" , NULL},
+ {0x54524123, "TriTech TR?????" , NULL},
X {0x574D4C00, "Wolfson WM9704" , NULL},
X {0x00000000, NULL, NULL}
X };
@@ -119,20 +126,20 @@
X unsigned int value;
X } mixer_defaults[SOUND_MIXER_NRDEVICES] = {
X /* all values 0 -> 100 in bytes */
- {SOUND_MIXER_VOLUME, 0x3232},
- {SOUND_MIXER_BASS, 0x3232},
- {SOUND_MIXER_TREBLE, 0x3232},
- {SOUND_MIXER_PCM, 0x3232},
- {SOUND_MIXER_SPEAKER, 0x3232},
- {SOUND_MIXER_LINE, 0x3232},
- {SOUND_MIXER_MIC, 0x3232},
- {SOUND_MIXER_CD, 0x3232},
- {SOUND_MIXER_ALTPCM, 0x3232},
- {SOUND_MIXER_IGAIN, 0x3232},
- {SOUND_MIXER_LINE1, 0x3232},
- {SOUND_MIXER_PHONEIN, 0x3232},
- {SOUND_MIXER_PHONEOUT, 0x3232},
- {SOUND_MIXER_VIDEO, 0x3232},
+ {SOUND_MIXER_VOLUME, 0x4343},
+ {SOUND_MIXER_BASS, 0x4343},
+ {SOUND_MIXER_TREBLE, 0x4343},
+ {SOUND_MIXER_PCM, 0x4343},
+ {SOUND_MIXER_SPEAKER, 0x4343},
+ {SOUND_MIXER_LINE, 0x4343},
+ {SOUND_MIXER_MIC, 0x4343},
+ {SOUND_MIXER_CD, 0x4343},
+ {SOUND_MIXER_ALTPCM, 0x4343},
+ {SOUND_MIXER_IGAIN, 0x4343},
+ {SOUND_MIXER_LINE1, 0x4343},
+ {SOUND_MIXER_PHONEIN, 0x4343},
+ {SOUND_MIXER_PHONEOUT, 0x4343},
+ {SOUND_MIXER_VIDEO, 0x4343},
X {-1,0}
X };
X
@@ -141,20 +148,20 @@
X unsigned char offset;
X int scale;
X } ac97_hw[SOUND_MIXER_NRDEVICES]= {
- [SOUND_MIXER_VOLUME] = {AC97_MASTER_VOL_STEREO,63},
- [SOUND_MIXER_BASS] = {AC97_MASTER_TONE, 15},
- [SOUND_MIXER_TREBLE] = {AC97_MASTER_TONE, 15},
- [SOUND_MIXER_PCM] = {AC97_PCMOUT_VOL, 31},
- [SOUND_MIXER_SPEAKER] = {AC97_PCBEEP_VOL, 15},
- [SOUND_MIXER_LINE] = {AC97_LINEIN_VOL, 31},
- [SOUND_MIXER_MIC] = {AC97_MIC_VOL, 31},
- [SOUND_MIXER_CD] = {AC97_CD_VOL, 31},
- [SOUND_MIXER_ALTPCM] = {AC97_HEADPHONE_VOL, 63},
- [SOUND_MIXER_IGAIN] = {AC97_RECORD_GAIN, 31},
- [SOUND_MIXER_LINE1] = {AC97_AUX_VOL, 31},
- [SOUND_MIXER_PHONEIN] = {AC97_PHONE_VOL, 15},
- [SOUND_MIXER_PHONEOUT] = {AC97_MASTER_VOL_MONO, 63},
- [SOUND_MIXER_VIDEO] = {AC97_VIDEO_VOL, 31},
+ [SOUND_MIXER_VOLUME] = {AC97_MASTER_VOL_STEREO,64},
+ [SOUND_MIXER_BASS] = {AC97_MASTER_TONE, 16},
+ [SOUND_MIXER_TREBLE] = {AC97_MASTER_TONE, 16},
+ [SOUND_MIXER_PCM] = {AC97_PCMOUT_VOL, 32},
+ [SOUND_MIXER_SPEAKER] = {AC97_PCBEEP_VOL, 16},
+ [SOUND_MIXER_LINE] = {AC97_LINEIN_VOL, 32},
+ [SOUND_MIXER_MIC] = {AC97_MIC_VOL, 32},
+ [SOUND_MIXER_CD] = {AC97_CD_VOL, 32},
+ [SOUND_MIXER_ALTPCM] = {AC97_HEADPHONE_VOL, 64},
+ [SOUND_MIXER_IGAIN] = {AC97_RECORD_GAIN, 16},
+ [SOUND_MIXER_LINE1] = {AC97_AUX_VOL, 32},
+ [SOUND_MIXER_PHONEIN] = {AC97_PHONE_VOL, 32},
+ [SOUND_MIXER_PHONEOUT] = {AC97_MASTER_VOL_MONO, 64},
+ [SOUND_MIXER_VIDEO] = {AC97_VIDEO_VOL, 32},
X };
X
X /* the following tables allow us to go from OSS <-> ac97 quickly. */
@@ -196,11 +203,14 @@
X {
X u16 val;
X int ret = 0;
+ int scale;
X struct ac97_mixer_hw *mh = &ac97_hw[oss_channel];
X
X val = codec->codec_read(codec , mh->offset);
X
- if (AC97_STEREO_MASK & (1 << oss_channel)) {
+ if (val & AC97_MUTE) {
+ ret = 0;
+ } else if (AC97_STEREO_MASK & (1 << oss_channel)) {
X /* nice stereo mixers .. */
X int left,right;
X
@@ -211,8 +221,14 @@
X right = (right * 100) / mh->scale;
X left = (left * 100) / mh->scale;
X } else {
- right = 100 - ((right * 100) / mh->scale);
- left = 100 - ((left * 100) / mh->scale);
+ /* these may have 5 or 6 bit resolution */
+ if(oss_channel == SOUND_MIXER_VOLUME || oss_channel == SOUND_MIXER_ALTPCM)
+ scale = (1 << codec->bit_resolution);
+ else
+ scale = mh->scale;
+
+ right = 100 - ((right * 100) / scale);
+ left = 100 - ((left * 100) / scale);
X }
X ret = left | (right << 8);
X } else if (oss_channel == SOUND_MIXER_SPEAKER) {
@@ -220,7 +236,8 @@
X } else if (oss_channel == SOUND_MIXER_PHONEIN) {
X ret = 100 - (((val & 0x1f) * 100) / mh->scale);
X } else if (oss_channel == SOUND_MIXER_PHONEOUT) {
- ret = 100 - (((val & 0x1f) * 100) / mh->scale);
+ scale = (1 << codec->bit_resolution);
+ ret = 100 - (((val & 0x1f) * 100) / scale);
X } else if (oss_channel == SOUND_MIXER_MIC) {
X ret = 100 - (((val & 0x1f) * 100) / mh->scale);
X /* the low bit is optional in the tone sliders and masking
@@ -247,6 +264,7 @@
X unsigned int left, unsigned int right)
X {
X u16 val = 0;
+ int scale;
X struct ac97_mixer_hw *mh = &ac97_hw[oss_channel];
X
X #ifdef DEBUG
@@ -258,31 +276,45 @@
X
X if (AC97_STEREO_MASK & (1 << oss_channel)) {
X /* stereo mixers */
- if (oss_channel == SOUND_MIXER_IGAIN) {
- right = (right * mh->scale) / 100;
- left = (left * mh->scale) / 100;
+ if (left == 0 && right == 0) {
+ val = AC97_MUTE;
X } else {
- right = ((100 - right) * mh->scale) / 100;
- left = ((100 - left) * mh->scale) / 100;
- }
- val = (left << 8) | right;
+ if (oss_channel == SOUND_MIXER_IGAIN) {
+ right = (right * mh->scale) / 100;
+ left = (left * mh->scale) / 100;
+ } else {
+ /* these may have 5 or 6 bit resolution */
+ if (oss_channel == SOUND_MIXER_VOLUME ||
+ oss_channel == SOUND_MIXER_ALTPCM)
+ scale = (1 << codec->bit_resolution);
+ else
+ scale = mh->scale;
+
+ right = ((100 - right) * scale) / 100;
+ left = ((100 - left) * scale) / 100;
+ }
+ val = (left << 8) | right;
+ }
+ } else if (oss_channel == SOUND_MIXER_BASS) {
+ val = codec->codec_read(codec , mh->offset) & ~0x0f00;
+ val |= ((((100 - left) * mh->scale) / 100) << 8) & 0x0e00;
+ } else if (oss_channel == SOUND_MIXER_TREBLE) {
+ val = codec->codec_read(codec , mh->offset) & ~0x000f;
+ val |= (((100 - left) * mh->scale) / 100) & 0x000e;
+ } else if(left == 0) {
+ val = AC97_MUTE;
X } else if (oss_channel == SOUND_MIXER_SPEAKER) {
X val = (((100 - left) * mh->scale) / 100) << 1;
X } else if (oss_channel == SOUND_MIXER_PHONEIN) {
X val = (((100 - left) * mh->scale) / 100);
X } else if (oss_channel == SOUND_MIXER_PHONEOUT) {
- val = (((100 - left) * mh->scale) / 100);
+ scale = (1 << codec->bit_resolution);
+ val = (((100 - left) * scale) / 100);
X } else if (oss_channel == SOUND_MIXER_MIC) {
X val = codec->codec_read(codec , mh->offset) & ~0x801f;
X val |= (((100 - left) * mh->scale) / 100);
X /* the low bit is optional in the tone sliders and masking
X it lets us avoid the 0xf 'bypass'.. */
- } else if (oss_channel == SOUND_MIXER_BASS) {
- val = codec->codec_read(codec , mh->offset) & ~0x0f00;
- val |= ((((100 - left) * mh->scale) / 100) << 8) & 0x0e00;
- } else if (oss_channel == SOUND_MIXER_TREBLE) {
- val = codec->codec_read(codec , mh->offset) & ~0x000f;
- val |= (((100 - left) * mh->scale) / 100) & 0x000e;
X }
X #ifdef DEBUG
X printk(" 0x%04x", val);
@@ -563,7 +595,7 @@
X if (codec->codec_wait)
X codec->codec_wait(codec);
X else
- schedule_timeout(5);
+ udelay(10);
X
X if ((audio = codec->codec_read(codec, AC97_RESET)) & 0x8000) {
X printk(KERN_ERR "ac97_codec: %s ac97 codec not present\n",
@@ -582,6 +614,7 @@
X id2 = codec->codec_read(codec, AC97_VENDOR_ID2);
X for (i = 0; i < arraysize(ac97_codec_ids); i++) {
X if (ac97_codec_ids[i].id == ((id1 << 16) | id2)) {
+ codec->type = ac97_codec_ids[i].id;
X codec->name = ac97_codec_ids[i].name;
X codec->codec_init = ac97_codec_ids[i].init;
X break;
@@ -589,8 +622,8 @@
X }
X if (codec->name == NULL)
X codec->name = "Unknown";
- printk(KERN_INFO "ac97_codec: AC97%s codec, id: 0x%04x:0x%04x (%s)\n",
- audio ? " audio" : (modem ? " modem" : ""),
+ printk(KERN_INFO "ac97_codec: AC97 %s codec, vendor id1: 0x%04x, "
+ "id2: 0x%04x (%s)\n", audio ? "Audio" : (modem ? "Modem" : ""),
X id1, id2, codec->name);
X
X return ac97_init_mixer(codec);
@@ -612,18 +645,21 @@
X if (!(cap & 0x10))
X codec->supported_mixers &= ~SOUND_MASK_ALTPCM;
X
+ /* detect bit resolution */
+ codec->codec_write(codec, AC97_MASTER_VOL_STEREO, 0x2020);
+ if(codec->codec_read(codec, AC97_MASTER_VOL_STEREO) == 0x1f1f)
+ codec->bit_resolution = 5;
+ else
+ codec->bit_resolution = 6;
+
X /* generic OSS to AC97 wrapper */
X codec->read_mixer = ac97_read_mixer;
X codec->write_mixer = ac97_write_mixer;
X codec->recmask_io = ac97_recmask_io;
X codec->mixer_ioctl = ac97_mixer_ioctl;
X
- /* initialize volume level */
- codec->codec_write(codec, AC97_MASTER_VOL_STEREO, 0L);
- codec->codec_write(codec, AC97_PCMOUT_VOL, 0L);
-
X /* codec specific initialization for 4-6 channel output or secondary codec stuff */
- if (codec->id != 0 && codec->codec_init != NULL) {
+ if (codec->codec_init != NULL) {
X codec->codec_init(codec);
X }
X
@@ -642,6 +678,10 @@
X
X static int sigmatel_init(struct ac97_codec * codec)
X {
+ /* Only set up secondary codec */
+ if (codec->id == 0)
+ return 1;
+
X codec->codec_write(codec, AC97_SURROUND_MASTER, 0L);
X
X /* initialize SigmaTel STAC9721/23 as secondary codec, decoding AC link
@@ -659,6 +699,18 @@


X
X return 1;
X }

+
+/*
+ * Bring up an AD1885
+ */
+
+static int enable_eapd(struct ac97_codec * codec)
+{
+ codec->codec_write(codec, AC97_POWER_CONTROL,
+ codec->codec_read(codec, AC97_POWER_CONTROL)|0x8000);


+ return 0;
+}
+

X
X EXPORT_SYMBOL(ac97_read_proc);
X EXPORT_SYMBOL(ac97_probe_codec);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/adlib_card.c linux/drivers/sound/adlib_card.c
--- v2.4.0-test8/linux/drivers/sound/adlib_card.c Fri Aug 11 08:26:43 2000
+++ linux/drivers/sound/adlib_card.c Sun Sep 17 09:45:06 2000
@@ -20,15 +20,10 @@
X static void __init attach_adlib_card(struct address_info *hw_config)
X {
X hw_config->slots[0] = opl3_init(hw_config->io_base, hw_config->osp, THIS_MODULE);
- request_region(hw_config->io_base, 4, "OPL3/OPL2");
X }
X
X static int __init probe_adlib(struct address_info *hw_config)


X {
- if (check_region(hw_config->io_base, 4)) {

- DDB(printk("opl3.c: I/O port %x already in use\n", hw_config->io_base));
- return 0;
- }
X return opl3_detect(hw_config->io_base, hw_config->osp);
X }
X
@@ -55,7 +50,6 @@
X
X static void __exit cleanup_adlib(void)
X {
- release_region(cfg.io_base, 4);
X sound_unload_synthdev(cfg.slots[0]);
X
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/aedsp16.c linux/drivers/sound/aedsp16.c
--- v2.4.0-test8/linux/drivers/sound/aedsp16.c Fri Aug 11 08:26:43 2000
+++ linux/drivers/sound/aedsp16.c Wed Sep 27 13:53:57 2000
@@ -241,6 +241,9 @@
X - Module informations added.
X - Removed aedsp16_delay_10msec(), now using mdelay(10)
X - All data and funcs moved to .*.init section.
+ v1.3
+ Arnaldo Carvalho de Melo <ac...@conectiva.com.br> - 2000/09/27
+ - got rid of check_region
X
X Known Problems:
X - Audio Excel DSP 16 III don't work with this driver.
@@ -252,7 +255,7 @@
X */
X
X
-#define VERSION "1.2" /* Version of Audio Excel DSP 16 driver */
+#define VERSION "1.3" /* Version of Audio Excel DSP 16 driver */
X
X #undef AEDSP16_DEBUG 1 /* Define this to enable debug code */
X #undef AEDSP16_DEBUG_MORE 1 /* Define this to enable more debug */
@@ -1174,25 +1177,18 @@
X if (ae_config.init & INIT_MSS)
X return FALSE;
X /*
- * We must check the CONFIG_AEDSP16_BASE region too because these are the I/O
- * ports to access card's control registers.
+ * We must allocate the CONFIG_AEDSP16_BASE region too because these are the
+ * I/O ports to access card's control registers.
X */
X if (!(ae_config.init & INIT_MPU401)) {
- if (check_region(ae_config.base_io, IOBASE_REGION_SIZE)) {
+ if (!request_region(ae_config.base_io, IOBASE_REGION_SIZE,
+ "aedsp16 (base)")) {
X printk(
X "AEDSP16 BASE I/O port region is already in use.\n");
X return FALSE;
X }
X }
X
-/*
- * We must allocate the CONFIG_AEDSP16_BASE region too because these are the
- * I/O ports to access card's control registers.
- */
- if (!(ae_config.init & INIT_MPU401))
- request_region(ae_config.base_io, IOBASE_REGION_SIZE,
- "aedsp16 (base)");
-
X ae_config.init |= INIT_MSS;
X
X DBG(("done.\n"));
@@ -1222,20 +1218,17 @@
X return FALSE;
X
X /*
- * We must check the CONFIG_AEDSP16_BASE region too because these are the I/O
+ * We must request the CONFIG_AEDSP16_BASE region too because these are the I/O
X * ports to access card's control registers.
X */
X if (!(ae_config.init & (INIT_MSS | INIT_SBPRO))) {
- if (check_region(ae_config.base_io, IOBASE_REGION_SIZE)) {
+ if (!request_region(ae_config.base_io, IOBASE_REGION_SIZE,
+ "aedsp16 (base)")) {
X printk(
X "AEDSP16 BASE I/O port region is already in use.\n");


X return FALSE;
X }
X }
-

- if (!(ae_config.init & (INIT_MSS | INIT_SBPRO)))
- request_region(ae_config.base_io, IOBASE_REGION_SIZE,
- "aedsp16 (base)");
X
X ae_config.init |= INIT_MPU401;
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/cmpci.c linux/drivers/sound/cmpci.c
--- v2.4.0-test8/linux/drivers/sound/cmpci.c Tue Aug 29 14:09:15 2000
+++ linux/drivers/sound/cmpci.c Wed Sep 27 13:53:57 2000
@@ -2287,8 +2287,6 @@


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 083'
echo 'File patch-2.4.0-test9 is continued in part 084'
echo "084" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part088

#!/bin/sh -x
# this is part 088 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 088; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&
-

-/*
- * Engine state
- */
-
- volatile int engine_state;
-#define ES_STOPPED 0
-#define ES_STARTED 1
-
- /* Voice spesific bitmaps */
- volatile int tremolomap;
- volatile int vibratomap;
-
-} softsyn_devc;
-
-void softsynth_resample_loop(short *buf, int loops);
-extern void softsyn_control_loop(void);
-
-#define DELAY_SIZE 4096
-
-#ifdef SOFTSYN_MAIN
- short voice_active[MAX_VOICE] = {0};
- voice_info softoss_voices[MAX_VOICE] = {{0}}; /* Voice spesific info */
- int left_delay[DELAY_SIZE]={0}, right_delay[DELAY_SIZE]={0};
- int delayp=0;
-#else
- extern softsyn_devc *devc;
-
- extern int left_delay[DELAY_SIZE], right_delay[DELAY_SIZE];
- extern int delayp;
- extern short voice_active[MAX_VOICE];
-#endif
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/softoss_rs.c linux/drivers/sound/softoss_rs.c
--- v2.4.0-test8/linux/drivers/sound/softoss_rs.c Mon Feb 28 07:18:20 2000
+++ linux/drivers/sound/softoss_rs.c Wed Dec 31 16:00:00 1969
@@ -1,127 +0,0 @@
-
-/*
- * sound/softoss_rs.c
- *
- * Software based MIDI synthsesizer driver, the actual mixing loop.
- * Keep the loop as simple as possible to make it easier to rewrite this
- * routine in assembly.


- *
- *
- * Copyright (C) by Hannu Savolainen 1993-1997
- *
- * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
- * Version 2 (June 1991). See the "COPYING" file distributed with this software
- * for more info.

- */
-#include "sound_config.h"
-#include "softoss.h"
-
-void softsynth_resample_loop(short *buf, int loops)
-{
- int iloop, voice;
- volatile voice_info *v;
-
-#ifdef OSS_BIG_ENDIAN
- unsigned char *cbuf = (unsigned char *) buf;
-
-#endif
-
- for (iloop = 0; iloop < loops; iloop++)
- { /* Mix one sample */
- int accum, left = 0, right = 0;
- int ix, position;


-
- for (voice = 0; voice < devc->maxvoice; voice++)
- {
- if (voice_active[voice])

- { /* Compute voice */
- v = &softoss_voices[voice];
-#ifdef SOFTOSS_TEST
- ix = iloop << 3;
- position = v->ptr;
-#else
- ix = (position = v->ptr) >> 9;
-#endif
- /* Interpolation (resolution of 512 steps) */
- {
- int fract = v->ptr & 0x1ff; /* 9 bits */
-
- /* This method works with less arithmetic operations */
- register int v1 = v->wave[ix];
- accum = v1 + ((((v->wave[ix + 1] - v1)) * (fract)) >> 9);
- }
-
- left += (accum * v->leftvol);
- right += (accum * v->rightvol);
-
- /* Update sample pointer */
- position += v->step;
- if (position <= v->endloop)
- v->ptr = position;
- else if (v->mode & WAVE_LOOPING)
- {
- if (v->mode & WAVE_BIDIR_LOOP)
- { v->mode ^= WAVE_LOOP_BACK; /* Turn around */


- v->step *= -1;

- }
- else
- {
- position -= v->looplen;
- v->ptr = position;
- }
- }
- /* else leave the voice looping the current sample */
-
- if (v->mode & WAVE_LOOP_BACK && position < v->startloop)
- {
- if (v->mode & WAVE_BIDIR_LOOP)
- { v->mode ^= WAVE_LOOP_BACK; /* Turn around */


- v->step *= -1;

- }
- else
- {
- position += v->looplen;
- v->ptr = position;
- }
- }
- } /* Compute voice */
- }
-#if 1 /* Delay */
- left += left_delay[delayp];
- right += right_delay[delayp];
-
- left_delay[delayp] = right >> 2;
- right_delay[delayp] = left >> 2;
- delayp = (delayp + 1) % devc->delay_size;
-#endif
-
-#define AFTERSCALE devc->afterscale;
-
- left >>= AFTERSCALE;
- right >>= AFTERSCALE;
-
- if (left > 32767)
- left = 32767;
- if (left < -32768)
- left = -32768;
- if (right > 32767)
- right = 32767;
- if (right < -32768)
- right = -32768;
-
-#ifdef OSS_BIG_ENDIAN
- *cbuf++ = left & 0xff;
- *cbuf++ = (left >> 8) & 0xff;
- *cbuf++ = right & 0xff;
- *cbuf++ = (right >> 8) & 0xff;
-#else
- *buf++ = left;
- *buf++ = right;
-#endif
- if (devc->control_counter++ >= devc->control_rate)
- {


- devc->control_counter = 0;

- softsyn_control_loop();
- }
- } /* Mix one sample */
-}
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/sonicvibes.c linux/drivers/sound/sonicvibes.c
--- v2.4.0-test8/linux/drivers/sound/sonicvibes.c Tue Aug 29 14:09:15 2000
+++ linux/drivers/sound/sonicvibes.c Mon Sep 18 14:57:01 2000
@@ -2589,7 +2589,7 @@
X }
X set_fs(fs);
X /* store it in the driver field */
- pcidev->driver_data = s;
+ pci_set_drvdata(pcidev, s);
X pcidev->dma_mask = 0x00ffffff;
X /* put it into driver list */
X list_add_tail(&s->devs, &devs);
@@ -2624,7 +2624,7 @@
X
X static void __devinit sv_remove(struct pci_dev *dev)
X {
- struct sv_state *s = (struct sv_state *)dev->driver_data;
+ struct sv_state *s = pci_get_drvdata(dev);
X
X if (!s)
X return;
@@ -2646,7 +2646,7 @@
X unregister_sound_midi(s->dev_midi);
X unregister_sound_special(s->dev_dmfm);
X kfree(s);
- dev->driver_data = NULL;
+ pci_set_drvdata(dev, NULL);
X }
X
X static struct pci_device_id id_table[] __devinitdata = {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/sound_core.c linux/drivers/sound/sound_core.c
--- v2.4.0-test8/linux/drivers/sound/sound_core.c Mon Aug 28 15:03:42 2000
+++ linux/drivers/sound/sound_core.c Mon Sep 25 12:32:54 2000
@@ -36,6 +36,7 @@
X

X #include <linux/config.h>
X #include <linux/module.h>

+#include <linux/init.h>
X #include <linux/malloc.h>
X #include <linux/types.h>
X #include <linux/kernel.h>
@@ -62,9 +63,6 @@
X #ifdef CONFIG_SOUND_MSNDPIN
X extern int msnd_pinnacle_init(void);
X #endif
-#ifdef CONFIG_SOUND_CMPCI
-extern int init_cmpci(void);
-#endif
X
X /*
X * Low level list operator. Scan the ordered list, find a hole and
@@ -545,12 +543,11 @@
X extern int mod_firmware_load(const char *, char **);
X EXPORT_SYMBOL(mod_firmware_load);
X
-#ifdef MODULE
X
X MODULE_DESCRIPTION("Core sound module");
X MODULE_AUTHOR("Alan Cox");
X
-void cleanup_module(void)
+static void __exit cleanup_soundcore(void)
X {
X /* We have nothing to really do here - we know the lists must be
X empty */
@@ -558,10 +555,7 @@
X devfs_unregister (devfs_handle);
X }
X
-int init_module(void)
-#else
-int soundcore_init(void)
-#endif
+static int __init init_soundcore(void)
X {
X if(devfs_register_chrdev(SOUND_MAJOR, "sound", &soundcore_fops)==-1)
X {
@@ -569,20 +563,9 @@
X return -EBUSY;
X }
X devfs_handle = devfs_mk_dir (NULL, "sound", NULL);
- /*
- * Now init non OSS drivers
- */
-#ifdef CONFIG_SOUND_CMPCI
- init_cmpci();
-#endif
-#ifdef CONFIG_SOUND_MSNDCLAS
- msnd_classic_init();
-#endif
-#ifdef CONFIG_SOUND_MSNDPIN
- msnd_pinnacle_init();
-#endif
-#ifdef CONFIG_SOUND_VWSND
- init_vwsnd();
-#endif
+
X return 0;
X }
+
+module_init(init_soundcore);
+module_exit(cleanup_soundcore);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/sound_syms.c linux/drivers/sound/sound_syms.c
--- v2.4.0-test8/linux/drivers/sound/sound_syms.c Fri Aug 11 08:26:44 2000
+++ linux/drivers/sound/sound_syms.c Mon Sep 25 12:32:54 2000
@@ -49,8 +49,5 @@
X EXPORT_SYMBOL(conf_printf);
X EXPORT_SYMBOL(conf_printf2);
X
-extern int softoss_dev;
-EXPORT_SYMBOL(softoss_dev);
-
X MODULE_DESCRIPTION("OSS Sound subsystem");
X MODULE_AUTHOR("Hannu Savolainen, et al.");
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/sound_timer.c linux/drivers/sound/sound_timer.c
--- v2.4.0-test8/linux/drivers/sound/sound_timer.c Fri Aug 11 08:26:44 2000
+++ linux/drivers/sound/sound_timer.c Sun Oct 1 20:35:16 2000
@@ -16,7 +16,7 @@
X
X #include "sound_config.h"
X
-static volatile int initialized = 0, opened = 0, tmr_running = 0;
+static volatile int initialized, opened, tmr_running;
X static volatile time_t tmr_offs, tmr_ctr;
X static volatile unsigned long ticks_offs;
X static volatile int curr_tempo, curr_timebase;
@@ -25,7 +25,7 @@
X static unsigned long prev_event_time;
X static volatile unsigned long usecs_per_tmr; /* Length of the current interval */
X
-static struct sound_lowlev_timer *tmr = NULL;
+static struct sound_lowlev_timer *tmr;
X
X static unsigned long tmr2ticks(int tmr_value)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/soundcard.c linux/drivers/sound/soundcard.c
--- v2.4.0-test8/linux/drivers/sound/soundcard.c Fri Aug 11 08:26:44 2000
+++ linux/drivers/sound/soundcard.c Mon Sep 25 12:32:54 2000
@@ -25,6 +25,7 @@
X #include <linux/config.h>
X
X #include "sound_config.h"
+#include <linux/init.h>
X #include <linux/types.h>
X #include <linux/errno.h>
X #include <linux/signal.h>
@@ -51,8 +52,6 @@
X #define valid_dma(n) ((n) >= 0 && (n) < MAX_DMA_CHANNELS && (n) != 4)
X #endif
X
-static int chrdev_registered = 0;
-
X /*
X * Table for permanently allocated memory (used when unloading the module)
X */
@@ -267,6 +266,7 @@
X DEB(printk("sound_release(dev=%d)\n", dev));
X switch (dev & 0x0f) {
X case SND_DEV_CTL:
+ dev >>= 4;
X if (mixer_devs[dev]->owner)
X __MOD_DEC_USE_COUNT (mixer_devs[dev]->owner);
X break;
@@ -582,34 +582,6 @@


X }
X }
X
-#ifdef MODULE

-static void
-#else
-void
-#endif
-soundcard_init(void)
-{
- /* drag in sound_syms.o */
- {
- extern char sound_syms_symbol;
- sound_syms_symbol = 0;
- }
-
-#ifndef MODULE
- create_special_devices();
- chrdev_registered = 1;
-#endif
-
- soundcard_register_devfs(1); /* register after we know # of devices */
-}
-
-#ifdef MODULE
-
-static void destroy_special_devices(void)
-{
- unregister_sound_special(1);
- unregister_sound_special(8);
-}
X
X static int dmabuf = 0;
X static int dmabug = 0;
@@ -617,14 +589,21 @@
X MODULE_PARM(dmabuf, "i");
X MODULE_PARM(dmabug, "i");
X
-int init_module(void)
+static int __init oss_init(void)
X {
X int err;
+
+ /* drag in sound_syms.o */
+ {
+ extern char sound_syms_symbol;
+ sound_syms_symbol = 0;
+ }
X
X #ifdef CONFIG_PCI
X if(dmabug)
X isa_dma_bridge_buggy = dmabug;
X #endif
+
X err = create_special_devices();
X if (err) {
X printk(KERN_ERR "sound: driver already loaded/included in kernel\n");
@@ -634,8 +613,7 @@
X /* Protecting the innocent */
X sound_dmap_flag = (dmabuf > 0 ? 1 : 0);
X
- chrdev_registered = 1;
- soundcard_init();
+ soundcard_register_devfs(1);
X
X if (sound_nblocks >= 1024)
X printk(KERN_ERR "Sound warning: Deallocation table was too small.\n");
@@ -643,7 +621,7 @@


X return 0;
X }
X

-void cleanup_module(void)
+static void __exit oss_cleanup(void)


X {
X int i;
X

@@ -651,8 +629,9 @@
X return;
X
X soundcard_register_devfs (0);
- if (chrdev_registered)
- destroy_special_devices();
+
+ unregister_sound_special(1);
+ unregister_sound_special(8);
X
X sound_stop_timer();
X
@@ -668,7 +647,10 @@
X vfree(sound_mem_blocks[i]);
X
X }
-#endif
+
+module_init(oss_init);
+module_exit(oss_cleanup);
+
X
X int sound_alloc_dma(int chn, char *deviceID)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/trident.c linux/drivers/sound/trident.c
--- v2.4.0-test8/linux/drivers/sound/trident.c Tue Aug 29 14:09:15 2000
+++ linux/drivers/sound/trident.c Mon Sep 18 14:57:01 2000
@@ -2484,7 +2484,7 @@
X /* edited by HMSEO for GT sound*/
X }
X
- pci_dev->driver_data = card;
+ pci_set_drvdata(pci_dev, card);
X pci_dev->dma_mask = TRIDENT_DMA_MASK;
X
X /* Enable Address Engine Interrupts */
@@ -2496,7 +2496,7 @@
X static void __exit trident_remove(struct pci_dev *pci_dev)
X {
X int i;
- struct trident_card *card = pci_dev->driver_data;
+ struct trident_card *card = pci_get_drvdata(pci_dev);
X
X /* Kill interrupts, and SP/DIF */
X trident_disable_loop_interrupts(card);
@@ -2514,6 +2514,8 @@
X unregister_sound_dsp(card->dev_audio);
X
X kfree(card);
+
+ pci_set_drvdata(pci_dev, NULL);
X }
X
X MODULE_AUTHOR("Alan Cox, Aaron Holtzman, Ollie Lho, Ching Ling Lee");
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/trix.c linux/drivers/sound/trix.c
--- v2.4.0-test8/linux/drivers/sound/trix.c Fri Aug 11 08:26:44 2000
+++ linux/drivers/sound/trix.c Wed Sep 27 13:53:56 2000


@@ -14,6 +14,7 @@
X * Changes

X * Alan Cox Modularisation, cleanup.


X * Christoph Hellwig Adapted to module_init/module_exit

+ * Arnaldo C. de Melo Got rid of attach_uart401


X */
X
X #include <linux/config.h>

@@ -337,12 +338,6 @@
X sb_be_quiet = old_quiet;
X }
X
-static void __init attach_trix_mpu(struct address_info *hw_config)
-{
- hw_config->name = "AudioTrix Pro";


- attach_uart401(hw_config, THIS_MODULE);
-}
-

X static int __init probe_trix_mpu(struct address_info *hw_config)


X {
X unsigned char conf;

@@ -365,11 +360,6 @@
X DDB(printk("Trix: MPU mode already initialized\n"));


X return 0;
X }
- if (check_region(hw_config->io_base, 4))
- {

- printk(KERN_ERR "AudioTrix: MPU I/O port conflict (%x)\n", hw_config->io_base);
- return 0;
- }
X if (hw_config->irq > 9)
X {
X printk(KERN_ERR "AudioTrix: Bad MPU IRQ %d\n", hw_config->irq);
@@ -401,7 +391,8 @@
X conf |= irq_bits[hw_config->irq] << 4;
X trix_write(0x19, (trix_read(0x19) & 0x83) | conf);
X mpu_initialized = 1;
- return probe_uart401(hw_config);
+ hw_config->name = "AudioTrix Pro";


+ return probe_uart401(hw_config, THIS_MODULE);
X }
X

X static void __exit unload_trix_wss(struct address_info *hw_config)
@@ -510,11 +501,8 @@
X attach_trix_sb(&cfg2);
X }
X
- if (cfg_mpu.io_base != -1) {
+ if (cfg_mpu.io_base != -1)
X mpu = probe_trix_mpu(&cfg_mpu);
- if (mpu)
- attach_trix_mpu(&cfg_mpu);
- }
X
X return 0;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/uart401.c linux/drivers/sound/uart401.c
--- v2.4.0-test8/linux/drivers/sound/uart401.c Fri Aug 11 08:26:44 2000
+++ linux/drivers/sound/uart401.c Wed Sep 27 13:53:57 2000
@@ -15,6 +15,7 @@
X * interrupt allocation. Protect against bogus unload
X * Fixed to allow IRQ > 15


X * Christoph Hellwig Adapted to module_init/module_exit

+ * Arnaldo C. de Melo got rid of check_region


X *
X * Status:

X * Untested


@@ -40,8 +41,6 @@
X }

X uart401_devc;
X
-static uart401_devc *detected_devc = NULL;
-
X #define DATAPORT (devc->base)
X #define COMDPORT (devc->base+1)
X #define STATPORT (devc->base+1)
@@ -241,95 +240,6 @@
X restore_flags(flags);
X }
X
-void attach_uart401(struct address_info *hw_config, struct module *owner)
-{
- uart401_devc *devc;
- char *name = "MPU-401 (UART) MIDI";
-
-
- if (hw_config->name)
- name = hw_config->name;
-
- if (detected_devc == NULL)
- return;
-
-
- devc = (uart401_devc *) kmalloc(sizeof(uart401_devc), GFP_KERNEL);
- if (devc == NULL)
- {
- printk(KERN_WARNING "uart401: Can't allocate memory\n");
- return;
- }
- memcpy((char *) devc, (char *) detected_devc, sizeof(uart401_devc));
- detected_devc = NULL;
-
- devc->irq = hw_config->irq;
- if (devc->irq < 0)
- {
- devc->share_irq = 1;
- devc->irq *= -1;
- }
- else
- devc->share_irq = 0;
-
- if (!devc->share_irq)
- {
- if (request_irq(devc->irq, uart401intr, 0, "MPU-401 UART", devc) < 0)
- {
- printk(KERN_WARNING "uart401: Failed to allocate IRQ%d\n", devc->irq);
- devc->share_irq = 1;
- }
- }
- devc->my_dev = sound_alloc_mididev();
-
- request_region(hw_config->io_base, 4, "MPU-401 UART");
- enter_uart_mode(devc);
-
- if (devc->my_dev == -1)
- {
- printk(KERN_INFO "uart401: Too many midi devices detected\n");
- kfree(devc);
- return;
- }
- conf_printf(name, hw_config);
-
- std_midi_synth.midi_dev = devc->my_dev;
- midi_devs[devc->my_dev] = (struct midi_operations *)kmalloc(sizeof(struct midi_operations), GFP_KERNEL);
- if (midi_devs[devc->my_dev] == NULL)
- {
- printk(KERN_ERR "uart401: Failed to allocate memory\n");
- sound_unload_mididev(devc->my_dev);
- kfree(devc);
- devc=NULL;
- return;
- }
- memcpy((char *) midi_devs[devc->my_dev], (char *) &uart401_operations,
- sizeof(struct midi_operations));
-
- if (owner)
- midi_devs[devc->my_dev]->owner = owner;
-
- midi_devs[devc->my_dev]->devc = devc;
- midi_devs[devc->my_dev]->converter = (struct synth_operations *)kmalloc(sizeof(struct synth_operations), GFP_KERNEL);
- if (midi_devs[devc->my_dev]->converter == NULL)
- {
- printk(KERN_WARNING "uart401: Failed to allocate memory\n");
- kfree(midi_devs[devc->my_dev]);
- kfree(devc);
- sound_unload_mididev(devc->my_dev);
- devc=NULL;
- return;
- }
- memcpy((char *) midi_devs[devc->my_dev]->converter, (char *) &std_midi_synth,
- sizeof(struct synth_operations));
-
- strcpy(midi_devs[devc->my_dev]->info.name, name);
- midi_devs[devc->my_dev]->converter->id = "UART401";
- hw_config->slots[4] = devc->my_dev;
- sequencer_init();
- devc->opened = 0;
-}
-
X static int reset_uart401(uart401_devc * devc)
X {
X int ok, timeout, n;
@@ -379,21 +289,28 @@
X return ok;
X }
X
-int probe_uart401(struct address_info *hw_config)
+int probe_uart401(struct address_info *hw_config, struct module *owner)
X {
+ uart401_devc *devc;
+ char *name = "MPU-401 (UART) MIDI";
X int ok = 0;
X unsigned long flags;
- static uart401_devc hw_info;
- uart401_devc *devc = &hw_info;
X
X DDB(printk("Entered probe_uart401()\n"));
X
X /* Default to "not found" */
X hw_config->slots[4] = -1;
- detected_devc = NULL;


X
- if (check_region(hw_config->io_base, 4))

+ if (!request_region(hw_config->io_base, 4, "MPU-401 UART")) {
+ printk(KERN_INFO "uart401: could not request_region(%d, 4)\n", hw_config->io_base);
X return 0;
+ }
+
+ devc = kmalloc(sizeof(uart401_devc), GFP_KERNEL);
+ if (!devc) {
+ printk(KERN_WARNING "uart401: Can't allocate memory\n");
+ goto cleanup_region;
+ }
X
X devc->base = hw_config->io_base;
X devc->irq = hw_config->irq;
@@ -409,10 +326,67 @@
X ok = reset_uart401(devc);
X restore_flags(flags);
X
- if (ok)
- detected_devc = devc;
+ if (!ok)
+ goto cleanup_devc;
X
- return ok;
+ if (hw_config->name)
+ name = hw_config->name;
+
+ if (devc->irq < 0) {
+ devc->share_irq = 1;
+ devc->irq *= -1;
+ } else
+ devc->share_irq = 0;
+
+ if (!devc->share_irq)
+ if (request_irq(devc->irq, uart401intr, 0, "MPU-401 UART", devc) < 0) {
+ printk(KERN_WARNING "uart401: Failed to allocate IRQ%d\n", devc->irq);
+ devc->share_irq = 1;
+ }
+ devc->my_dev = sound_alloc_mididev();
+ enter_uart_mode(devc);
+
+ if (devc->my_dev == -1) {
+ printk(KERN_INFO "uart401: Too many midi devices detected\n");
+ goto cleanup_irq;
+ }
+ conf_printf(name, hw_config);
+ std_midi_synth.midi_dev = devc->my_dev;
+ midi_devs[devc->my_dev] = kmalloc(sizeof(struct midi_operations), GFP_KERNEL);
+ if (!midi_devs[devc->my_dev]) {
+ printk(KERN_ERR "uart401: Failed to allocate memory\n");
+ goto cleanup_unload_mididev;
+ }
+ memcpy(midi_devs[devc->my_dev], &uart401_operations, sizeof(struct midi_operations));
+
+ if (owner)
+ midi_devs[devc->my_dev]->owner = owner;
+
+ midi_devs[devc->my_dev]->devc = devc;
+ midi_devs[devc->my_dev]->converter = kmalloc(sizeof(struct synth_operations), GFP_KERNEL);
+ if (!midi_devs[devc->my_dev]->converter) {
+ printk(KERN_WARNING "uart401: Failed to allocate memory\n");
+ goto cleanup_midi_devs;
+ }
+ memcpy(midi_devs[devc->my_dev]->converter, &std_midi_synth, sizeof(struct synth_operations));
+ strcpy(midi_devs[devc->my_dev]->info.name, name);
+ midi_devs[devc->my_dev]->converter->id = "UART401";
+ hw_config->slots[4] = devc->my_dev;
+ sequencer_init();
+ devc->opened = 0;
+ return 1;
+cleanup_midi_devs:
+ kfree(midi_devs[devc->my_dev]);
+cleanup_unload_mididev:
+ sound_unload_mididev(devc->my_dev);
+cleanup_irq:
+ if (!devc->share_irq)
+ free_irq(devc->irq, devc);
+cleanup_devc:
+ kfree(devc);
+cleanup_region:
+ release_region(hw_config->io_base, 4);
+ return 0;
X }
X
X void unload_uart401(struct address_info *hw_config)
@@ -446,7 +420,6 @@
X sound_unload_mididev(hw_config->slots[4]);
X }
X
-EXPORT_SYMBOL(attach_uart401);
X EXPORT_SYMBOL(probe_uart401);
X EXPORT_SYMBOL(unload_uart401);
X EXPORT_SYMBOL(uart401intr);
@@ -469,9 +442,8 @@
X to others */
X if (cfg_mpu.io_base != -1 && cfg_mpu.irq != -1) {
X printk(KERN_INFO "MPU-401 UART driver Copyright (C) Hannu Savolainen 1993-1997");
- if (probe_uart401(&cfg_mpu) == 0)
+ if (!probe_uart401(&cfg_mpu, THIS_MODULE))
X return -ENODEV;
- attach_uart401(&cfg_mpu, THIS_MODULE);


X }
X
X return 0;

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/uart6850.c linux/drivers/sound/uart6850.c
--- v2.4.0-test8/linux/drivers/sound/uart6850.c Fri Aug 11 08:26:44 2000
+++ linux/drivers/sound/uart6850.c Sun Sep 17 09:45:07 2000
@@ -13,8 +13,11 @@
X * Alan Cox: Updated for new modular code. Removed snd_* irq handling. Now
X * uses native linux resources


X * Christoph Hellwig: Adapted to module_init/module_exit

+ * Jeff Garzik: Made it work again, in theory
+ * FIXME: If the request_irq() succeeds, the probe succeeds. Ug.
+ *
+ * Status: Testing required (no shit -jgarzik)
X *
- * Status: Testing required
X *
X */
X
@@ -64,12 +67,11 @@
X #define UART_RESET 0x95
X #define UART_MODE_ON 0x03
X
-static int uart6850_opened = 0;
+static int uart6850_opened;
X static int uart6850_irq;
-static int uart6850_detected = 0;
+static int uart6850_detected;
X static int my_dev;
X
-static int reset_uart6850(void);
X static void (*midi_input_intr) (int dev, unsigned char data);
X static void poll_uart6850(unsigned long dummy);
X
@@ -251,6 +253,9 @@
X int ok, timeout;


X unsigned long flags;
X

+ if (!uart6850_detected)
+ return;
+
X if ((my_dev = sound_alloc_mididev()) == -1)
X {
X printk(KERN_INFO "uart6850: Too many midi devices detected\n");
@@ -260,11 +265,6 @@
X uart6850_osp = hw_config->osp;
X uart6850_irq = hw_config->irq;
X
- if (!uart6850_detected)
- {
- sound_unload_mididev(my_dev);
- return;
- }
X save_flags(flags);
X cli();
X
@@ -283,7 +283,7 @@
X sequencer_init();
X }
X
-static int reset_uart6850(void)
+static inline int reset_uart6850(void)
X {
X uart6850_read();
X return 1; /*
@@ -291,10 +291,9 @@
X */
X }
X
-
X static int __init probe_uart6850(struct address_info *hw_config)
X {
- int ok = 0;
+ int ok;
X
X uart6850_osp = hw_config->osp;
X uart6850_base = hw_config->io_base;


@@ -334,6 +333,7 @@
X

X if (probe_uart6850(&cfg_mpu))
X return -ENODEV;
+ attach_uart6850(&cfg_mpu);
X
X return 0;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/vidc.c linux/drivers/sound/vidc.c
--- v2.4.0-test8/linux/drivers/sound/vidc.c Fri Aug 11 08:26:44 2000
+++ linux/drivers/sound/vidc.c Wed Sep 27 13:39:23 2000
@@ -1,9 +1,13 @@
X /*
- * drivers/sound/vidc.c
+ * linux/drivers/sound/vidc.c
X *
- * VIDC20 audio driver.
+ * Copyright (C) 1997-2000 by Russell King <r...@arm.linux.org.uk>
X *
- * Copyright (C) 1997-2000 by Russell King <r...@arm.linux.org.uk>
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * VIDC20 audio driver.
X *
X * The VIDC20 sound hardware consists of the VIDC20 itself, a DAC and a DMA
X * engine. The DMA transfers fixed-format (16-bit little-endian linear)
@@ -13,7 +17,6 @@
X * We currently support a mixer device, but it is currently non-functional.
X */
X
-#include <linux/config.h>
X #include <linux/init.h>
X #include <linux/module.h>
X #include <linux/kernel.h>
@@ -21,7 +24,7 @@
X #include <asm/hardware.h>
X #include <asm/dma.h>
X #include <asm/io.h>
-#include <asm/iomd.h>
+#include <asm/hardware/iomd.h>
X #include <asm/irq.h>
X #include <asm/system.h>
X
@@ -79,7 +82,6 @@
X static void (*old_mksound)(unsigned int hz, unsigned int ticks);
X extern void (*kd_mksound)(unsigned int hz, unsigned int ticks);
X extern void vidc_update_filler(int bits, int channels);
-extern int softoss_dev;
X
X static void
X vidc_mksound(unsigned int hz, unsigned int ticks)
@@ -287,10 +289,10 @@
X struct dma_buffparms *dmap = audio_devs[dev]->dmap_out;


X unsigned long flags;
X

- save_flags_cli(flags);
+ local_irq_save(flags);
X dma_start = buf - (unsigned long)dmap->raw_buf_phys + (unsigned long)dmap->raw_buf;
X dma_count = total_count;
- restore_flags(flags);
+ local_irq_restore(flags);


X }
X
X static void

@@ -345,7 +347,7 @@
X if (!(adev->flags & DMA_ACTIVE)) {


X unsigned long flags;
X

- save_flags_cli(flags);
+ local_irq_save(flags);
X
X /* prevent recusion */
X adev->flags |= DMA_ACTIVE;
@@ -354,7 +356,7 @@
X vidc_sound_dma_irq(0, NULL, NULL);
X outb(DMA_CR_E | 0x10, IOMD_SD0CR);
X
- restore_flags(flags);
+ local_irq_restore(flags);
X }
X }
X }
@@ -471,9 +473,6 @@
X vidc_adev = adev;
X vidc_mixer_set(SOUND_MIXER_VOLUME, (85 | 85 << 8));
X
-#if defined(CONFIG_SOUND_SOFTOSS) || defined(CONFIG_SOUND_SOFTOSS_MODULE)
- softoss_dev = adev;
-#endif
X return;
X
X irq_failed:
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/vidc.h linux/drivers/sound/vidc.h
--- v2.4.0-test8/linux/drivers/sound/vidc.h Thu Feb 24 22:44:47 2000
+++ linux/drivers/sound/vidc.h Mon Sep 18 15:15:22 2000
@@ -1,9 +1,13 @@
X /*
- * drivers/sound/vidc.h
+ * linux/drivers/sound/vidc.h
X *
- * VIDC sound function prototypes
+ * Copyright (C) 1997 Russell King <r...@arm.linux.org.uk>
X *
- * Copyright (C) 1997 Russell King <r...@arm.uk.linux.org>
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * VIDC sound function prototypes
X */
X
X /* vidc.c */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/vidc_fill.S linux/drivers/sound/vidc_fill.S
--- v2.4.0-test8/linux/drivers/sound/vidc_fill.S Thu Feb 24 22:44:47 2000
+++ linux/drivers/sound/vidc_fill.S Mon Sep 18 15:15:22 2000
@@ -1,15 +1,19 @@
X /*
- * sound/vidc_fill.S
+ * linux/drivers/sound/vidc_fill.S
X *
- * Filler routines for DMA buffers
+ * Copyright (C) 1997 Russell King
X *
- * Copyright (C) 1997 Russell King
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Filler routines for DMA buffers
X */
X #define __ASSEMBLY__
X #include <linux/linkage.h>
X #include <asm/assembler.h>
X #include <asm/hardware.h>
-#include <asm/iomd.h>
+#include <asm/hardware/iomd.h>
X
X .text
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/vwsnd.c linux/drivers/sound/vwsnd.c
--- v2.4.0-test8/linux/drivers/sound/vwsnd.c Tue Aug 29 14:09:15 2000
+++ linux/drivers/sound/vwsnd.c Mon Sep 25 12:32:54 2000
@@ -138,6 +138,8 @@
X */
X
X #include <linux/module.h>
+#include <linux/init.h>
+
X #include <linux/stddef.h>
X #include <linux/spinlock.h>
X #include <linux/smp_lock.h>
@@ -3452,12 +3454,10 @@
X CO_IRQ(CO_APIC_LI_AUDIO) /* irq */


X };
X
-#ifdef MODULE
-

X MODULE_DESCRIPTION("SGI Visual Workstation sound module");
X MODULE_AUTHOR("Bob Miller <kb...@sgi.com>");
X
-extern int init_module(void)
+static int __init init_vwsnd(void)
X {
X int err;
X
@@ -3472,23 +3472,15 @@


X return 0;
X }
X

-extern void cleanup_module(void)
+static void __exit cleanup_vwsnd(void)
X {
X DBGX("sound::vwsnd::cleanup_module()\n");
X
X unload_vwsnd(&the_hw_config);
X }
X
-#else
-
-extern void init_vwsnd(void)
-{
- DBGX("sound::vwsnd::init_vwsnd()\n");
- if (probe_vwsnd(&the_hw_config))
- (void) attach_vwsnd(&the_hw_config);
-}
-
-#endif /* !MODULE */
+module_init(init_vwsnd);
+module_exit(cleanup_vwsnd);
X
X /*
X * Local variables:
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/waveartist.c linux/drivers/sound/waveartist.c
--- v2.4.0-test8/linux/drivers/sound/waveartist.c Tue Aug 29 14:09:15 2000
+++ linux/drivers/sound/waveartist.c Mon Sep 18 15:15:22 2000
@@ -38,7 +38,6 @@
X #include <linux/smp.h>
X #include <linux/spinlock.h>
X
-#include <asm/dec21285.h>
X #include <asm/hardware.h>
X #include <asm/mach-types.h>
X #include <asm/system.h>
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/wf_midi.c linux/drivers/sound/wf_midi.c
--- v2.4.0-test8/linux/drivers/sound/wf_midi.c Fri Aug 11 08:26:44 2000
+++ linux/drivers/sound/wf_midi.c Sun Sep 17 09:45:07 2000
@@ -781,8 +781,7 @@


X return 0;
X }
X

-static int __init detect_wf_mpu (int irq, int io_base)
-
+int __init detect_wf_mpu (int irq, int io_base)
X {
X if (check_region (io_base, 2)) {
X printk (KERN_WARNING "WF-MPU: I/O port %x already in use.\n",
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/ymf_sb.c linux/drivers/sound/ymf_sb.c
--- v2.4.0-test8/linux/drivers/sound/ymf_sb.c Fri Aug 11 08:26:44 2000
+++ linux/drivers/sound/ymf_sb.c Wed Sep 27 13:53:57 2000
@@ -40,6 +40,9 @@
X in 724hwmcode.h.
X * fixed wrong legacy_io setting on YMF744/YMF754 .
X
+ Thu Sep 21 05:32:51 BRT 2000 0.0.5
+ * got rid of attach_uart401 and attach_sbmpu
+ Arnaldo Carvalho de Melo <ac...@conectiva.com.br>
X */
X
X #include <linux/module.h>
@@ -217,17 +220,15 @@
X
X #define PFX "ymf_sb: "
X
-#define YMFSB_VERSION "0.0.4"
+#define YMFSB_VERSION "0.0.5"
X #define YMFSB_CARD_NAME "YMF7xx Legacy Audio driver " YMFSB_VERSION
X
X #ifdef SUPPORT_UART401_MIDI
X #if 0
X # define ymf7xxsb_probe_midi probe_uart401
-# define ymf7xxsb_attach_midi attach_uart401
X # define ymf7xxsb_unload_midi unload_uart401
X #else
X # define ymf7xxsb_probe_midi probe_sbmpu
-# define ymf7xxsb_attach_midi attach_sbmpu
X # define ymf7xxsb_unload_midi unload_sbmpu
X #endif
X #endif
@@ -771,14 +772,13 @@
X /* register legacy MIDI */
X if ( mpu_io > 0 && 0)
X {
- if (!ymf7xxsb_probe_midi (&mpu_data[cards])) {
+ if (!ymf7xxsb_probe_midi (&mpu_data[cards], THIS_MODULE)) {
X printk (KERN_ERR PFX
X "MIDI probe @ 0x%X failed, aborting\n",
X mpu_io);
X ymf7xxsb_unload_sb (&sb_data[cards], 0);
X return -ENODEV;
X }
- ymf7xxsb_attach_midi (&mpu_data[cards], THIS_MODULE);
X }
X #endif
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/telephony/Makefile linux/drivers/telephony/Makefile
--- v2.4.0-test8/linux/drivers/telephony/Makefile Wed Dec 29 17:13:59 1999
+++ linux/drivers/telephony/Makefile Sun Sep 17 09:45:07 2000
@@ -1,35 +1,29 @@
X #
-# Makefile for the kernel miscellaneous drivers.
+# Makefile for drivers/telephony
X #
X # Note! Dependencies are done automagically by 'make dep', which also
X # removes any old dependencies. DON'T put your own dependencies here
X # unless it's something special (ie not a .c file).
X #
-# Note 2! The CFLAGS definitions are now inherited from the
-# parent makes..
X
-SUB_DIRS :=
+SUB_DIRS :=
X MOD_SUB_DIRS := $(SUB_DIRS)
X ALL_SUB_DIRS := $(SUB_DIRS)
X
-L_TARGET := telephony.a
-MX_OBJS :=
-M_OBJS :=
-
-ifeq ($(CONFIG_PHONE),y)
- LX_OBJS += phonedev.o
-else
- ifeq ($(CONFIG_PHONE),m)
- MX_OBJS += phonedev.o
- endif
-endif
-
-ifeq ($(CONFIG_PHONE_IXJ),y)
- L_OBJS += ixj.o
-else
- ifeq ($(CONFIG_PHONE_IXJ),m)
- M_OBJS += ixj.o
- endif
-endif
+obj-y :=
+obj-n :=
+obj-m :=
+obj- :=
+export-objs := phonedev.o
+
+obj-$(CONFIG_PHONE) += phonedev.o
+obj-$(CONFIG_PHONE_IXJ) += ixj.o
+
+O_TARGET := telephony.o
+O_OBJS := $(filter-out $(export-objs), $(obj-y))
+OX_OBJS := $(filter $(export-objs), $(obj-y))
+M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m)))
+MX_OBJS := $(sort $(filter $(export-objs), $(obj-m)))
X
X include $(TOPDIR)/Rules.make
+
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/telephony/ixj.c linux/drivers/telephony/ixj.c
--- v2.4.0-test8/linux/drivers/telephony/ixj.c Wed Jul 12 21:58:43 2000
+++ linux/drivers/telephony/ixj.c Tue Sep 19 08:31:53 2000
@@ -1,10 +1,10 @@
-/*
+/****************************************************************************
X * ixj.c
X *
X * Device Driver for the Internet PhoneJACK and
X * Internet LineJACK Telephony Cards.
X *
- * (c) Copyright 1999 Quicknet Technologies, Inc.
+ * (c) Copyright 1999-2000 Quicknet Technologies, Inc.
X *
X * This program is free software; you can redistribute it and/or
X * modify it under the terms of the GNU General Public License
@@ -12,29 +12,41 @@
X * 2 of the License, or (at your option) any later version.
X *
X * Author: Ed Okerson, <eoke...@quicknet.net>
- *
+ *
X * Contributors: Greg Herlein, <gher...@quicknet.net>
X * David W. Erhart, <der...@quicknet.net>
X * John Sellers, <jsel...@quicknet.net>
X * Mike Preston, <mpre...@quicknet.net>
- *
+ *
X * Fixes:
- *
- * 2.3.x port : Alan Cox
- *
- * More information about the hardware related to this driver can be found
+ * Marc Boucher, <ma...@mbsi.ca>
+ *
+ * More information about the hardware related to this driver can be found
X * at our website: http://www.quicknet.net
X *
- */
+ * IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF QUICKNET
+ * TECHNOLOGIES, INC.HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * QUICKNET TECHNOLOGIES, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND QUICKNET TECHNOLOGIES, INC. HAS NO OBLIGATION
+ * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ ***************************************************************************/
X
-static char ixj_c_rcsid[] = "$Id: ixj.c,v 3.4 1999/12/16 22:18:36 root Exp root $";
+static char ixj_c_rcsid[] = "$Id: ixj.c,v 3.31 2000/04/14 19:24:47 jaugenst Exp $";
+static char ixj_c_revision[] = "$Revision: 3.31 $";
X
X //#define PERFMON_STATS
X #define IXJDEBUG 0
X #define MAXRINGS 5
X
-#include <linux/module.h>
X #include <linux/config.h>
+#include <linux/module.h>
+
X #include <linux/init.h>
X #include <linux/sched.h>
X #include <linux/kernel.h> /* printk() */
@@ -50,7 +62,6 @@
X #include <linux/timer.h>
X #include <linux/delay.h>
X #include <linux/pci.h>
-#include <linux/smp_lock.h>
X
X #include <asm/io.h>
X #include <asm/segment.h>
@@ -102,14 +113,17 @@
X static void ixj_write_frame(int board);
X static void ixj_init_timer(void);
X static void ixj_add_timer(void);
-static void ixj_del_timer(void);
X static void ixj_timeout(unsigned long ptr);
X static int read_filters(int board);
X static int LineMonitor(int board);
X static int ixj_fasync(int fd, struct file *, int mode);
+static int ixj_set_port(int board, int arg);
+static int ixj_set_pots(int board, int arg);
X static int ixj_hookstate(int board);
X static int ixj_record_start(int board);
X static void ixj_record_stop(int board);
+static void set_rec_volume(int board, int volume);
+static void ixj_vad(int board, int arg);
X static int ixj_play_start(int board);
X static void ixj_play_stop(int board);
X static int ixj_set_tone_on(unsigned short arg, int board);
@@ -126,6 +140,7 @@
X static char daa_int_read(int board);
X static int daa_set_mode(int board, int mode);
X static int ixj_linetest(int board);
+static int ixj_daa_write(int board);
X static int ixj_daa_cid_read(int board);
X static void DAA_Coeff_US(int board);
X static void DAA_Coeff_UK(int board);
@@ -136,12 +151,18 @@
X static int ixj_init_filter(int board, IXJ_FILTER * jf);
X static int ixj_init_tone(int board, IXJ_TONE * ti);
X static int ixj_build_cadence(int board, IXJ_CADENCE * cp);
+static int ixj_build_filter_cadence(int board, IXJ_FILTER_CADENCE * cp);
X // Serial Control Interface funtions
X static int SCI_Control(int board, int control);
X static int SCI_Prepare(int board);
X static int SCI_WaitHighSCI(int board);
X static int SCI_WaitLowSCI(int board);
X static DWORD PCIEE_GetSerialNumber(WORD wAddress);
+static int ixj_PCcontrol_wait(int board);
+static void ixj_write_cid(int board);
+static void ixj_write_cid_bit(int board, int bit);
+static int set_base_frame(int board, int size);
+static int set_play_codec(int board, int rate);
X
X /************************************************************************
X CT8020/CT8021 Host Programmers Model
@@ -162,12 +183,19 @@
X ixj[board].hsr.bytes.low = inb_p(ixj[board].DSPbase + 8);
X ixj[board].hsr.bytes.high = inb_p(ixj[board].DSPbase + 9);
X }
+
X extern __inline__ int IsControlReady(int board)
X {
X ixj_read_HSR(board);
X return ixj[board].hsr.bits.controlrdy ? 1 : 0;
X }
X
+extern __inline__ int IsPCControlReady(int board)
+{
+ ixj[board].pccr1.byte = inb_p(ixj[board].XILINXbase + 3);
+ return ixj[board].pccr1.bits.crr ? 1 : 0;
+}
+
X extern __inline__ int IsStatusReady(int board)
X {
X ixj_read_HSR(board);
@@ -177,21 +205,54 @@
X extern __inline__ int IsRxReady(int board)
X {
X ixj_read_HSR(board);
+#ifdef PERFMON_STATS
+ ++ixj[board].rxreadycheck;
+#endif
X return ixj[board].hsr.bits.rxrdy ? 1 : 0;
X }
X
X extern __inline__ int IsTxReady(int board)
X {
X ixj_read_HSR(board);
+#ifdef PERFMON_STATS
+ ++ixj[board].txreadycheck;
+#endif
X return ixj[board].hsr.bits.txrdy ? 1 : 0;
X }
X
+extern __inline__ void set_play_volume(int board, int volume)
+{
+ ixj_WriteDSPCommand(0xCF02, board);
+ ixj_WriteDSPCommand(volume, board);
+}
+
+extern __inline__ int get_play_volume(int board)
+{
+ ixj_WriteDSPCommand(0xCF00, board);
+ return ixj[board].ssr.high << 8 | ixj[board].ssr.low;
+}
+
X extern __inline__ BYTE SLIC_GetState(int board)
X {
X IXJ *j = &ixj[board];
X
- j->pld_slicr.byte = inb_p(j->XILINXbase + 0x01);
-
+ if (j->cardtype == 600) {
+ j->pccr1.byte = 0;
+ j->psccr.bits.dev = 3;
+ j->psccr.bits.rw = 1;
+ outw_p(j->psccr.byte << 8, j->XILINXbase + 0x00);
+ ixj_PCcontrol_wait(board);
+ j->pslic.byte = inw_p(j->XILINXbase + 0x00) & 0xFF;
+ ixj_PCcontrol_wait(board);
+ if (j->pslic.bits.powerdown)
+ return PLD_SLIC_STATE_OC;
+ else if (!j->pslic.bits.ring0 && !j->pslic.bits.ring1)
+ return PLD_SLIC_STATE_ACTIVE;
+ else
+ return PLD_SLIC_STATE_RINGING;
+ } else {
+ j->pld_slicr.byte = inb_p(j->XILINXbase + 0x01);
+ }
X return j->pld_slicr.bits.state;
X }
X
@@ -200,78 +261,122 @@
X BOOL fRetVal = FALSE;
X IXJ *j = &ixj[board];
X
- // Set the C1, C2, C3 & B2EN signals.
- switch (byState) {
- case PLD_SLIC_STATE_OC:
- j->pld_slicw.bits.c1 = 0;
- j->pld_slicw.bits.c2 = 0;
- j->pld_slicw.bits.c3 = 0;
- j->pld_slicw.bits.b2en = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- fRetVal = TRUE;
- break;
- case PLD_SLIC_STATE_RINGING:
- j->pld_slicw.bits.c1 = 1;
- j->pld_slicw.bits.c2 = 0;
- j->pld_slicw.bits.c3 = 0;
- j->pld_slicw.bits.b2en = 1;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- fRetVal = TRUE;
- break;
- case PLD_SLIC_STATE_ACTIVE:
- j->pld_slicw.bits.c1 = 0;
- j->pld_slicw.bits.c2 = 1;
- j->pld_slicw.bits.c3 = 0;
- j->pld_slicw.bits.b2en = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- fRetVal = TRUE;
- break;
- case PLD_SLIC_STATE_OHT: // On-hook transmit
+ if (j->cardtype == 600) {
+ if (j->flags.pcmciasct) {
+ switch (byState) {
+ case PLD_SLIC_STATE_TIPOPEN:
+ case PLD_SLIC_STATE_OC:
+ j->pslic.bits.powerdown = 1;
+ j->pslic.bits.ring0 = j->pslic.bits.ring1 = 0;
+ fRetVal = TRUE;
+ break;
+ case PLD_SLIC_STATE_RINGING:
+ if (j->readers || j->writers) {
+ j->pslic.bits.powerdown = 0;
+ j->pslic.bits.ring0 = 1;
+ j->pslic.bits.ring1 = 0;
+ fRetVal = TRUE;
+ }
+ break;
+ case PLD_SLIC_STATE_OHT: // On-hook transmit
X
- j->pld_slicw.bits.c1 = 1;
- j->pld_slicw.bits.c2 = 1;
- j->pld_slicw.bits.c3 = 0;
- j->pld_slicw.bits.b2en = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- fRetVal = TRUE;
- break;
- case PLD_SLIC_STATE_TIPOPEN:
- j->pld_slicw.bits.c1 = 0;
- j->pld_slicw.bits.c2 = 0;
- j->pld_slicw.bits.c3 = 1;
- j->pld_slicw.bits.b2en = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- fRetVal = TRUE;
- break;
- case PLD_SLIC_STATE_STANDBY:
- j->pld_slicw.bits.c1 = 1;
- j->pld_slicw.bits.c2 = 0;
- j->pld_slicw.bits.c3 = 1;
- j->pld_slicw.bits.b2en = 1;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- fRetVal = TRUE;
- break;
- case PLD_SLIC_STATE_APR: // Active polarity reversal
+ case PLD_SLIC_STATE_STANDBY:
+ case PLD_SLIC_STATE_ACTIVE:
+ if (j->readers || j->writers) {
+ j->pslic.bits.powerdown = 0;
+ } else {
+ j->pslic.bits.powerdown = 1;
+ }
+ j->pslic.bits.ring0 = j->pslic.bits.ring1 = 0;
+ fRetVal = TRUE;
+ break;
+ case PLD_SLIC_STATE_APR: // Active polarity reversal
X
- j->pld_slicw.bits.c1 = 0;
- j->pld_slicw.bits.c2 = 1;
- j->pld_slicw.bits.c3 = 1;
- j->pld_slicw.bits.b2en = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- fRetVal = TRUE;
- break;
- case PLD_SLIC_STATE_OHTPR: // OHT polarity reversal
+ case PLD_SLIC_STATE_OHTPR: // OHT polarity reversal
X
- j->pld_slicw.bits.c1 = 1;
- j->pld_slicw.bits.c2 = 1;
- j->pld_slicw.bits.c3 = 1;
- j->pld_slicw.bits.b2en = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- fRetVal = TRUE;
- break;
- default:
- fRetVal = FALSE;
- break;
+ default:
+ fRetVal = FALSE;
+ break;
+ }
+ j->psccr.bits.dev = 3;
+ j->psccr.bits.rw = 0;
+ outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00);
+ ixj_PCcontrol_wait(board);
+ }
+ } else {
+ // Set the C1, C2, C3 & B2EN signals.
+ switch (byState) {
+ case PLD_SLIC_STATE_OC:
+ j->pld_slicw.bits.c1 = 0;
+ j->pld_slicw.bits.c2 = 0;
+ j->pld_slicw.bits.c3 = 0;
+ j->pld_slicw.bits.b2en = 0;
+ outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+ fRetVal = TRUE;
+ break;
+ case PLD_SLIC_STATE_RINGING:
+ j->pld_slicw.bits.c1 = 1;
+ j->pld_slicw.bits.c2 = 0;
+ j->pld_slicw.bits.c3 = 0;
+ j->pld_slicw.bits.b2en = 1;
+ outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+ fRetVal = TRUE;
+ break;
+ case PLD_SLIC_STATE_ACTIVE:
+ j->pld_slicw.bits.c1 = 0;
+ j->pld_slicw.bits.c2 = 1;
+ j->pld_slicw.bits.c3 = 0;
+ j->pld_slicw.bits.b2en = 0;
+ outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+ fRetVal = TRUE;
+ break;
+ case PLD_SLIC_STATE_OHT: // On-hook transmit
+
+ j->pld_slicw.bits.c1 = 1;
+ j->pld_slicw.bits.c2 = 1;
+ j->pld_slicw.bits.c3 = 0;
+ j->pld_slicw.bits.b2en = 0;
+ outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+ fRetVal = TRUE;
+ break;
+ case PLD_SLIC_STATE_TIPOPEN:
+ j->pld_slicw.bits.c1 = 0;
+ j->pld_slicw.bits.c2 = 0;
+ j->pld_slicw.bits.c3 = 1;
+ j->pld_slicw.bits.b2en = 0;
+ outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+ fRetVal = TRUE;
+ break;
+ case PLD_SLIC_STATE_STANDBY:
+ j->pld_slicw.bits.c1 = 1;
+ j->pld_slicw.bits.c2 = 0;
+ j->pld_slicw.bits.c3 = 1;
+ j->pld_slicw.bits.b2en = 1;
+ outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+ fRetVal = TRUE;
+ break;
+ case PLD_SLIC_STATE_APR: // Active polarity reversal
+
+ j->pld_slicw.bits.c1 = 0;
+ j->pld_slicw.bits.c2 = 1;
+ j->pld_slicw.bits.c3 = 1;
+ j->pld_slicw.bits.b2en = 0;
+ outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+ fRetVal = TRUE;
+ break;
+ case PLD_SLIC_STATE_OHTPR: // OHT polarity reversal
+
+ j->pld_slicw.bits.c1 = 1;
+ j->pld_slicw.bits.c2 = 1;
+ j->pld_slicw.bits.c3 = 1;
+ j->pld_slicw.bits.b2en = 0;
+ outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+ fRetVal = TRUE;
+ break;
+ default:
+ fRetVal = FALSE;
+ break;
+ }
X }
X
X return fRetVal;
@@ -363,51 +468,42 @@
X add_timer(&ixj_timer);
X }
X
-static void ixj_del_timer(void)
-{
- del_timer(&ixj_timer);
-}
-
X static void ixj_tone_timeout(int board)
X {
X IXJ *j = &ixj[board];
X IXJ_TONE ti;
-
+
X j->tone_state++;
X if (j->tone_state == 3) {
X j->tone_state = 0;
X if (j->cadence_t) {
X j->tone_cadence_state++;
- if (j->tone_cadence_state >= j->cadence_t->elements_used)
- {
- switch (j->cadence_t->termination)
- {
- case PLAY_ONCE:
- ixj_cpt_stop(board);
- break;
- case REPEAT_LAST_ELEMENT:
- j->tone_cadence_state--;
- ixj_play_tone(board, j->cadence_t->ce[j->tone_cadence_state].index);
- break;
- case REPEAT_ALL:
- j->tone_cadence_state = 0;
- if (j->cadence_t->ce[j->tone_cadence_state].freq0)
- {
- ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index;
- ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0;
- ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0;
- ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1;
- ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1;
- ixj_init_tone(board, &ti);
- }
- ixj_set_tone_on(j->cadence_t->ce[0].tone_on_time, board);
- ixj_set_tone_off(j->cadence_t->ce[0].tone_off_time, board);
- ixj_play_tone(board, j->cadence_t->ce[0].index);
- break;
+ if (j->tone_cadence_state >= j->cadence_t->elements_used) {
+ switch (j->cadence_t->termination) {
+ case PLAY_ONCE:
+ ixj_cpt_stop(board);
+ break;
+ case REPEAT_LAST_ELEMENT:
+ j->tone_cadence_state--;
+ ixj_play_tone(board, j->cadence_t->ce[j->tone_cadence_state].index);
+ break;
+ case REPEAT_ALL:
+ j->tone_cadence_state = 0;
+ if (j->cadence_t->ce[j->tone_cadence_state].freq0) {
+ ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index;
+ ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0;
+ ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0;
+ ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1;
+ ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1;
+ ixj_init_tone(board, &ti);
+ }
+ ixj_set_tone_on(j->cadence_t->ce[0].tone_on_time, board);
+ ixj_set_tone_off(j->cadence_t->ce[0].tone_off_time, board);
+ ixj_play_tone(board, j->cadence_t->ce[0].index);
+ break;
X }
X } else {
- if (j->cadence_t->ce[j->tone_cadence_state].gain0)
- {
+ if (j->cadence_t->ce[j->tone_cadence_state].gain0) {
X ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index;
X ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0;
X ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0;


@@ -423,49 +519,49 @@
X }

X }
X
+extern __inline__ void ixj_kill_fasync(int board, int dir)
+{
+ kill_fasync(&ixj[board].async_queue, SIGIO, dir); // Send apps notice of change
+
+}
X static void ixj_timeout(unsigned long ptr)
X {
X int board;
X unsigned long jifon;
X IXJ *j;
X
- for (board = 0; board < IXJMAX; board++)
- {
+ for (board = 0; board < IXJMAX; board++) {
X j = &ixj[board];
X
- if (j->DSPbase)
- {
+ if (j->DSPbase) {
X #ifdef PERFMON_STATS
X j->timerchecks++;
X #endif
- if (j->tone_state)
- {
- if (!ixj_hookstate(board))
- {
+ if (j->tone_state) {
+ if (!ixj_hookstate(board)) {
X ixj_cpt_stop(board);
- if (j->m_hook)
- {
+ if (j->m_hook) {
X j->m_hook = 0;
X j->ex.bits.hookstate = 1;
- kill_fasync(&j->async_queue, SIGIO, POLL_IN); // Send apps notice of change
+ ixj_kill_fasync(board, POLL_IN);
X }
- goto timer_end;
+ continue;
X }
X if (j->tone_state == 1)
X jifon = (hertz * j->tone_on_time * 25 / 100000);
X else
X jifon = (hertz * j->tone_on_time * 25 / 100000) +
X (hertz * j->tone_off_time * 25 / 100000);
- if (jiffies < j->tone_start_jif + jifon) {
+ if (time_before(jiffies, j->tone_start_jif + jifon)) {
X if (j->tone_state == 1) {
X ixj_play_tone(board, j->tone_index);
X if (j->dsp.low == 0x20) {
- goto timer_end;
+ continue;
X }
X } else {
X ixj_play_tone(board, 0);
X if (j->dsp.low == 0x20) {
- goto timer_end;
+ continue;
X }
X }
X } else {
@@ -476,13 +572,13 @@
X if (j->flags.busytone) {
X ixj_busytone(board);
X if (j->dsp.low == 0x20) {
- goto timer_end;
+ continue;
X }
X }
X if (j->flags.ringback) {
X ixj_ringback(board);
X if (j->dsp.low == 0x20) {
- goto timer_end;
+ continue;
X }
X }
X if (!j->tone_state) {
@@ -499,7 +595,7 @@
X if (IsRxReady(board)) {
X ixj_read_frame(board);
X }
- if (IsTxReady(board)) {
+ if (IsTxReady(board) && !j->flags.cidplay) {
X ixj_write_frame(board);
X }
X }
@@ -509,6 +605,11 @@
X ixj_ring_off(board);
X } else {
X if (jiffies - j->ring_cadence_jif >= (hertz/2)) {
+ if (j->flags.cidring && !j->flags.cidsent) {
+ j->flags.cidsent = 1;
+ ixj_write_cid(board);
+ j->flags.cidring = 0;
+ }
X j->ring_cadence_t--;
X if (j->ring_cadence_t == -1)
X j->ring_cadence_t = 15;
@@ -518,16 +619,15 @@
X ixj_ring_on(board);
X } else {
X ixj_ring_off(board);
+ j->flags.cidring = 1;
X }
- goto timer_end;
+ continue;
X }
X }
X if (!j->flags.ringing) {
X if (ixj_hookstate(board)) {
- if (j->dsp.low == 0x21 &&
- j->pld_slicr.bits.state != PLD_SLIC_STATE_ACTIVE)
- // Internet LineJACK
- {
+ if (j->dsp.low != 0x20 &&
+ SLIC_GetState(board) != PLD_SLIC_STATE_ACTIVE) {
X SLIC_SetState(PLD_SLIC_STATE_ACTIVE, board);
X }
X LineMonitor(board);
@@ -536,12 +636,12 @@
X j->proc_load = j->ssr.high << 8 | j->ssr.low;
X if (!j->m_hook) {
X j->m_hook = j->ex.bits.hookstate = 1;
- kill_fasync(&j->async_queue, SIGIO, POLL_IN); // Send apps notice of change
+ ixj_kill_fasync(board, POLL_IN);
X }
X } else {
- if (j->dsp.low == 0x21 &&
- j->pld_slicr.bits.state == PLD_SLIC_STATE_ACTIVE)
- // Internet LineJACK
+ if (j->dsp.low != 0x20 &&
+ SLIC_GetState(board) == PLD_SLIC_STATE_ACTIVE)
+ // Internet LineJACK
X {
X SLIC_SetState(PLD_SLIC_STATE_STANDBY, board);
X }
@@ -551,14 +651,14 @@
X if (j->m_hook) {
X j->m_hook = 0;
X j->ex.bits.hookstate = 1;
- kill_fasync(&j->async_queue, SIGIO, POLL_IN); // Send apps notice of change
+ ixj_kill_fasync(board, POLL_IN);
X }
X }
X }
- if (j->cardtype == 300) {
+ if (j->cardtype == 300 && !j->flags.incheck) {
X if (j->flags.pstn_present) {
X j->pld_scrr.byte = inb_p(j->XILINXbase);
- if (jiffies >= j->pstn_sleeptil && j->pld_scrr.bits.daaflag) {
+ if (j->pld_scrr.bits.daaflag) {
X daa_int_read(board);
X if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.RING) {
X if (!j->flags.pstn_ringing) {
@@ -567,22 +667,38 @@
X daa_set_mode(board, SOP_PU_RINGING);
X }
X }
- if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
+ if (time_after(jiffies, j->pstn_sleeptil) && j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
X j->pstn_winkstart = 0;
+ j->pstn_ring_stop = 0;
+ ixj[board].pld_scrw.bits.led1 = 1;
X if (j->flags.pstn_ringing && !j->pstn_envelope) {
+ if (j->daa_mode != SOP_PU_RINGING) {
+ j->flags.pstn_ringing = 0;
+ } else {
+ ixj[board].pld_scrw.bits.led2 = 0;
+ j->pstn_envelope = 1;
+ j->pstn_ring_start = jiffies;
+ j->pstn_ring_stop = 0;
+ }
X j->ex.bits.pstn_ring = 0;
- j->pstn_envelope = 1;
- j->pstn_ring_start = jiffies;
X }
+ outb_p(ixj[board].pld_scrw.byte, ixj[board].XILINXbase);
X } else {
- if (j->flags.pstn_ringing && j->pstn_envelope &&
- jiffies > j->pstn_ring_start + ((hertz * 15) / 10)) {
- j->ex.bits.pstn_ring = 1;
- j->pstn_envelope = 0;
+ ixj[board].pld_scrw.bits.led1 = 0;
+ ixj[board].pld_scrw.bits.led2 = 1;
+ outb_p(ixj[board].pld_scrw.byte, ixj[board].XILINXbase);
+ if (j->flags.pstn_ringing && j->pstn_envelope) {
+ if(!j->pstn_ring_stop) {
+ j->pstn_ring_stop = jiffies;
+ } else if (time_after(jiffies, j->pstn_ring_stop + ((hertz * 5) / 100))){
+ j->pstn_ring_stop = 0;
+ j->ex.bits.pstn_ring = 1;
+ j->pstn_envelope = 0;
+ }
X } else if (j->daa_mode == SOP_PU_CONVERSATION) {
X if (!j->pstn_winkstart) {
X j->pstn_winkstart = jiffies;
- } else if (jiffies > j->pstn_winkstart + (hertz * j->winktime / 1000)) {
+ } else if (time_after(jiffies, j->pstn_winkstart + (hertz * j->winktime / 1000))) {
X daa_set_mode(board, SOP_PU_SLEEP);
X j->pstn_winkstart = 0;
X j->ex.bits.pstn_wink = 1;
@@ -619,13 +735,23 @@
X j->ex.bits.caller_id = 0;
X }
X if (!j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
+ ixj[board].pld_scrw.bits.led1 = 0;
+ ixj[board].pld_scrw.bits.led2 = 1;
+ outb_p(ixj[board].pld_scrw.byte, ixj[board].XILINXbase);
X if (j->flags.pstn_ringing && j->pstn_envelope) {
- j->ex.bits.pstn_ring = 1;
- j->pstn_envelope = 0;
+ if(!j->pstn_ring_stop) {
+ j->pstn_ring_stop = jiffies;
+ } else if (time_after(jiffies, j->pstn_ring_stop + ((hertz * 5) / 100))){
+ j->pstn_ring_stop = 0;
+ j->ex.bits.pstn_ring = 1;
+ j->pstn_envelope = 0;
+ }
+ ixj[board].pld_scrw.bits.led1 = 0;
+ outb_p(ixj[board].pld_scrw.byte, ixj[board].XILINXbase);
X } else if (j->daa_mode == SOP_PU_CONVERSATION) {
X if (!j->pstn_winkstart) {
X j->pstn_winkstart = jiffies;
- } else if (jiffies > j->pstn_winkstart + (hertz * 320 / 1000)) {
+ } else if (time_after(jiffies, j->pstn_winkstart + (hertz * j->winktime / 1000))) {
X daa_set_mode(board, SOP_PU_SLEEP);
X j->pstn_winkstart = 0;
X j->ex.bits.pstn_wink = 1;
@@ -635,18 +761,15 @@
X }
X }
X }
- if ((j->ex.bits.f0 || j->ex.bits.f1 || j->ex.bits.f2 || j->ex.bits.f3)
- && j->filter_cadence) {
- }
X if (j->ex.bytes) {
X wake_up_interruptible(&j->poll_q); // Wake any blocked selects
- kill_fasync(&j->async_queue, SIGIO, POLL_IN); // Send apps notice of change
+
+ ixj_kill_fasync(board, POLL_IN);
X }
X } else {
X break;
X }
X }
-timer_end:
X ixj_add_timer();
X }
X
@@ -663,6 +786,19 @@


X return 0;
X }
X

+static int ixj_PCcontrol_wait(int board)
+{
+ unsigned long jif;
+
+ jif = jiffies;
+ while (!IsPCControlReady(board)) {
+ if (jiffies - jif > (60 * (hertz / 100))) {


+ return -1;
+ }
+ }

+ return 0;
+}
+

X int ixj_WriteDSPCommand(unsigned short cmd, int board)
X {
X BYTES bytes;
@@ -708,7 +844,7 @@
X
X extern __inline__ void LED_SetState(int state, int board)
X {
- if (ixj[board].dsp.low == 0x21) {
+ if (ixj[board].cardtype == 300) {
X ixj[board].pld_scrw.bits.led1 = state & 0x1 ? 1 : 0;
X ixj[board].pld_scrw.bits.led2 = state & 0x2 ? 1 : 0;
X ixj[board].pld_scrw.bits.led3 = state & 0x4 ? 1 : 0;
@@ -746,12 +882,19 @@
X case PORT_POTS:
X j->port = PORT_POTS;
X switch (j->cardtype) {
+ case 600:
+ if (j->flags.pcmciasct == 1)
+ SLIC_SetState(PLD_SLIC_STATE_ACTIVE, board);
+ else
+ return 11;
+ break;
X case 500:
X j->pld_slicw.pcib.mic = 0;
X j->pld_slicw.pcib.spk = 0;
X outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
X break;
X case 300:
+ ixj_set_pots(board, 0);
X if (ixj_WriteDSPCommand(0xC528, board)) /* Write CODEC config to
X Software Control Register */
X return 2;
@@ -789,12 +932,21 @@
X case PORT_SPEAKER:
X j->port = PORT_SPEAKER;
X switch (j->cardtype) {
+ case 600:
+ if (j->flags.pcmciasct) {
+ SLIC_SetState(PLD_SLIC_STATE_OC, board);
+// while(SLIC_GetState(board) != PLD_SLIC_STATE_OC) {
+ // SLIC_SetState(PLD_SLIC_STATE_OC,board);
+ // }
+ }
+ break;
X case 500:
X j->pld_slicw.pcib.mic = 1;
X j->pld_slicw.pcib.spk = 1;
X outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
X break;
X case 300:
+ ixj_set_pots(board, 0);
X break;
X case 100:
X j->gpio.bytes.high = 0x0B;
@@ -859,8 +1011,7 @@
X j->gpio.bits.gpio2 = 1;
X j->gpio.bits.gpio5 = 0;
X ixj_WriteDSPCommand(j->gpio.word, board); /* send the ring signal */
- } else // Internet LineJACK, Internet PhoneJACK Lite or
- // Internet PhoneJACK PCI
+ } else // Internet LineJACK, Internet PhoneJACK Lite or Internet PhoneJACK PCI
X {
X if (ixjdebug > 0)
X printk(KERN_INFO "IXJ Ring On /dev/phone%d\n", board);
@@ -869,6 +1020,212 @@
X }
X }
X
+static int ixj_pcmcia_cable_check(int board)
+{
+ IXJ *j = &ixj[board];
+
+ j->pccr1.byte = inb_p(j->XILINXbase + 0x03);
+ if (!j->flags.pcmciastate) {
+ j->pccr2.byte = inb_p(j->XILINXbase + 0x02);
+ if (j->pccr1.bits.drf || j->pccr2.bits.rstc) {
+ j->flags.pcmciastate = 4;
+ return 0;
+ }
+ if (j->pccr1.bits.ed) {
+ j->pccr1.bits.ed = 0;
+ j->psccr.bits.dev = 3;
+ j->psccr.bits.rw = 1;
+ outw_p(j->psccr.byte << 8, j->XILINXbase + 0x00);
+ ixj_PCcontrol_wait(board);
+ j->pslic.byte = inw_p(j->XILINXbase + 0x00) & 0xFF;
+ j->pslic.bits.led2 = j->pslic.bits.det ? 1 : 0;
+ j->psccr.bits.dev = 3;
+ j->psccr.bits.rw = 0;
+ outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00);
+ ixj_PCcontrol_wait(board);
+ return j->pslic.bits.led2 ? 1 : 0;
+ } else if (j->flags.pcmciasct) {
+ return j->r_hook;
+ } else {
+ return 1;
+ }
+ } else if (j->flags.pcmciastate == 4) {
+ if (!j->pccr1.bits.drf) {
+ j->flags.pcmciastate = 3;
+ }
+ return 0;
+ } else if (j->flags.pcmciastate == 3) {
+ j->pccr2.bits.pwr = 0;
+ j->pccr2.bits.rstc = 1;
+ outb_p(j->pccr2.byte, j->XILINXbase + 0x02);
+ j->checkwait = jiffies + hertz * 2;
+ j->flags.incheck = 1;
+ j->flags.pcmciastate = 2;
+ return 0;
+ } else if (j->flags.pcmciastate == 2) {
+ if (j->flags.incheck) {
+ if (time_before(jiffies, j->checkwait)) {
+ return 0;
+ } else {
+ j->flags.incheck = 0;
+ }
+ }
+ j->pccr2.bits.pwr = 0;
+ j->pccr2.bits.rstc = 0;
+ outb_p(j->pccr2.byte, j->XILINXbase + 0x02);
+ j->flags.pcmciastate = 1;
+ return 0;
+ } else if (j->flags.pcmciastate == 1) {
+ j->flags.pcmciastate = 0;
+ if (!j->pccr1.bits.drf) {
+ j->psccr.bits.dev = 3;
+ j->psccr.bits.rw = 1;
+ outb_p(j->psccr.byte, j->XILINXbase + 0x01);


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 088'
echo 'File patch-2.4.0-test9 is continued in part 089'
echo "089" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part086

#!/bin/sh -x
# this is part 086 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 086; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+//****************************************************************************
+#define SSCR_SB 0x00000004L
+#define SSCR_HVC 0x00000008L
+#define SSCR_LPFIFO 0x00000040L
+#define SSCR_LPSRC 0x00000080L
+#define SSCR_XLPSRC 0x00000100L
+#define SSCR_MVMD 0x00010000L
+#define SSCR_MVAD 0x00020000L
+#define SSCR_MVLD 0x00040000L
+#define SSCR_MVCS 0x00080000L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the Clock Control Register 1.
+// (CLKCR1)
+//
+//****************************************************************************
+#define CLKCR1_DLLSS_MASK 0x0000000CL
+#define CLKCR1_DLLSS_SHIFT 2L
+#define CLKCR1_DLLP 0x00000010L
+#define CLKCR1_SWCE 0x00000020L
+#define CLKCR1_DLLOS 0x00000040L
+#define CLKCR1_CKRA 0x00010000L
+#define CLKCR1_CKRN 0x00020000L
+#define CLKCR1_DLLRDY 0x01000000L
+#define CLKCR1_CLKON 0x02000000L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the Sound Blaster Read Buffer
+// Status.(SBRBS)
+//
+//****************************************************************************
+#define SBRBS_RD_MASK 0x0000007FL
+#define SBRBS_RD_SHIFT 0L
+#define SBRBS_RBF 0x00000080L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the serial port master control
+// register.(SERMC)
+//
+//****************************************************************************
+#define SERMC_MSPE 0x00000001L
+#define SERMC_PTC_MASK 0x0000000EL
+#define SERMC_PTC_SHIFT 1L
+#define SERMC_PTC_AC97 0x00000002L
+#define SERMC_PLB 0x00000010L
+#define SERMC_PXLB 0x00000020L
+#define SERMC_LOFV 0x00080000L
+#define SERMC_SLB 0x00100000L
+#define SERMC_SXLB 0x00200000L
+#define SERMC_ODSEN1 0x01000000L
+#define SERMC_ODSEN2 0x02000000L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the General Purpose I/O Register.
+// (GPIOR)
+//
+//****************************************************************************
+#define GPIOR_VDNS 0x00000001L
+#define GPIOR_VUPS 0x00000002L
+#define GPIOR_GP1S 0x00000004L
+#define GPIOR_GP3S 0x00000008L
+#define GPIOR_GPSS 0x00000010L
+#define GPIOR_GPPS 0x00000020L
+#define GPIOR_GP1D 0x00000400L
+#define GPIOR_GP3D 0x00000800L
+#define GPIOR_VDNLT 0x00010000L
+#define GPIOR_VDNPO 0x00020000L
+#define GPIOR_VDNST 0x00040000L
+#define GPIOR_VDNW 0x00080000L
+#define GPIOR_VUPLT 0x00100000L
+#define GPIOR_VUPPO 0x00200000L
+#define GPIOR_VUPST 0x00400000L
+#define GPIOR_VUPW 0x00800000L
+#define GPIOR_GP1OE 0x01000000L
+#define GPIOR_GP1PT 0x02000000L
+#define GPIOR_GP1ST 0x04000000L
+#define GPIOR_GP1W 0x08000000L
+#define GPIOR_GP3OE 0x10000000L
+#define GPIOR_GP3PT 0x20000000L
+#define GPIOR_GP3ST 0x40000000L
+#define GPIOR_GP3W 0x80000000L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the clock control register 1.
+//
+//****************************************************************************
+#define CLKCR1_PLLSS_MASK 0x0000000CL
+#define CLKCR1_PLLSS_SERIAL 0x00000000L
+#define CLKCR1_PLLSS_CRYSTAL 0x00000004L
+#define CLKCR1_PLLSS_PCI 0x00000008L
+#define CLKCR1_PLLSS_RESERVED 0x0000000CL
+#define CLKCR1_PLLP 0x00000010L
+#define CLKCR1_SWCE 0x00000020L
+#define CLKCR1_PLLOS 0x00000040L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the feature reporting register.
+//
+//****************************************************************************
+#define FRR_FAB_MASK 0x00000003L
+#define FRR_MASK_MASK 0x0000001CL
+#define FRR_ID_MASK 0x00003000L
+#define FRR_FAB_SHIFT 0L
+#define FRR_MASK_SHIFT 2L
+#define FRR_ID_SHIFT 12L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the serial port 1 configuration
+// register.
+//
+//****************************************************************************
+#define SERC1_VALUE 0x00000003L
+#define SERC1_SO1EN 0x00000001L
+#define SERC1_SO1F_MASK 0x0000000EL
+#define SERC1_SO1F_CS423X 0x00000000L
+#define SERC1_SO1F_AC97 0x00000002L
+#define SERC1_SO1F_DAC 0x00000004L
+#define SERC1_SO1F_SPDIF 0x00000006L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the serial port 2 configuration
+// register.
+//
+//****************************************************************************
+#define SERC2_VALUE 0x00000003L
+#define SERC2_SI1EN 0x00000001L
+#define SERC2_SI1F_MASK 0x0000000EL
+#define SERC2_SI1F_CS423X 0x00000000L
+#define SERC2_SI1F_AC97 0x00000002L
+#define SERC2_SI1F_ADC 0x00000004L
+#define SERC2_SI1F_SPDIF 0x00000006L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 control register.
+//
+//****************************************************************************
+#define ACCTL_ESYN 0x00000002L
+#define ACCTL_VFRM 0x00000004L
+#define ACCTL_DCV 0x00000008L
+#define ACCTL_CRW 0x00000010L
+#define ACCTL_TC 0x00000040L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 status register.
+//
+//****************************************************************************
+#define ACSTS_CRDY 0x00000001L
+#define ACSTS_VSTS 0x00000002L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 output slot valid
+// register.
+//
+//****************************************************************************
+#define ACOSV_SLV3 0x00000001L
+#define ACOSV_SLV4 0x00000002L
+#define ACOSV_SLV5 0x00000004L
+#define ACOSV_SLV6 0x00000008L
+#define ACOSV_SLV7 0x00000010L
+#define ACOSV_SLV8 0x00000020L
+#define ACOSV_SLV9 0x00000040L
+#define ACOSV_SLV10 0x00000080L
+#define ACOSV_SLV11 0x00000100L
+#define ACOSV_SLV12 0x00000200L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 command address
+// register.
+//
+//****************************************************************************
+#define ACCAD_CI_MASK 0x0000007FL
+#define ACCAD_CI_SHIFT 0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 command data register.
+//
+//****************************************************************************
+#define ACCDA_CD_MASK 0x0000FFFFL
+#define ACCDA_CD_SHIFT 0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 input slot valid
+// register.
+//
+//****************************************************************************
+#define ACISV_ISV3 0x00000001L
+#define ACISV_ISV4 0x00000002L
+#define ACISV_ISV5 0x00000004L
+#define ACISV_ISV6 0x00000008L
+#define ACISV_ISV7 0x00000010L
+#define ACISV_ISV8 0x00000020L
+#define ACISV_ISV9 0x00000040L
+#define ACISV_ISV10 0x00000080L
+#define ACISV_ISV11 0x00000100L
+#define ACISV_ISV12 0x00000200L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 status address
+// register.
+//
+//****************************************************************************
+#define ACSAD_SI_MASK 0x0000007FL
+#define ACSAD_SI_SHIFT 0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 status data register.
+//
+//****************************************************************************
+#define ACSDA_SD_MASK 0x0000FFFFL
+#define ACSDA_SD_SHIFT 0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the I/O trap address and control
+// registers (all 12).
+//
+//****************************************************************************
+#define IOTAC_SA_MASK 0x0000FFFFL
+#define IOTAC_MSK_MASK 0x000F0000L
+#define IOTAC_IODC_MASK 0x06000000L
+#define IOTAC_IODC_16_BIT 0x00000000L
+#define IOTAC_IODC_10_BIT 0x02000000L
+#define IOTAC_IODC_12_BIT 0x04000000L
+#define IOTAC_WSPI 0x08000000L
+#define IOTAC_RSPI 0x10000000L
+#define IOTAC_WSE 0x20000000L
+#define IOTAC_WE 0x40000000L
+#define IOTAC_RE 0x80000000L
+#define IOTAC_SA_SHIFT 0L
+#define IOTAC_MSK_SHIFT 16L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PC/PCI master enable
+// register.
+//
+//****************************************************************************
+#define PCPCIEN_EN 0x00000001L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the joystick poll/trigger
+// register.
+//
+//****************************************************************************
+#define JSPT_CAX 0x00000001L
+#define JSPT_CAY 0x00000002L
+#define JSPT_CBX 0x00000004L
+#define JSPT_CBY 0x00000008L
+#define JSPT_BA1 0x00000010L
+#define JSPT_BA2 0x00000020L
+#define JSPT_BB1 0x00000040L
+#define JSPT_BB2 0x00000080L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the joystick control register.
+// The TBF bit has been moved from MIDSR register to JSCTL register bit 8.
+//
+//****************************************************************************
+#define JSCTL_SP_MASK 0x00000003L
+#define JSCTL_SP_SLOW 0x00000000L
+#define JSCTL_SP_MEDIUM_SLOW 0x00000001L
+#define JSCTL_SP_MEDIUM_FAST 0x00000002L
+#define JSCTL_SP_FAST 0x00000003L
+#define JSCTL_ARE 0x00000004L
+#define JSCTL_TBF 0x00000100L
+
+
+//****************************************************************************
+//
+// The following defines are for the flags in the MIDI control register.
+//
+//****************************************************************************
+#define MIDCR_TXE 0x00000001L
+#define MIDCR_RXE 0x00000002L
+#define MIDCR_RIE 0x00000004L
+#define MIDCR_TIE 0x00000008L
+#define MIDCR_MLB 0x00000010L
+#define MIDCR_MRST 0x00000020L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the MIDI status register.
+//
+//****************************************************************************
+#define MIDSR_RBE 0x00000080L
+#define MIDSR_RDA 0x00008000L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the MIDI write port register.
+//
+//****************************************************************************
+#define MIDWP_MWD_MASK 0x000000FFL
+#define MIDWP_MWD_SHIFT 0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the MIDI read port register.
+//
+//****************************************************************************
+#define MIDRP_MRD_MASK 0x000000FFL
+#define MIDRP_MRD_SHIFT 0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the configuration interface
+// register.
+//
+//****************************************************************************
+#define CFGI_CLK 0x00000001L
+#define CFGI_DOUT 0x00000002L
+#define CFGI_DIN_EEN 0x00000004L
+#define CFGI_EELD 0x00000008L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the subsystem ID and vendor ID
+// register.
+//
+//****************************************************************************
+#define SSVID_VID_MASK 0x0000FFFFL
+#define SSVID_SID_MASK 0xFFFF0000L
+#define SSVID_VID_SHIFT 0L
+#define SSVID_SID_SHIFT 16L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the GPIO pin interface register.
+//
+//****************************************************************************
+#define GPIOR_VOLDN 0x00000001L
+#define GPIOR_VOLUP 0x00000002L
+#define GPIOR_SI2D 0x00000004L
+#define GPIOR_SI2OE 0x00000008L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 status register 2.
+//
+//****************************************************************************
+#define ACSTS2_CRDY 0x00000001L
+#define ACSTS2_VSTS 0x00000002L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 input slot valid
+// register 2.
+//
+//****************************************************************************
+#define ACISV2_ISV3 0x00000001L
+#define ACISV2_ISV4 0x00000002L
+#define ACISV2_ISV5 0x00000004L
+#define ACISV2_ISV6 0x00000008L
+#define ACISV2_ISV7 0x00000010L
+#define ACISV2_ISV8 0x00000020L
+#define ACISV2_ISV9 0x00000040L
+#define ACISV2_ISV10 0x00000080L
+#define ACISV2_ISV11 0x00000100L
+#define ACISV2_ISV12 0x00000200L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 status address
+// register 2.
+//
+//****************************************************************************
+#define ACSAD2_SI_MASK 0x0000007FL
+#define ACSAD2_SI_SHIFT 0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 status data register 2.
+//
+//****************************************************************************
+#define ACSDA2_SD_MASK 0x0000FFFFL
+#define ACSDA2_SD_SHIFT 0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the I/O trap control register.
+//
+//****************************************************************************
+#define IOTCR_ITD 0x00000001L
+#define IOTCR_HRV 0x00000002L
+#define IOTCR_SRV 0x00000004L
+#define IOTCR_DTI 0x00000008L
+#define IOTCR_DFI 0x00000010L
+#define IOTCR_DDP 0x00000020L
+#define IOTCR_JTE 0x00000040L
+#define IOTCR_PPE 0x00000080L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the I/O trap address and control
+// registers for Hardware Master Volume.
+//
+//****************************************************************************
+#define IOTGP_SA_MASK 0x0000FFFFL
+#define IOTGP_MSK_MASK 0x000F0000L
+#define IOTGP_IODC_MASK 0x06000000L
+#define IOTGP_IODC_16_BIT 0x00000000L
+#define IOTGP_IODC_10_BIT 0x02000000L
+#define IOTGP_IODC_12_BIT 0x04000000L
+#define IOTGP_WSPI 0x08000000L
+#define IOTGP_RSPI 0x10000000L
+#define IOTGP_WSE 0x20000000L
+#define IOTGP_WE 0x40000000L
+#define IOTGP_RE 0x80000000L
+#define IOTGP_SA_SHIFT 0L
+#define IOTGP_MSK_SHIFT 16L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the I/O trap address and control
+// registers for Sound Blaster
+//
+//****************************************************************************
+#define IOTSB_SA_MASK 0x0000FFFFL
+#define IOTSB_MSK_MASK 0x000F0000L
+#define IOTSB_IODC_MASK 0x06000000L
+#define IOTSB_IODC_16_BIT 0x00000000L
+#define IOTSB_IODC_10_BIT 0x02000000L
+#define IOTSB_IODC_12_BIT 0x04000000L
+#define IOTSB_WSPI 0x08000000L
+#define IOTSB_RSPI 0x10000000L
+#define IOTSB_WSE 0x20000000L
+#define IOTSB_WE 0x40000000L
+#define IOTSB_RE 0x80000000L
+#define IOTSB_SA_SHIFT 0L
+#define IOTSB_MSK_SHIFT 16L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the I/O trap address and control
+// registers for FM.
+//
+//****************************************************************************
+#define IOTFM_SA_MASK 0x0000FFFFL
+#define IOTFM_MSK_MASK 0x000F0000L
+#define IOTFM_IODC_MASK 0x06000000L
+#define IOTFM_IODC_16_BIT 0x00000000L
+#define IOTFM_IODC_10_BIT 0x02000000L
+#define IOTFM_IODC_12_BIT 0x04000000L
+#define IOTFM_WSPI 0x08000000L
+#define IOTFM_RSPI 0x10000000L
+#define IOTFM_WSE 0x20000000L
+#define IOTFM_WE 0x40000000L
+#define IOTFM_RE 0x80000000L
+#define IOTFM_SA_SHIFT 0L
+#define IOTFM_MSK_SHIFT 16L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PC/PCI request register.
+//
+//****************************************************************************
+#define PCPRR_RDC_MASK 0x00000007L
+#define PCPRR_REQ 0x00008000L
+#define PCPRR_RDC_SHIFT 0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PC/PCI grant register.
+//
+//****************************************************************************
+#define PCPGR_GDC_MASK 0x00000007L
+#define PCPGR_VL 0x00008000L
+#define PCPGR_GDC_SHIFT 0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PC/PCI Control Register.
+//
+//****************************************************************************
+#define PCPCR_EN 0x00000001L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the debug index register.
+//
+//****************************************************************************
+#define DREG_REGID_MASK 0x0000007FL
+#define DREG_DEBUG 0x00000080L
+#define DREG_RGBK_MASK 0x00000700L
+#define DREG_TRAP 0x00000800L
+#if !defined(NO_CS4612)
+#if !defined(NO_CS4615)
+#define DREG_TRAPX 0x00001000L
+#endif
+#endif
+#define DREG_REGID_SHIFT 0L
+#define DREG_RGBK_SHIFT 8L
+#define DREG_RGBK_REGID_MASK 0x0000077FL
+#define DREG_REGID_R0 0x00000010L
+#define DREG_REGID_R1 0x00000011L
+#define DREG_REGID_R2 0x00000012L
+#define DREG_REGID_R3 0x00000013L
+#define DREG_REGID_R4 0x00000014L
+#define DREG_REGID_R5 0x00000015L
+#define DREG_REGID_R6 0x00000016L
+#define DREG_REGID_R7 0x00000017L
+#define DREG_REGID_R8 0x00000018L
+#define DREG_REGID_R9 0x00000019L
+#define DREG_REGID_RA 0x0000001AL
+#define DREG_REGID_RB 0x0000001BL
+#define DREG_REGID_RC 0x0000001CL
+#define DREG_REGID_RD 0x0000001DL
+#define DREG_REGID_RE 0x0000001EL
+#define DREG_REGID_RF 0x0000001FL
+#define DREG_REGID_RA_BUS_LOW 0x00000020L
+#define DREG_REGID_RA_BUS_HIGH 0x00000038L
+#define DREG_REGID_YBUS_LOW 0x00000050L
+#define DREG_REGID_YBUS_HIGH 0x00000058L
+#define DREG_REGID_TRAP_0 0x00000100L
+#define DREG_REGID_TRAP_1 0x00000101L
+#define DREG_REGID_TRAP_2 0x00000102L
+#define DREG_REGID_TRAP_3 0x00000103L
+#define DREG_REGID_TRAP_4 0x00000104L
+#define DREG_REGID_TRAP_5 0x00000105L
+#define DREG_REGID_TRAP_6 0x00000106L
+#define DREG_REGID_TRAP_7 0x00000107L
+#define DREG_REGID_INDIRECT_ADDRESS 0x0000010EL
+#define DREG_REGID_TOP_OF_STACK 0x0000010FL
+#if !defined(NO_CS4612)
+#if !defined(NO_CS4615)
+#define DREG_REGID_TRAP_8 0x00000110L
+#define DREG_REGID_TRAP_9 0x00000111L
+#define DREG_REGID_TRAP_10 0x00000112L
+#define DREG_REGID_TRAP_11 0x00000113L
+#define DREG_REGID_TRAP_12 0x00000114L
+#define DREG_REGID_TRAP_13 0x00000115L
+#define DREG_REGID_TRAP_14 0x00000116L
+#define DREG_REGID_TRAP_15 0x00000117L
+#define DREG_REGID_TRAP_16 0x00000118L
+#define DREG_REGID_TRAP_17 0x00000119L
+#define DREG_REGID_TRAP_18 0x0000011AL
+#define DREG_REGID_TRAP_19 0x0000011BL
+#define DREG_REGID_TRAP_20 0x0000011CL
+#define DREG_REGID_TRAP_21 0x0000011DL
+#define DREG_REGID_TRAP_22 0x0000011EL
+#define DREG_REGID_TRAP_23 0x0000011FL
+#endif
+#endif
+#define DREG_REGID_RSA0_LOW 0x00000200L
+#define DREG_REGID_RSA0_HIGH 0x00000201L
+#define DREG_REGID_RSA1_LOW 0x00000202L
+#define DREG_REGID_RSA1_HIGH 0x00000203L
+#define DREG_REGID_RSA2 0x00000204L
+#define DREG_REGID_RSA3 0x00000205L
+#define DREG_REGID_RSI0_LOW 0x00000206L
+#define DREG_REGID_RSI0_HIGH 0x00000207L
+#define DREG_REGID_RSI1 0x00000208L
+#define DREG_REGID_RSI2 0x00000209L
+#define DREG_REGID_SAGUSTATUS 0x0000020AL
+#define DREG_REGID_RSCONFIG01_LOW 0x0000020BL
+#define DREG_REGID_RSCONFIG01_HIGH 0x0000020CL
+#define DREG_REGID_RSCONFIG23_LOW 0x0000020DL
+#define DREG_REGID_RSCONFIG23_HIGH 0x0000020EL
+#define DREG_REGID_RSDMA01E 0x0000020FL
+#define DREG_REGID_RSDMA23E 0x00000210L
+#define DREG_REGID_RSD0_LOW 0x00000211L
+#define DREG_REGID_RSD0_HIGH 0x00000212L
+#define DREG_REGID_RSD1_LOW 0x00000213L
+#define DREG_REGID_RSD1_HIGH 0x00000214L
+#define DREG_REGID_RSD2_LOW 0x00000215L
+#define DREG_REGID_RSD2_HIGH 0x00000216L
+#define DREG_REGID_RSD3_LOW 0x00000217L
+#define DREG_REGID_RSD3_HIGH 0x00000218L
+#define DREG_REGID_SRAR_HIGH 0x0000021AL
+#define DREG_REGID_SRAR_LOW 0x0000021BL
+#define DREG_REGID_DMA_STATE 0x0000021CL
+#define DREG_REGID_CURRENT_DMA_STREAM 0x0000021DL
+#define DREG_REGID_NEXT_DMA_STREAM 0x0000021EL
+#define DREG_REGID_CPU_STATUS 0x00000300L
+#define DREG_REGID_MAC_MODE 0x00000301L
+#define DREG_REGID_STACK_AND_REPEAT 0x00000302L
+#define DREG_REGID_INDEX0 0x00000304L
+#define DREG_REGID_INDEX1 0x00000305L
+#define DREG_REGID_DMA_STATE_0_3 0x00000400L
+#define DREG_REGID_DMA_STATE_4_7 0x00000404L
+#define DREG_REGID_DMA_STATE_8_11 0x00000408L
+#define DREG_REGID_DMA_STATE_12_15 0x0000040CL
+#define DREG_REGID_DMA_STATE_16_19 0x00000410L
+#define DREG_REGID_DMA_STATE_20_23 0x00000414L
+#define DREG_REGID_DMA_STATE_24_27 0x00000418L
+#define DREG_REGID_DMA_STATE_28_31 0x0000041CL
+#define DREG_REGID_DMA_STATE_32_35 0x00000420L
+#define DREG_REGID_DMA_STATE_36_39 0x00000424L
+#define DREG_REGID_DMA_STATE_40_43 0x00000428L
+#define DREG_REGID_DMA_STATE_44_47 0x0000042CL
+#define DREG_REGID_DMA_STATE_48_51 0x00000430L
+#define DREG_REGID_DMA_STATE_52_55 0x00000434L
+#define DREG_REGID_DMA_STATE_56_59 0x00000438L
+#define DREG_REGID_DMA_STATE_60_63 0x0000043CL
+#define DREG_REGID_DMA_STATE_64_67 0x00000440L
+#define DREG_REGID_DMA_STATE_68_71 0x00000444L
+#define DREG_REGID_DMA_STATE_72_75 0x00000448L
+#define DREG_REGID_DMA_STATE_76_79 0x0000044CL
+#define DREG_REGID_DMA_STATE_80_83 0x00000450L
+#define DREG_REGID_DMA_STATE_84_87 0x00000454L
+#define DREG_REGID_DMA_STATE_88_91 0x00000458L
+#define DREG_REGID_DMA_STATE_92_95 0x0000045CL
+#define DREG_REGID_TRAP_SELECT 0x00000500L
+#define DREG_REGID_TRAP_WRITE_0 0x00000500L
+#define DREG_REGID_TRAP_WRITE_1 0x00000501L
+#define DREG_REGID_TRAP_WRITE_2 0x00000502L
+#define DREG_REGID_TRAP_WRITE_3 0x00000503L
+#define DREG_REGID_TRAP_WRITE_4 0x00000504L
+#define DREG_REGID_TRAP_WRITE_5 0x00000505L
+#define DREG_REGID_TRAP_WRITE_6 0x00000506L
+#define DREG_REGID_TRAP_WRITE_7 0x00000507L
+#if !defined(NO_CS4612)
+#if !defined(NO_CS4615)
+#define DREG_REGID_TRAP_WRITE_8 0x00000510L
+#define DREG_REGID_TRAP_WRITE_9 0x00000511L
+#define DREG_REGID_TRAP_WRITE_10 0x00000512L
+#define DREG_REGID_TRAP_WRITE_11 0x00000513L
+#define DREG_REGID_TRAP_WRITE_12 0x00000514L
+#define DREG_REGID_TRAP_WRITE_13 0x00000515L
+#define DREG_REGID_TRAP_WRITE_14 0x00000516L
+#define DREG_REGID_TRAP_WRITE_15 0x00000517L
+#define DREG_REGID_TRAP_WRITE_16 0x00000518L
+#define DREG_REGID_TRAP_WRITE_17 0x00000519L
+#define DREG_REGID_TRAP_WRITE_18 0x0000051AL
+#define DREG_REGID_TRAP_WRITE_19 0x0000051BL
+#define DREG_REGID_TRAP_WRITE_20 0x0000051CL
+#define DREG_REGID_TRAP_WRITE_21 0x0000051DL
+#define DREG_REGID_TRAP_WRITE_22 0x0000051EL
+#define DREG_REGID_TRAP_WRITE_23 0x0000051FL
+#endif
+#endif
+#define DREG_REGID_MAC0_ACC0_LOW 0x00000600L
+#define DREG_REGID_MAC0_ACC1_LOW 0x00000601L
+#define DREG_REGID_MAC0_ACC2_LOW 0x00000602L
+#define DREG_REGID_MAC0_ACC3_LOW 0x00000603L
+#define DREG_REGID_MAC1_ACC0_LOW 0x00000604L
+#define DREG_REGID_MAC1_ACC1_LOW 0x00000605L
+#define DREG_REGID_MAC1_ACC2_LOW 0x00000606L
+#define DREG_REGID_MAC1_ACC3_LOW 0x00000607L
+#define DREG_REGID_MAC0_ACC0_MID 0x00000608L
+#define DREG_REGID_MAC0_ACC1_MID 0x00000609L
+#define DREG_REGID_MAC0_ACC2_MID 0x0000060AL
+#define DREG_REGID_MAC0_ACC3_MID 0x0000060BL
+#define DREG_REGID_MAC1_ACC0_MID 0x0000060CL
+#define DREG_REGID_MAC1_ACC1_MID 0x0000060DL
+#define DREG_REGID_MAC1_ACC2_MID 0x0000060EL
+#define DREG_REGID_MAC1_ACC3_MID 0x0000060FL
+#define DREG_REGID_MAC0_ACC0_HIGH 0x00000610L
+#define DREG_REGID_MAC0_ACC1_HIGH 0x00000611L
+#define DREG_REGID_MAC0_ACC2_HIGH 0x00000612L
+#define DREG_REGID_MAC0_ACC3_HIGH 0x00000613L
+#define DREG_REGID_MAC1_ACC0_HIGH 0x00000614L
+#define DREG_REGID_MAC1_ACC1_HIGH 0x00000615L
+#define DREG_REGID_MAC1_ACC2_HIGH 0x00000616L
+#define DREG_REGID_MAC1_ACC3_HIGH 0x00000617L
+#define DREG_REGID_RSHOUT_LOW 0x00000620L
+#define DREG_REGID_RSHOUT_MID 0x00000628L
+#define DREG_REGID_RSHOUT_HIGH 0x00000630L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 S/PDIF Control register.
+//
+//****************************************************************************
+#define SPDIF_CONTROL_SPDIF_EN 0x00008000L
+#define SPDIF_CONTROL_VAL 0x00004000L
+#define SPDIF_CONTROL_COPY 0x00000004L
+#define SPDIF_CONTROL_CC0 0x00000010L
+#define SPDIF_CONTROL_CC1 0x00000020L
+#define SPDIF_CONTROL_CC2 0x00000040L
+#define SPDIF_CONTROL_CC3 0x00000080L
+#define SPDIF_CONTROL_CC4 0x00000100L
+#define SPDIF_CONTROL_CC5 0x00000200L
+#define SPDIF_CONTROL_CC6 0x00000400L
+#define SPDIF_CONTROL_L 0x00000800L
+
+#endif // _H_HWDEFS
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/cs46xx.c linux/drivers/sound/cs46xx.c
--- v2.4.0-test8/linux/drivers/sound/cs46xx.c Tue Aug 29 14:09:15 2000
+++ linux/drivers/sound/cs46xx.c Sun Sep 17 09:45:05 2000
@@ -100,12 +100,6 @@
X /* maxinum number of AC97 codecs connected, AC97 2.0 defined 4 */
X #define NR_AC97 2
X
-/* minor number of /dev/dspW */
-#define SND_DEV_DSP8 1
-
-/* minor number of /dev/dspW */
-#define SND_DEV_DSP16 1
-
X static const unsigned sample_size[] = { 1, 2, 2, 4 };
X static const unsigned sample_shift[] = { 0, 1, 1, 2 };
X
@@ -2485,7 +2479,7 @@
X void (*active)(struct cs_card *, int);
X };
X
-static struct cs_card_type __init cards[]={
+static struct cs_card_type __initdata cards[]={
X {0x1489, 0x7001, "Genius Soundmaker 128 value", amp_none, NULL},
X {0x5053, 0x3357, "Voyetra", amp_voyetra, NULL},
X /* MI6020/21 use the same chipset as the Thinkpads, maybe needed */
@@ -2494,7 +2488,7 @@
X {PCI_VENDOR_ID_IBM, 0x0132, "Thinkpad 570", amp_none, clkrun_hack},
X {PCI_VENDOR_ID_IBM, 0x0153, "Thinkpad 600X/A20/T20", amp_none, clkrun_hack},
X {PCI_VENDOR_ID_IBM, 0x1010, "Thinkpad 600E (unsupported)", NULL, NULL},
- {0, 0, NULL, NULL}
+ {0, 0, NULL, NULL, NULL}
X };
X
X static int __init cs_install(struct pci_dev *pci_dev)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/dev_table.c linux/drivers/sound/dev_table.c
--- v2.4.0-test8/linux/drivers/sound/dev_table.c Sun Apr 2 15:45:06 2000
+++ linux/drivers/sound/dev_table.c Mon Sep 25 12:32:54 2000
@@ -16,8 +16,6 @@
X #define _DEV_TABLE_C_
X #include "sound_config.h"
X
-int softoss_dev = 0;
-
X int sound_install_audiodrv(int vers, char *name, struct audio_driver *driver,
X int driver_size, int flags, unsigned int format_mask,
X void *devc, int dma1, int dma2)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/dmasound/awacs_defs.h linux/drivers/sound/dmasound/awacs_defs.h
--- v2.4.0-test8/linux/drivers/sound/dmasound/awacs_defs.h Mon Jul 12 16:21:25 1999
+++ linux/drivers/sound/dmasound/awacs_defs.h Sun Sep 17 09:48:05 2000
@@ -62,6 +62,11 @@
X #define MASK_ADDR_VOLC MASK_ADDR4 /* Volume Control C -- Speaker */
X #define MASK_ADDR_VOLSPK MASK_ADDR4
X
+/* additional registers of screamer */
+#define MASK_ADDR5 (0x5 << 12) /* Expanded Data Mode Address 5 */
+#define MASK_ADDR6 (0x6 << 12) /* Expanded Data Mode Address 6 */
+#define MASK_ADDR7 (0x7 << 12) /* Expanded Data Mode Address 7 */
+
X /* Address 0 Bit Masks & Macros */
X /* ------- - --- ----- - ------ */
X #define MASK_GAINRIGHT (0xf) /* Gain Right Mask */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/dmasound/dmasound_awacs.c linux/drivers/sound/dmasound/dmasound_awacs.c
--- v2.4.0-test8/linux/drivers/sound/dmasound/dmasound_awacs.c Tue Jun 20 07:52:36 2000
+++ linux/drivers/sound/dmasound/dmasound_awacs.c Sun Sep 17 09:48:05 2000
@@ -17,8 +17,12 @@
X #include <linux/adb.h>
X #include <linux/nvram.h>
X #include <linux/vt_kern.h>
+#ifdef CONFIG_ADB_CUDA
X #include <linux/cuda.h>
+#endif
+#ifdef CONFIG_ADB_PMU
X #include <linux/pmu.h>
+#endif
X
X #include <asm/uaccess.h>
X #include <asm/prom.h>
@@ -45,6 +49,9 @@
X
X static char awacs_name[64];
X static int awacs_revision;
+int awacs_is_screamer = 0;
+int awacs_device_id = 0;
+int awacs_has_iic = 0;
X #define AWACS_BURGUNDY 100 /* fake revision # for burgundy */
X
X /*
@@ -60,7 +67,7 @@
X * Cached values of AWACS registers (we can't read them).
X * Except on the burgundy. XXX
X */
-int awacs_reg[5];
+int awacs_reg[8];
X
X #define HAS_16BIT_TABLES
X #undef HAS_8BIT_TABLES
@@ -1303,6 +1310,11 @@
X awacs_write(awacs_reg[1] | MASK_ADDR1);
X awacs_write(awacs_reg[2] | MASK_ADDR2);
X awacs_write(awacs_reg[4] | MASK_ADDR4);
+ if (awacs_is_screamer) {
+ awacs_write(awacs_reg[5] + MASK_ADDR5);
+ awacs_write(awacs_reg[6] + MASK_ADDR6);
+ awacs_write(awacs_reg[7] + MASK_ADDR7);
+ }
X out_le32(&awacs->byteswap, dmasound.hard.format != AFMT_S16_BE);
X enable_irq(awacs_irq);
X enable_irq(awacs_tx_irq);
@@ -1551,6 +1563,7 @@
X if (sys_ctrler != SYS_CTRLER_CUDA)
X return;
X
+#ifdef CONFIG_ADB_CUDA
X /* turn on headphones */
X cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,
X 0x8a, 4, 0);
@@ -1570,6 +1583,7 @@
X cuda_request(&req, NULL, 5, CUDA_PACKET,
X CUDA_GET_SET_IIC, 0x8a, 1, 0x29);
X while (!req.complete) cuda_poll();
+#endif /* CONFIG_ADB_CUDA */
X }
X
X
@@ -1974,6 +1988,13 @@
X awacs_subframe = *prop;
X if (device_is_compatible(sound, "burgundy"))
X awacs_revision = AWACS_BURGUNDY;
+ /* This should be verified on older screamers */
+ if (device_is_compatible(sound, "screamer"))
+ awacs_is_screamer = 1;
+ prop = (unsigned int *)get_property(sound, "device-id", 0);
+ if (prop != 0)
+ awacs_device_id = *prop;
+ awacs_has_iic = (find_devices("perch") != NULL);
X
X /* look for a property saying what sample rates
X are available */
@@ -2029,10 +2050,12 @@
X #ifdef CONFIG_PMAC_PBOOK
X if (machine_is_compatible("PowerBook1,1")
X || machine_is_compatible("AAPL,PowerBook1998")) {
+ pmu_suspend();
X feature_set(np, FEATURE_Sound_CLK_enable);
X feature_set(np, FEATURE_Sound_power);
X /* Shorter delay will not work */
X mdelay(1000);
+ pmu_resume();
X }
X #endif
X awacs_tx_cmds = (volatile struct dbdma_cmd *)
@@ -2050,16 +2073,28 @@
X
X
X awacs_reg[0] = MASK_MUX_CD;
- awacs_reg[1] = MASK_LOOPTHRU | MASK_PAROUT;
+ /* FIXME: Only machines with external SRS module need MASK_PAROUT */
+ awacs_reg[1] = MASK_LOOPTHRU;
+ if (awacs_has_iic || awacs_device_id == 0x5 || /*awacs_device_id == 0x8
+ || */awacs_device_id == 0xb)
+ awacs_reg[1] |= MASK_PAROUT;
X /* get default volume from nvram */
X vol = (~nvram_read_byte(0x1308) & 7) << 1;
X awacs_reg[2] = vol + (vol << 6);
X awacs_reg[4] = vol + (vol << 6);
+ awacs_reg[5] = 0;
+ awacs_reg[6] = 0;
+ awacs_reg[7] = 0;
X out_le32(&awacs->control, 0x11);
X awacs_write(awacs_reg[0] + MASK_ADDR0);
X awacs_write(awacs_reg[1] + MASK_ADDR1);
X awacs_write(awacs_reg[2] + MASK_ADDR2);
X awacs_write(awacs_reg[4] + MASK_ADDR4);
+ if (awacs_is_screamer) {
+ awacs_write(awacs_reg[5] + MASK_ADDR5);
+ awacs_write(awacs_reg[6] + MASK_ADDR6);
+ awacs_write(awacs_reg[7] + MASK_ADDR7);
+ }
X
X /* Initialize recent versions of the awacs */
X if (awacs_revision == 0) {
@@ -2118,7 +2153,15 @@
X break;
X }
X }
- /* enable CD sound input */
+ /*
+ * Enable CD sound input.
+ * The relevant bits for writing to this byte are 0x8f.
+ * I haven't found out what the 0x80 bit does.
+ * For the 0xf bits, writing 3 or 7 enables the CD
+ * input, any other value disables it. Values
+ * 1, 3, 5, 7 enable the microphone. Values 0, 2,
+ * 4, 6, 8 - f enable the input from the modem.
+ */
X if (macio_base)
X out_8(macio_base + 0x37, 3);
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/emu10k1/audio.c linux/drivers/sound/emu10k1/audio.c
--- v2.4.0-test8/linux/drivers/sound/emu10k1/audio.c Tue Aug 29 14:09:15 2000
+++ linux/drivers/sound/emu10k1/audio.c Thu Sep 21 13:25:09 2000
@@ -363,6 +363,7 @@
X
X if (get_user(val, (int *) arg))
X return -EFAULT;
+
X DPD(2, "val is %d\n", val);
X
X if (val > 0) {


@@ -418,6 +419,7 @@
X

X if (get_user(val, (int *) arg))
X return -EFAULT;
+
X DPD(2, " val is %d\n", val);
X
X if (file->f_mode & FMODE_READ) {
@@ -464,6 +466,7 @@
X
X if (get_user(val, (int *) arg))
X return -EFAULT;
+
X DPD(2, " val is %d\n", val);
X
X if (val > 0) {
@@ -527,6 +530,7 @@
X
X if (get_user(val, (int *) arg))
X return -EFAULT;
+
X DPD(2, " val is %d\n", val);
X
X if (val != AFMT_QUERY) {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/emu10k1/ecard.h linux/drivers/sound/emu10k1/ecard.h
--- v2.4.0-test8/linux/drivers/sound/emu10k1/ecard.h Mon Aug 14 08:32:48 2000
+++ linux/drivers/sound/emu10k1/ecard.h Fri Sep 22 14:21:17 2000
@@ -29,6 +29,7 @@
X #include "8010.h"
X #include "hwaccess.h"
X #include <linux/init.h>
+#include <linux/sched.h>
X
X /* In A1 Silicon, these bits are in the HC register */
X #define HOOKN_BIT (1L << 12)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/emu10k1/emu_wrapper.h linux/drivers/sound/emu10k1/emu_wrapper.h
--- v2.4.0-test8/linux/drivers/sound/emu10k1/emu_wrapper.h Mon Aug 14 08:32:48 2000
+++ linux/drivers/sound/emu10k1/emu_wrapper.h Sun Sep 17 09:45:06 2000
@@ -5,9 +5,4 @@
X
X #define PCI_SET_DMA_MASK(pdev,mask) (((pdev)->dma_mask) = (mask))
X
-#ifndef PCI_GET_DRIVER_DATA
- #define PCI_GET_DRIVER_DATA(pdev) ((pdev)->driver_data)
- #define PCI_SET_DRIVER_DATA(pdev,data) (((pdev)->driver_data) = (data))
-#endif /* PCI_GET_DRIVER_DATA */
-
X #endif
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/emu10k1/main.c linux/drivers/sound/emu10k1/main.c
--- v2.4.0-test8/linux/drivers/sound/emu10k1/main.c Mon Aug 14 08:32:48 2000
+++ linux/drivers/sound/emu10k1/main.c Thu Sep 21 13:25:09 2000
@@ -121,14 +121,14 @@
X
X /* stereo voice */
X card->waveout.send_a[1] = 0x00;
- card->waveout.send_b[1] = 0xff;
- card->waveout.send_c[1] = 0x00;
+ card->waveout.send_b[1] = 0x00;
+ card->waveout.send_c[1] = 0xff;
X card->waveout.send_d[1] = 0x00;
X card->waveout.send_routing[1] = 0xd01c;
X
X card->waveout.send_a[2] = 0x00;
- card->waveout.send_b[2] = 0x00;
- card->waveout.send_c[2] = 0xff;
+ card->waveout.send_b[2] = 0xff;
+ card->waveout.send_c[2] = 0x00;
X card->waveout.send_d[2] = 0x00;
X card->waveout.send_routing[2] = 0xd01c;
X
@@ -641,7 +641,7 @@


X return -ENODEV;
X }
X

- PCI_SET_DRIVER_DATA(pci_dev, card);
+ pci_set_drvdata(pci_dev, card);
X PCI_SET_DMA_MASK(pci_dev, EMU10K1_DMA_MASK);
X
X card->irq = pci_dev->irq;
@@ -736,7 +736,7 @@
X
X static void __devexit emu10k1_remove(struct pci_dev *pci_dev)
X {
- struct emu10k1_card *card = PCI_GET_DRIVER_DATA(pci_dev);
+ struct emu10k1_card *card = pci_get_drvdata(pci_dev);
X
X midi_exit(card);
X emu10k1_exit(card);
@@ -755,7 +755,7 @@
X
X kfree(card);
X
- return;


+ pci_set_drvdata(pci_dev, NULL);
X }
X

X MODULE_AUTHOR("Bertrand Lee, Cai Ying. (Email to: emu10k...@opensource.creative.com)");
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/emu10k1/midi.c linux/drivers/sound/emu10k1/midi.c
--- v2.4.0-test8/linux/drivers/sound/emu10k1/midi.c Mon Aug 14 08:32:48 2000
+++ linux/drivers/sound/emu10k1/midi.c Thu Sep 21 13:25:09 2000
@@ -43,7 +43,7 @@
X #include "cardmi.h"
X #include "midi.h"
X
-static spinlock_t midi_spinlock = SPIN_LOCK_UNLOCKED;
+static spinlock_t midi_spinlock __attribute((unused)) = SPIN_LOCK_UNLOCKED;
X
X static void init_midi_hdr(struct midi_hdr *midihdr)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/emu10k1/mixer.c linux/drivers/sound/emu10k1/mixer.c
--- v2.4.0-test8/linux/drivers/sound/emu10k1/mixer.c Tue Aug 29 14:09:15 2000
+++ linux/drivers/sound/emu10k1/mixer.c Thu Sep 21 13:25:09 2000
@@ -1040,6 +1040,7 @@
X
X if (get_user(val, (int *) arg))
X return -EFAULT;
+
X i = hweight32(val);
X if (i == 0)
X return 0; /* val = mixer_recmask(s); */
@@ -1065,6 +1066,7 @@
X return -EINVAL;
X if (get_user(val, (int *) arg))
X return -EFAULT;
+
X if (emu10k1_mixer_wrch(card, i, val))
X return -EINVAL;
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/es1370.c linux/drivers/sound/es1370.c
--- v2.4.0-test8/linux/drivers/sound/es1370.c Tue Aug 29 14:09:15 2000
+++ linux/drivers/sound/es1370.c Mon Sep 18 14:57:01 2000
@@ -2593,7 +2593,7 @@


X }
X set_fs(fs);
X /* store it in the driver field */
- pcidev->driver_data = s;
+ pci_set_drvdata(pcidev, s);

X pcidev->dma_mask = 0xffffffff;


X /* put it into driver list */
X list_add_tail(&s->devs, &devs);

@@ -2620,7 +2620,7 @@
X
X static void __devinit es1370_remove(struct pci_dev *dev)
X {
- struct es1370_state *s = (struct es1370_state *)dev->driver_data;
+ struct es1370_state *s = pci_get_drvdata(dev);


X
X if (!s)
X return;

@@ -2635,7 +2635,7 @@
X unregister_sound_dsp(s->dev_dac);
X unregister_sound_midi(s->dev_midi);


X kfree(s);
- dev->driver_data = NULL;
+ pci_set_drvdata(dev, NULL);
X }
X

X static struct pci_device_id id_table[] __devinitdata = {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/es1371.c linux/drivers/sound/es1371.c
--- v2.4.0-test8/linux/drivers/sound/es1371.c Tue Aug 29 14:09:15 2000
+++ linux/drivers/sound/es1371.c Fri Sep 22 17:24:45 2000
@@ -2859,7 +2859,7 @@
X /* turn on S/PDIF output driver if requested */
X outl(cssr, s->io+ES1371_REG_STATUS);


X /* store it in the driver field */
- pcidev->driver_data = s;
+ pci_set_drvdata(pcidev, s);

X pcidev->dma_mask = 0xffffffff;


X /* put it into driver list */
X list_add_tail(&s->devs, &devs);

@@ -2886,7 +2886,7 @@
X
X static void __devinit es1371_remove(struct pci_dev *dev)
X {
- struct es1371_state *s = (struct es1371_state *)dev->driver_data;
+ struct es1371_state *s = pci_get_drvdata(dev);


X
X if (!s)
X return;

@@ -2905,7 +2905,7 @@
X unregister_sound_dsp(s->dev_dac);
X unregister_sound_midi(s->dev_midi);


X kfree(s);
- dev->driver_data = NULL;
+ pci_set_drvdata(dev, NULL);
X }
X

X static struct pci_device_id id_table[] __devinitdata = {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/esssolo1.c linux/drivers/sound/esssolo1.c
--- v2.4.0-test8/linux/drivers/sound/esssolo1.c Tue Aug 29 14:09:15 2000
+++ linux/drivers/sound/esssolo1.c Wed Sep 27 13:53:57 2000
@@ -2085,12 +2085,11 @@
X return -ERESTARTSYS;
X down(&s->open_sem);
X }
- if (check_region(s->sbbase, FMSYNTH_EXTENT)) {
+ if (!request_region(s->sbbase, FMSYNTH_EXTENT, "ESS Solo1")) {
X up(&s->open_sem);
X printk(KERN_ERR "solo1: FM synth io ports in use, opl3 loaded?\n");
X return -EBUSY;
X }
- request_region(s->sbbase, FMSYNTH_EXTENT, "ESS Solo1");
X /* init the stuff */
X outb(1, s->sbbase);
X outb(0x20, s->sbbase+1); /* enable waveforms */
@@ -2305,7 +2304,7 @@
X if (setup_solo1(s))
X goto err;


X /* store it in the driver field */
- pcidev->driver_data = s;
+ pci_set_drvdata(pcidev, s);

X pcidev->dma_mask = dma_mask;


X /* put it into driver list */
X list_add_tail(&s->devs, &devs);

@@ -2342,7 +2341,7 @@
X
X static void __devinit solo1_remove(struct pci_dev *dev)
X {
- struct solo1_state *s = (struct solo1_state *)dev->driver_data;
+ struct solo1_state *s = pci_get_drvdata(dev);


X
X if (!s)
X return;

@@ -2363,7 +2362,7 @@


X unregister_sound_midi(s->dev_midi);
X unregister_sound_special(s->dev_dmfm);
X kfree(s);
- dev->driver_data = NULL;
+ pci_set_drvdata(dev, NULL);
X }
X

X static struct pci_device_id id_table[] __devinitdata = {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/gus_card.c linux/drivers/sound/gus_card.c
--- v2.4.0-test8/linux/drivers/sound/gus_card.c Fri Aug 11 08:26:43 2000
+++ linux/drivers/sound/gus_card.c Sun Sep 17 09:45:05 2000
@@ -198,7 +198,9 @@
X }
X #endif
X
+#ifdef CONFIG_SOUND_GUS16
X static int gus16 = 0;
+#endif
X #ifdef CONFIG_SOUND_GUSMAX
X static int no_wave_dma = 0;/* Set if no dma is to be used for the
X wave table (GF1 chip) */
@@ -223,12 +225,12 @@
X MODULE_PARM(dma, "i");
X MODULE_PARM(dma16, "i");
X MODULE_PARM(type, "i");
-MODULE_PARM(gus16, "i");
X #ifdef CONFIG_SOUND_GUSMAX
X MODULE_PARM(no_wave_dma, "i");
X #endif
X #ifdef CONFIG_SOUND_GUS16
X MODULE_PARM(db16, "i");
+MODULE_PARM(gus16, "i");
X #endif
X
X static int __init init_gus(void)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/mad16.c linux/drivers/sound/mad16.c
--- v2.4.0-test8/linux/drivers/sound/mad16.c Fri Aug 11 08:26:43 2000
+++ linux/drivers/sound/mad16.c Wed Sep 27 13:53:56 2000
@@ -66,6 +66,7 @@
X * Paul Grayson Added support for Midi on later Mozart cards.
X * 25-Nov-1999
X * Christoph Hellwig Adapted to module_init/module_exit.
+ * Arnaldo C. de Melo got rid of attach_uart401 21-Sep-2000


X */
X
X #include <linux/config.h>

@@ -714,28 +715,6 @@
X request_region(hw_config->io_base, 4, "MAD16 WSS config");
X }
X
-static void __init attach_mad16_mpu(struct address_info *hw_config)
-{
-#ifdef CONFIG_MAD16_OLDCARD
-
- if (mad_read(MC1_PORT) & 0x20)
- hw_config->io_base = 0x240;
- else
- hw_config->io_base = 0x220;
-
- hw_config->name = "Mad16/Mozart";
- sb_dsp_init(hw_config, THIS_MODULE);
- return;
-#endif
-
- if (!already_initialized)
- return;
-
- hw_config->driver_use_1 = SB_MIDI_ONLY;
- hw_config->name = "Mad16/Mozart";


- attach_uart401(hw_config, THIS_MODULE);
-}
-

X static int __init probe_mad16_mpu(struct address_info *hw_config)
X {
X static int mpu_attached = 0;
@@ -791,7 +770,17 @@
X
X mad_write(MC3_PORT, tmp | 0x04);
X hw_config->driver_use_1 = SB_MIDI_ONLY;
- return sb_dsp_detect(hw_config, 0, 0, NULL);
+ if (!sb_dsp_detect(hw_config, 0, 0, NULL))
+ return 0;
+
+ if (mad_read(MC1_PORT) & 0x20)
+ hw_config->io_base = 0x240;
+ else
+ hw_config->io_base = 0x220;
+
+ hw_config->name = "Mad16/Mozart";
+ sb_dsp_init(hw_config, THIS_MODULE);
+ return 1;
X #else
X /* assuming all later Mozart cards are identified as
X * either 82C928 or Mozart. If so, following code attempts


@@ -845,8 +834,7 @@
X }
X

X mad_write(MC8_PORT, tmp); /* write MPU port parameters */
-
- return probe_uart401(hw_config);
+ goto probe_401;
X #endif
X }
X tmp = mad_read(MC6_PORT) & 0x83;
@@ -888,8 +876,12 @@
X }
X }
X mad_write(MC6_PORT, tmp); /* Write MPU401 config */
-
- return probe_uart401(hw_config);
+#ifndef CONFIG_MAD16_OLDCARD
+probe_401:
+#endif
+ hw_config->driver_use_1 = SB_MIDI_ONLY;
+ hw_config->name = "Mad16/Mozart";


+ return probe_uart401(hw_config, THIS_MODULE);
X }
X

X static void __exit unload_mad16(struct address_info *hw_config)
@@ -1090,10 +1082,6 @@
X attach_mad16(&cfg);
X
X found_mpu = probe_mad16_mpu(&cfg_mpu);
-
- if (found_mpu)
- attach_mad16_mpu(&cfg_mpu);
-


X return 0;
X }
X

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/mpu401.h linux/drivers/sound/mpu401.h
--- v2.4.0-test8/linux/drivers/sound/mpu401.h Fri Aug 11 08:26:43 2000
+++ linux/drivers/sound/mpu401.h Wed Sep 27 13:53:56 2000
@@ -6,8 +6,7 @@
X */
X
X /* From uart401.c */
-int probe_uart401 (struct address_info *hw_config);
-void attach_uart401 (struct address_info *hw_config, struct module *owner);
+int probe_uart401 (struct address_info *hw_config, struct module *owner);
X void unload_uart401 (struct address_info *hw_config);
X
X void uart401intr (int irq, void *dev_id, struct pt_regs * dummy);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/msnd_pinnacle.c linux/drivers/sound/msnd_pinnacle.c
--- v2.4.0-test8/linux/drivers/sound/msnd_pinnacle.c Mon Aug 7 21:01:35 2000
+++ linux/drivers/sound/msnd_pinnacle.c Mon Sep 25 12:32:54 2000
@@ -1610,10 +1610,6 @@
X static int fifosize __initdata = DEFFIFOSIZE;
X static int calibrate_signal __initdata;
X
-/* If we're a module, this is just init_module */
-
-int init_module(void)
-
X #else /* not a module */
X
X static int write_ndelay __initdata = -1;
@@ -1692,14 +1688,10 @@
X #endif
X static int
X calibrate_signal __initdata = CONFIG_MSND_CALSIGNAL;
+#endif /* MODULE */
X
-#ifdef MSND_CLASSIC
-int __init msnd_classic_init(void)
-#else
-int __init msnd_pinnacle_init(void)
-#endif /* MSND_CLASSIC */


X
-#endif /* MODULE */

+static int __init msnd_init(void)
X {
X int err;
X #ifndef MSND_CLASSIC
@@ -1875,11 +1867,12 @@


X return 0;
X }
X

-#ifdef MODULE
-void cleanup_module(void)
+static void __exit msdn_cleanup(void)
X {
X unload_multisound();
X msnd_fifo_free(&dev.DAPF);
X msnd_fifo_free(&dev.DARF);
X }
-#endif
+
+module_init(msnd_init);
+module_exit(msdn_cleanup);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/sound/opl3.c linux/drivers/sound/opl3.c
--- v2.4.0-test8/linux/drivers/sound/opl3.c Fri Aug 11 08:26:43 2000
+++ linux/drivers/sound/opl3.c Sun Sep 17 09:45:06 2000
@@ -15,6 +15,8 @@
X * Thomas Sailer ioctl code reworked (vmalloc/vfree removed)
X * Alan Cox modularisation, fixed sound_mem allocs.


X * Christoph Hellwig Adapted to module_init/module_exit

+ * Arnaldo C. de Melo get rid of check_region, use request_region for
+ * OPL4, release it on exit, some cleanups.


X *
X * Status

X * Believed to work. Badly needs rewriting a bit to support multiple
@@ -172,6 +174,15 @@
X "structure \n ");


X return 0;
X }
+

+ memset(devc, 0, sizeof(*devc));
+ strcpy(devc->fm_info.name, "OPL2");
+
+ if (!request_region(ioaddr, 4, devc->fm_info.name)) {
+ printk(KERN_WARNING "opl3: I/O port 0x%x already in use\n", ioaddr);
+ goto cleanup_devc;
+ }
+
X devc->osp = osp;
X devc->base = ioaddr;
X
@@ -187,7 +198,7 @@
X signature != 0x0f)
X {
X MDB(printk(KERN_INFO "OPL3 not detected %x\n", signature));
- return 0;
+ goto cleanup_region;
X }
X
X if (signature == 0x06) /* OPL2 */
@@ -214,7 +225,7 @@
X detected_model = 4;
X }
X
- if (!check_region(ioaddr - 8, 2)) /* OPL4 port is free */
+ if (request_region(ioaddr - 8, 2, "OPL4")) /* OPL4 port was free */
X {
X int tmp;
X
@@ -232,7 +243,10 @@
X udelay(10);
X }
X else
+ { /* release OPL4 port */
+ release_region(ioaddr - 8, 2);
X detected_model = 3;
+ }
X }
X opl3_command(ioaddr + 2, OPL3_MODE_REGISTER, 0);
X }
@@ -246,6 +260,12 @@
X * Melodic mode.
X */
X return 1;
+cleanup_region:
+ release_region(ioaddr, 4);
+cleanup_devc:
+ kfree(devc);
+ devc = NULL;


+ return 0;
X }
X

X static int opl3_kill_note (int devno, int voice, int note, int velocity)
@@ -1099,12 +1119,7 @@
X return -1;
X }
X
- memset((char *) devc, 0x00, sizeof(*devc));
- devc->osp = osp;
- devc->base = ioaddr;
-
X devc->nr_voice = 9;
- strcpy(devc->fm_info.name, "OPL2");
X
X devc->fm_info.device = 0;
X devc->fm_info.synth_type = SYNTH_TYPE_FM;
@@ -1191,18 +1206,12 @@
X
X if (io != -1) /* User loading pure OPL3 module */
X {
- if (check_region(io, 4))
- {


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 086'
echo 'File patch-2.4.0-test9 is continued in part 087'
echo "087" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part089

#!/bin/sh -x
# this is part 089 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 089; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ ixj_PCcontrol_wait(board);
+ j->flags.pcmciascp = 1; // Set Cable Present Flag
+
+ j->flags.pcmciasct = (inw_p(j->XILINXbase + 0x00) >> 8) & 0x03; // Get Cable Type
+
+ if (j->flags.pcmciasct == 3) {


+ j->flags.pcmciastate = 4;
+ return 0;

+ } else if (j->flags.pcmciasct == 0) {
+ j->pccr2.bits.pwr = 1;


+ j->pccr2.bits.rstc = 0;
+ outb_p(j->pccr2.byte, j->XILINXbase + 0x02);

+ j->port = PORT_SPEAKER;
+ } else {
+ j->port = PORT_POTS;
+ }
+ j->sic1.bits.cpd = 0; // Chip Power Down
+
+ j->sic1.bits.mpd = 0; // MIC Bias Power Down
+
+ j->sic1.bits.hpd = 0; // Handset Bias Power Down
+
+ j->sic1.bits.lpd = 0; // Line Bias Power Down
+
+ j->sic1.bits.spd = 1; // Speaker Drive Power Down
+
+ j->psccr.bits.addr = 1; // R/W Smart Cable Register Address
+
+ j->psccr.bits.rw = 0; // Read / Write flag
+
+ j->psccr.bits.dev = 0;
+ outb(j->sic1.byte, j->XILINXbase + 0x00);
+ outb(j->psccr.byte, j->XILINXbase + 0x01);
+ ixj_PCcontrol_wait(board);
+ j->sic2.bits.al = 0; // Analog Loopback DAC analog -> ADC analog
+
+ j->sic2.bits.dl2 = 0; // Digital Loopback DAC -> ADC one bit
+
+ j->sic2.bits.dl1 = 0; // Digital Loopback ADC -> DAC one bit
+
+ j->sic2.bits.pll = 0; // 1 = div 10, 0 = div 5
+
+ j->sic2.bits.hpd = 0; // HPF disable
+
+ j->psccr.bits.addr = 2; // R/W Smart Cable Register Address
+
+ j->psccr.bits.rw = 0; // Read / Write flag
+
+ j->psccr.bits.dev = 0;
+ outb(j->sic2.byte, j->XILINXbase + 0x00);
+ outb(j->psccr.byte, j->XILINXbase + 0x01);
+ ixj_PCcontrol_wait(board);
+ j->psccr.bits.addr = 3; // R/W Smart Cable Register Address
+
+ j->psccr.bits.rw = 0; // Read / Write flag
+
+ j->psccr.bits.dev = 0;
+ outb(0x00, j->XILINXbase + 0x00); // PLL Divide N1
+
+ outb(j->psccr.byte, j->XILINXbase + 0x01);
+ ixj_PCcontrol_wait(board);
+ j->psccr.bits.addr = 4; // R/W Smart Cable Register Address
+
+ j->psccr.bits.rw = 0; // Read / Write flag
+
+ j->psccr.bits.dev = 0;
+ outb(0x09, j->XILINXbase + 0x00); // PLL Multiply M1
+
+ outb(j->psccr.byte, j->XILINXbase + 0x01);
+ ixj_PCcontrol_wait(board);
+ j->sirxg.bits.lig = 1; // Line In Gain
+
+ j->sirxg.bits.lim = 1; // Line In Mute
+
+ j->sirxg.bits.mcg = 0; // MIC In Gain // was 3
+
+ j->sirxg.bits.mcm = 0; // MIC In Mute
+
+ j->sirxg.bits.him = 0; // Handset In Mute
+
+ j->sirxg.bits.iir = 1; // IIR
+
+ j->psccr.bits.addr = 5; // R/W Smart Cable Register Address
+
+ j->psccr.bits.rw = 0; // Read / Write flag
+
+ j->psccr.bits.dev = 0;
+ outb(j->sirxg.byte, j->XILINXbase + 0x00);
+ outb(j->psccr.byte, j->XILINXbase + 0x01);
+ ixj_PCcontrol_wait(board);
+ j->siadc.bits.hom = 0; // Handset Out Mute
+
+ j->siadc.bits.lom = 0; // Line Out Mute
+
+ j->siadc.bits.rxg = 23; //(0xC000 - 0x41C8) / 0x4EF; // RX PGA Gain
+
+ j->psccr.bits.addr = 6; // R/W Smart Cable Register Address
+
+ j->psccr.bits.rw = 0; // Read / Write flag
+
+ j->psccr.bits.dev = 0;
+ outb(j->siadc.byte, j->XILINXbase + 0x00);
+ outb(j->psccr.byte, j->XILINXbase + 0x01);
+ ixj_PCcontrol_wait(board);
+ j->sidac.bits.srm = 1; // Speaker Right Mute
+
+ j->sidac.bits.slm = 1; // Speaker Left Mute
+
+ j->sidac.bits.txg = (0xC000 - 0x45E4) / 0x5D3; // TX PGA Gain
+
+ j->psccr.bits.addr = 7; // R/W Smart Cable Register Address
+
+ j->psccr.bits.rw = 0; // Read / Write flag
+
+ j->psccr.bits.dev = 0;
+ outb(j->sidac.byte, j->XILINXbase + 0x00);
+ outb(j->psccr.byte, j->XILINXbase + 0x01);
+ ixj_PCcontrol_wait(board);
+ j->siaatt.bits.sot = 0;
+ j->psccr.bits.addr = 9; // R/W Smart Cable Register Address
+
+ j->psccr.bits.rw = 0; // Read / Write flag
+
+ j->psccr.bits.dev = 0;
+ outb(j->siaatt.byte, j->XILINXbase + 0x00);
+ outb(j->psccr.byte, j->XILINXbase + 0x01);
+ ixj_PCcontrol_wait(board);
+
+ if (j->flags.pcmciasct == 1 && !j->readers && !j->writers) {
+ j->psccr.byte = j->pslic.byte = 0;


+ j->pslic.bits.powerdown = 1;

+ j->psccr.bits.dev = 3;
+ j->psccr.bits.rw = 0;
+ outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00);
+ ixj_PCcontrol_wait(board);
+ }
+ }

+ return 0;
+ } else {

+ j->flags.pcmciascp = 0;


+ return 0;
+ }
+ return 0;
+}
+

X static int ixj_hookstate(int board)

X {
X unsigned long det;
@@ -885,15 +1242,12 @@
X case 500:
X SLIC_GetState(board);
X if (j->pld_slicr.bits.state == PLD_SLIC_STATE_ACTIVE ||
- j->pld_slicr.bits.state == PLD_SLIC_STATE_STANDBY)
- {
- if (j->flags.ringing)
- {
- if(!in_interrupt())
- {
+ j->pld_slicr.bits.state == PLD_SLIC_STATE_STANDBY) {
+ if (j->flags.ringing) {
+ if (!in_interrupt()) {
X det = jiffies + (hertz / 50);
X while (time_before(jiffies, det)) {
- current->state = TASK_INTERRUPTIBLE;
+ set_current_state(TASK_INTERRUPTIBLE);
X schedule_timeout(1);
X }
X }
@@ -909,13 +1263,17 @@
X fOffHook = j->pld_slicr.bits.det ? 1 : 0;
X }
X break;
+ case 600:
+ fOffHook = ixj_pcmcia_cable_check(board);
+ break;
X }
X if (j->r_hook != fOffHook) {
X j->r_hook = fOffHook;
X if (j->port != PORT_POTS) {


X j->ex.bits.hookstate = 1;
- kill_fasync(&j->async_queue, SIGIO, POLL_IN); // Send apps notice of change

-
+ ixj_kill_fasync(board, POLL_IN);
+ } else if (!fOffHook) {
+ j->flash_end = jiffies + (hertz / 10 * 6);
X }
X }
X if (j->port == PORT_PSTN && j->daa_mode == SOP_PU_CONVERSATION)
@@ -927,7 +1285,10 @@
X if (j->port == PORT_HANDSET)
X fOffHook |= 2;
X
- return fOffHook;
+ if (fOffHook && time_before(jiffies, j->flash_end))


+ return 0;
+ else

+ return fOffHook;
X }
X
X static void ixj_ring_off(board)
@@ -949,7 +1310,7 @@
X if (ixjdebug > 0)
X printk(KERN_INFO "IXJ Ring Off\n");
X
- SLIC_SetState(PLD_SLIC_STATE_STANDBY, board);
+ SLIC_SetState(PLD_SLIC_STATE_STANDBY, board);
X
X SLIC_GetState(board);
X }
@@ -997,9 +1358,9 @@
X j->flags.ringing = 0;
X return 1;
X }
- current->state = TASK_INTERRUPTIBLE;
+ set_current_state(TASK_INTERRUPTIBLE);
X schedule_timeout(1);
- if(signal_pending(current))
+ if (signal_pending(current))
X break;
X }
X jif = jiffies + (3 * hertz);
@@ -1008,9 +1369,9 @@
X if (ixj_hookstate(board) & 1) {
X det = jiffies + (hertz / 100);
X while (time_before(jiffies, det)) {
- current->state = TASK_INTERRUPTIBLE;
+ set_current_state(TASK_INTERRUPTIBLE);
X schedule_timeout(1);
- if(signal_pending(current))
+ if (signal_pending(current))
X break;
X }
X if (ixj_hookstate(board) & 1) {
@@ -1018,9 +1379,9 @@


X return 1;
X }
X }

- current->state = TASK_INTERRUPTIBLE;
+ set_current_state(TASK_INTERRUPTIBLE);
X schedule_timeout(1);
- if(signal_pending(current))
+ if (signal_pending(current))
X break;
X }
X }
@@ -1031,39 +1392,70 @@
X
X int ixj_open(struct phone_device *p, struct file *file_p)
X {
- IXJ *j = &ixj[p->board];
+ IXJ *j = file_p->private_data = &ixj[p->board];
X
X if (!j->DSPbase)
X return -ENODEV;
X
- if (file_p->f_mode & FMODE_READ)
- j->readers++;
- if (file_p->f_mode & FMODE_WRITE)
- j->writers++;
+ if (file_p->f_mode & FMODE_READ) {
+ if(!j->readers) {
+ j->readers++;
+ } else {


+ return -EBUSY;
+ }
+ }

+
+ if (file_p->f_mode & FMODE_WRITE) {
+ if(!j->writers) {
+ j->writers++;
+ } else {
+ if (file_p->f_mode & FMODE_READ){
+ j->readers--;
+ }


+ return -EBUSY;
+ }
+ }

+


+ if (j->cardtype == 600) {

+ j->pslic.bits.powerdown = 0;

+ j->psccr.bits.dev = 3;
+ j->psccr.bits.rw = 0;
+ outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00);

+ ixj_PCcontrol_wait(p->board);
+ }
+ MOD_INC_USE_COUNT;


X
X if (ixjdebug > 0)

-// printk(KERN_INFO "Opening board %d\n", NUM(inode->i_rdev));
X printk(KERN_INFO "Opening board %d\n", p->board);
X
+ j->framesread = j->frameswritten = 0;


X return 0;
X }
X

X int ixj_release(struct inode *inode, struct file *file_p)
X {
X IXJ_TONE ti;
- int board = NUM(inode->i_rdev);
- IXJ *j = &ixj[board];
+// int board = NUM(inode->i_rdev);
+ IXJ *j = file_p->private_data;
+ int board = j->p.board;
+// IXJ *j = &ixj[board];
X
X if (ixjdebug > 0)
X printk(KERN_INFO "Closing board %d\n", NUM(inode->i_rdev));
X
- lock_kernel();
X daa_set_mode(board, SOP_PU_SLEEP);
- ixj_set_port(board, PORT_POTS);


+ if (j->cardtype == 600)

+ ixj_set_port(board, PORT_SPEAKER);
+ else
+ ixj_set_port(board, PORT_POTS);
X aec_stop(board);
X ixj_play_stop(board);
X ixj_record_stop(board);
+ set_play_volume(board, 0x100);
+ set_rec_volume(board, 0x100);
+ ixj_ring_off(board);
X
+ // Restore the tone table to default settings.
X ti.tone_index = 10;
X ti.gain0 = 1;
X ti.freq0 = hz941;
@@ -1172,6 +1564,10 @@
X
X idle(board);
X
+// if(j->cardtype == 600) { // && j->flags.pcmciasct == 1 && j->readers == 1 && j->writers == 1) {
+ SLIC_SetState(PLD_SLIC_STATE_OC, board);
+// }
+
X if (file_p->f_mode & FMODE_READ)
X j->readers--;
X if (file_p->f_mode & FMODE_WRITE)
@@ -1189,15 +1585,24 @@
X }
X j->rec_codec = j->play_codec = 0;
X j->rec_frame_size = j->play_frame_size = 0;
+ j->flags.cidsent = j->flags.cidring = 0;
X ixj_fasync(-1, file_p, 0); // remove from list of async notification
X
- unlock_kernel();
+ if(j->cardtype == 300 && !j->readers && !j->writers) {
+ ixj_set_port(board, PORT_PSTN);
+ ixj_set_pots(board, 1);
+ }
+ ixj_WriteDSPCommand(0x0FE3, board); // Put the DSP in 1/5 power mode.
+
+ file_p->private_data = NULL;
+ MOD_DEC_USE_COUNT;


X return 0;
X }
X

X static int read_filters(int board)

X {
X unsigned short fc, cnt;
+ int var;


X IXJ *j = &ixj[board];
X

X if (ixj_WriteDSPCommand(0x5144, board))
@@ -1209,6 +1614,11 @@
X
X j->frame_count = fc;
X
+ if (j->dtmf_proc)
+ return 1;
+
+ var = 10;
+
X for (cnt = 0; cnt < 4; cnt++) {
X if (ixj_WriteDSPCommand(0x5154 + cnt, board))
X return -1;
@@ -1217,8 +1627,108 @@
X return -1;
X
X j->filter_hist[cnt] = j->ssr.high << 8 | j->ssr.low;
- if ((j->filter_hist[cnt] & 1 && !(j->filter_hist[cnt] & 2)) ||
- (j->filter_hist[cnt] & 2 && !(j->filter_hist[cnt] & 1))) {
+
+ if (j->cadence_f[cnt].enable) {
+ if (j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12)) {
+ if (j->cadence_f[cnt].state == 0) {
+ j->cadence_f[cnt].state = 1;
+ j->cadence_f[cnt].on1min = jiffies + (j->cadence_f[cnt].on1 * hertz * (100 - var) / 10000);
+ j->cadence_f[cnt].on1dot = jiffies + (j->cadence_f[cnt].on1 * hertz * (100) / 10000);
+ j->cadence_f[cnt].on1max = jiffies + (j->cadence_f[cnt].on1 * hertz * (100 + var) / 10000);
+ } else if (j->cadence_f[cnt].state == 2 &&
+ (time_after(jiffies, j->cadence_f[cnt].off1min) &&
+ time_before(jiffies, j->cadence_f[cnt].off1max))) {
+ if (j->cadence_f[cnt].on2) {
+ j->cadence_f[cnt].state = 3;
+ j->cadence_f[cnt].on2min = jiffies + (j->cadence_f[cnt].on2 * hertz * (100 - var) / 10000);
+ j->cadence_f[cnt].on2dot = jiffies + (j->cadence_f[cnt].on2 * hertz * (100) / 10000);
+ j->cadence_f[cnt].on2max = jiffies + (j->cadence_f[cnt].on2 * hertz * (100 + var) / 10000);
+ } else {
+ j->cadence_f[cnt].state = 6;
+ }
+ } else if (j->cadence_f[cnt].state == 4 &&
+ (time_after(jiffies, j->cadence_f[cnt].off2min) &&
+ time_before(jiffies, j->cadence_f[cnt].off2max))) {
+ if (j->cadence_f[cnt].on2) {
+ j->cadence_f[cnt].state = 5;
+ j->cadence_f[cnt].on3min = jiffies + (j->cadence_f[cnt].on3 * hertz * (100 - var) / 10000);
+ j->cadence_f[cnt].on3dot = jiffies + (j->cadence_f[cnt].on3 * hertz * (100) / 10000);
+ j->cadence_f[cnt].on3max = jiffies + (j->cadence_f[cnt].on3 * hertz * (100 + var) / 10000);
+ } else {
+ j->cadence_f[cnt].state = 6;
+ }
+ } else {
+ j->cadence_f[cnt].state = 0;
+ }
+ } else if (j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3)) {
+ if (j->cadence_f[cnt].state == 1 &&
+ (time_after(jiffies, j->cadence_f[cnt].on1min) &&
+ time_before(jiffies, j->cadence_f[cnt].on1max))) {
+ j->cadence_f[cnt].state = 2;
+ j->cadence_f[cnt].off1min = jiffies + (j->cadence_f[cnt].off1 * hertz * (100 - var) / 10000);
+ j->cadence_f[cnt].off1max = jiffies + (j->cadence_f[cnt].off1 * hertz * (100 + var) / 10000);
+ } else if (j->cadence_f[cnt].state == 3 &&
+ (time_after(jiffies, j->cadence_f[cnt].on2min) &&
+ time_before(jiffies, j->cadence_f[cnt].on2max))) {
+ j->cadence_f[cnt].state = 4;
+ j->cadence_f[cnt].off2min = jiffies + (j->cadence_f[cnt].off2 * hertz * (100 - var) / 10000);
+ j->cadence_f[cnt].off2max = jiffies + (j->cadence_f[cnt].off2 * hertz * (100 + var) / 10000);
+ } else if (j->cadence_f[cnt].state == 5 &&
+ (time_after(jiffies, j->cadence_f[cnt].on3min) &&
+ time_before(jiffies, j->cadence_f[cnt].on3max))) {
+ j->cadence_f[cnt].state = 6;
+ j->cadence_f[cnt].off3min = jiffies + (j->cadence_f[cnt].off3 * hertz * (100 - var) / 10000);
+ j->cadence_f[cnt].off3max = jiffies + (j->cadence_f[cnt].off3 * hertz * (100 + var) / 10000);
+ } else {
+ j->cadence_f[cnt].state = 0;
+ }
+ } else {
+ switch(j->cadence_f[cnt].state) {
+ case 1:
+ if(time_after(jiffies, j->cadence_f[cnt].on1dot) &&
+ !j->cadence_f[cnt].off1 &&
+ !j->cadence_f[cnt].on2 && !j->cadence_f[cnt].off2 &&
+ !j->cadence_f[cnt].on3 && !j->cadence_f[cnt].off3) {
+ j->cadence_f[cnt].state = 6;
+ }
+ break;
+ case 3:
+ if(time_after(jiffies, j->cadence_f[cnt].on2dot) &&
+ !j->cadence_f[cnt].off2 &&
+ !j->cadence_f[cnt].on3 && !j->cadence_f[cnt].off3) {
+ j->cadence_f[cnt].state = 6;
+ }
+ break;
+ case 5:
+ if(time_after(jiffies, j->cadence_f[cnt].on3dot) &&
+ !j->cadence_f[cnt].off3) {
+ j->cadence_f[cnt].state = 6;
+ }


+ break;
+ }
+ }
+ }

+ if (j->cadence_f[cnt].state == 6) {
+ j->cadence_f[cnt].state = 0;
+ if (j->cadence_f[cnt].enable == 1)
+ j->cadence_f[cnt].enable = 0;
+ switch (cnt) {
+ case 0:
+ j->ex.bits.fc0 = 1;


+ break;
+ case 1:

+ j->ex.bits.fc1 = 1;
+ break;
+ case 2:
+ j->ex.bits.fc2 = 1;
+ break;
+ case 3:
+ j->ex.bits.fc3 = 1;
+ break;
+ }
+ }
+ if (j->filter_en[cnt] && ((j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12)) ||
+ (j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3)))) {
X switch (cnt) {
X case 0:
X j->ex.bits.f0 = 1;
@@ -1259,11 +1769,16 @@
X }
X if (j->dtmf_state && !j->dtmf.bits.dtmf_valid) // && j->dtmf_wp != j->dtmf_rp)
X {
- j->dtmfbuffer[j->dtmf_wp] = j->dtmf_current;
- j->dtmf_wp++;
- if (j->dtmf_wp == 79)
- j->dtmf_wp = 0;
- j->ex.bits.dtmf_ready = 1;
+ if(!j->flags.cidplay) {
+ j->dtmfbuffer[j->dtmf_wp] = j->dtmf_current;
+ j->dtmf_wp++;
+ if (j->dtmf_wp == 79)
+ j->dtmf_wp = 0;
+ j->ex.bits.dtmf_ready = 1;
+ }
+ else if(j->dtmf_current == 25 || j->dtmf_current == 31) {
+ j->flags.cidcw_ack = 1;
+ }
X j->dtmf_state = 0;
X }
X j->dtmf_proc = 0;
@@ -1277,39 +1792,54 @@
X IXJ *j = &ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
X DECLARE_WAITQUEUE(wait, current);
X
+ if (j->flags.inread)
+ return -EALREADY;
+
+ j->flags.inread = 1;
+
X add_wait_queue(&j->read_q, &wait);
- current->state = TASK_INTERRUPTIBLE;
+ set_current_state(TASK_INTERRUPTIBLE);
X mb();
X
X while (!j->read_buffer_ready || (j->dtmf_state && j->flags.dtmf_oob)) {
X ++j->read_wait;
+ if(j->tone_state) {
+ j->flags.inread = 0;
+ return -EAGAIN;
+ }
X if (file_p->f_flags & O_NONBLOCK) {
- current->state = TASK_RUNNING;
+ set_current_state(TASK_RUNNING);
X remove_wait_queue(&j->read_q, &wait);
+ j->flags.inread = 0;
X return -EAGAIN;
X }
X if (!ixj_hookstate(NUM(file_p->f_dentry->d_inode->i_rdev))) {
- current->state = TASK_RUNNING;
+ set_current_state(TASK_RUNNING);
X remove_wait_queue(&j->read_q, &wait);
+ j->flags.inread = 0;
X return 0;
X }
X interruptible_sleep_on(&j->read_q);
X if (signal_pending(current)) {
- current->state = TASK_RUNNING;
+ set_current_state(TASK_RUNNING);
X remove_wait_queue(&j->read_q, &wait);
+ j->flags.inread = 0;
X return -EINTR;
X }
X }
X
X remove_wait_queue(&j->read_q, &wait);
- current->state = TASK_RUNNING;
+ set_current_state(TASK_RUNNING);
X /* Don't ever copy more than the user asks */
X i = copy_to_user(buf, j->read_buffer, min(length, j->read_buffer_size));
X j->read_buffer_ready = 0;
- if (i)
+ if (i) {
+ j->flags.inread = 0;
X return -EFAULT;
- else
+ } else {
+ j->flags.inread = 0;
X return min(length, j->read_buffer_size);
+ }
X }
X
X ssize_t ixj_enhanced_read(struct file * file_p, char *buf, size_t length,
@@ -1337,50 +1867,62 @@
X return read_retval;
X }
X
-ssize_t ixj_write(struct file * file_p, const char *buf, size_t count, loff_t * ppos)
+ssize_t ixj_write(struct file *file_p, const char *buf, size_t count, loff_t * ppos)
X {
X unsigned long i = *ppos;
- int board = NUM(file_p->f_dentry->d_inode->i_rdev);
- IXJ *j = &ixj[board];
+ IXJ *j = file_p->private_data;
X DECLARE_WAITQUEUE(wait, current);
X
- add_wait_queue(&j->read_q, &wait);
- current->state = TASK_INTERRUPTIBLE;
+ if (j->flags.inwrite)
+ return -EALREADY;
+
+ j->flags.inwrite = 1;
+
+ add_wait_queue(&j->write_q, &wait);
+ set_current_state(TASK_INTERRUPTIBLE);
X mb();
X
X
X while (!j->write_buffers_empty) {
X ++j->write_wait;
+ if(j->tone_state) {
+ j->flags.inwrite = 0;
+ return -EAGAIN;
+ }
X if (file_p->f_flags & O_NONBLOCK) {
- current->state = TASK_RUNNING;
- remove_wait_queue(&j->read_q, &wait);
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&j->write_q, &wait);
+ j->flags.inwrite = 0;
X return -EAGAIN;
X }
X if (!ixj_hookstate(NUM(file_p->f_dentry->d_inode->i_rdev))) {
- current->state = TASK_RUNNING;
- remove_wait_queue(&j->read_q, &wait);
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&j->write_q, &wait);
+ j->flags.inwrite = 0;
X return 0;
X }
X interruptible_sleep_on(&j->write_q);
X if (signal_pending(current)) {
- current->state = TASK_RUNNING;
- remove_wait_queue(&j->read_q, &wait);
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&j->write_q, &wait);
+ j->flags.inwrite = 0;
X return -EINTR;
X }
X }
- current->state = TASK_RUNNING;
- remove_wait_queue(&j->read_q, &wait);
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&j->write_q, &wait);
X if (j->write_buffer_wp + count >= j->write_buffer_end)
X j->write_buffer_wp = j->write_buffer;
X i = copy_from_user(j->write_buffer_wp, buf, min(count, j->write_buffer_size));
- if (i)
+ if (i) {
+ j->flags.inwrite = 0;
X return -EFAULT;
-
+ }
+ j->flags.inwrite = 0;
X return min(count, j->write_buffer_size);
X }
X
-ssize_t ixj_enhanced_write(struct file * file_p, const char *buf, size_t count,
- loff_t * ppos)
+ssize_t ixj_enhanced_write(struct file * file_p, const char *buf, size_t count, loff_t * ppos)
X {
X int pre_retval;
X ssize_t write_retval = 0;
@@ -1437,9 +1979,7 @@
X *(j->read_buffer + cnt) = inb_p(j->DSPbase + 0x0E);
X *(j->read_buffer + cnt + 1) = inb_p(j->DSPbase + 0x0F);
X }
-#ifdef PERFMON_STATS
X ++j->framesread;
-#endif
X if (j->intercom != -1) {
X if (IsTxReady(j->intercom)) {
X for (cnt = 0; cnt < j->rec_frame_size * 2; cnt += 2) {
@@ -1456,9 +1996,7 @@
X outb_p(*(j->read_buffer + cnt), ixj[j->intercom].DSPbase + 0x0C);
X outb_p(*(j->read_buffer + cnt + 1), ixj[j->intercom].DSPbase + 0x0D);
X }
-#ifdef PERFMON_STATS
X ++ixj[j->intercom].frameswritten;
-#endif
X }
X } else {
X j->read_buffer_ready = 1;
@@ -1466,12 +2004,472 @@
X

X wake_up_interruptible(&j->poll_q); // Wake any blocked selects

X
- kill_fasync(&j->async_queue, SIGIO, POLL_IN); // Send apps notice of frame
+ ixj_kill_fasync(board, POLL_OUT);
+ }
+ }
+}
+
+static short fsk[][6][20] =
+{
+ {
+ {
+ 0, 17846, 29934, 32364, 24351, 8481, -10126, -25465, -32587, -29196,
+ -16384, 1715, 19260, 30591, 32051, 23170, 6813, -11743, -26509, -32722
+ },
+ {
+ -28377, -14876, 3425, 20621, 31163, 31650, 21925, 5126, -13328, -27481,
+ -32767, -27481, -13328, 5126, 21925, 31650, 31163, 20621, 3425, -14876
+ },
+ {
+ -28377, -32722, -26509, -11743, 6813, 23170, 32051, 30591, 19260, 1715,
+ -16384, -29196, -32587, -25465, -10126, 8481, 24351, 32364, 29934, 17846
+ },
+ {
+ 0, -17846, -29934, -32364, -24351, -8481, 10126, 25465, 32587, 29196,
+ 16384, -1715, -19260, -30591, -32051, -23170, -6813, 11743, 26509, 32722
+ },
+ {
+ 28377, 14876, -3425, -20621, -31163, -31650, -21925, -5126, 13328, 27481,
+ 32767, 27481, 13328, -5126, -21925, -31650, -31163, -20621, -3425, 14876
+ },
+ {
+ 28377, 32722, 26509, 11743, -6813, -23170, -32051, -30591, -19260, -1715,
+ 16384, 29196, 32587, 25465, 10126, -8481, -24351, -32364, -29934, -17846
+ }
+ },
+ {
+ {
+ 0, 10126, 19260, 26509, 31163, 32767, 31163, 26509, 19260, 10126,
+ 0, -10126, -19260, -26509, -31163, -32767, -31163, -26509, -19260, -10126
+ },
+ {
+ -28377, -21925, -13328, -3425, 6813, 16384, 24351, 29934, 32587, 32051,
+ 28377, 21925, 13328, 3425, -6813, -16384, -24351, -29934, -32587, -32051
+ },
+ {
+ -28377, -32051, -32587, -29934, -24351, -16384, -6813, 3425, 13328, 21925,
+ 28377, 32051, 32587, 29934, 24351, 16384, 6813, -3425, -13328, -21925
+ },
+ {
+ 0, -10126, -19260, -26509, -31163, -32767, -31163, -26509, -19260, -10126,
+ 0, 10126, 19260, 26509, 31163, 32767, 31163, 26509, 19260, 10126
+ },
+ {
+ 28377, 21925, 13328, 3425, -6813, -16383, -24351, -29934, -32587, -32051,
+ -28377, -21925, -13328, -3425, 6813, 16383, 24351, 29934, 32587, 32051
+ },
+ {
+ 28377, 32051, 32587, 29934, 24351, 16384, 6813, -3425, -13328, -21925,
+ -28377, -32051, -32587, -29934, -24351, -16384, -6813, 3425, 13328, 21925


+ }
+ }
+};
+
+

+static void ixj_write_cid_bit(int board, int bit)

+{
+ int dly;
+ IXJ_WORD dat;


+ IXJ *j = &ixj[board];
+

+ while (j->fskcnt < 20) {
+ if (!IsTxReady(board)) {
+ dly = 0;
+ while (!IsTxReady(board)) {
+ if (dly++ > 5) {
+ dly = 0;
+ // break;
+ // printk("CID delay\n");
+ }
+ udelay(10);
+ }
+ }
+ dat.word = j->fskdata[j->fskdcnt++] =
+ fsk[bit][j->fskz][j->fskcnt];
+ outb_p(dat.bytes.low, j->DSPbase + 0x0C);
+ outb_p(dat.bytes.high, j->DSPbase + 0x0D);
+ j->fskcnt += 3;
+ }
+ j->fskcnt %= 20;
+
+ if (!bit)
+ j->fskz++;
+ if (j->fskz >= 6)
+ j->fskz = 0;
+
+}
+
+static void ixj_write_cid_byte(int board, char byte)
+{
+ IXJ_CBYTE cb;
+
+// printk("Writing CID data %x - %c\n", byte, byte);
+ cb.cbyte = byte;
+ ixj_write_cid_bit(board, 0);
+ ixj_write_cid_bit(board, cb.cbits.b0 ? 1 : 0);
+ ixj_write_cid_bit(board, cb.cbits.b1 ? 1 : 0);
+ ixj_write_cid_bit(board, cb.cbits.b2 ? 1 : 0);
+ ixj_write_cid_bit(board, cb.cbits.b3 ? 1 : 0);
+ ixj_write_cid_bit(board, cb.cbits.b4 ? 1 : 0);
+ ixj_write_cid_bit(board, cb.cbits.b5 ? 1 : 0);
+ ixj_write_cid_bit(board, cb.cbits.b6 ? 1 : 0);
+ ixj_write_cid_bit(board, cb.cbits.b7 ? 1 : 0);
+ ixj_write_cid_bit(board, 1);
+}
+
+static void ixj_write_cid_seize(int board)
+{
+ int cnt;
+
+ for (cnt = 0; cnt < 150; cnt++) {
+ ixj_write_cid_bit(board, 0);
+ ixj_write_cid_bit(board, 1);
+ }
+ for (cnt = 0; cnt < 180; cnt++) {
+ ixj_write_cid_bit(board, 1);
+ }
+}
+
+static void ixj_write_cidcw_seize(int board)
+{
+ int cnt;
+
+ for (cnt = 0; cnt < 80; cnt++) {
+ ixj_write_cid_bit(board, 1);
+ }
+}
+
+static int ixj_write_cid_string(int board, char *s, int checksum)
+{
+ int cnt;
+
+ for (cnt = 0; cnt < strlen(s); cnt++) {
+ ixj_write_cid_byte(board, s[cnt]);
+ checksum = (checksum + s[cnt]);
+ }
+ return checksum;
+}
X
+static void ixj_pad_fsk(int board, int pad)
+{
+ int cnt, dly;


+ IXJ *j = &ixj[board];
+

+ for (cnt = 0; cnt < pad; cnt++) {
+ if (!IsTxReady(board)) {
+ dly = 0;
+ while (!IsTxReady(board)) {
+ if (dly++ > 5) {
+ dly = 0;
+ }
+ udelay(10);
+ }
+ }
+ outb_p(0x00, j->DSPbase + 0x0C);
+ outb_p(0x00, j->DSPbase + 0x0D);
+ }
+ for (cnt = 0; cnt < 720; cnt++) {
+ if (!IsTxReady(board)) {
+ dly = 0;
+ while (!IsTxReady(board)) {
+ if (dly++ > 5) {
+ dly = 0;
+ }
+ udelay(10);
+ }
X }
+ outb_p(0x00, j->DSPbase + 0x0C);
+ outb_p(0x00, j->DSPbase + 0x0D);
X }
X }
X
+static void ixj_write_cid(int board)


+{
+ IXJ *j = &ixj[board];
+

+ char sdmf1[50];
+ char sdmf2[50];
+ char sdmf3[80];
+ char mdmflen, len1, len2, len3;
+ int pad;
+
+ int checksum = 0;
+
+ if (ixj[board].dsp.low == 0x20)
+ return;
+
+ ixj[board].fskz = ixj[board].fskphase = ixj[board].fskcnt =
+ ixj[board].fskdcnt = 0;
+
+ ixj[board].flags.cidplay = 1;
+
+ strcpy(sdmf1, j->cid_send.month);
+ strcat(sdmf1, j->cid_send.day);
+ strcat(sdmf1, j->cid_send.hour);
+ strcat(sdmf1, j->cid_send.min);
+ strcpy(sdmf2, j->cid_send.number);
+ strcpy(sdmf3, j->cid_send.name);
+
+ len1 = strlen(sdmf1);
+ len2 = strlen(sdmf2);
+ len3 = strlen(sdmf3);
+ mdmflen = len1 + len2 + len3 + 6;
+
+ printk("CID Lengths = %d %d %d %d\n", len1, len2, len3, mdmflen);
+
+ set_base_frame(board, 30);
+ set_play_codec(board, LINEAR16);
+
+ if (ixj[board].port == PORT_POTS)
+ if(!j->r_hook)
+ SLIC_SetState(PLD_SLIC_STATE_OHT, board);
+
+ set_play_volume(board, 0x1B);
+ ixj_play_start(board);
+ ixj_write_cid_seize(board);
+
+ ixj_write_cid_byte(board, 0x80);
+ checksum = 0x80;
+ ixj_write_cid_byte(board, mdmflen);
+ checksum = checksum + mdmflen;
+
+ ixj_write_cid_byte(board, 0x01);
+ checksum = checksum + 0x01;
+ ixj_write_cid_byte(board, len1);
+ checksum = checksum + len1;
+ checksum = ixj_write_cid_string(board, sdmf1, checksum);
+
+ ixj_write_cid_byte(board, 0x02);
+ checksum = checksum + 0x02;
+ ixj_write_cid_byte(board, len2);
+ checksum = checksum + len2;
+ checksum = ixj_write_cid_string(board, sdmf2, checksum);
+
+ ixj_write_cid_byte(board, 0x07);
+ checksum = checksum + 0x07;
+ ixj_write_cid_byte(board, len3);
+ checksum = checksum + len3;
+ checksum = ixj_write_cid_string(board, sdmf3, checksum);
+
+ checksum %= 256;
+ checksum ^= 0xFF;
+ checksum += 1;
+ printk("14Checksum = %d\n", checksum);
+
+ ixj_write_cid_byte(board, (char) checksum);
+
+ pad = j->fskdcnt % 240;
+ if (pad) {
+ pad = 240 - pad;
+ }
+ ixj_pad_fsk(board, pad);
+ SLIC_SetState(PLD_SLIC_STATE_STANDBY, board);
+ ixj[board].flags.cidplay = 0;
+ ixj_play_stop(board);
+}
+
+static void ixj_write_cidcw(int board)
+{
+ IXJ_TONE ti;


+
+ IXJ *j = &ixj[board];
+

+ char sdmf1[50];
+ char sdmf2[50];
+ char sdmf3[80];
+ char mdmflen, len1, len2, len3;
+ int pad;
+
+ int checksum = 0;
+
+ if (ixj[board].dsp.low == 0x20)
+ return;
+
+ ixj[board].fskz = ixj[board].fskphase = ixj[board].fskcnt = ixj[board].fskdcnt = 0;
+
+ ixj[board].flags.cidplay = 1;
+
+ ti.tone_index = 23;
+ ti.gain0 = 1;
+ ti.freq0 = hz440;
+ ti.gain1 = 0;
+ ti.freq1 = 0;
+ ixj_init_tone(board, &ti);
+
+ ti.tone_index = 24;
+ ti.gain0 = 1;
+ ti.freq0 = hz2130;
+ ti.gain1 = 0;
+ ti.freq1 = hz2750;
+ ixj_init_tone(board, &ti);
+
+ ixj_set_tone_on(1200, board);
+ ixj_play_tone(board, 23);
+
+ while(j->tone_state) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(1);
+ }
+
+ ixj_set_tone_on(320, board);
+ ixj_play_tone(board, 24);
+
+ while(j->tone_state) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(1);
+ }
+
+ j->cidcw_wait = jiffies + (200 * hertz / 100000);
+
+ while(!j->flags.cidcw_ack && time_before(jiffies, j->cidcw_wait)) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(1);
+ }
+
+ if(!j->flags.cidcw_ack) {
+ return;
+ }
+
+ strcpy(sdmf1, j->cid_send.month);
+ strcat(sdmf1, j->cid_send.day);
+ strcat(sdmf1, j->cid_send.hour);
+ strcat(sdmf1, j->cid_send.min);
+ strcpy(sdmf2, j->cid_send.number);
+ strcpy(sdmf3, j->cid_send.name);
+
+ len1 = strlen(sdmf1);
+ len2 = strlen(sdmf2);
+ len3 = strlen(sdmf3);
+ mdmflen = len1 + len2 + len3 + 6;
+
+ printk("CID Lengths = %d %d %d %d\n", len1, len2, len3, mdmflen);
+
+ j->cid_play_codec = j->play_codec;
+ ixj_play_stop(board);
+
+ switch(j->baseframe.low) {
+ case 0xA0:
+ j->cid_base_frame_size = 20;


+ break;
+ case 0x50:

+ j->cid_base_frame_size = 10;
+ break;
+ default:
+ j->cid_base_frame_size = 30;
+ break;
+ }
+ set_base_frame(board, 30);
+ set_play_codec(board, LINEAR16);
+
+ set_play_volume(board, 0x1B);
+ ixj_play_start(board);
+ ixj_write_cidcw_seize(board);
+
+ ixj_write_cid_byte(board, 0x80);
+ checksum = 0x80;
+ ixj_write_cid_byte(board, mdmflen);
+ checksum = checksum + mdmflen;
+
+ ixj_write_cid_byte(board, 0x01);
+ checksum = checksum + 0x01;
+ ixj_write_cid_byte(board, len1);
+ checksum = checksum + len1;
+ checksum = ixj_write_cid_string(board, sdmf1, checksum);
+
+ ixj_write_cid_byte(board, 0x02);
+ checksum = checksum + 0x02;
+ ixj_write_cid_byte(board, len2);
+ checksum = checksum + len2;
+ checksum = ixj_write_cid_string(board, sdmf2, checksum);
+
+ ixj_write_cid_byte(board, 0x07);
+ checksum = checksum + 0x07;
+ ixj_write_cid_byte(board, len3);
+ checksum = checksum + len3;
+ checksum = ixj_write_cid_string(board, sdmf3, checksum);
+
+ checksum %= 256;
+ checksum ^= 0xFF;
+ checksum += 1;
+ printk("14Checksum = %d\n", checksum);
+
+ ixj_write_cid_byte(board, (char) checksum);
+
+ pad = j->fskdcnt % 240;
+ if (pad) {
+ pad = 240 - pad;
+ }
+ ixj_pad_fsk(board, pad);
+ ixj[board].flags.cidplay = 0;
+ ixj_play_stop(board);
+
+ set_base_frame(board, j->cid_base_frame_size);
+ set_play_codec(board, j->cid_play_codec);
+}
+
+static void ixj_write_vmwi(int board, int msg)


+{
+ IXJ *j = &ixj[board];
+

+ char mdmflen;
+ int pad;
+
+ int checksum = 0;
+
+ if (ixj[board].dsp.low == 0x20)
+ return;
+
+ ixj[board].fskz = ixj[board].fskphase = ixj[board].fskcnt = ixj[board].fskdcnt = 0;
+
+ ixj[board].flags.cidplay = 1;
+
+ mdmflen = 3;
+
+ set_base_frame(board, 30);
+ set_play_codec(board, LINEAR16);
+
+ if (ixj[board].port == PORT_POTS)
+ SLIC_SetState(PLD_SLIC_STATE_OHT, board);
+
+ set_play_volume(board, 0x1B);
+ ixj_play_start(board);
+ ixj_write_cid_seize(board);
+
+ ixj_write_cid_byte(board, 0x82);
+ checksum = 0x82;
+ ixj_write_cid_byte(board, mdmflen);
+ checksum = checksum + mdmflen;
+
+ ixj_write_cid_byte(board, 0x0B);
+ checksum = checksum + 0x0B;
+ ixj_write_cid_byte(board, 1);
+ checksum = checksum + 1;
+
+ if(msg) {
+ ixj_write_cid_byte(board, 0xFF);
+ checksum = checksum + 0xFF;
+ }
+ else {
+ ixj_write_cid_byte(board, 0x00);
+ checksum = checksum + 0x00;
+ }
+
+ checksum %= 256;
+ checksum ^= 0xFF;
+ checksum += 1;
+
+ ixj_write_cid_byte(board, (char) checksum);
+
+ pad = j->fskdcnt % 240;
+ if (pad) {
+ pad = 240 - pad;
+ }
+ ixj_pad_fsk(board, pad);
+ SLIC_SetState(PLD_SLIC_STATE_STANDBY, board);
+ ixj[board].flags.cidplay = 0;
+ ixj_play_stop(board);
+}
+
X static void ixj_write_frame(int board)
X {
X int cnt, frame_count, dly;
@@ -1547,14 +2545,12 @@
X j->write_buffer_rp = j->write_buffer;
X }
X j->write_buffers_empty++;
- wake_up_interruptible(&(j->write_q)); // Wake any blocked writers
+ wake_up_interruptible(&j->write_q); // Wake any blocked writers
X

X wake_up_interruptible(&j->poll_q); // Wake any blocked selects

X
- kill_fasync(&j->async_queue, SIGIO, POLL_IN); // Send apps notice of empty buffer
-#ifdef PERFMON_STATS
+ ixj_kill_fasync(board, POLL_OUT);
X ++j->frameswritten;
-#endif
X }
X } else {
X j->drybuffer++;
@@ -1787,6 +2783,12 @@
X unsigned short cmd = 0x0000;


X IXJ *j = &ixj[board];
X

+ if (j->read_buffer) {
+ ixj_record_stop(board);
+ }
+ j->flags.recording = 1;
+ ixj_WriteDSPCommand(0x0FE0, board); // Put the DSP in full power mode.
+
X if (!j->rec_mode) {
X switch (j->rec_codec) {
X case G723_63:
@@ -1885,10 +2887,26 @@


X {
X IXJ *j = &ixj[board];
X

+ if (j->read_buffer) {
+ kfree(j->read_buffer);
+ j->read_buffer = NULL;
+ j->read_buffer_size = 0;
+ }
X if (j->rec_mode > -1) {
X ixj_WriteDSPCommand(0x5120, board);
X j->rec_mode = -1;
X }
+ j->flags.recording = 0;
+ if (!j->flags.playing)
+ ixj_WriteDSPCommand(0x0FE3, board); // Put the DSP in 1/5 power mode.
+
+}


+static void ixj_vad(int board, int arg)

+{
+ if (arg)
+ ixj_WriteDSPCommand(0x513F, board);
+ else
+ ixj_WriteDSPCommand(0x513E, board);
X }
X
X static void set_rec_depth(int board, int depth)
@@ -1906,13 +2924,23 @@
X ixj_WriteDSPCommand(volume, board);
X }
X
+static int get_rec_volume(int board)
+{
+ ixj_WriteDSPCommand(0xCF03, board);


+ return ixj[board].ssr.high << 8 | ixj[board].ssr.low;
+}
+

X static int get_rec_level(int board)
X {
+ int retval;
+


X IXJ *j = &ixj[board];
X

X ixj_WriteDSPCommand(0xCF88, board);
X
- return j->ssr.high << 8 | j->ssr.low;
+ retval = j->ssr.high << 8 | j->ssr.low;
+ retval = (retval * 256) / 240;
+ return retval;
X }
X
X static void ixj_aec_start(int board, int level)
@@ -1921,7 +2949,7 @@
X
X j->aec_level = level;
X if (!level) {
- ixj_WriteDSPCommand(0xB002, board);
+ aec_stop(board);
X } else {
X if (j->rec_codec == G729 || j->play_codec == G729) {
X ixj_WriteDSPCommand(0xE022, board); // Move AEC filter buffer
@@ -1933,26 +2961,41 @@
X ixj_WriteDSPCommand(0xE013, board); // Advanced AEC C1
X
X switch (level) {
- case 1:
+ case AEC_LOW:
X ixj_WriteDSPCommand(0x0000, board); // Advanced AEC C2 = off
X
X ixj_WriteDSPCommand(0xE011, board);
X ixj_WriteDSPCommand(0xFFFF, board);
X break;
X
- case 2:
+ case AEC_MED:
X ixj_WriteDSPCommand(0x0600, board); // Advanced AEC C2 = on medium
X
X ixj_WriteDSPCommand(0xE011, board);
X ixj_WriteDSPCommand(0x0080, board);
X break;
X
- case 3:
+ case AEC_HIGH:
X ixj_WriteDSPCommand(0x0C00, board); // Advanced AEC C2 = on high
X
X ixj_WriteDSPCommand(0xE011, board);
X ixj_WriteDSPCommand(0x0080, board);
X break;
+
+ case AEC_AUTO:
+ ixj_WriteDSPCommand(0x0002, board); // Attenuation scaling factor of 2
+
+ ixj_WriteDSPCommand(0xE011, board);
+ ixj_WriteDSPCommand(0x0100, board); // Higher Threshold Floor
+
+ ixj_WriteDSPCommand(0xE012, board); // Set Train and Lock
+
+ ixj_WriteDSPCommand(0x0023, board);
+
+ ixj_WriteDSPCommand(0xE014, board);
+ ixj_WriteDSPCommand(0x0003, board); // Lock threashold at 3dB
+
+ break;
X }


X }
X }
@@ -2140,6 +3183,12 @@

X unsigned short cmd = 0x0000;


X IXJ *j = &ixj[board];
X

+ if (j->write_buffer) {
+ ixj_play_stop(board);
+ }
+ j->flags.playing = 1;
+ ixj_WriteDSPCommand(0x0FE0, board); // Put the DSP in full power mode.
+
X j->flags.play_first_frame = 1;
X j->drybuffer = 0;
X
@@ -2175,12 +3224,10 @@
X if (ixj_WriteDSPCommand(cmd, board))
X return -1;
X }
+ j->write_buffer = kmalloc(j->play_frame_size * 2, GFP_ATOMIC);
X if (!j->write_buffer) {
- j->write_buffer = kmalloc(j->play_frame_size * 2, GFP_ATOMIC);
- if (!j->write_buffer) {
- printk("Write buffer allocation for ixj board %d failed!\n", board);
- return -ENOMEM;
- }
+ printk("Write buffer allocation for ixj board %d failed!\n", board);
+ return -ENOMEM;
X }
X j->write_buffers_empty = 2;
X j->write_buffer_size = j->play_frame_size * 2;
@@ -2242,11 +3289,20 @@


X {
X IXJ *j = &ixj[board];
X

+ if (j->write_buffer) {
+ kfree(j->write_buffer);
+ j->write_buffer = NULL;
+ j->write_buffer_size = 0;
+ }
X if (j->play_mode > -1) {
- ixj_WriteDSPCommand(0x5221, board); // Stop playback
+ ixj_WriteDSPCommand(0x5221, board); // Stop playback and flush buffers. 8022 reference page 9-40
X
X j->play_mode = -1;
X }
+ j->flags.playing = 0;
+ if (!j->flags.recording)
+ ixj_WriteDSPCommand(0x0FE3, board); // Put the DSP in 1/5 power mode.
+
X }
X
X extern __inline__ void set_play_depth(int board, int depth)
@@ -2258,16 +3314,15 @@
X ixj_WriteDSPCommand(0x5280 + depth, board);
X }
X
-extern __inline__ void set_play_volume(int board, int volume)
-{
- ixj_WriteDSPCommand(0xCF02, board);
- ixj_WriteDSPCommand(volume, board);
-}
-
X extern __inline__ int get_play_level(int board)
X {
- ixj_WriteDSPCommand(0xCF8F, board);
+ int retval;
+
+ ixj_WriteDSPCommand(0xCF8F, board); // 8022 Reference page 9-38
X return ixj[board].ssr.high << 8 | ixj[board].ssr.low;
+ retval = ixj[board].ssr.high << 8 | ixj[board].ssr.low;
+ retval = (retval * 256) / 240;
+ return retval;
X }
X
X static unsigned int ixj_poll(struct file *file_p, poll_table * wait)
@@ -2476,6 +3531,8 @@
X break;
X }
X
+ j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = reg;
+
X switch (j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGX) {
X case 0:
X j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 0;
@@ -2645,7 +3702,7 @@
X }
X pIn += 5, pOut += 4;
X }
- memset(&j->cid, 0, sizeof(IXJ_CID));
+ memset(&j->cid, 0, sizeof(PHONE_CID));
X pOut = j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID;
X pOut += 4;
X strncpy(j->cid.month, pOut, 2);
@@ -2721,7 +3778,6 @@
X // ALIS-A part.
X //
X
-
X BYTES bytes;


X IXJ *j = &ixj[board];
X

@@ -2730,6 +3786,19 @@
X
X switch (mode) {
X case SOP_PU_SLEEP:
+ if(j->daa_mode == SOP_PU_CONVERSATION)
+ {
+ j->pld_scrw.bits.daafsyncen = 0; // Turn off DAA Frame Sync
+
+ outb_p(j->pld_scrw.byte, j->XILINXbase);
+ j->pld_slicw.bits.rly2 = 0;


+ outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);

+ bytes.high = 0x10;
+ bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
+ daa_load(&bytes, board);
+ if (!SCI_Prepare(board))
+ return 0;
+ }
X j->pld_scrw.bits.daafsyncen = 0; // Turn off DAA Frame Sync
X
X outb_p(j->pld_scrw.byte, j->XILINXbase);
@@ -2740,10 +3809,15 @@
X daa_load(&bytes, board);
X if (!SCI_Prepare(board))
X return 0;
+
X j->daa_mode = SOP_PU_SLEEP;
X j->flags.pstn_ringing = 0;
- j->pstn_sleeptil = jiffies + (hertz * 3);
- break;
+ j->ex.bits.pstn_ring = 0;
+ j->pstn_sleeptil = jiffies + (hertz / 2);
+ wake_up_interruptible(&j->read_q); // Wake any blocked readers
+ wake_up_interruptible(&j->write_q); // Wake any blocked writers
+ wake_up_interruptible(&j->poll_q); // Wake any blocked selects
+ break;
X case SOP_PU_RINGING:
X j->pld_scrw.bits.daafsyncen = 0; // Turn off DAA Frame Sync
X
@@ -3281,14 +4355,11 @@
X int ixj_set_tone_off(unsigned short arg, int board)
X {
X ixj[board].tone_off_time = arg;
-
X if (ixj_WriteDSPCommand(0x6E05, board)) // Set Tone Off Period
X
X return -1;
-
X if (ixj_WriteDSPCommand(arg, board))
X return -1;
-


X return 0;
X }
X

@@ -3297,7 +4368,6 @@
X if (ixj_WriteDSPCommand(0x6E06, board)) // Get Tone On Period
X
X return -1;
-


X return 0;
X }
X

@@ -3306,7 +4376,6 @@
X if (ixj_WriteDSPCommand(0x6E07, board)) // Get Tone Off Period
X
X return -1;
-


X return 0;
X }
X

@@ -3315,7 +4384,6 @@
X ixj[board].flags.ringback = 0;
X ixj[board].flags.dialtone = 0;
X ixj[board].flags.busytone = 1;
-
X ixj_set_tone_on(0x07D0, board);
X ixj_set_tone_off(0x07D0, board);
X ixj_play_tone(board, 27);
@@ -3326,13 +4394,11 @@
X ixj[board].flags.ringback = 0;
X ixj[board].flags.dialtone = 1;
X ixj[board].flags.busytone = 0;
-
X if (ixj[board].dsp.low == 0x20) {
X return;
X } else {
X ixj_set_tone_on(0xFFFF, board);
X ixj_set_tone_off(0x0000, board);
-
X ixj_play_tone(board, 25);
X }
X }
@@ -3340,28 +4406,24 @@
X static void ixj_cpt_stop(board)


X {
X IXJ *j = &ixj[board];

-
- j->flags.dialtone = 0;
- j->flags.busytone = 0;
- j->flags.ringback = 0;
-
- ixj_set_tone_on(0x0001, board);
- ixj_set_tone_off(0x0000, board);
-
- ixj_play_tone(board, 0);
-
- j->tone_state = 0;
-
- ixj_del_timer();
- if (j->cadence_t) {
- if (j->cadence_t->ce) {
- kfree(j->cadence_t->ce);
+ if(j->tone_state)
+ {
+ j->flags.dialtone = 0;
+ j->flags.busytone = 0;
+ j->flags.ringback = 0;
+ ixj_set_tone_on(0x0001, board);
+ ixj_set_tone_off(0x0000, board);
+ ixj_play_tone(board, 0);
+ j->tone_state = 0;
+ if (j->cadence_t) {
+ if (j->cadence_t->ce) {
+ kfree(j->cadence_t->ce);
+ }
+ kfree(j->cadence_t);
+ j->cadence_t = NULL;
X }
- kfree(j->cadence_t);
- j->cadence_t = NULL;
X }
- ixj_add_timer();
- if (j->dsp.low == 0x20 || (j->play_mode == -1 && j->rec_mode == -1))
+ if (j->play_mode == -1 && j->rec_mode == -1)
X idle(board);
X if (j->play_mode != -1)
X ixj_play_start(board);
@@ -3374,7 +4436,6 @@
X ixj[board].flags.busytone = 0;
X ixj[board].flags.dialtone = 0;
X ixj[board].flags.ringback = 1;
-
X ixj_set_tone_on(0x0FA0, board);
X ixj_set_tone_off(0x2EE0, board);
X ixj_play_tone(board, 26);
@@ -3391,28 +4452,29 @@
X IXJ_CADENCE_ELEMENT *lcep;
X IXJ_TONE ti;


X IXJ *j = &ixj[board];

-
X lcp = kmalloc(sizeof(IXJ_CADENCE), GFP_KERNEL);
X if (lcp == NULL)
X return -ENOMEM;
-
X if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_CADENCE)))
+ {
+ kfree(lcp);
X return -EFAULT;
-
+ }
X lcep = kmalloc(sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used, GFP_KERNEL);
X if (lcep == NULL) {
X kfree(lcp);
X return -ENOMEM;
X }
X if (copy_from_user(lcep, lcp->ce, sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used))
- return -EFAULT;
-
- if(j->cadence_t)
X {
+ kfree(lcep);
+ kfree(lcp);
+ return -EFAULT;
+ }
+ if (j->cadence_t) {
X kfree(j->cadence_t->ce);
X kfree(j->cadence_t);
X }
-
X lcp->ce = (void *) lcep;
X j->cadence_t = lcp;
X j->tone_cadence_state = 0;
@@ -3427,16 +4489,50 @@
X ixj_init_tone(board, &ti);
X }
X ixj_play_tone(board, lcp->ce[0].index);
-


X return 1;
X }
X

+static int ixj_build_filter_cadence(int board, IXJ_FILTER_CADENCE * cp)

+{
+ IXJ_FILTER_CADENCE *lcp;


+ IXJ *j = &ixj[board];

+ lcp = kmalloc(sizeof(IXJ_CADENCE), GFP_KERNEL);
+ if (lcp == NULL)
+ return -ENOMEM;
+ if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_FILTER_CADENCE)))
+ return -EFAULT;
+ if (lcp->filter > 4)
+ return -1;
+ j->cadence_f[lcp->filter].state = 0;
+ j->cadence_f[lcp->filter].enable = lcp->enable;
+ j->filter_en[lcp->filter] = j->cadence_f[lcp->filter].en_filter = lcp->en_filter;
+ j->cadence_f[lcp->filter].on1 = lcp->on1;
+ j->cadence_f[lcp->filter].on1min = 0;
+ j->cadence_f[lcp->filter].on1max = 0;
+ j->cadence_f[lcp->filter].off1 = lcp->off1;
+ j->cadence_f[lcp->filter].off1min = 0;
+ j->cadence_f[lcp->filter].off1max = 0;
+ j->cadence_f[lcp->filter].on2 = lcp->on2;
+ j->cadence_f[lcp->filter].on2min = 0;
+ j->cadence_f[lcp->filter].on2max = 0;
+ j->cadence_f[lcp->filter].off2 = lcp->off2;
+ j->cadence_f[lcp->filter].off2min = 0;
+ j->cadence_f[lcp->filter].off2max = 0;
+ j->cadence_f[lcp->filter].on3 = lcp->on3;
+ j->cadence_f[lcp->filter].on3min = 0;
+ j->cadence_f[lcp->filter].on3max = 0;
+ j->cadence_f[lcp->filter].off3 = lcp->off3;
+ j->cadence_f[lcp->filter].off3min = 0;
+ j->cadence_f[lcp->filter].off3max = 0;
+ kfree(lcp);


+ return 0;
+}
+

X static void add_caps(int board)


X {
X IXJ *j = &ixj[board];

X j->caps = 0;
-
- j->caplist[j->caps].cap = vendor;
+ j->caplist[j->caps].cap = PHONE_VENDOR_QUICKNET;
X strcpy(j->caplist[j->caps].desc, "Quicknet Technologies, Inc. (www.quicknet.net)");
X j->caplist[j->caps].captype = vendor;
X j->caplist[j->caps].handle = j->caps++;
@@ -3532,10 +4628,9 @@
X int cnt;


X IXJ *j = &ixj[board];

X int retval = 0;
-
X for (cnt = 0; cnt < j->caps; cnt++) {
- if (pcreq->captype == j->caplist[cnt].captype &&
- pcreq->cap == j->caplist[cnt].cap) {
+ if (pcreq->captype == j->caplist[cnt].captype
+ && pcreq->cap == j->caplist[cnt].cap) {
X retval = 1;
X break;
X }
@@ -3543,8 +4638,7 @@
X return retval;
X }
X
-int ixj_ioctl(struct inode *inode, struct file *file_p,
- unsigned int cmd, unsigned long arg)
+int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, unsigned long arg)
X {
X IXJ_TONE ti;
X IXJ_FILTER jf;
@@ -3552,16 +4646,13 @@
X int board = NUM(inode->i_rdev);
X IXJ *j = &ixj[NUM(inode->i_rdev)];
X int retval = 0;
-
X if (ixjdebug > 1)
X printk(KERN_DEBUG "phone%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg);
X if (minor >= IXJMAX)
X return -ENODEV;
-
X /*
X * Check ioctls only root can use.
X */
-
X if (!capable(CAP_SYS_ADMIN)) {
X switch (cmd) {
X case IXJCTL_TESTRAM:
@@ -3580,10 +4671,33 @@
X case IXJCTL_SERIAL:
X retval = j->serial;
X break;
+ case IXJCTL_VERSION:
+ if (copy_to_user((char *) arg, ixj_c_revision, strlen(ixj_c_revision)))
+ return -EFAULT;
+ break;
X case PHONE_RING_CADENCE:
X j->ring_cadence = arg;
X break;
+ case IXJCTL_CIDCW:
+ if(arg) {
+ copy_from_user(&j->cid_send, (char *)arg, sizeof(PHONE_CID));
+ }
+ else {
+ memset(&j->cid_send, 0, sizeof(PHONE_CID));
+ }
+ ixj_write_cidcw(board);
+ break;
+ /* Binary compatbility */
+ case OLD_PHONE_RING_START:
+ arg = 0;
+ /* Fall through */
X case PHONE_RING_START:
+ if(arg) {
+ copy_from_user(&j->cid_send, (char *)arg, sizeof(PHONE_CID));
+ }
+ else {
+ memset(&j->cid_send, 0, sizeof(PHONE_CID));
+ }
X ixj_ring_start(board);
X break;
X case PHONE_RING_STOP:
@@ -3595,7 +4709,19 @@
X break;
X case PHONE_EXCEPTION:
X retval = j->ex.bytes;
- j->ex.bytes &= 0x03;
+ j->ex.bits.flash = 0;
+ j->ex.bits.pstn_ring = 0;
+ j->ex.bits.caller_id = 0;
+ j->ex.bits.pstn_wink = 0;
+ j->ex.bits.f0 = 0;
+ j->ex.bits.f1 = 0;
+ j->ex.bits.f2 = 0;
+ j->ex.bits.f3 = 0;
+ j->ex.bits.fc0 = 0;
+ j->ex.bits.fc1 = 0;
+ j->ex.bits.fc2 = 0;
+ j->ex.bits.fc3 = 0;
+ j->ex.bits.reserved = 0;
X break;
X case PHONE_HOOKSTATE:
X j->ex.bits.hookstate = 0;
@@ -3610,6 +4736,9 @@
X case PHONE_REC_CODEC:
X retval = set_rec_codec(board, arg);
X break;
+ case PHONE_VAD:
+ ixj_vad(board, arg);
+ break;
X case PHONE_REC_START:
X ixj_record_start(board);
X break;
@@ -3620,7 +4749,13 @@
X set_rec_depth(board, arg);
X break;
X case PHONE_REC_VOLUME:
- set_rec_volume(board, arg);
+ if(arg == -1) {
+ retval = get_rec_volume(board);
+ }
+ else {
+ set_rec_volume(board, arg);
+ retval = arg;
+ }
X break;
X case PHONE_REC_LEVEL:
X retval = get_rec_level(board);
@@ -3638,7 +4773,7 @@
X retval = set_play_codec(board, arg);
X break;
X case PHONE_PLAY_START:
- ixj_play_start(board);
+ retval = ixj_play_start(board);
X break;
X case PHONE_PLAY_STOP:
X ixj_play_stop(board);
@@ -3647,7 +4782,13 @@
X set_play_depth(board, arg);
X break;
X case PHONE_PLAY_VOLUME:
- set_play_volume(board, arg);
+ if(arg == -1) {
+ retval = get_play_volume(board);
+ }
+ else {
+ set_play_volume(board, arg);
+ retval = arg;
+ }
X break;
X case PHONE_PLAY_LEVEL:
X retval = get_play_level(board);
@@ -3828,41 +4969,45 @@
X switch (arg) {
X case DAA_US:
X DAA_Coeff_US(board);
- ixj_daa_write(board);
+ retval = ixj_daa_write(board);
X break;
X case DAA_UK:
X DAA_Coeff_UK(board);
- ixj_daa_write(board);
+ retval = ixj_daa_write(board);
X break;
X case DAA_FRANCE:
X DAA_Coeff_France(board);
- ixj_daa_write(board);
+ retval = ixj_daa_write(board);
X break;
X case DAA_GERMANY:
X DAA_Coeff_Germany(board);
- ixj_daa_write(board);
+ retval = ixj_daa_write(board);
X break;
X case DAA_AUSTRALIA:
X DAA_Coeff_Australia(board);
- ixj_daa_write(board);
+ retval = ixj_daa_write(board);
X break;
X case DAA_JAPAN:
X DAA_Coeff_Japan(board);
- ixj_daa_write(board);
+ retval = ixj_daa_write(board);
X break;
X default:
+ retval = 1;
X break;
X }
+ j->country = arg;
X break;
X case IXJCTL_DAA_AGAIN:
X ixj_daa_cr4(board, arg | 0x02);
X break;
X case IXJCTL_PSTN_LINETEST:
- case PHONE_PSTN_LINETEST:
X retval = ixj_linetest(board);
X break;
+ case IXJCTL_VMWI:
+ ixj_write_vmwi(board, arg);
+ break;
X case IXJCTL_CID:
- if (copy_to_user((char *) arg, &j->cid, sizeof(IXJ_CID)))
+ if (copy_to_user((char *) arg, &j->cid, sizeof(PHONE_CID)))
X return -EFAULT;


X j->ex.bits.caller_id = 0;

X break;
@@ -3883,7 +5028,7 @@
X break;
X case PHONE_CAPABILITIES_LIST:
X if (copy_to_user((char *) arg, j->caplist, sizeof(struct phone_capability) * j->caps))
- return -EFAULT;
+ return -EFAULT;
X break;
X case PHONE_CAPABILITIES_CHECK:
X retval = capabilities_check(board, (struct phone_capability *) arg);
@@ -3896,7 +5041,7 @@


X j->ex.bits.pstn_ring = 0;

X break;
X case IXJCTL_SET_FILTER:
- if (copy_from_user(&jf, (char *) arg, sizeof(ti)))
+ if (copy_from_user(&jf, (char *) arg, sizeof(jf)))
X return -EFAULT;
X retval = ixj_init_filter(board, &jf);
X break;
@@ -3910,6 +5055,9 @@
X case IXJCTL_TONE_CADENCE:
X retval = ixj_build_cadence(board, (IXJ_CADENCE *) arg);
X break;
+ case IXJCTL_FILTER_CADENCE:
+ retval = ixj_build_filter_cadence(board, (IXJ_FILTER_CADENCE *) arg);
+ break;
X case IXJCTL_INTERCOM_STOP:
X ixj[board].intercom = -1;
X ixj[arg].intercom = -1;
@@ -3948,7 +5096,7 @@
X poll: ixj_poll,
X ioctl: ixj_ioctl,
X release: ixj_release,
- fasync: ixj_fasync,
+ fasync: ixj_fasync
X };
X

X static int ixj_linetest(int board)

@@ -3956,8 +5104,9 @@
X unsigned long jifwait;


X IXJ *j = &ixj[board];
X

+ j->flags.incheck = 1; // Testing
X if (!j->flags.pots_correct) {
- j->flags.pots_correct = 1; // Testing
+ j->flags.pots_correct = 1;
X
X daa_int_read(board); //Clear DAA Interrupt flags
X //
@@ -3988,7 +5137,7 @@
X daa_set_mode(board, SOP_PU_CONVERSATION);
X jifwait = jiffies + hertz;
X while (time_before(jiffies, jifwait)) {
- current->state = TASK_INTERRUPTIBLE;
+ set_current_state(TASK_INTERRUPTIBLE);
X schedule_timeout(1);
X }
X daa_int_read(board);
@@ -4009,23 +5158,23 @@
X }
X }
X }
- if (!j->flags.pstn_present) {
- j->pld_slicw.bits.rly3 = 0;


- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);

- daa_set_mode(board, SOP_PU_CONVERSATION);
- jifwait = jiffies + hertz;
- while (time_before(jiffies, jifwait)) {
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(1);
- }
- daa_int_read(board);
- daa_set_mode(board, SOP_PU_SLEEP);
- if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
- j->flags.pstn_present = 1;
- } else {
- j->flags.pstn_present = 0;
- }
+// if (!j->flags.pstn_present) {
+ j->pld_slicw.bits.rly3 = 0;


+ outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);

+ daa_set_mode(board, SOP_PU_CONVERSATION);
+ jifwait = jiffies + hertz;
+ while (time_before(jiffies, jifwait)) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(1);
+ }
+ daa_int_read(board);
+ daa_set_mode(board, SOP_PU_SLEEP);
+ if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
+ j->flags.pstn_present = 1;
+ } else {
+ j->flags.pstn_present = 0;
X }
+// }
X if (j->flags.pstn_present) {
X if (j->flags.pots_correct) {
X LED_SetState(0xA, board);
@@ -4039,6 +5188,7 @@
X LED_SetState(0x5, board);
X }
X }
+ j->flags.incheck = 0; // Testing
X return j->flags.pstn_present;
X }
X
@@ -4046,59 +5196,44 @@
X {
X unsigned short cmd;
X unsigned long jif;
+ int cnt;
X BYTES bytes;


X IXJ *j = &ixj[board];
X

- /*
- * First initialise the queues
- */
-
+ init_waitqueue_head(&j->poll_q);
X init_waitqueue_head(&j->read_q);
X init_waitqueue_head(&j->write_q);
- init_waitqueue_head(&j->poll_q);
-
- /*
- * Now we can probe
- */
-
X if (ixjdebug > 0)
X printk(KERN_INFO "Write IDLE to Software Control Register\n");
+ ixj_WriteDSPCommand(0x0FE0, board); // Put the DSP in full power mode.
X
X if (ixj_WriteDSPCommand(0x0000, board)) /* Write IDLE to Software Control Register */
X return -1;
-
X // The read values of the SSR should be 0x00 for the IDLE command
X if (j->ssr.low || j->ssr.high)
X return -1;
-
X if (ixjdebug > 0)
X printk(KERN_INFO "Get Device ID Code\n");
-
X if (ixj_WriteDSPCommand(0x3400, board)) /* Get Device ID Code */
X return -1;
-
X j->dsp.low = j->ssr.low;
X j->dsp.high = j->ssr.high;
-
X if (ixjdebug > 0)
X printk(KERN_INFO "Get Device Version Code\n");
-
X if (ixj_WriteDSPCommand(0x3800, board)) /* Get Device Version Code */
X return -1;
-
X j->ver.low = j->ssr.low;
X j->ver.high = j->ssr.high;
-
X if (!j->cardtype) {
X if (j->dsp.low == 0x21) {
- j->XILINXbase = j->DSPbase + 0x10;
+// j->XILINXbase = j->DSPbase + 0x10;
X bytes.high = bytes.low = inb_p(j->XILINXbase + 0x02);
X outb_p(bytes.low ^ 0xFF, j->XILINXbase + 0x02);
- // Test for Internet LineJACK or Internet PhoneJACK Lite
+// Test for Internet LineJACK or Internet PhoneJACK Lite
X bytes.low = inb_p(j->XILINXbase + 0x02);
X if (bytes.low == bytes.high) // Register is read only on
- // Internet PhoneJack Lite
- {
+ // Internet PhoneJack Lite
+ {
X j->cardtype = 400; // Internet PhoneJACK Lite
X
X if (check_region(j->XILINXbase, 4)) {
@@ -4158,18 +5293,18 @@
X j->pld_slicw.pcib.e1 = 1;
X outb_p(j->pld_slicw.byte, j->XILINXbase);
X break;
+ case 600: //Internet PhoneCARD
+
+ break;
X }
X }
X if (j->dsp.low == 0x20 || j->cardtype == 400 || j->cardtype == 500) {
X if (ixjdebug > 0)
X printk(KERN_INFO "Write CODEC config to Software Control Register\n");
-
X if (ixj_WriteDSPCommand(0xC462, board)) /* Write CODEC config to Software Control Register */
X return -1;
-
X if (ixjdebug > 0)
X printk(KERN_INFO "Write CODEC timing to Software Control Register\n");
-
X if (j->cardtype == 100) {
X cmd = 0x9FF2;
X } else {
@@ -4180,17 +5315,17 @@
X } else {
X if (set_base_frame(board, 30) != 30)
X return -1;
-
+ if (ixjdebug > 0)
+ printk(KERN_INFO "Write CODEC config to Software Control Register\n");


+ if (j->cardtype == 600) {

+ if (ixj_WriteDSPCommand(0xC528, board)) /* Write CODEC config to Software Control Register */
+ return -1;
+ }
X if (j->cardtype == 300) {
- if (ixjdebug > 0)
- printk(KERN_INFO "Write CODEC config to Software Control Register\n");
-
X if (ixj_WriteDSPCommand(0xC528, board)) /* Write CODEC config to Software Control Register */
X return -1;
-
X if (ixjdebug > 0)
X printk(KERN_INFO "Turn on the PLD Clock at 8Khz\n");
-
X j->pld_clock.byte = 0;
X outb_p(j->pld_clock.byte, j->XILINXbase + 0x04);
X }
@@ -4199,9 +5334,8 @@


X if (j->dsp.low == 0x20) {

X if (ixjdebug > 0)
X printk(KERN_INFO "Configure GPIO pins\n");
-
X j->gpio.bytes.high = 0x09;
- /* bytes.low = 0xEF; 0xF7 */
+/* bytes.low = 0xEF; 0xF7 */
X j->gpio.bits.gpio1 = 1;


X j->gpio.bits.gpio2 = 1;

X j->gpio.bits.gpio3 = 0;
@@ -4210,10 +5344,8 @@
X j->gpio.bits.gpio6 = 1;
X j->gpio.bits.gpio7 = 1;
X ixj_WriteDSPCommand(ixj[board].gpio.word, board); /* Set GPIO pin directions */
-
X if (ixjdebug > 0)
X printk(KERN_INFO "Enable SLIC\n");
-


X j->gpio.bytes.high = 0x0B;

X j->gpio.bytes.low = 0x00;
X j->gpio.bits.gpio1 = 0;
@@ -4226,45 +5358,38 @@
X LED_SetState(0x1, board);
X jif = jiffies + (hertz / 10);
X while (time_before(jiffies, jif)) {
- current->state = TASK_INTERRUPTIBLE;
+ set_current_state(TASK_INTERRUPTIBLE);
X schedule_timeout(1);
X }
X LED_SetState(0x2, board);
X jif = jiffies + (hertz / 10);
X while (time_before(jiffies, jif)) {
- current->state = TASK_INTERRUPTIBLE;
+ set_current_state(TASK_INTERRUPTIBLE);
X schedule_timeout(1);
X }
X LED_SetState(0x4, board);
X jif = jiffies + (hertz / 10);
X while (time_before(jiffies, jif)) {
- current->state = TASK_INTERRUPTIBLE;
+ set_current_state(TASK_INTERRUPTIBLE);
X schedule_timeout(1);
X }
X LED_SetState(0x8, board);
X jif = jiffies + (hertz / 10);
X while (time_before(jiffies, jif)) {
- current->state = TASK_INTERRUPTIBLE;
+ set_current_state(TASK_INTERRUPTIBLE);
X schedule_timeout(1);
X }
X LED_SetState(0x0, board);
-
X daa_get_version(board);
-
X if (ixjdebug > 0)
X printk("Loading DAA Coefficients\n");
-
X DAA_Coeff_US(board);
X if (!ixj_daa_write(board))
X printk("DAA write failed on board %d\n", board);
-
X ixj_daa_cid_reset(board);
-
X j->flags.pots_correct = 0;
X j->flags.pstn_present = 0;
-
X ixj_linetest(board);
-
X if (j->flags.pots_correct) {
X j->pld_scrw.bits.daafsyncen = 0; // Turn off DAA Frame Sync
X
@@ -4275,9 +5400,10 @@
X SLIC_SetState(PLD_SLIC_STATE_STANDBY, board);


X j->port = PORT_POTS;
X }

+ ixj_set_port(board, PORT_PSTN);
+ ixj_set_pots(board, 1);
X if (ixjdebug > 0)
X printk(KERN_INFO "Enable Mixer\n");
-
X ixj_mixer(0x0000, board); //Master Volume Left unmute 0db
X
X ixj_mixer(0x0100, board); //Master Volume Right unmute 0db
@@ -4301,43 +5427,43 @@
X ixj_mixer(0x1800, board); //ADC Source select
X
X } else {
- j->port = PORT_POTS;
- SLIC_SetState(PLD_SLIC_STATE_STANDBY, board);


+ if (j->cardtype == 600) {

+ ixj_WriteDSPCommand(0xCF07, board);
+ ixj_WriteDSPCommand(0x00B0, board);
+ ixj_set_port(board, PORT_SPEAKER);
+ } else {
+ ixj_set_port(board, PORT_POTS);
+ SLIC_SetState(PLD_SLIC_STATE_STANDBY, board);
+ }
X }
X }
X
X j->intercom = -1;
X j->framesread = j->frameswritten = 0;
+ j->read_wait = j->write_wait = 0;
X j->rxreadycheck = j->txreadycheck = 0;
-
+ set_play_volume(board, 0x100);
+ set_rec_volume(board, 0x100);
X if (ixj_WriteDSPCommand(0x0000, board)) /* Write IDLE to Software Control Register */
X return -1;
-
- // The read values of the SSR should be 0x00 for the IDLE command
+// The read values of the SSR should be 0x00 for the IDLE command
X if (j->ssr.low || j->ssr.high)
X return -1;
-
X if (ixjdebug > 0)
X printk(KERN_INFO "Enable Line Monitor\n");
-
X if (ixjdebug > 0)
X printk(KERN_INFO "Set Line Monitor to Asyncronous Mode\n");
-
X if (ixj_WriteDSPCommand(0x7E01, board)) // Asynchronous Line Monitor
X
X return -1;
-
X if (ixjdebug > 0)
X printk(KERN_INFO "Enable DTMF Detectors\n");
-
X if (ixj_WriteDSPCommand(0x5151, board)) // Enable DTMF detection
X
X return -1;
-
X if (ixj_WriteDSPCommand(0x6E01, board)) // Set Asyncronous Tone Generation
X
X return -1;
-
X set_rec_depth(board, 2); // Set Record Channel Limit to 2 frames
X
X set_play_depth(board, 2); // Set Playback Channel Limit to 2 frames
@@ -4345,7 +5471,6 @@
X j->ex.bits.dtmf_ready = 0;
X j->dtmf_state = 0;
X j->dtmf_wp = ixj[board].dtmf_rp = 0;


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 089'
echo 'File patch-2.4.0-test9 is continued in part 090'
echo "090" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part090

#!/bin/sh -x
# this is part 090 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 090; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

-
X j->rec_mode = ixj[board].play_mode = -1;


X j->flags.ringing = 0;

X j->maxrings = MAXRINGS;
@@ -4353,25 +5478,600 @@


X j->drybuffer = 0;

X j->winktime = 320;
X j->flags.dtmf_oob = 0;
-
+ for (cnt = 0; cnt < 4; cnt++)


+ j->cadence_f[cnt].enable = 0;

X /* must be a device on the specified address */


+ ixj_WriteDSPCommand(0x0FE3, board); // Put the DSP in 1/5 power mode.

X /* Register with the Telephony for Linux subsystem */
X j->p.f_op = &ixj_fops;
X j->p.open = ixj_open;
+ j->p.board = board;
X phone_register_device(&j->p, PHONE_UNIT_ANY);
-
X add_caps(board);


+ return 0;
+}
+

+int ixj_get_status_proc(char *buf)
+{
+ int len;
+ int cnt;
+ IXJ *j;
+ len = 0;
+ len += sprintf(buf + len, "\n%s", ixj_c_rcsid);
+ len += sprintf(buf + len, "\n%s", ixj_h_rcsid);
+ len += sprintf(buf + len, "\n%s", ixjuser_h_rcsid);
+ for (cnt = 0; cnt < IXJMAX; cnt++) {
+ j = &ixj[cnt];
+ if (j->DSPbase) {
+ len += sprintf(buf + len, "\nCard Num %d", cnt);
+ len += sprintf(buf + len, "\nDSP Base Address 0x%4.4x", j->DSPbase);
+ if (j->cardtype != 100)
+ len += sprintf(buf + len, "\nXILINX Base Address 0x%4.4x", j->XILINXbase);
+ len += sprintf(buf + len, "\nDSP Type %2.2x%2.2x", j->dsp.high, j->dsp.low);
+ len += sprintf(buf + len, "\nDSP Version %2.2x.%2.2x", j->ver.high, j->ver.low);
+ len += sprintf(buf + len, "\nSerial Number %8.8x", j->serial);
+ switch (j->cardtype) {
+ case (100):
+ len += sprintf(buf + len, "\nCard Type = Internet PhoneJACK");
+ break;
+ case (300):
+ len += sprintf(buf + len, "\nCard Type = Internet LineJACK");
+ if (j->flags.g729_loaded)
+ len += sprintf(buf + len, " w/G.729 A/B");
+ len += sprintf(buf + len, " Country = %d", j->country);
+ break;
+ case (400):
+ len += sprintf(buf + len, "\nCard Type = Internet PhoneJACK Lite");
+ if (j->flags.g729_loaded)
+ len += sprintf(buf + len, " w/G.729 A/B");
+ break;
+ case (500):
+ len += sprintf(buf + len, "\nCard Type = Internet PhoneJACK PCI");
+ if (j->flags.g729_loaded)
+ len += sprintf(buf + len, " w/G.729 A/B");
+ break;
+ case (600):
+ len += sprintf(buf + len, "\nCard Type = Internet PhoneCARD");
+ if (j->flags.g729_loaded)
+ len += sprintf(buf + len, " w/G.729 A/B");
+ len += sprintf(buf + len, "\nSmart Cable %spresent", j->pccr1.bits.drf ? "not " : "");
+ if (!j->pccr1.bits.drf)
+ len += sprintf(buf + len, "\nSmart Cable type %d", j->flags.pcmciasct);
+ len += sprintf(buf + len, "\nSmart Cable state %d", j->flags.pcmciastate);
+ break;
+ default:
+ len += sprintf(buf + len, "\nCard Type = %d", j->cardtype);
+ break;
+ }
+ len += sprintf(buf + len, "\nReaders %d", j->readers);
+ len += sprintf(buf + len, "\nWriters %d", j->writers);
+ len += sprintf(buf + len, "\nFSK words %d", ixj[2].fskdcnt);
+ len += sprintf(buf + len, "\nCapabilities %d", j->caps);
+ if (j->dsp.low != 0x20)
+ len += sprintf(buf + len, "\nDSP Processor load %d", j->proc_load);
+ if (j->flags.cidsent)
+ len += sprintf(buf + len, "\nCaller ID data sent");
+ else
+ len += sprintf(buf + len, "\nCaller ID data not sent");
+
+ len += sprintf(buf + len, "\nCaller ID Date %s%s", j->cid_send.month, j->cid_send.day);
+ len += sprintf(buf + len, "\nCaller ID Time %s%s", j->cid_send.hour, j->cid_send.min);
+ len += sprintf(buf + len, "\nCaller ID Name %s", j->cid_send.name);
+ len += sprintf(buf + len, "\nCaller ID Number %s", j->cid_send.number);
+
+ len += sprintf(buf + len, "\nPlay CODEC ");
+ switch (j->play_codec) {
+ case G723_63:
+ len += sprintf(buf + len, "G.723.1 6.3");
+ break;
+ case G723_53:
+ len += sprintf(buf + len, "G.723.1 5.3");
+ break;
+ case TS85:
+ len += sprintf(buf + len, "TrueSpeech 8.5");
+ break;
+ case TS48:
+ len += sprintf(buf + len, "TrueSpeech 4.8");
+ break;
+ case TS41:
+ len += sprintf(buf + len, "TrueSpeech 4.1");
+ break;
+ case G728:
+ len += sprintf(buf + len, "G.728");
+ break;
+ case G729:
+ len += sprintf(buf + len, "G.729");
+ break;
+ case ULAW:
+ len += sprintf(buf + len, "uLaw");
+ break;
+ case ALAW:
+ len += sprintf(buf + len, "aLaw");
+ break;
+ case LINEAR16:
+ len += sprintf(buf + len, "16 bit Linear");
+ break;
+ case LINEAR8:
+ len += sprintf(buf + len, "8 bit Linear");
+ break;
+ case WSS:
+ len += sprintf(buf + len, "Windows Sound System");
+ break;
+ default:
+ len += sprintf(buf + len, "NO CODEC CHOSEN");
+ break;
+ }
+ len += sprintf(buf + len, "\nRecord CODEC ");
+ switch (j->rec_codec) {
+ case G723_63:
+ len += sprintf(buf + len, "G.723.1 6.3");
+ break;
+ case G723_53:
+ len += sprintf(buf + len, "G.723.1 5.3");
+ break;
+ case TS85:
+ len += sprintf(buf + len, "TrueSpeech 8.5");
+ break;
+ case TS48:
+ len += sprintf(buf + len, "TrueSpeech 4.8");
+ break;
+ case TS41:
+ len += sprintf(buf + len, "TrueSpeech 4.1");
+ break;
+ case G728:
+ len += sprintf(buf + len, "G.728");
+ break;
+ case G729:
+ len += sprintf(buf + len, "G.729");
+ break;
+ case ULAW:
+ len += sprintf(buf + len, "uLaw");
+ break;
+ case ALAW:
+ len += sprintf(buf + len, "aLaw");
+ break;
+ case LINEAR16:
+ len += sprintf(buf + len, "16 bit Linear");
+ break;
+ case LINEAR8:
+ len += sprintf(buf + len, "8 bit Linear");
+ break;
+ case WSS:
+ len += sprintf(buf + len, "Windows Sound System");
+ break;
+ default:
+ len += sprintf(buf + len, "NO CODEC CHOSEN");
+ break;
+ }
+ switch (j->aec_level) {
+ case AEC_OFF:
+ len += sprintf(buf + len, "\n AEC OFF");
+ break;
+ case AEC_LOW:
+ len += sprintf(buf + len, "\n AEC LOW");
+ break;
+ case AEC_MED:
+ len += sprintf(buf + len, "\n AEC MED");
+ break;
+ case AEC_HIGH:
+ len += sprintf(buf + len, "\n AEC HIGH");
+ break;
+ }
+ len += sprintf(buf + len, "\nHook state %d", j->r_hook); // ixj_hookstate(cnt));
+
+ if (j->cardtype == 300) {
+ len += sprintf(buf + len, "\nPOTS Correct %d", j->flags.pots_correct);
+ len += sprintf(buf + len, "\nPSTN Present %d", j->flags.pstn_present);
+ len += sprintf(buf + len, "\nPOTS to PSTN %d", j->flags.pots_pstn);
+ len += sprintf(buf + len, "\nPSTN sleeptil %ld - jiffies %ld", j->pstn_sleeptil, jiffies);
+ switch (j->daa_mode) {
+ case SOP_PU_SLEEP:
+ len += sprintf(buf + len, "\nDAA PSTN On Hook");
+ break;
+ case SOP_PU_RINGING:
+ len += sprintf(buf + len, "\nDAA PSTN Ringing");
+ break;
+ case SOP_PU_CONVERSATION:
+ len += sprintf(buf + len, "\nDAA PSTN Off Hook");
+ break;
+ case SOP_PU_PULSEDIALING:
+ len += sprintf(buf + len, "\nDAA PSTN Pulse Dialing");
+ break;
+ }
+ }
+ switch (j->port) {
+ case PORT_POTS:
+ len += sprintf(buf + len, "\nPort POTS");
+ break;
+ case PORT_PSTN:
+ len += sprintf(buf + len, "\nPort PSTN");
+ break;
+ case PORT_SPEAKER:
+ len += sprintf(buf + len, "\nPort SPEAKER/MIC");
+ break;
+ case PORT_HANDSET:
+ len += sprintf(buf + len, "\nPort HANDSET");
+ break;
+ }
+ if (j->dsp.low == 0x21 || j->dsp.low == 0x22) {
+ len += sprintf(buf + len, "\nSLIC state ");
+ switch (SLIC_GetState(cnt)) {
+ case PLD_SLIC_STATE_OC:
+ len += sprintf(buf + len, "OC");


+ break;
+ case PLD_SLIC_STATE_RINGING:

+ len += sprintf(buf + len, "RINGING");


+ break;
+ case PLD_SLIC_STATE_ACTIVE:

+ len += sprintf(buf + len, "ACTIVE");


+ break;
+ case PLD_SLIC_STATE_OHT: // On-hook transmit
+

+ len += sprintf(buf + len, "OHT");


+ break;
+ case PLD_SLIC_STATE_TIPOPEN:

+ len += sprintf(buf + len, "TIPOPEN");


+ break;
+ case PLD_SLIC_STATE_STANDBY:

+ len += sprintf(buf + len, "STANDBY");


+ break;
+ case PLD_SLIC_STATE_APR: // Active polarity reversal
+

+ len += sprintf(buf + len, "APR");


+ break;
+ case PLD_SLIC_STATE_OHTPR: // OHT polarity reversal
+

+ len += sprintf(buf + len, "OHTPR");
+ break;
+ default:
+ len += sprintf(buf + len, "%d", SLIC_GetState(cnt));
+ break;
+ }
+ }
+#ifdef PERFMON_STATS
+ len += sprintf(buf + len, "\nTimer Checks %ld", j->timerchecks);
+ len += sprintf(buf + len, "\nRX Ready Checks %ld", j->rxreadycheck);
+ len += sprintf(buf + len, "\nTX Ready Checks %ld", j->txreadycheck);
+ len += sprintf(buf + len, "\nBase Frame %2.2x.%2.2x", j->baseframe.high, j->baseframe.low);
+ len += sprintf(buf + len, "\nFrames Read %ld", j->framesread);
+ len += sprintf(buf + len, "\nFrames Written %ld", j->frameswritten);
+ len += sprintf(buf + len, "\nDry Buffer %ld", j->drybuffer);
+ len += sprintf(buf + len, "\nRead Waits %ld", j->read_wait);
+ len += sprintf(buf + len, "\nWrite Waits %ld", j->write_wait);
+#endif
+ len += sprintf(buf + len, "\n");
+ }
+ }
+ return len;
+}
+int ixj_get_status_proc_fsk(char *buf)
+{
+ int len;
+ len = 0;
+ if (ixj[2].fskdcnt) {
+ memcpy(buf, &ixj[2].fskdata, (ixj[2].fskdcnt) * 2);
+ len += ixj[2].fskdcnt * 2;
+ }


+ return len;
+}
+

+static int ixj_read_proc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int len = ixj_get_status_proc(page);
+ if (len <= off+count) *eof = 1;
+ *start = page + off;
+ len -= off;
+ if (len>count) len = count;
+ if (len<0) len = 0;
+ return len;
+}
X
+static int ixj_read_proc_fsk(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int len = ixj_get_status_proc_fsk(page);
+ if (len <= off+count) *eof = 1;
+ *start = page + off;
+ len -= off;
+ if (len>count) len = count;
+ if (len<0) len = 0;


+ return len;
+}
+

+MODULE_DESCRIPTION("Internet Phone/Internet LineJack module - www.quicknet.net");
+MODULE_AUTHOR("Ed Okerson <eoke...@quicknet.net>");
+#ifdef CONFIG_PCMCIA


+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;

+MODULE_PARM(pc_debug, "i");
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+#else
+#define DEBUG(n, args...)
+#endif
+typedef struct ixj_info_t {
+ int ndev;
+ dev_node_t node;
+ struct ixj *port;
+} ixj_info_t;
+static dev_link_t *ixj_attach(void);
+static void ixj_detach(dev_link_t *);
+static void ixj_config(dev_link_t * link);
+static void ixj_cs_release(u_long arg);
+static int ixj_event(event_t event, int priority, event_callback_args_t * args);
+static dev_info_t dev_info = "ixj_cs";
+static dev_link_t *dev_list = NULL;
+static void cs_error(client_handle_t handle, int func, int ret)
+{
+ error_info_t err =
+ {
+ func, ret
+ };
+ CardServices(ReportError, handle, &err);
+}
+
+static dev_link_t *ixj_attach(void)
+{
+ client_reg_t client_reg;
+ dev_link_t *link;
+ int ret;
+ DEBUG(0, "ixj_attach()\n");
+ /* Create new ixj device */
+ link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
+ memset(link, 0, sizeof(struct dev_link_t));
+ link->release.function = &ixj_cs_release;
+ link->release.data = (u_long) link;
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
+ link->io.IOAddrLines = 3;
+ link->conf.Vcc = 50;
+ link->conf.IntType = INT_MEMORY_AND_IO;
+ link->priv = kmalloc(sizeof(struct ixj_info_t), GFP_KERNEL);
+ memset(link->priv, 0, sizeof(struct ixj_info_t));
+ /* Register with Card Services */
+ link->next = dev_list;
+ dev_list = link;
+ client_reg.dev_info = &dev_info;
+ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
+ client_reg.EventMask =
+ CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
+ CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
+ CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
+ client_reg.event_handler = &ixj_event;
+ client_reg.Version = 0x0210;
+ client_reg.event_callback_args.client_data = link;
+ ret = CardServices(RegisterClient, &link->handle, &client_reg);
+ if (ret != CS_SUCCESS) {
+ cs_error(link->handle, RegisterClient, ret);
+ ixj_detach(link);
+ return NULL;
+ }
+ return link;
+}
+
+static void ixj_detach(dev_link_t * link)
+{
+ dev_link_t **linkp;
+ long flags;
+ int ret;
+ DEBUG(0, "ixj_detach(0x%p)\n", link);
+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
+ if (*linkp == link)
+ break;
+ if (*linkp == NULL)
+ return;
+ save_flags(flags);
+ cli();
+ if (link->state & DEV_RELEASE_PENDING) {
+ del_timer(&link->release);
+ link->state &= ~DEV_RELEASE_PENDING;
+ }
+ restore_flags(flags);
+ if (link->state & DEV_CONFIG)
+ ixj_cs_release((u_long) link);
+ if (link->handle) {
+ ret = CardServices(DeregisterClient, link->handle);
+ if (ret != CS_SUCCESS)
+ cs_error(link->handle, DeregisterClient, ret);
+ }
+ /* Unlink device structure, free bits */
+ *linkp = link->next;
+ kfree_s(link->priv, sizeof(ixj_info_t));
+ kfree_s(link, sizeof(struct dev_link_t));
+}
+
+#define CS_CHECK(fn, args...) \
+while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
+
+#define CFG_CHECK(fn, args...) \
+if (CardServices(fn, args) != 0) goto next_entry
+
+void ixj_get_serial(dev_link_t * link, IXJ * j)
+{
+ client_handle_t handle;
+ tuple_t tuple;
+ u_short buf[128];
+ char *str;
+ int last_ret, last_fn, i, place;
+ handle = link->handle;
+ DEBUG(0, "ixj_get_serial(0x%p)\n", link);
+ tuple.TupleData = (cisdata_t *) buf;
+ tuple.TupleOffset = 0;
+ tuple.TupleDataMax = 80;
+ tuple.Attributes = 0;
+ tuple.DesiredTuple = CISTPL_VERS_1;
+ CS_CHECK(GetFirstTuple, handle, &tuple);
+ CS_CHECK(GetTupleData, handle, &tuple);
+ str = (char *) buf;
+ printk("PCMCIA Version %d.%d\n", str[0], str[1]);
+ str += 2;
+ printk("%s", str);
+ str = str + strlen(str) + 1;
+ printk(" %s", str);
+ str = str + strlen(str) + 1;
+ place = 1;
+ for (i = strlen(str) - 1; i >= 0; i--) {
+ switch (str[i]) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ j->serial += (str[i] - 48) * place;
+ break;
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ j->serial += (str[i] - 55) * place;
+ break;
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ j->serial += (str[i] - 87) * place;
+ break;
+ }
+ place = place * 0x10;
+ }
+ str = str + strlen(str) + 1;
+ printk(" version %s\n", str);
+ cs_failed:
+ return;
+}
+
+void ixj_config(dev_link_t * link)
+{
+ client_handle_t handle;
+ ixj_info_t *info;
+ tuple_t tuple;
+ u_short buf[128];
+ cisparse_t parse;
+ config_info_t conf;
+ cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
+ cistpl_cftable_entry_t dflt =
+ {
+ 0
+ };
+ int last_ret, last_fn;
+ handle = link->handle;
+ info = link->priv;
+ DEBUG(0, "ixj_config(0x%p)\n", link);
+ tuple.TupleData = (cisdata_t *) buf;
+ tuple.TupleOffset = 0;
+ tuple.TupleDataMax = 255;
+ tuple.Attributes = 0;
+ tuple.DesiredTuple = CISTPL_CONFIG;
+ CS_CHECK(GetFirstTuple, handle, &tuple);
+ CS_CHECK(GetTupleData, handle, &tuple);
+ CS_CHECK(ParseTuple, handle, &tuple, &parse);
+ link->conf.ConfigBase = parse.config.base;
+ link->conf.Present = parse.config.rmask[0];
+ link->state |= DEV_CONFIG;
+ CS_CHECK(GetConfigurationInfo, handle, &conf);
+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ tuple.Attributes = 0;
+ CS_CHECK(GetFirstTuple, handle, &tuple);
+ while (1) {
+ CFG_CHECK(GetTupleData, handle, &tuple);
+ CFG_CHECK(ParseTuple, handle, &tuple, &parse);
+ if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+ link->conf.ConfigIndex = cfg->index;
+ link->io.BasePort1 = io->win[0].base;
+ link->io.NumPorts1 = io->win[0].len;
+ if (io->nwin == 2) {
+ link->io.BasePort2 = io->win[1].base;
+ link->io.NumPorts2 = io->win[1].len;
+ }
+ CFG_CHECK(RequestIO, link->handle, &link->io);
+ /* If we've got this far, we're done */
+ break;
+ }
+ next_entry:
+ if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+ dflt = *cfg;
+ CS_CHECK(GetNextTuple, handle, &tuple);
+ }
+
+ CS_CHECK(RequestConfiguration, handle, &link->conf);
+ ixj[0].DSPbase = link->io.BasePort1;
+ ixj[0].XILINXbase = link->io.BasePort1 + 0x10;
+ ixj[0].cardtype = 600;
+ ixj_selfprobe(0);
+ info->ndev = 1;
+ info->node.major = PHONE_MAJOR;
+ link->dev = &info->node;
+ ixj_get_serial(link, &ixj[0]);
+ link->state &= ~DEV_CONFIG_PENDING;
+ return;
+ cs_failed:
+ cs_error(link->handle, last_fn, last_ret);
+ ixj_cs_release((u_long) link);
+}
+
+void ixj_cs_release(u_long arg)
+{
+ dev_link_t *link = (dev_link_t *) arg;
+ ixj_info_t *info = link->priv;
+ DEBUG(0, "ixj_cs_release(0x%p)\n", link);
+ info->ndev = 0;
+ link->dev = NULL;
+ CardServices(ReleaseConfiguration, link->handle);
+ CardServices(ReleaseIO, link->handle, &link->io);
+ link->state &= ~DEV_CONFIG;
+}
+
+int ixj_event(event_t event, int priority, event_callback_args_t * args)
+{
+ dev_link_t *link = args->client_data;
+ DEBUG(1, "ixj_event(0x%06x)\n", event);
+ switch (event) {
+ case CS_EVENT_CARD_REMOVAL:
+ link->state &= ~DEV_PRESENT;
+ if (link->state & DEV_CONFIG) {
+ link->release.expires = RUN_AT(HZ / 20);
+ link->state |= DEV_RELEASE_PENDING;
+ add_timer(&link->release);
+ }
+ break;
+ case CS_EVENT_CARD_INSERTION:
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ ixj_config(link);
+ break;
+ case CS_EVENT_PM_SUSPEND:
+ link->state |= DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_RESET_PHYSICAL:
+ if (link->state & DEV_CONFIG)
+ CardServices(ReleaseConfiguration, link->handle);
+ break;
+ case CS_EVENT_PM_RESUME:
+ link->state &= ~DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_CARD_RESET:
+ if (DEV_OK(link))
+ CardServices(RequestConfiguration, link->handle, &link->conf);
+ break;
+ }


X return 0;
X }
X

+#endif // PCMCIA
+
X static void cleanup(void)
X {
X int cnt;
-
X del_timer(&ixj_timer);
-// if (ixj_major)
- // unregister_chrdev(ixj_major, "ixj");
X for (cnt = 0; cnt < IXJMAX; cnt++) {
X if (ixj[cnt].cardtype == 300) {
X ixj[cnt].pld_scrw.bits.daafsyncen = 0; // Turn off DAA Frame Sync
@@ -4382,7 +6082,6 @@
X ixj[cnt].pld_slicw.bits.rly3 = 0;
X outb_p(ixj[cnt].pld_slicw.byte, ixj[cnt].XILINXbase + 0x01);
X LED_SetState(0x0, cnt);
-
X release_region(ixj[cnt].XILINXbase, 8);
X }
X if (ixj[cnt].cardtype == 400 || ixj[cnt].cardtype == 500) {
@@ -4400,16 +6099,22 @@
X if (ixj[cnt].dev)
X ixj[cnt].dev->deactivate(ixj[cnt].dev);
X #endif
+#ifdef CONFIG_PCMCIA
+ DEBUG(0, "ixj_cs: unloading\n");
+ unregister_pcmcia_driver(&dev_info);
+ while (dev_list != NULL)
+ ixj_detach(dev_list);
+#endif
X }
+ remove_proc_entry ("ixj", NULL);
+ remove_proc_entry ("ixjfsk", NULL);
X }
X
-
X // Typedefs
X typedef struct {
X BYTE length;
X DWORD bits;
X } DATABLOCK;
-
X static void PCIEE_WriteBit(WORD wEEPROMAddress, BYTE lastLCC, BYTE byData)
X {
X lastLCC = lastLCC & 0xfb;
@@ -4422,7 +6127,6 @@
X
X byData = byData << 1;
X lastLCC = lastLCC & 0xfe;
-
X udelay(1000);
X outb(lastLCC, wEEPROMAddress); //after delay, SK falling edge
X
@@ -4447,11 +6151,8 @@
X WORD wEEPROMAddress = wAddress + 3;
X DWORD i;
X BYTE byResult;
-
X *pwResult = 0;
-
X lastLCC = inb(wEEPROMAddress);
-
X lastLCC = lastLCC | 0x02;
X lastLCC = lastLCC & 0xfe;
X outb(lastLCC, wEEPROMAddress); // CS hi, SK lo
@@ -4461,7 +6162,6 @@
X PCIEE_WriteBit(wEEPROMAddress, lastLCC, 1);
X PCIEE_WriteBit(wEEPROMAddress, lastLCC, 1);
X PCIEE_WriteBit(wEEPROMAddress, lastLCC, 0);
-
X for (i = 0; i < 8; i++) {
X PCIEE_WriteBit(wEEPROMAddress, lastLCC, wLoc & 0x80 ? 1 : 0);
X wLoc <<= 1;
@@ -4483,45 +6183,58 @@


X static DWORD PCIEE_GetSerialNumber(WORD wAddress)

X {
X WORD wLo, wHi;
-
X if (PCIEE_ReadWord(wAddress, 62, &wLo))
X return 0;
-
X if (PCIEE_ReadWord(wAddress, 63, &wHi))
X return 0;
-
X return (((DWORD) wHi << 16) | wLo);
X }
X
-static int dspio[IXJMAX + 1] = {0,};
-static int xio[IXJMAX + 1] = {0,};
-
-MODULE_DESCRIPTION("Internet PhoneJACK/Internet LineJACK module - www.quicknet.net");
-MODULE_AUTHOR("Ed Okerson <eoke...@quicknet.net>");
+#ifndef CONFIG_PCMCIA
+#ifndef CONFIG_ISAPNP
+static int dspio[IXJMAX + 1] =
+{
+ 0,
+};
+static int xio[IXJMAX + 1] =
+{
+ 0,
+};
X
X MODULE_PARM(dspio, "1-" __MODULE_STRING(IXJMAX) "i");
X MODULE_PARM(xio, "1-" __MODULE_STRING(IXJMAX) "i");
+#endif
+#endif
X
-#ifdef MODULE
-
-void cleanup_module(void)
+void ixj_exit(void)
X {
X cleanup();


X }
X
-int init_module(void)
-#else

X int __init ixj_init(void)
-#endif
X {
X int result;
-
- int func = 0x110, i = 0;


+ int i = 0;

X int cnt = 0;
X int probe = 0;
+#ifdef CONFIG_ISAPNP
+ int func = 0x110;
X struct pci_dev *dev = NULL, *old_dev = NULL;
+#endif
+#ifdef CONFIG_PCI
X struct pci_dev *pci = NULL;
-
+#endif
+#ifdef CONFIG_PCMCIA
+ servinfo_t serv;
+ DEBUG(0, "%s\n", version);
+ CardServices(GetCardServicesInfo, &serv);
+ if (serv.Revision != CS_RELEASE_CODE) {
+ printk(KERN_NOTICE "ixj_cs: Card Services release does not match!\n");
+ return -1;
+ }
+ register_pcmcia_driver(&dev_info, &ixj_attach, &ixj_detach);
+ probe = 0;
+#else
X #ifdef CONFIG_ISAPNP
X while (1) {
X do {
@@ -4530,7 +6243,6 @@
X ISAPNP_FUNCTION(func), old_dev);
X if (!dev)
X break;
- printk("preparing %x\n", func);
X result = dev->prepare(dev);
X if (result < 0) {
X printk("preparing failed %d \n", result);
@@ -4548,7 +6260,6 @@
X ixj[cnt].DSPbase = dev->resource[0].start; /* get real port */
X if (func != 0x110)
X ixj[cnt].XILINXbase = dev->resource[1].start; /* get real port */
-
X result = check_region(ixj[cnt].DSPbase, 16);
X if (result) {
X printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", ixj[cnt].DSPbase);
@@ -4568,13 +6279,21 @@
X break;
X }
X probe = ixj_selfprobe(cnt);
-
X ixj[cnt].serial = dev->bus->serial;
X ixj[cnt].dev = dev;
- printk(KERN_INFO "ixj: found card at 0x%x\n", ixj[cnt].DSPbase);
+ switch (func) {
+ case 0x110:
+ printk(KERN_INFO "ixj: found Internet PhoneJACK at 0x%x\n", ixj[cnt].DSPbase);
+ break;
+ case 0x310:
+ printk(KERN_INFO "ixj: found Internet LineJACK at 0x%x\n", ixj[cnt].DSPbase);
+ break;
+ case 0x410:
+ printk(KERN_INFO "ixj: found Internet PhoneJACK Lite at 0x%x\n", ixj[cnt].DSPbase);
+ break;
+ }
X cnt++;
X } while (dev);
-
X if (func == 0x410)
X break;
X if (func == 0x310)
@@ -4585,11 +6304,10 @@
X }
X #else //CONFIG_ISAPNP
X /* Use passed parameters for older kernels without PnP */
-
- for (cnt = 0; cnt < IXJMAX; cnt++) {
- if (dspio[cnt]) {
- ixj[cnt].DSPbase = dspio[cnt];
- ixj[cnt].XILINXbase = xio[cnt];
+ for (i = 0; i < IXJMAX; i++) {
+ if (dspio[i]) {
+ ixj[cnt].DSPbase = dspio[i];
+ ixj[cnt].XILINXbase = xio[i];
X ixj[cnt].cardtype = 0;
X result = check_region(ixj[cnt].DSPbase, 16);
X if (result) {
@@ -4600,9 +6318,11 @@
X request_region(ixj[cnt].DSPbase, 16, "ixj DSP");
X probe = ixj_selfprobe(cnt);
X ixj[cnt].dev = NULL;
+ cnt++;
X }
X }
-#endif
+#endif // !CONFIG_ISAPNP
+#endif // CONFIG_PCMCIA
X #ifdef CONFIG_PCI
X if (pci_present()) {
X for (i = 0; i < IXJMAX - cnt; i++) {
@@ -4615,7 +6335,6 @@
X ixj[cnt].DSPbase = pci_resource_start(pci, 0);
X ixj[cnt].XILINXbase = ixj[cnt].DSPbase + 0x10;
X ixj[cnt].serial = (PCIEE_GetSerialNumber)pci_resource_start(pci, 2);
-
X result = check_region(ixj[cnt].DSPbase, 16);
X if (result) {
X printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", ixj[cnt].DSPbase);
@@ -4625,32 +6344,38 @@
X request_region(ixj[cnt].DSPbase, 16, "ixj DSP");
X ixj[cnt].cardtype = 500;
X probe = ixj_selfprobe(cnt);
+ if (probe)
+ printk(KERN_INFO "ixj: found Internet PhoneJACK PCI at 0x%x\n", ixj[cnt].DSPbase);
X cnt++;
X }
X }
X }
X #endif
X printk("%s\n", ixj_c_rcsid);
-
+ create_proc_read_entry ("ixj", 0, NULL, ixj_read_proc, NULL);
+ create_proc_read_entry ("ixjfsk", 0, NULL, ixj_read_proc_fsk, NULL);
X ixj_init_timer();
- ixj_add_timer();
+ ixj_add_timer();
X return probe;
X }
X
+module_init(ixj_init);
+module_exit(ixj_exit);
+
X static void DAA_Coeff_US(int board)


X {
X IXJ *j = &ixj[board];

-
X int i;
X
+ j->daa_country = DAA_US;
X //-----------------------------------------------
X // CAO
X for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
X j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
X }
X
- // Bytes for IM-filter part 1 (04): 0E,32,E2,2F,C2,5A,C0,00
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x0E;
+// Bytes for IM-filter part 1 (04): 0E,32,E2,2F,C2,5A,C0,00
+ j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x0E;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0x32;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xE2;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x2F;
@@ -4658,7 +6383,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x5A;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xC0;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-
X // Bytes for IM-filter part 2 (05): 72,85,00,0E,2B,3A,D0,08
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x72;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x85;
@@ -4668,7 +6392,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x3A;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xD0;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-
X // Bytes for FRX-filter (08): 03,8F,48,F2,8F,48,70,08
X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x03;
X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x8F;
@@ -4678,7 +6401,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x48;
X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x70;
X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-
X // Bytes for FRR-filter (07): 04,8F,38,7F,9B,EA,B0,08
X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x04;
X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x8F;
@@ -4688,19 +6410,16 @@
X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xEA;
X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xB0;
X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-
X // Bytes for AX-filter (0A): 16,55,DD,CA
X j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x16;
X j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0x55;
X j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
X j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-
X // Bytes for AR-filter (09): 52,D3,11,42
X j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x52;
X j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xD3;
X j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x11;
X j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0x42;
-
X // Bytes for TH-filter part 1 (00): 00,42,48,81,B3,80,00,98
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42;
@@ -4710,7 +6429,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-
X // Bytes for TH-filter part 2 (01): 02,F2,33,A0,68,AB,8A,AD
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xF2;
@@ -4720,7 +6438,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0xAB;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x8A;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xAD;
-
X // Bytes for TH-filter part 3 (02): 00,88,DA,54,A4,BA,2D,BB
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
@@ -4730,7 +6447,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xBA;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x2D;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xBB;
-
X // ; (10K, 0.68uF)
X //
X // Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23
@@ -4742,7 +6458,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x1C;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xB3;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-
X // Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x13;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0x42;
@@ -4752,14 +6467,12 @@
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x73;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0xCA;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-
X //
X // Levelmetering Ringing (0D):B2,45,0F,8E
X j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xB2;
X j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45;
X j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
X j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
-
X // Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
@@ -4769,7 +6482,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-
X // Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
@@ -4779,64 +6491,52 @@
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-
X //
X // ;CR Registers
X // Config. Reg. 0 (filters) (cr0):FE ; CLK gen. by crystal
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFE;
-
+ j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
X // Config. Reg. 1 (dialing) (cr1):05
X j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-
X // Config. Reg. 2 (caller ID) (cr2):04
X j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-
X // Config. Reg. 3 (testloops) (cr3):03 ; SEL Bit==0, HP-disabled
X j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x03;
-
X // Config. Reg. 4 (analog gain) (cr4):01
X j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; //0x01;
-
-// Config. Reg. 5 (Version) (cr5):02
+ // Config. Reg. 5 (Version) (cr5):02
X // Config. Reg. 6 (Reserved) (cr6):00
X // Config. Reg. 7 (Reserved) (cr7):00
X //
-
-// ;xr Registers
+ // ;xr Registers
X // Ext. Reg. 0 (Interrupt Reg.) (xr0):02
+
X j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; // SO_1 set to '1' because it is inverted.
+ // Ext. Reg. 1 (Interrupt enable) (xr1):1C // Cadence, RING, Caller ID, VDD_OK
X
-// Ext. Reg. 1 (Interrupt enable) (xr1):1C // Cadence, RING, Caller ID, VDD_OK
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x3C;
-
X // Ext. Reg. 2 (Cadence Time Out) (xr2):7D
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-
X // Ext. Reg. 3 (DC Char) (xr3):32 ; B-Filter Off == 1
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x12; //0x32;
+ // Ext. Reg. 4 (Cadence) (xr4):00
X
-// Ext. Reg. 4 (Cadence) (xr4):00
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-
X // Ext. Reg. 5 (Ring timer) (xr5):22
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-
X // Ext. Reg. 6 (Power State) (xr6):00
X j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-
X // Ext. Reg. 7 (Vdd) (xr7):40
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; // 0x40 ??? Should it be 0x00?
-
-//
+ //
X // DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz
X // 12,33,5A,C3 ; 770 Hz
X // 13,3C,5B,32 ; 852 Hz
X // 1D,1B,5C,CC ; 941 Hz
+
X j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-
X // DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz
X // EC,1D,52,22 ; 1336 Hz
X // AA,AC,51,D2 ; 1477 Hz
@@ -4845,23 +6545,22 @@
X j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
-
X }
X
X static void DAA_Coeff_UK(int board)


X {
X IXJ *j = &ixj[board];

-
X int i;
X
+ j->daa_country = DAA_UK;
X //-----------------------------------------------
X // CAO
X for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
X j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
X }
X
- // Bytes for IM-filter part 1 (04): 00,C2,BB,A8,CB,81,A0,00
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00;
+// Bytes for IM-filter part 1 (04): 00,C2,BB,A8,CB,81,A0,00
+ j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xC2;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xBB;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0xA8;
@@ -4869,8 +6568,7 @@
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x81;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-
- // Bytes for IM-filter part 2 (05): 40,00,00,0A,A4,33,E0,08
+// Bytes for IM-filter part 2 (05): 40,00,00,0A,A4,33,E0,08
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x40;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
@@ -4879,7 +6577,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-
X // Bytes for FRX-filter (08): 07,9B,ED,24,B2,A2,A0,08
X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;
X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x9B;
@@ -4889,7 +6586,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0xA2;
X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xA0;
X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-
X // Bytes for FRR-filter (07): 0F,92,F2,B2,87,D2,30,08
X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x0F;
X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x92;
@@ -4899,19 +6595,16 @@
X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xD2;
X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x30;
X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-
X // Bytes for AX-filter (0A): 1B,A5,DD,CA
X j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x1B;
X j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xA5;
X j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
X j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-
X // Bytes for AR-filter (09): E2,27,10,D6
X j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0xE2;
X j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x27;
X j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
X j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
-
X // Bytes for TH-filter part 1 (00): 80,2D,38,8B,D0,00,00,98
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x2D;
@@ -4921,7 +6614,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-
X // Bytes for TH-filter part 2 (01): 02,5A,53,F0,0B,5F,84,D4
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0x5A;
@@ -4931,7 +6623,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x5F;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x84;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xD4;
-
X // Bytes for TH-filter part 3 (02): 00,88,6A,A4,8F,52,F5,32
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
@@ -4941,10 +6632,8 @@
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x52;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0xF5;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x32;
-
X // ; idle
-
-// Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23
+ // Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
@@ -4953,7 +6642,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-
X // Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
@@ -4963,13 +6651,11 @@
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-
X // Levelmetering Ringing (0D):AA,35,0F,8E ; 25Hz 30V less possible?
X j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA;
X j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35;
X j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
X j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
-
X // Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
@@ -4979,7 +6665,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-
X // Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
@@ -4989,61 +6674,49 @@
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-
X // ;CR Registers
X // Config. Reg. 0 (filters) (cr0):FF
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF; //0xFE;
-
+ j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFE;
X // Config. Reg. 1 (dialing) (cr1):05
X j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-
X // Config. Reg. 2 (caller ID) (cr2):04
X j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-
X // Config. Reg. 3 (testloops) (cr3):00 ;
X j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-
X // Config. Reg. 4 (analog gain) (cr4):01
X j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; //0x01;
-
-// Config. Reg. 5 (Version) (cr5):02
+ // Config. Reg. 5 (Version) (cr5):02
X // Config. Reg. 6 (Reserved) (cr6):00
X // Config. Reg. 7 (Reserved) (cr7):00
-
-// ;xr Registers
+ // ;xr Registers
X // Ext. Reg. 0 (Interrupt Reg.) (xr0):02
+
X j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; // SO_1 set to '1' because it is inverted.
+ // Ext. Reg. 1 (Interrupt enable) (xr1):1C
X
-// Ext. Reg. 1 (Interrupt enable) (xr1):1C
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; // RING, Caller ID, VDD_OK
+ // Ext. Reg. 2 (Cadence Time Out) (xr2):7D
X
-// Ext. Reg. 2 (Cadence Time Out) (xr2):7D
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-
X // Ext. Reg. 3 (DC Char) (xr3):36 ;
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x36;
-
X // Ext. Reg. 4 (Cadence) (xr4):00
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-
X // Ext. Reg. 5 (Ring timer) (xr5):22
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-
X // Ext. Reg. 6 (Power State) (xr6):00
X j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-
X // Ext. Reg. 7 (Vdd) (xr7):46
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x46; // 0x46 ??? Should it be 0x00?
-
-// DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz
+ // DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz
X // 12,33,5A,C3 ; 770 Hz
X // 13,3C,5B,32 ; 852 Hz
X // 1D,1B,5C,CC ; 941 Hz
+
X j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-
X // DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz
X // EC,1D,52,22 ; 1336 Hz
X // AA,AC,51,D2 ; 1477 Hz
@@ -5052,24 +6725,23 @@
X j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
-
X }
X
X
X static void DAA_Coeff_France(int board)


X {
X IXJ *j = &ixj[board];

-
X int i;
X
+ j->daa_country = DAA_FRANCE;
X //-----------------------------------------------
X // CAO
X for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
X j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
X }
X
- // Bytes for IM-filter part 1 (04): 02,A2,43,2C,22,AF,A0,00
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x02;
+// Bytes for IM-filter part 1 (04): 02,A2,43,2C,22,AF,A0,00
+ j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x02;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xA2;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0x43;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x2C;
@@ -5077,7 +6749,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xAF;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-
X // Bytes for IM-filter part 2 (05): 67,CE,00,0C,22,33,E0,08
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x67;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0xCE;
@@ -5087,7 +6758,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-
X // Bytes for FRX-filter (08): 07,9A,28,F6,23,4A,B0,08
X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;
X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x9A;
@@ -5097,7 +6767,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x4A;
X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xB0;
X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-
X // Bytes for FRR-filter (07): 03,8F,F9,2F,9E,FA,20,08
X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x03;
X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x8F;
@@ -5107,19 +6776,16 @@
X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xFA;
X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x20;
X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-
X // Bytes for AX-filter (0A): 16,B5,DD,CA
X j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x16;
X j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xB5;
X j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
X j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-
X // Bytes for AR-filter (09): 52,C7,10,D6
X j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0xE2;
X j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xC7;
X j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
X j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
-
X // Bytes for TH-filter part 1 (00): 00,42,48,81,A6,80,00,98
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42;
@@ -5129,7 +6795,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-
X // Bytes for TH-filter part 2 (01): 02,AC,2A,30,78,AC,8A,2C
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xAC;
@@ -5139,7 +6804,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0xAC;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x8A;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x2C;
-
X // Bytes for TH-filter part 3 (02): 00,88,DA,A5,22,BA,2C,45
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
@@ -5149,10 +6813,8 @@
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xBA;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x2C;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x45;
-
X // ; idle
-
-// Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23
+ // Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
@@ -5161,7 +6823,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-
X // Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
@@ -5171,13 +6832,11 @@
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-
X // Levelmetering Ringing (0D):32,45,B5,84 ; 50Hz 20V
X j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0x32;
X j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45;
X j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0xB5;
X j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x84;
-
X // Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
@@ -5187,7 +6846,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-
X // Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
@@ -5197,61 +6855,49 @@
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-
X // ;CR Registers
X // Config. Reg. 0 (filters) (cr0):FF
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
-
+ j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFE;
X // Config. Reg. 1 (dialing) (cr1):05
X j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-
X // Config. Reg. 2 (caller ID) (cr2):04
X j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-
X // Config. Reg. 3 (testloops) (cr3):00 ;
X j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-
X // Config. Reg. 4 (analog gain) (cr4):01
X j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; //0x01;
-
-// Config. Reg. 5 (Version) (cr5):02
+ // Config. Reg. 5 (Version) (cr5):02
X // Config. Reg. 6 (Reserved) (cr6):00
X // Config. Reg. 7 (Reserved) (cr7):00
-
-// ;xr Registers
+ // ;xr Registers
X // Ext. Reg. 0 (Interrupt Reg.) (xr0):02
+
X j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; // SO_1 set to '1' because it is inverted.
+ // Ext. Reg. 1 (Interrupt enable) (xr1):1C
X
-// Ext. Reg. 1 (Interrupt enable) (xr1):1C
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; // RING, Caller ID, VDD_OK
+ // Ext. Reg. 2 (Cadence Time Out) (xr2):7D
X
-// Ext. Reg. 2 (Cadence Time Out) (xr2):7D
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-
X // Ext. Reg. 3 (DC Char) (xr3):36 ;
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x36;
-
X // Ext. Reg. 4 (Cadence) (xr4):00
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-
X // Ext. Reg. 5 (Ring timer) (xr5):22
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-
X // Ext. Reg. 6 (Power State) (xr6):00
X j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-
X // Ext. Reg. 7 (Vdd) (xr7):46
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x46; // 0x46 ??? Should it be 0x00?
-
-// DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz
+ // DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz
X // 12,33,5A,C3 ; 770 Hz
X // 13,3C,5B,32 ; 852 Hz
X // 1D,1B,5C,CC ; 941 Hz
+
X j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-
X // DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz
X // EC,1D,52,22 ; 1336 Hz
X // AA,AC,51,D2 ; 1477 Hz
@@ -5260,24 +6906,23 @@
X j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
-
X }
X
X
X static void DAA_Coeff_Germany(int board)


X {
X IXJ *j = &ixj[board];

-
X int i;
X
+ j->daa_country = DAA_GERMANY;
X //-----------------------------------------------
X // CAO
X for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
X j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
X }
X
- // Bytes for IM-filter part 1 (04): 00,CE,BB,B8,D2,81,B0,00
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00;
+// Bytes for IM-filter part 1 (04): 00,CE,BB,B8,D2,81,B0,00
+ j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xCE;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xBB;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0xB8;
@@ -5285,7 +6930,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x81;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xB0;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-
X // Bytes for IM-filter part 2 (05): 45,8F,00,0C,D2,3A,D0,08
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x45;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x8F;
@@ -5295,7 +6939,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x3A;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xD0;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-
X // Bytes for FRX-filter (08): 07,AA,E2,34,24,89,20,08
X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;
X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0xAA;
@@ -5305,7 +6948,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x89;
X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x20;
X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-
X // Bytes for FRR-filter (07): 02,87,FA,37,9A,CA,B0,08
X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x02;
X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x87;
@@ -5315,19 +6957,16 @@
X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xCA;
X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xB0;
X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-
X // Bytes for AX-filter (0A): 72,D5,DD,CA
X j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x72;
X j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xD5;
X j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
X j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-
X // Bytes for AR-filter (09): 72,42,13,4B
X j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x72;
X j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x42;
X j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x13;
X j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0x4B;
-
X // Bytes for TH-filter part 1 (00): 80,52,48,81,AD,80,00,98
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x52;
@@ -5337,7 +6976,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-
X // Bytes for TH-filter part 2 (01): 02,42,5A,20,E8,1A,81,27
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0x42;
@@ -5347,7 +6985,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x1A;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x81;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x27;
-
X // Bytes for TH-filter part 3 (02): 00,88,63,26,BD,4B,A3,C2
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
@@ -5357,10 +6994,8 @@
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x4B;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0xA3;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xC2;
-
X // ; (10K, 0.68uF)
-
-// Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23
+ // Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3B;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x9B;
@@ -5369,7 +7004,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x1C;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xB3;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-
X // Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x13;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0x42;
@@ -5379,13 +7013,11 @@
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x73;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0xCA;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-
X // Levelmetering Ringing (0D):B2,45,0F,8E
X j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xB2;
X j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45;
X j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
X j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
-
X // Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
@@ -5395,7 +7027,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-
X // Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
@@ -5405,61 +7036,49 @@
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-
X // ;CR Registers
X // Config. Reg. 0 (filters) (cr0):FF ; all Filters enabled, CLK from ext. source
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
-
+ j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFE;
X // Config. Reg. 1 (dialing) (cr1):05 ; Manual Ring, Ring metering enabled
X j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-
X // Config. Reg. 2 (caller ID) (cr2):04 ; Analog Gain 0dB, FSC internal
X j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-
X // Config. Reg. 3 (testloops) (cr3):00 ; SEL Bit==0, HP-enabled
X j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-
X // Config. Reg. 4 (analog gain) (cr4):01
X j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; //0x01;
-
-// Config. Reg. 5 (Version) (cr5):02
+ // Config. Reg. 5 (Version) (cr5):02
X // Config. Reg. 6 (Reserved) (cr6):00
X // Config. Reg. 7 (Reserved) (cr7):00
-
-// ;xr Registers
+ // ;xr Registers
X // Ext. Reg. 0 (Interrupt Reg.) (xr0):02
+
X j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; // SO_1 set to '1' because it is inverted.
+ // Ext. Reg. 1 (Interrupt enable) (xr1):1C ; Ring, CID, VDDOK Interrupts enabled
X
-// Ext. Reg. 1 (Interrupt enable) (xr1):1C ; Ring, CID, VDDOK Interrupts enabled
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; // RING, Caller ID, VDD_OK
+ // Ext. Reg. 2 (Cadence Time Out) (xr2):7D
X
-// Ext. Reg. 2 (Cadence Time Out) (xr2):7D
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-
X // Ext. Reg. 3 (DC Char) (xr3):32 ; B-Filter Off==1, U0=3.5V, R=200Ohm
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x32;
-
X // Ext. Reg. 4 (Cadence) (xr4):00
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 090'
echo 'File patch-2.4.0-test9 is continued in part 091'
echo "091" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part091

#!/bin/sh -x
# this is part 091 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 091; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&
-

X // Ext. Reg. 5 (Ring timer) (xr5):22
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-
X // Ext. Reg. 6 (Power State) (xr6):00
X j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-

X // Ext. Reg. 7 (Vdd) (xr7):40 ; VDD=4.25 V


X j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; // 0x40 ??? Should it be 0x00?
-

-// DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz
+ // DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz
X // 12,33,5A,C3 ; 770 Hz
X // 13,3C,5B,32 ; 852 Hz
X // 1D,1B,5C,CC ; 941 Hz
+
X j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-
X // DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz
X // EC,1D,52,22 ; 1336 Hz
X // AA,AC,51,D2 ; 1477 Hz

@@ -5468,24 +7087,23 @@


X j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
-
X }
X
X

X static void DAA_Coeff_Australia(int board)


X {
X IXJ *j = &ixj[board];
-
X int i;
X

+ j->daa_country = DAA_AUSTRALIA;


X //-----------------------------------------------
X // CAO
X for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
X j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
X }
X

- // Bytes for IM-filter part 1 (04): 00,A3,AA,28,B3,82,D0,00


- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00;

+// Bytes for IM-filter part 1 (04): 00,A3,AA,28,B3,82,D0,00


+ j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00;

X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xA3;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xAA;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x28;
@@ -5493,7 +7111,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x82;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xD0;


X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-

X // Bytes for IM-filter part 2 (05): 70,96,00,09,32,6B,C0,08
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x70;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x96;
@@ -5503,7 +7120,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x6B;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xC0;


X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-

X // Bytes for FRX-filter (08): 07,96,E2,34,32,9B,30,08


X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;

X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x96;
@@ -5513,7 +7129,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x9B;
X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x30;


X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-

X // Bytes for FRR-filter (07): 0F,9A,E9,2F,22,CC,A0,08


X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x0F;

X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x9A;
@@ -5523,19 +7138,16 @@
X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xCC;
X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xA0;


X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-

X // Bytes for AX-filter (0A): CB,45,DD,CA
X j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0xCB;
X j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0x45;


X j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
X j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-

X // Bytes for AR-filter (09): 1B,67,10,D6
X j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x1B;
X j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x67;


X j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
X j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
-

X // Bytes for TH-filter part 1 (00): 80,52,48,81,AF,80,00,98


X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x52;

@@ -5545,7 +7157,6 @@


X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-

X // Bytes for TH-filter part 2 (01): 02,DB,52,B0,38,01,82,AC


X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;

X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xDB;
@@ -5555,7 +7166,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x01;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x82;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xAC;
-
X // Bytes for TH-filter part 3 (02): 00,88,4A,3E,2C,3B,24,46


X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;

@@ -5565,10 +7175,8 @@
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x3B;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x24;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x46;


-
X // ; idle
-
-// Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23
+ // Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;

@@ -5577,7 +7185,6 @@


X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-
X // Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;

@@ -5587,13 +7194,11 @@


X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-
X // Levelmetering Ringing (0D):32,45,B5,84 ; 50Hz 20V
X j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0x32;
X j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45;
X j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0xB5;
X j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x84;
-
X // Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;

@@ -5603,7 +7208,6 @@


X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-
X // Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;

@@ -5613,61 +7217,49 @@


X j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-
X // ;CR Registers
X // Config. Reg. 0 (filters) (cr0):FF

X j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
-

X // Ext. Reg. 3 (DC Char) (xr3):2B ;
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x2B;


-
X // Ext. Reg. 4 (Cadence) (xr4):00
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-
X // Ext. Reg. 5 (Ring timer) (xr5):22
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-
X // Ext. Reg. 6 (Power State) (xr6):00
X j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-

X // Ext. Reg. 7 (Vdd) (xr7):40
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; // 0x40 ??? Should it be 0x00?
-

-// DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz
+ // DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz
X // 12,33,5A,C3 ; 770 Hz
X // 13,3C,5B,32 ; 852 Hz
X // 1D,1B,5C,CC ; 941 Hz
+
X j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-
X // DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz
X // EC,1D,52,22 ; 1336 Hz
X // AA,AC,51,D2 ; 1477 Hz

@@ -5676,23 +7268,22 @@


X j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
-
X }
X

X static void DAA_Coeff_Japan(int board)


X {
X IXJ *j = &ixj[board];
-
X int i;
X

+ j->daa_country = DAA_JAPAN;


X //-----------------------------------------------
X // CAO
X for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
X j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
X }
X

- // Bytes for IM-filter part 1 (04): 06,BD,E2,2D,BA,F9,A0,00
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x06;
+// Bytes for IM-filter part 1 (04): 06,BD,E2,2D,BA,F9,A0,00
+ j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x06;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xBD;


X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xE2;

X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x2D;
@@ -5700,7 +7291,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xF9;


X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-

X // Bytes for IM-filter part 2 (05): 6F,F7,00,0E,34,33,E0,08
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x6F;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0xF7;
@@ -5710,7 +7300,6 @@


X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0;
X j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-

X // Bytes for FRX-filter (08): 02,8F,68,77,9C,58,F0,08
X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x02;


X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x8F;

@@ -5720,7 +7309,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x58;
X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xF0;


X j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-

X // Bytes for FRR-filter (07): 03,8F,38,73,87,EA,20,08


X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x03;
X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x8F;

@@ -5730,19 +7318,16 @@


X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xEA;

X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x20;
X j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-

X // Bytes for AX-filter (0A): 51,C5,DD,CA
X j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x51;
X j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xC5;


X j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
X j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-

X // Bytes for AR-filter (09): 25,A7,10,D6
X j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x25;
X j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xA7;


X j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
X j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
-

X // Bytes for TH-filter part 1 (00): 00,42,48,81,AE,80,00,98


X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42;

@@ -5752,7 +7337,6 @@


X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-

X // Bytes for TH-filter part 2 (01): 02,AB,2A,20,99,5B,89,28


X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;

X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xAB;
@@ -5762,7 +7346,6 @@
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x5B;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x89;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x28;
-
X // Bytes for TH-filter part 3 (02): 00,88,DA,25,34,C5,4C,BA


X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;

@@ -5772,10 +7355,8 @@
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xC5;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x4C;
X j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xBA;


-
X // ; idle
-
-// Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23
+ // Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;

@@ -5784,7 +7365,6 @@


X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-
X // Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;

@@ -5794,13 +7374,11 @@


X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
X j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-

X // Levelmetering Ringing (0D):AA,35,0F,8E ; 25Hz 30V ?????????


X j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA;
X j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35;
X j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
X j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
-
X // Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;

@@ -5810,7 +7388,6 @@


X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-
X // Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
X j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;

@@ -5820,76 +7397,62 @@

X // Ext. Reg. 3 (DC Char) (xr3):22 ;
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x22;
-
X // Ext. Reg. 4 (Cadence) (xr4):00


X j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-
X // Ext. Reg. 5 (Ring timer) (xr5):22
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-
X // Ext. Reg. 6 (Power State) (xr6):00
X j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-
X // Ext. Reg. 7 (Vdd) (xr7):40
X j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; // 0x40 ??? Should it be 0x00?
-

-// DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz
+ // DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz
X // 12,33,5A,C3 ; 770 Hz
X // 13,3C,5B,32 ; 852 Hz
X // 1D,1B,5C,CC ; 941 Hz
+
X j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-
X // DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz
X // EC,1D,52,22 ; 1336 Hz
X // AA,AC,51,D2 ; 1477 Hz

X // 9B,3B,51,25 ; 1633 Hz
-
X j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;


X j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
X j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
-
X }
X

X static s16 tone_table[][19] =
X {
- { // f20_50[]
+ { // f20_50[] 11
X 32538, // A1 = 1.985962
X -32325, // A2 = -0.986511
X -343, // B2 = -0.010493
@@ -5910,7 +7473,7 @@
X 21, // 21/32 in-band to broad-band ratio
X 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
X },
- { // f133_200[]
+ { // f133_200[] 12
X 32072, // A1 = 1.95752
X -31896, // A2 = -0.973419
X -435, // B2 = -0.013294
@@ -5931,7 +7494,7 @@
X 21, // 21/32 in-band to broad-band ratio
X 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
X },
- { // 300.txt
+ { // 300.txt 13
X 31769, // A1 = -1.939026
X -32584, // A2 = 0.994385
X -475, // B2 = -0.014522
@@ -5952,7 +7515,7 @@
X 21, // 21/32 in-band to broad-band ratio
X 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
X },
- { // f300_420[]
+ { // f300_420[] 14
X 30750, // A1 = 1.876892
X -31212, // A2 = -0.952515
X -804, // B2 = -0.024541
@@ -5973,7 +7536,7 @@
X 21, // 21/32 in-band to broad-band ratio
X 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
X },
- { // 330.txt
+ { // 330.txt 15
X 31613, // A1 = -1.929565
X -32646, // A2 = 0.996277
X -185, // B2 = -0.005657
@@ -5994,7 +7557,7 @@
X 21, // 21/32 in-band to broad-band ratio
X 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
X },
- { // f300_425[]
+ { // f300_425[] 16
X 30741, // A1 = 1.876282
X -31475, // A2 = -0.960541
X -703, // B2 = -0.021484
@@ -6015,7 +7578,7 @@
X 21, // 21/32 in-band to broad-band ratio
X 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
X },
- { // f330_440[]
+ { // f330_440[] 17
X 30627, // A1 = 1.869324
X -31338, // A2 = -0.95636
X -843, // B2 = -0.025749
@@ -6036,7 +7599,7 @@
X 21, // 21/32 in-band to broad-band ratio
X 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
X },
- { // 340.txt
+ { // 340.txt 18
X 31546, // A1 = -1.925476
X -32646, // A2 = 0.996277
X -445, // B2 = -0.013588
@@ -6057,7 +7620,7 @@
X 21, // 21/32 in-band to broad-band ratio
X 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
X },
- { // f350_400[]
+ { // f350_400[] 19
X 31006, // A1 = 1.892517
X -32029, // A2 = -0.977448
X -461, // B2 = -0.014096
@@ -7421,21 +8984,19 @@
X 159, // Minimum in-band energy threshold
X 21, // 21/32 in-band to broad-band ratio
X 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
- },};
-
+ },
+};


X static int ixj_init_filter(int board, IXJ_FILTER * jf)

X {
X unsigned short cmd;

X int cnt, max;


X IXJ *j = &ixj[board];
-

X if (jf->filter > 3) {
X return -1;
X }
X if (ixj_WriteDSPCommand(0x5154 + jf->filter, board)) // Select Filter


X
X return -1;
-

X if (!jf->enable) {
X if (ixj_WriteDSPCommand(0x5152, board)) // Disable Filter
X
@@ -7446,7 +9007,6 @@
X if (ixj_WriteDSPCommand(0x5153, board)) // Enable Filter


X
X return -1;
-

X // Select the filter (f0 - f3) to use.
X if (ixj_WriteDSPCommand(0x5154 + jf->filter, board))
X return -1;
@@ -7463,7 +9023,6 @@
X // frequency we want.
X if (ixj_WriteDSPCommand(0x5170 + jf->filter, board))
X return -1;
-
X if (j->ver.low != 0x12) {
X cmd = 0x515B;
X max = 19;
@@ -7473,23 +9032,12 @@
X }


X if (ixj_WriteDSPCommand(cmd, board))
X return -1;

-
X for (cnt = 0; cnt < max; cnt++) {
- if (ixj_WriteDSPCommand(tone_table[jf->freq][cnt], board))
+ if (ixj_WriteDSPCommand(tone_table[jf->freq - 12][cnt], board))
X return -1;
X }
-/* if(j->ver.low != 0x12)
- {
- if(ixj_WriteDSPCommand(7, board))
- return -1;
- if(ixj_WriteDSPCommand(159, board))
- return -1;
- if(ixj_WriteDSPCommand(21, board))
- return -1;
- if(ixj_WriteDSPCommand(0x0FF5, board))
- return -1;
- } */
X }
+ j->filter_en[jf->filter] = jf->enable;


X return 0;
X }
X

@@ -7497,7 +9045,6 @@
X {
X int freq0, freq1;
X unsigned short data;
-
X if (ti->freq0) {
X freq0 = ti->freq0;
X } else {
@@ -7510,18 +9057,15 @@
X freq1 = 0x7FFF;
X }
X
-// if(ti->tone_index > 12 && ti->tone_index < 28)
+ if(ti->tone_index > 12 && ti->tone_index < 28)
X {
X if (ixj_WriteDSPCommand(0x6800 + ti->tone_index, board))
X return -1;
-
X if (ixj_WriteDSPCommand(0x6000 + (ti->gain0 << 4) + ti->gain1, board))
X return -1;
-
X data = freq0;
X if (ixj_WriteDSPCommand(data, board))
X return -1;
-
X data = freq1;
X if (ixj_WriteDSPCommand(data, board))
X return -1;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/telephony/ixj.h linux/drivers/telephony/ixj.h
--- v2.4.0-test8/linux/drivers/telephony/ixj.h Wed Dec 29 17:13:59 1999
+++ linux/drivers/telephony/ixj.h Mon Sep 18 15:02:03 2000
@@ -1,4 +1,4 @@
-/*
+/******************************************************************************
X * ixj.h


X *
X * Device Driver for the Internet PhoneJACK and

@@ -22,9 +22,20 @@


X * at our website: http://www.quicknet.net
X *

X * Fixes:
- * Linux 2.3 port, Alan Cox
- */
-static char ixj_h_rcsid[] = "$Id: ixj.h,v 3.4 1999/12/16 22:18:36 root Exp root $";
+ *


+ * IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF QUICKNET
+ * TECHNOLOGIES, INC.HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * QUICKNET TECHNOLOGIES, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND QUICKNET TECHNOLOGIES, INC. HAS NO OBLIGATION
+ * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *

+ *****************************************************************************/
+static char ixj_h_rcsid[] = "$Id: ixj.h,v 3.14 2000/03/30 22:06:48 eokerson Exp $";
X
X #ifndef _I386_TYPES_H
X #include <asm/types.h>
@@ -61,6 +72,27 @@
X unsigned char high;
X } BYTES;
X
+typedef union {
+ BYTES bytes;
+ short word;
+} IXJ_WORD;
+
+typedef struct{
+ unsigned int b0:1;
+ unsigned int b1:1;
+ unsigned int b2:1;
+ unsigned int b3:1;
+ unsigned int b4:1;
+ unsigned int b5:1;
+ unsigned int b6:1;
+ unsigned int b7:1;
+} IXJ_CBITS;
+
+typedef union{
+ IXJ_CBITS cbits;
+ char cbyte;
+} IXJ_CBYTE;
+
X int ixj_WriteDSPCommand(unsigned short, int board);
X
X /******************************************************************************
@@ -328,6 +360,199 @@


X
X /******************************************************************************
X *

+* These structures deal with the control logic on the Internet PhoneCARD
+*
+******************************************************************************/
+typedef struct {
+ unsigned int x0:4; // unused bits
+
+ unsigned int ed:1; // Event Detect
+
+ unsigned int drf:1; // Smart Cable Removal Flag 1=no cable
+
+ unsigned int dspf:1; // DSP Flag 1=DSP Ready
+
+ unsigned int crr:1; // Control Register Ready
+
+} COMMAND_REG1;
+
+typedef union {
+ COMMAND_REG1 bits;
+ unsigned char byte;
+} PCMCIA_CR1;
+
+typedef struct {
+ unsigned int x0:4; // unused bits
+
+ unsigned int rstc:1; // Smart Cable Reset
+
+ unsigned int pwr:1; // Smart Cable Power
+
+ unsigned int x1:2; // unused bits
+
+} COMMAND_REG2;
+
+typedef union {
+ COMMAND_REG2 bits;
+ unsigned char byte;
+} PCMCIA_CR2;
+
+typedef struct {
+ unsigned int addr:5; // R/W Smart Cable Register Address
+
+ unsigned int rw:1; // Read / Write flag
+
+ unsigned int dev:2; // 2 bit Smart Cable Device Address
+
+} CONTROL_REG;
+
+typedef union {
+ CONTROL_REG bits;
+ unsigned char byte;
+} PCMCIA_SCCR;
+
+typedef struct {
+ unsigned int hsw:1;
+ unsigned int det:1;
+ unsigned int led2:1;
+ unsigned int led1:1;
+ unsigned int ring1:1;
+ unsigned int ring0:1;
+ unsigned int x:1;
+ unsigned int powerdown:1;
+} PCMCIA_SLIC_REG;
+
+typedef union {
+ PCMCIA_SLIC_REG bits;
+ unsigned char byte;
+} PCMCIA_SLIC;
+
+typedef struct {
+ unsigned int cpd:1; // Chip Power Down
+
+ unsigned int mpd:1; // MIC Bias Power Down
+
+ unsigned int hpd:1; // Handset Drive Power Down
+
+ unsigned int lpd:1; // Line Drive Power Down
+
+ unsigned int spd:1; // Speaker Drive Power Down
+
+ unsigned int x:2; // unused bits
+
+ unsigned int sr:1; // Software Reset
+
+} Si3CONTROL1;
+
+typedef union {
+ Si3CONTROL1 bits;
+ unsigned char byte;
+} Si3C1;
+
+typedef struct {
+ unsigned int al:1; // Analog Loopback DAC analog -> ADC analog
+
+ unsigned int dl2:1; // Digital Loopback DAC -> ADC one bit
+
+ unsigned int dl1:1; // Digital Loopback ADC -> DAC one bit
+
+ unsigned int pll:1; // 1 = div 10, 0 = div 5
+
+ unsigned int hpd:1; // HPF disable
+
+ unsigned int x:3; // unused bits
+
+} Si3CONTROL2;
+
+typedef union {
+ Si3CONTROL2 bits;
+ unsigned char byte;
+} Si3C2;
+
+typedef struct {
+ unsigned int iir:1; // 1 enables IIR, 0 enables FIR
+
+ unsigned int him:1; // Handset Input Mute
+
+ unsigned int mcm:1; // MIC In Mute
+
+ unsigned int mcg:2; // MIC In Gain
+
+ unsigned int lim:1; // Line In Mute
+
+ unsigned int lig:2; // Line In Gain
+
+} Si3RXGAIN;
+
+typedef union {
+ Si3RXGAIN bits;
+ unsigned char byte;
+} Si3RXG;
+
+typedef struct {
+ unsigned int hom:1; // Handset Out Mute
+
+ unsigned int lom:1; // Line Out Mute
+
+ unsigned int rxg:5; // RX PGA Gain
+
+ unsigned int x:1; // unused bit
+
+} Si3ADCVOLUME;
+
+typedef union {
+ Si3ADCVOLUME bits;
+ unsigned char byte;
+} Si3ADC;
+
+typedef struct {
+ unsigned int srm:1; // Speaker Right Mute
+
+ unsigned int slm:1; // Speaker Left Mute
+
+ unsigned int txg:5; // TX PGA Gain
+
+ unsigned int x:1; // unused bit
+
+} Si3DACVOLUME;
+
+typedef union {
+ Si3DACVOLUME bits;
+ unsigned char byte;
+} Si3DAC;
+
+typedef struct {
+ unsigned int x:5; // unused bit
+
+ unsigned int losc:1; // Line Out Short Circuit
+
+ unsigned int srsc:1; // Speaker Right Short Circuit
+
+ unsigned int slsc:1; // Speaker Left Short Circuit
+
+} Si3STATUSREPORT;
+
+typedef union {
+ Si3STATUSREPORT bits;
+ unsigned char byte;
+} Si3STAT;
+
+typedef struct {
+ unsigned int sot:2; // Speaker Out Attenuation
+
+ unsigned int lot:2; // Line Out Attenuation
+
+ unsigned int x:4; // unused bits
+
+} Si3ANALOGATTN;
+
+typedef union {
+ Si3ANALOGATTN bits;
+ unsigned char byte;
+} Si3AATT;
+
+/******************************************************************************
+*
X * These structures deal with the DAA on the Internet LineJACK
X *
X ******************************************************************************/
@@ -855,10 +1080,49 @@
X };
X
X typedef struct {
+ char enable;
+ char en_filter;
+ unsigned int filter;
+ unsigned int state; // State 0 when cadence has not started.
+
+ unsigned int on1; // State 1
+
+ unsigned long on1min; // State 1 - 10% + jiffies
+ unsigned long on1dot; // State 1 + jiffies
+
+ unsigned long on1max; // State 1 + 10% + jiffies
+
+ unsigned int off1; // State 2
+
+ unsigned long off1min;
+ unsigned long off1max;
+ unsigned int on2; // State 3
+
+ unsigned long on2min;
+ unsigned long on2dot;
+ unsigned long on2max;
+ unsigned int off2; // State 4
+
+ unsigned long off2min;
+ unsigned long off2max;
+ unsigned int on3; // State 5
+
+ unsigned long on3min;
+ unsigned long on3dot;
+ unsigned long on3max;
+ unsigned int off3; // State 6
+
+ unsigned long off3min;
+ unsigned long off3max;
+} IXJ_CADENCE_F;
+
+typedef struct {
X unsigned int busytone:1;
X unsigned int dialtone:1;
X unsigned int ringback:1;
X unsigned int ringing:1;
+ unsigned int playing:1;
+ unsigned int recording:1;
X unsigned int cringing:1;
X unsigned int play_first_frame:1;
X unsigned int pstn_present:1;
@@ -869,6 +1133,28 @@
X unsigned int ts85_loaded:1;
X unsigned int dtmf_oob:1; // DTMF Out-Of-Band
X
+ unsigned int pcmciascp:1; // Smart Cable Present
+
+ unsigned int pcmciasct:2; // Smart Cable Type
+
+ unsigned int pcmciastate:3; // Smart Cable Init State
+
+ unsigned int inwrite:1; // Currently writing
+
+ unsigned int inread:1; // Currently reading
+
+ unsigned int incheck:1; // Currently checking the smart cable
+
+ unsigned int cidplay:1; // Currently playing Caller ID
+
+ unsigned int cidring:1; // This is the ring for Caller ID
+
+ unsigned int cidsent:1; // Caller ID has been sent
+
+ unsigned int cidcw_ack:1; // Caller ID CW ACK (from CPE)
+
+ unsigned int x:6; // unsed bits
+
X } IXJ_FLAGS;
X
X /******************************************************************************
@@ -885,15 +1171,19 @@
X unsigned int serial;
X struct phone_capability caplist[30];
X unsigned int caps;
+ unsigned int country;
X struct pci_dev *dev;
X unsigned int cardtype;
X unsigned int rec_codec;
X char rec_mode;
X unsigned int play_codec;
+ unsigned int cid_play_codec;
X char play_mode;
X IXJ_FLAGS flags;
X unsigned int rec_frame_size;
X unsigned int play_frame_size;
+ unsigned int cid_base_frame_size;
+ unsigned long cidcw_wait;
X int aec_level;
X int readers, writers;
X wait_queue_head_t poll_q;
@@ -920,6 +1210,7 @@
X char maxrings;
X IXJ_CADENCE *cadence_t;
X int tone_cadence_state;
+ IXJ_CADENCE_F cadence_f[4];
X DTMF dtmf;
X CPTF cptf;
X BYTES dsp;
@@ -934,30 +1225,50 @@
X PLD_SLICW pld_slicw;
X PLD_SLICR pld_slicr;
X PLD_CLOCK pld_clock;
+ PCMCIA_CR1 pccr1;
+ PCMCIA_CR2 pccr2;
+ PCMCIA_SCCR psccr;
+ PCMCIA_SLIC pslic;
+ char pscdd;
+ Si3C1 sic1;
+ Si3C2 sic2;
+ Si3RXG sirxg;
+ Si3ADC siadc;
+ Si3DAC sidac;
+ Si3STAT sistat;
+ Si3AATT siaatt;
X MIX mix;
X unsigned short ring_cadence;
X int ring_cadence_t;
X unsigned long ring_cadence_jif;
+ unsigned long checkwait;
X int intercom;
X int m_hook;
X int r_hook;
X char pstn_envelope;
X char pstn_cid_intr;
+ unsigned char fskz;
+ unsigned char fskphase;
+ unsigned char fskcnt;
X unsigned pstn_cid_recieved;
- IXJ_CID cid;
+ PHONE_CID cid;
+ PHONE_CID cid_send;
X unsigned long pstn_ring_start;
+ unsigned long pstn_ring_stop;
X unsigned long pstn_winkstart;
X unsigned int winktime;
+ unsigned long flash_end;
X char port;
X union telephony_exception ex;
X char daa_mode;
+ char daa_country;
X unsigned long pstn_sleeptil;
X DAA_REGS m_DAAShadowRegs;
X Proc_Info_Type Info_read;
X Proc_Info_Type Info_write;
X unsigned short frame_count;
- unsigned int filter_cadence;
X unsigned int filter_hist[4];
+ unsigned char filter_en[4];
X unsigned short proc_load;
X unsigned long framesread;
X unsigned long frameswritten;
@@ -966,6 +1277,8 @@
X unsigned long timerchecks;
X unsigned long txreadycheck;
X unsigned long rxreadycheck;
+ short fskdata[8000];
+ int fskdcnt;
X } IXJ;
X
X typedef int (*IXJ_REGFUNC) (IXJ * j, unsigned long arg);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/telephony/phonedev.c linux/drivers/telephony/phonedev.c
--- v2.4.0-test8/linux/drivers/telephony/phonedev.c Mon Jul 24 17:04:12 2000
+++ linux/drivers/telephony/phonedev.c Tue Sep 19 08:31:53 2000
@@ -14,7 +14,6 @@
X * phone_register_device now works with unit!=PHONE_UNIT_ANY


X */
X
-#include <linux/config.h>

X #include <linux/version.h>
X #include <linux/module.h>
X #include <linux/types.h>
@@ -24,6 +23,7 @@
X #include <linux/string.h>
X #include <linux/errno.h>
X #include <linux/phonedev.h>
+#include <linux/init.h>
X #include <asm/uaccess.h>
X #include <asm/system.h>
X
@@ -143,40 +143,29 @@
X * Board init functions
X */
X
-extern int ixj_init(void);
X
X /*
X * Initialise Telephony for linux
X */
X
-int telephony_init(void)
+static int __init telephony_init(void)
X {
X printk(KERN_INFO "Linux telephony interface: v1.00\n");
X if (register_chrdev(PHONE_MAJOR, "telephony", &phone_fops)) {
X printk("phonedev: unable to get major %d\n", PHONE_MAJOR);
X return -EIO;
X }
- /*
- * Init kernel installed drivers
- */
-#ifdef CONFIG_PHONE_IXJ
- ixj_init();
-#endif


- return 0;
-}
X

-#ifdef MODULE
-int init_module(void)
-{
- return telephony_init();


+ return 0;
X }
X

-void cleanup_module(void)
+static void __exit telephony_exit(void)
X {
X unregister_chrdev(PHONE_MAJOR, "telephony");
X }
X
-#endif
+module_init(telephony_init);
+module_exit(telephony_exit);
X
X EXPORT_SYMBOL(phone_register_device);
X EXPORT_SYMBOL(phone_unregister_device);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/Config.in linux/drivers/usb/Config.in
--- v2.4.0-test8/linux/drivers/usb/Config.in Tue Aug 22 15:20:52 2000
+++ linux/drivers/usb/Config.in Mon Sep 18 15:23:30 2000
@@ -72,6 +72,7 @@
X dep_tristate ' USB Diamond Rio500 support (EXPERIMENTAL)' CONFIG_USB_RIO500 $CONFIG_USB
X dep_tristate ' D-Link USB FM radio support (EXPERIMENTAL)' CONFIG_USB_DSBR $CONFIG_USB $CONFIG_VIDEO_DEV
X dep_tristate ' USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB
+ dep_tristate ' NetChip 1080-based USB Host-to-Host Link (EXPERIMENTAL)' CONFIG_USB_NET1080 $CONFIG_USB $CONFIG_NET
X fi
X
X comment 'USB Human Interface Devices (HID)'
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/Makefile linux/drivers/usb/Makefile
--- v2.4.0-test8/linux/drivers/usb/Makefile Mon Aug 28 16:59:14 2000
+++ linux/drivers/usb/Makefile Wed Sep 27 13:53:56 2000
@@ -6,7 +6,6 @@
X
X SUB_DIRS :=
X MOD_SUB_DIRS := $(SUB_DIRS)
-MOD_IN_SUB_DIRS := $(SUB_DIRS)
X ALL_SUB_DIRS := $(SUB_DIRS) serial storage
X
X # The target object and module list name.
@@ -65,6 +64,7 @@
X obj-$(CONFIG_USB_DSBR) += dsbr100.o
X obj-$(CONFIG_USB_MICROTEK) += microtek.o
X obj-$(CONFIG_USB_BLUETOOTH) += bluetooth.o
+obj-$(CONFIG_USB_NET1080) += net1080.o
X
X # Object files in subdirectories
X
@@ -73,7 +73,7 @@
X obj-y += serial/usb-serial.o
X else
X ifeq ($(CONFIG_USB_SERIAL),m)
- MOD_IN_SUB_DIRS += serial
+ MOD_SUB_DIRS += serial
X endif
X endif
X
@@ -82,7 +82,7 @@
X obj-y += storage/storage.o
X else
X ifeq ($(CONFIG_USB_STORAGE),m)
- MOD_IN_SUB_DIRS += storage
+ MOD_SUB_DIRS += storage
X endif
X endif
X
@@ -98,10 +98,6 @@
X

X obj-m := $(filter-out $(obj-y), $(obj-m))
X int-m := $(filter-out $(int-y), $(int-m))

-


-# Take multi-part drivers out of obj-y and put components in.
-
-obj-y := $(filter-out $(list-multi), $(obj-y)) $(int-y)

X
X # Translate to Rules.make lists.
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/acm.c linux/drivers/usb/acm.c
--- v2.4.0-test8/linux/drivers/usb/acm.c Thu Jul 27 18:36:54 2000
+++ linux/drivers/usb/acm.c Mon Sep 18 15:23:30 2000
@@ -49,7 +49,7 @@
X #include <linux/tty_flip.h>
X #include <linux/tty.h>
X #include <linux/module.h>
-#define DEBUG
+#undef DEBUG
X #include <linux/usb.h>
X
X /*
@@ -559,9 +559,11 @@
X
X FILL_BULK_URB(&acm->readurb, dev, usb_rcvbulkpipe(dev, epread->bEndpointAddress),
X buf += ctrlsize, readsize, acm_read_bulk, acm);
+ acm->readurb.transfer_flags |= USB_NO_FSBR;
X
X FILL_BULK_URB(&acm->writeurb, dev, usb_sndbulkpipe(dev, epwrite->bEndpointAddress),
X buf += readsize, acm->writesize, acm_write_bulk, acm);
+ acm->writeurb.transfer_flags |= USB_NO_FSBR;
X
X printk(KERN_INFO "ttyACM%d: USB ACM device\n", minor);
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/dabusb.h linux/drivers/usb/dabusb.h
--- v2.4.0-test8/linux/drivers/usb/dabusb.h Mon Jun 19 13:42:41 2000
+++ linux/drivers/usb/dabusb.h Tue Oct 3 09:24:40 2000
@@ -23,7 +23,7 @@
X wait_queue_head_t wait;
X wait_queue_head_t remove_ok;
X spinlock_t lock;
- volatile atomic_t pending_io;
+ atomic_t pending_io;
X driver_state_t state;
X int remove_pending;
X int got_mem;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/dc2xx.c linux/drivers/usb/dc2xx.c
--- v2.4.0-test8/linux/drivers/usb/dc2xx.c Tue Aug 22 11:48:54 2000
+++ linux/drivers/usb/dc2xx.c Mon Sep 25 16:18:55 2000
@@ -1,5 +1,5 @@
X /*
- * Copyright (C) 1999-2000 by David Brownell <dav...@pacbell.net>
+ * Copyright (C) 1999-2000 by David Brownell <dbro...@users.sourceforge.net>
X *
X * This program is free software; you can redistribute it and/or modify it
X * under the terms of the GNU General Public License as published by the
@@ -90,6 +90,7 @@
X /* These have the same application level protocol */
X { 0x040a, 0x0120 }, // Kodak DC-240
X { 0x040a, 0x0130 }, // Kodak DC-280
+ { 0x040a, 0x0132 }, // Kodak DC-3400
X
X /* These have a different application level protocol which
X * is part of the Flashpoint "DigitaOS". That supports some
@@ -498,7 +499,7 @@
X }
X
X
-MODULE_AUTHOR("David Brownell, dav...@pacbell.net");
+MODULE_AUTHOR("David Brownell, <dbro...@users.sourceforge.net>");
X MODULE_DESCRIPTION("USB Camera Driver for Kodak DC-2xx series cameras");
X
X module_init (usb_dc2xx_init);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/devices.c linux/drivers/usb/devices.c
--- v2.4.0-test8/linux/drivers/usb/devices.c Mon Jul 24 19:04:33 2000
+++ linux/drivers/usb/devices.c Mon Sep 25 15:25:29 2000
@@ -496,8 +496,10 @@
X lock_kernel();
X if (!st) {
X st = kmalloc(sizeof(struct usb_device_status), GFP_KERNEL);
- if (!st)
+ if (!st) {
+ unlock_kernel();
X return POLLIN;
+ }
X /*
X * need to prevent the module from being unloaded, since
X * proc_unregister does not call the release method and
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/devio.c linux/drivers/usb/devio.c
--- v2.4.0-test8/linux/drivers/usb/devio.c Tue Aug 29 14:09:15 2000
+++ linux/drivers/usb/devio.c Wed Sep 27 13:53:57 2000
@@ -55,113 +55,6 @@
X urb_t urb;
X };
X
-/*
- * my own sync control and bulk methods. Here to experiment
- * and because the kernel ones set the process to TASK_UNINTERRUPTIBLE.
- */
-
-struct sync {
- wait_queue_head_t wait;
-};
-
-static void sync_completed(purb_t urb)
-{
- struct sync *s = (struct sync *)urb->context;
-
- wake_up(&s->wait);
-}
-
-static int do_sync(purb_t urb, int timeout)
-{
- DECLARE_WAITQUEUE(wait, current);
- unsigned long tm;
- signed long tmdiff;
- struct sync s;
- int ret;
-
- tm = jiffies+timeout;
- init_waitqueue_head(&s.wait);
- add_wait_queue(&s.wait, &wait);
- urb->context = &s;
- urb->complete = sync_completed;
- set_current_state(TASK_INTERRUPTIBLE);
- if ((ret = usb_submit_urb(urb)))
- goto out;
- while (urb->status == -EINPROGRESS) {
- tmdiff = tm - jiffies;
- if (tmdiff <= 0) {
- ret = -ETIMEDOUT;
- goto out;
- }
- if (signal_pending(current)) {
- ret = -EINTR;
- goto out;
- }
- schedule_timeout(tmdiff);
- }
- ret = urb->status;
- out:
- set_current_state(TASK_RUNNING);
- usb_unlink_urb(urb);
- remove_wait_queue(&s.wait, &wait);
- return ret;
-}
-
-static int my_usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype,
- __u16 value, __u16 index, void *data, __u16 size, int timeout)
-{
- urb_t *urb;
- int ret;
-
- if (!(urb = usb_alloc_urb(0)))
- return -ENOMEM;
- if (!(urb->setup_packet = kmalloc(8, GFP_KERNEL))) {
- usb_free_urb(urb);
- return -ENOMEM;
- }
- urb->setup_packet[0] = requesttype;
- urb->setup_packet[1] = request;
- urb->setup_packet[2] = value;
- urb->setup_packet[3] = value >> 8;
- urb->setup_packet[4] = index;
- urb->setup_packet[5] = index >> 8;
- urb->setup_packet[6] = size;
- urb->setup_packet[7] = size >> 8;
- urb->dev = dev;
- urb->pipe = pipe;
- urb->transfer_buffer = data;
- urb->transfer_buffer_length = size;
- ret = do_sync(urb, timeout);
- //if (ret >= 0)
- // ret = urb->status;
- if (ret >= 0)
- ret = urb->actual_length;
- kfree(urb->setup_packet);
- usb_free_urb(urb);
- return ret;
-}
-
-static int my_usb_bulk_msg(struct usb_device *dev, unsigned int pipe,
- void *data, int len, int *actual_length, int timeout)
-{
- urb_t *urb;
- int ret;
-
- if (!(urb = usb_alloc_urb(0)))
- return -ENOMEM;
- urb->dev = dev;
- urb->pipe = pipe;
- urb->transfer_buffer = data;
- urb->transfer_buffer_length = len;
- ret = do_sync(urb, timeout);
- //if (ret >= 0)
- // ret = urb->status;
- if (ret >= 0 && actual_length != NULL)
- *actual_length = urb->actual_length;
- usb_free_urb(urb);
- return ret;
-}
-
X static loff_t usbdev_lseek(struct file *file, loff_t offset, int orig)
X {
X switch (orig) {


@@ -289,6 +182,8 @@
X {

X if (as->urb.transfer_buffer)
X kfree(as->urb.transfer_buffer);
+ if (as->urb.setup_packet)
+ kfree(as->urb.setup_packet);
X kfree(as);
X }
X
@@ -536,6 +431,28 @@
X }
X #endif
X
+static int check_ctrlrecip(struct dev_state *ps, unsigned int recip, unsigned int index)
+{
+ int ret;
+
+ switch (recip & USB_RECIP_MASK) {
+ case USB_RECIP_ENDPOINT:
+ if ((ret = findintfep(ps->dev, index & 0xff)) < 0)
+ return ret;
+ if ((ret = checkintf(ps, ret)))
+ return ret;
+ break;
+
+ case USB_RECIP_INTERFACE:
+ if ((ret = findintfif(ps->dev, index & 0xff)) < 0)
+ return ret;
+ if ((ret = checkintf(ps, ret)))
+ return ret;
+ break;
+ }


+ return 0;
+}
+

X /*
X * file operations
X */
@@ -609,21 +526,8 @@
X
X if (copy_from_user(&ctrl, (void *)arg, sizeof(ctrl)))
X return -EFAULT;
- switch (ctrl.requesttype & 0x1f) {
- case USB_RECIP_ENDPOINT:
- if ((ret = findintfep(ps->dev, ctrl.index & 0xff)) < 0)
- return ret;
- if ((ret = checkintf(ps, ret)))
- return ret;
- break;
-
- case USB_RECIP_INTERFACE:
- if ((ret = findintfif(ps->dev, ctrl.index & 0xff)) < 0)
- return ret;
- if ((ret = checkintf(ps, ret)))
- return ret;
- break;
- }
+ if ((ret = check_ctrlrecip(ps, ctrl.requesttype, ctrl.index)))
+ return ret;
X if (ctrl.length > PAGE_SIZE)
X return -EINVAL;
X if (!(tbuf = (unsigned char *)__get_free_page(GFP_KERNEL)))
@@ -634,7 +538,7 @@
X free_page((unsigned long)tbuf);
X return -EINVAL;
X }
- i = my_usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ctrl.request, ctrl.requesttype,
+ i = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ctrl.request, ctrl.requesttype,
X ctrl.value, ctrl.index, tbuf, ctrl.length, tmo);
X if ((i > 0) && ctrl.length) {
X if (copy_to_user(ctrl.data, tbuf, ctrl.length))
@@ -645,7 +549,7 @@
X if (copy_from_user(tbuf, ctrl.data, ctrl.length))
X return -EFAULT;
X }
- i = my_usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ctrl.request, ctrl.requesttype,
+ i = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ctrl.request, ctrl.requesttype,
X ctrl.value, ctrl.index, tbuf, ctrl.length, tmo);
X }
X free_page((unsigned long)tbuf);
@@ -688,7 +592,7 @@
X free_page((unsigned long)tbuf);
X return -EINVAL;
X }
- i = my_usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo);
+ i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo);
X if (!i && len2) {
X if (copy_to_user(bulk.data, tbuf, len2))
X return -EFAULT;
@@ -698,7 +602,7 @@
X if (copy_from_user(tbuf, bulk.data, len1))
X return -EFAULT;
X }
- i = my_usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo);
+ i = usb_bulk_msg(dev, pipe, tbuf, len1, &len2, tmo);
X }
X free_page((unsigned long)tbuf);
X if (i < 0) {
@@ -840,23 +744,61 @@
X {
X struct usbdevfs_urb uurb;
X struct usbdevfs_iso_packet_desc *isopkt = NULL;
+ struct usb_endpoint_descriptor *ep_desc;
X struct async *as;
+ devrequest *dr = NULL;
X unsigned int u, totlen, isofrmlen;
X int ret;
X
X if (copy_from_user(&uurb, arg, sizeof(uurb)))
X return -EFAULT;
- if (uurb.flags & ~(USBDEVFS_URB_ISO_ASAP|USBDEVFS_URB_DISABLE_SPD))
+ if (uurb.flags & ~(USBDEVFS_URB_ISO_ASAP|USBDEVFS_URB_DISABLE_SPD|USBDEVFS_URB_QUEUE_BULK))
X return -EINVAL;
X if (!uurb.buffer)
X return -EINVAL;
X if (uurb.signr != 0 && (uurb.signr < SIGRTMIN || uurb.signr > SIGRTMAX))
X return -EINVAL;
- if ((ret = findintfep(ps->dev, uurb.endpoint)) < 0)
- return ret;
- if ((ret = checkintf(ps, ret)))
- return ret;
+ if (!(uurb.type == USBDEVFS_URB_TYPE_CONTROL && (uurb.endpoint & ~USB_ENDPOINT_DIR_MASK) == 0)) {
+ if ((ret = findintfep(ps->dev, uurb.endpoint)) < 0)
+ return ret;
+ if ((ret = checkintf(ps, ret)))
+ return ret;
+ }
X switch(uurb.type) {
+ case USBDEVFS_URB_TYPE_CONTROL:
+ if ((uurb.endpoint & ~USB_ENDPOINT_DIR_MASK) != 0) {
+ if (!(ep_desc = usb_epnum_to_ep_desc(ps->dev, uurb.endpoint)))
+ return -ENOENT;
+ if ((ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_CONTROL)
+ return -EINVAL;
+ }
+ /* min 8 byte setup packet, max arbitrary */
+ if (uurb.buffer_length < 8 || uurb.buffer_length > PAGE_SIZE)
+ return -EINVAL;
+ if (!(dr = kmalloc(sizeof(devrequest), GFP_KERNEL)))
+ return -ENOMEM;
+ if (copy_from_user(dr, (unsigned char*)uurb.buffer, 8)) {
+ kfree(dr);
+ return -EFAULT;
+ }
+ if (uurb.buffer_length < (le16_to_cpup(&dr->length) + 8)) {
+ kfree(dr);
+ return -EINVAL;
+ }
+ if ((ret = check_ctrlrecip(ps, dr->requesttype, le16_to_cpup(&dr->index)))) {
+ kfree(dr);
+ return ret;
+ }
+ uurb.endpoint = (uurb.endpoint & ~USB_ENDPOINT_DIR_MASK) | (dr->requesttype & USB_ENDPOINT_DIR_MASK);
+ uurb.number_of_packets = 0;
+ uurb.buffer_length = le16_to_cpup(&dr->length);
+ uurb.buffer += 8;
+ if (!access_ok((uurb.endpoint & USB_DIR_IN) ? VERIFY_WRITE : VERIFY_READ, uurb.buffer, uurb.buffer_length)) {
+ kfree(dr);
+ return -EFAULT;
+ }
+ break;
+
X case USBDEVFS_URB_TYPE_BULK:
X uurb.number_of_packets = 0;
X if (uurb.buffer_length > 16384)
@@ -896,11 +838,15 @@
X if (!(as = alloc_async(uurb.number_of_packets))) {
X if (isopkt)
X kfree(isopkt);
+ if (dr)
+ kfree(dr);
X return -ENOMEM;
X }
X if (!(as->urb.transfer_buffer = kmalloc(uurb.buffer_length, GFP_KERNEL))) {
X if (isopkt)
X kfree(isopkt);
+ if (dr)
+ kfree(dr);
X free_async(as);
X return -ENOMEM;
X }
@@ -909,6 +855,7 @@
X as->urb.pipe = (uurb.type << 30) | __create_pipe(ps->dev, uurb.endpoint & 0xf) | (uurb.endpoint & USB_DIR_IN);
X as->urb.transfer_flags = uurb.flags;
X as->urb.transfer_buffer_length = uurb.buffer_length;
+ as->urb.setup_packet = (unsigned char*)dr;
X as->urb.start_frame = uurb.start_frame;
X as->urb.number_of_packets = uurb.number_of_packets;
X as->urb.context = as;
@@ -963,20 +910,23 @@
X if (copy_to_user(as->userbuffer, as->urb.transfer_buffer, as->urb.transfer_buffer_length))
X return -EFAULT;
X if (put_user(as->urb.status,
- &((struct usbdevfs_urb *)as->userurb)->status) ||
- __put_user(as->urb.actual_length,
- &((struct usbdevfs_urb *)as->userurb)->actual_length) ||
- __put_user(as->urb.error_count,
- &((struct usbdevfs_urb *)as->userurb)->error_count))
+ &((struct usbdevfs_urb *)as->userurb)->status))
+ return -EFAULT;
+ if (put_user(as->urb.actual_length,
+ &((struct usbdevfs_urb *)as->userurb)->actual_length))
+ return -EFAULT;
+ if (put_user(as->urb.error_count,
+ &((struct usbdevfs_urb *)as->userurb)->error_count))
X return -EFAULT;
X
X if (!(usb_pipeisoc(as->urb.pipe)))
X return 0;
X for (i = 0; i < as->urb.number_of_packets; i++) {
X if (put_user(as->urb.iso_frame_desc[i].actual_length,
- &((struct usbdevfs_urb *)as->userurb)->iso_frame_desc[i].actual_length) ||
- __put_user(as->urb.iso_frame_desc[i].status,
- &((struct usbdevfs_urb *)as->userurb)->iso_frame_desc[i].status))
+ &((struct usbdevfs_urb *)as->userurb)->iso_frame_desc[i].actual_length))
+ return -EFAULT;
+ if (put_user(as->urb.iso_frame_desc[i].status,
+ &((struct usbdevfs_urb *)as->userurb)->iso_frame_desc[i].status))
X return -EFAULT;
X }
X return 0;
@@ -1090,7 +1040,7 @@
X kfree (buf);
X return -EFAULT;
X } else
- memset (arg, 0, size);
+ memset (buf, 0, size);
X }
X
X /* ioctl to device */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/hid.c linux/drivers/usb/hid.c
--- v2.4.0-test8/linux/drivers/usb/hid.c Tue Aug 22 09:06:31 2000
+++ linux/drivers/usb/hid.c Mon Oct 2 14:20:39 2000
@@ -1,5 +1,5 @@
X /*
- * $Id: hid.c,v 1.14 2000/08/14 21:05:26 vojtech Exp $
+ * $Id: hid.c,v 1.16 2000/09/18 21:38:55 vojtech Exp $
X *
X * Copyright (c) 1999 Andreas Gal
X * Copyright (c) 2000 Vojtech Pavlik
@@ -924,6 +924,8 @@
X usage->code = find_next_zero_bit(bit, max + 1, usage->code);
X }
X
+ if (usage->code > max) return;
+
X if (usage->type == EV_ABS) {
X int a = field->logical_minimum;
X int b = field->logical_maximum;
@@ -936,7 +938,7 @@
X
X if (usage->hat) {
X int i;
- for (i = usage->code; i < usage->code + 2; i++) {
+ for (i = usage->code; i < usage->code + 2 && i <= max; i++) {
X input->absmax[i] = 1;
X input->absmin[i] = -1;
X input->absfuzz[i] = 0;
@@ -1229,6 +1231,7 @@
X hid->urbout.transfer_buffer_length = hid->out[hid->outtail].dr.length;
X hid->urbout.transfer_buffer = hid->out[hid->outtail].buffer;
X hid->urbout.setup_packet = (void *) &(hid->out[hid->outtail].dr);
+ hid->urbout.dev = hid->dev;
X
X if (usb_submit_urb(&hid->urbout)) {
X err("usb_submit_urb(out) failed");
@@ -1286,7 +1289,9 @@
X if (hid->open++)
X return 0;
X
- if (usb_submit_urb(&hid->urb))
+ hid->urb.dev = hid->dev;
+
+ if (usb_submit_urb(&hid->urb))
X return -EIO;
X
X return 0;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/hub.c linux/drivers/usb/hub.c
--- v2.4.0-test8/linux/drivers/usb/hub.c Tue Sep 5 13:41:53 2000
+++ linux/drivers/usb/hub.c Thu Sep 28 13:20:48 2000
@@ -8,6 +8,7 @@
X
X #include <linux/config.h>
X #include <linux/kernel.h>
+#include <linux/module.h>
X #include <linux/sched.h>
X #include <linux/list.h>
X #include <linux/malloc.h>
@@ -76,30 +77,32 @@
X data, sizeof(struct usb_hub_status), HZ);
X }
X
-/*
- * A irq handler returns non-zero to indicate to
- * the low-level driver that it wants to be re-activated,
- * or zero to say "I'm done".
- */
X static void hub_irq(struct urb *urb)
X {
X struct usb_hub *hub = (struct usb_hub *)urb->context;


X unsigned long flags;
X

+ /* Cause a hub reset after 10 consecutive errors */
X if (urb->status) {
- if (urb->status != -ENOENT)
- dbg("nonzero status in irq %d", urb->status);
+ if (urb->status == -ENOENT)
+ return;
X
- return;
+ dbg("nonzero status in irq %d", urb->status);
+
+ if ((++hub->nerrors < 10) || hub->error)
+ return;
+
+ hub->error = urb->status;
X }
X
+ hub->nerrors = 0;
+
X /* Something happened, let khubd figure it out */
X if (waitqueue_active(&khubd_wait)) {
X /* Add the hub to the event queue */
X spin_lock_irqsave(&hub_event_lock, flags);
- if (hub->event_list.next == &hub->event_list) {
+ if (list_empty(&hub->event_list)) {
X list_add(&hub->event_list, &hub_event_list);
- /* Wake up khubd */
X wake_up(&khubd_wait);
X }
X spin_unlock_irqrestore(&hub_event_lock, flags);
@@ -114,40 +117,43 @@
X dbg("enabling power on all ports");
X for (i = 0; i < hub->nports; i++)
X usb_set_port_feature(hub->dev, i + 1, USB_PORT_FEAT_POWER);
+
+ /* Wait for power to be enabled */
+ wait_ms(hub->descriptor->bPwrOn2PwrGood * 2);
X }
X
-static int usb_hub_configure(struct usb_hub *hub)
+static int usb_hub_configure(struct usb_hub *hub, struct usb_endpoint_descriptor *endpoint)
X {
X struct usb_device *dev = hub->dev;
- unsigned char buffer[HUB_DESCRIPTOR_MAX_SIZE], *bitmap;
- struct usb_hub_descriptor *descriptor;
- struct usb_descriptor_header *header;
- struct usb_hub_status *hubsts;
- int i, ret;
+ struct usb_hub_status hubstatus;
+ char portstr[USB_MAXCHILDREN + 1];
+ unsigned int pipe;
+ int i, maxp, ret;
+
+ hub->descriptor = kmalloc(HUB_DESCRIPTOR_MAX_SIZE, GFP_KERNEL);
+ if (!hub->descriptor) {
+ err("Unable to kmalloc %d bytes for hub descriptor", HUB_DESCRIPTOR_MAX_SIZE);


+ return -1;
+ }
X

X /* Request the entire hub descriptor. */
- header = (struct usb_descriptor_header *)buffer;
- ret = usb_get_hub_descriptor(dev, buffer, sizeof(buffer));
- /* <buffer> is large enough for a hub with 127 ports;
+ ret = usb_get_hub_descriptor(dev, hub->descriptor, HUB_DESCRIPTOR_MAX_SIZE);
+ /* <hub->descriptor> is large enough for a hub with 127 ports;
X * the hub can/will return fewer bytes here. */
X if (ret < 0) {
X err("Unable to get hub descriptor (err = %d)", ret);


X return -1;
X }
X

- bitmap = kmalloc(header->bLength, GFP_KERNEL);
- if (!bitmap) {
- err("Unable to kmalloc %d bytes for bitmap", header->bLength);


- return -1;
- }
-

- memcpy (bitmap, buffer, header->bLength);
- descriptor = (struct usb_hub_descriptor *)bitmap;
-
- hub->nports = dev->maxchild = descriptor->bNbrPorts;
+ hub->nports = dev->maxchild = hub->descriptor->bNbrPorts;
X info("%d port%s detected", hub->nports, (hub->nports == 1) ? "" : "s");
X
- switch (descriptor->wHubCharacteristics & HUB_CHAR_LPSM) {
+ if (hub->descriptor->wHubCharacteristics & HUB_CHAR_COMPOUND)
+ dbg("part of a compound device");
+ else
+ dbg("standalone hub");
+
+ switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_LPSM) {
X case 0x00:
X dbg("ganged power switching");
X break;
@@ -160,12 +166,7 @@
X break;
X }
X
- if (descriptor->wHubCharacteristics & HUB_CHAR_COMPOUND)
- dbg("part of a compound device");
- else
- dbg("standalone hub");
-
- switch (descriptor->wHubCharacteristics & HUB_CHAR_OCPM) {
+ switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_OCPM) {
X case 0x00:
X dbg("global over-current protection");
X break;
@@ -178,28 +179,52 @@
X break;
X }
X
- dbg("power on to power good time: %dms", descriptor->bPwrOn2PwrGood * 2);
- dbg("hub controller current requirement: %dmA", descriptor->bHubContrCurrent);
+ dbg("power on to power good time: %dms", hub->descriptor->bPwrOn2PwrGood * 2);
+ dbg("hub controller current requirement: %dmA", hub->descriptor->bHubContrCurrent);
X
X for (i = 0; i < dev->maxchild; i++)
- dbg("port %d is%s removable", i + 1,
- bitmap[7 + ((i + 1)/8)] & (1 << ((i + 1) % 8))
- ? " not" : "");
+ portstr[i] = hub->descriptor->bitmap[((i + 1) / 8)] & (1 << ((i + 1) % 8)) ? 'F' : 'R';
+ portstr[dev->maxchild] = 0;
X
- kfree(bitmap);
+ dbg("port removable status: %s", portstr);
X
- ret = usb_get_hub_status(dev, buffer);
+ ret = usb_get_hub_status(dev, &hubstatus);
X if (ret < 0) {
X err("Unable to get hub status (err = %d)", ret);


X return -1;
X }
X

- hubsts = (struct usb_hub_status *)buffer;
+ le16_to_cpus(&hubstatus.wHubStatus);
+
X dbg("local power source is %s",
- (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_LOCAL_POWER) ? "lost (inactive)" : "good");
+ (hubstatus.wHubStatus & HUB_STATUS_LOCAL_POWER) ? "lost (inactive)" : "good");
X
X dbg("%sover-current condition exists",
- (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_OVERCURRENT) ? "" : "no ");
+ (hubstatus.wHubStatus & HUB_STATUS_OVERCURRENT) ? "" : "no ");
+
+ /* Start the interrupt endpoint */
+ pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
+ maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
+
+ if (maxp > sizeof(hub->buffer))
+ maxp = sizeof(hub->buffer);
+
+ hub->urb = usb_alloc_urb(0);
+ if (!hub->urb) {
+ err("couldn't allocate interrupt urb");


+ return -1;
+ }
+

+ FILL_INT_URB(hub->urb, dev, pipe, hub->buffer, maxp, hub_irq,


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 091'
echo 'File patch-2.4.0-test9 is continued in part 092'
echo "092" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part092

#!/bin/sh -x
# this is part 092 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 092; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ hub, endpoint->bInterval);
+ ret = usb_submit_urb(hub->urb);
+ if (ret) {
+ err("usb_submit_urb failed (%d)", ret);


+ return -1;
+ }
+

+ /* Wake up khubd */
+ wake_up(&khubd_wait);
X
X usb_hub_power_on(hub);
X
@@ -212,8 +237,6 @@
X struct usb_endpoint_descriptor *endpoint;
X struct usb_hub *hub;
X unsigned long flags;
- unsigned int pipe;
- int maxp, ret;
X
X interface = &dev->actconfig->interface[i].altsetting[0];
X
@@ -265,34 +288,11 @@
X list_add(&hub->hub_list, &hub_list);
X spin_unlock_irqrestore(&hub_event_lock, flags);
X
- if (usb_hub_configure(hub) >= 0) {
- pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
- maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
-
- if (maxp > sizeof(hub->buffer))
- maxp = sizeof(hub->buffer);
-
- hub->urb = usb_alloc_urb(0);
- if (!hub->urb) {
- err("couldn't allocate interrupt urb");
- goto fail;
- }
-
- FILL_INT_URB(hub->urb, dev, pipe, hub->buffer, maxp, hub_irq,
- hub, endpoint->bInterval);
- ret = usb_submit_urb(hub->urb);
- if (ret) {
- err("usb_submit_urb failed (%d)", ret);
- goto fail;
- }
-


- /* Wake up khubd */

- wake_up(&khubd_wait);
- }
+ if (usb_hub_configure(hub, endpoint) >= 0)
+ return hub;
X
- return hub;
+ err("hub configuration failed");
X
-fail:
X /* free hub, but first clean up its list. */
X spin_lock_irqsave(&hub_event_lock, flags);
X
@@ -330,11 +330,16 @@
X hub->urb = NULL;
X }
X
+ if (hub->descriptor) {
+ kfree(hub->descriptor);
+ hub->descriptor = NULL;
+ }
+
X /* Free the memory */
X kfree(hub);
X }
X
-static int hub_ioctl (struct usb_device *hub, unsigned int code, void *user_data)
+static int hub_ioctl(struct usb_device *hub, unsigned int code, void *user_data)
X {
X /* assert ifno == 0 (part of hub spec) */
X switch (code) {
@@ -343,19 +348,19 @@
X unsigned long flags;
X int i;
X
- spin_lock_irqsave (&hub_event_lock, flags);
+ spin_lock_irqsave(&hub_event_lock, flags);
X if (hub->devnum <= 0)
X info->nports = 0;
X else {
X info->nports = hub->maxchild;
X for (i = 0; i < info->nports; i++) {
- if (hub->children [i] == NULL)
- info->port [i] = 0;
+ if (hub->children[i] == NULL)
+ info->port[i] = 0;
X else
- info->port [i] = hub->children [i]->devnum;
+ info->port[i] = hub->children[i]->devnum;
X }
X }
- spin_unlock_irqrestore (&hub_event_lock, flags);
+ spin_unlock_irqrestore(&hub_event_lock, flags);
X
X return info->nports + 1;
X }
@@ -365,121 +370,260 @@
X }
X }
X
-static void usb_hub_port_connect_change(struct usb_device *hub, int port)
+static int usb_hub_reset(struct usb_hub *hub)
X {
- struct usb_device *usb;
- struct usb_port_status portsts;
- unsigned short portstatus, portchange;
- int ret, tries;
-
- wait_ms(100);
+ struct usb_device *dev = hub->dev;
+ int i;
X
- ret = usb_get_port_status(hub, port + 1, &portsts);
- if (ret < 0) {
- err("get_port_status(%d) failed (err = %d)", port + 1, ret);
- return;
+ /* Disconnect any attached devices */
+ for (i = 0; i < hub->nports; i++) {
+ if (dev->children[i])
+ usb_disconnect(&dev->children[i]);
X }
X
- portstatus = le16_to_cpu(portsts.wPortStatus);
- portchange = le16_to_cpu(portsts.wPortChange);
- dbg("portstatus %x, change %x, %s", portstatus, portchange,
- portstatus&(1<<USB_PORT_FEAT_LOWSPEED) ? "1.5 Mb/s" : "12 Mb/s");
+ /* Attempt to reset the hub */
+ if (hub->urb)
+ usb_unlink_urb(hub->urb);
+ else
+ return -1;
X
- /* Clear the connection change status */
- usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_C_CONNECTION);
+ if (usb_reset_device(dev))
+ return -1;
X
- /* Disconnect any existing devices under this port */
- if (((!(portstatus & USB_PORT_STAT_CONNECTION)) &&
- (!(portstatus & USB_PORT_STAT_ENABLE)))|| (hub->children[port])) {
- usb_disconnect(&hub->children[port]);
- /* Return now if nothing is connected */
- if (!(portstatus & USB_PORT_STAT_CONNECTION))
- return;
+ if (usb_submit_urb(hub->urb))
+ return -1;
+
+ usb_hub_power_on(hub);


+
+ return 0;
+}
+

+static void usb_hub_disconnect(struct usb_device *dev)
+{
+ struct usb_device *parent = dev->parent;
+ int i;
+
+ /* Find the device pointer to disconnect */
+ if (parent) {
+ for (i = 0; i < parent->maxchild; i++) {
+ if (parent->children[i] == dev) {
+ usb_disconnect(&parent->children[i]);
+ return;
+ }
+ }
X }
- wait_ms(400);
X
- down(&usb_address0_sem);
+ err("cannot disconnect hub %d", dev->devnum);
+}
X
-#define MAX_TRIES 5
- /* Reset the port */
- for (tries = 0; tries < MAX_TRIES ; tries++) {
- usb_set_port_feature(hub, port + 1, USB_PORT_FEAT_RESET);
- wait_ms(200);
+#define HUB_RESET_TRIES 5
+#define HUB_PROBE_TRIES 2
+#define HUB_SHORT_RESET_TIME 10
+#define HUB_LONG_RESET_TIME 200
+#define HUB_RESET_TIMEOUT 500
+
+static int usb_hub_port_wait_reset(struct usb_device *hub, int port,
+ struct usb_device *dev, unsigned int delay)
+{
+ int delay_time, ret;
+ struct usb_port_status portsts;
+ unsigned short portchange, portstatus;
+
+ for (delay_time = 0; delay_time < HUB_RESET_TIMEOUT; delay_time += delay) {
+ /* wait to give the device a chance to reset */
+ wait_ms(delay);
X
+ /* read and decode port status */
X ret = usb_get_port_status(hub, port + 1, &portsts);
X if (ret < 0) {
X err("get_port_status(%d) failed (err = %d)", port + 1, ret);
- goto out;
+ return -1;
X }
X
X portstatus = le16_to_cpu(portsts.wPortStatus);
X portchange = le16_to_cpu(portsts.wPortChange);
- dbg("portstatus %x, change %x, %s", portstatus ,portchange,
- portstatus&(1<<USB_PORT_FEAT_LOWSPEED) ? "1.5 Mb/s" : "12 Mb/s");
+ dbg("port %d, portstatus %x, change %x, %s", port + 1,
+ portstatus, portchange,
+ portstatus & (1 << USB_PORT_FEAT_LOWSPEED) ? "1.5 Mb/s" : "12 Mb/s");
X
+ /* bomb out completely if something weird happened */
X if ((portchange & USB_PORT_STAT_C_CONNECTION) ||
X !(portstatus & USB_PORT_STAT_CONNECTION))
- goto out;
+ return -1;
X
- if (portstatus & USB_PORT_STAT_ENABLE)
- break;
+ /* if we`ve finished resetting, then break out of the loop */
+ if (!(portstatus & USB_PORT_STAT_RESET) &&
+ (portstatus & USB_PORT_STAT_ENABLE)) {
+ dev->slow = (portstatus & USB_PORT_STAT_LOW_SPEED) ? 1 : 0;
+ return 0;
+ }
X
- wait_ms(200);
+ /* switch to the long delay after two short delay failures */
+ if (delay_time >= 2 * HUB_SHORT_RESET_TIME)
+ delay = HUB_LONG_RESET_TIME;
+
+ dbg("port %d of hub %d not reset yet, waiting %dms", port + 1,
+ hub->devnum, delay);
X }
X
- if (tries >= MAX_TRIES) {
- err("Cannot enable port %i after %i retries, disabling port.", port+1, MAX_TRIES);
- err("Maybe the USB cable is bad?");
- goto out;


+ return -1;
+}
+

+static int usb_hub_port_reset(struct usb_device *hub, int port,
+ struct usb_device *dev, unsigned int delay)
+{
+ int i;
+
+ /* Reset the port */
+ for (i = 0; i < HUB_RESET_TRIES; i++) {
+ usb_set_port_feature(hub, port + 1, USB_PORT_FEAT_RESET);
+
+ /* return success if the port reset OK */
+ if (!usb_hub_port_wait_reset(hub, port, dev, delay)) {
+ usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_C_RESET);


+ return 0;
+ }
+

+ dbg("port %d of hub %d not enabled, trying reset again...",
+ port + 1, hub->devnum);
+ delay = HUB_LONG_RESET_TIME;
X }
X
- usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_C_RESET);
+ err("Cannot enable port %i of hub %d, disabling port.",
+ port + 1, hub->devnum);
+ err("Maybe the USB cable is bad?");
+


+ return -1;
+}
+

+void usb_hub_port_disable(struct usb_device *hub, int port)


+{
+ int ret;
+

+ ret = usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_ENABLE);
+ if (ret)
+ err("cannot disable port %d of hub %d (err = %d)",
+ port + 1, hub->devnum, ret);
+}
+
+static void usb_hub_port_connect_change(struct usb_device *hub, int port,
+ struct usb_port_status *portsts)
+{
+ struct usb_device *dev;
+ unsigned short portstatus, portchange;
+ unsigned int delay = HUB_SHORT_RESET_TIME;
+ int i;
+ char *portstr, *tempstr;
+
+ portstatus = le16_to_cpu(portsts->wPortStatus);
+ portchange = le16_to_cpu(portsts->wPortChange);
+ dbg("port %d, portstatus %x, change %x, %s", port + 1, portstatus,
+ portchange, portstatus & (1 << USB_PORT_FEAT_LOWSPEED) ? "1.5 Mb/s" : "12 Mb/s");
+
+ /* Clear the connection change status */
+ usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_C_CONNECTION);
X
- /* Allocate a new device struct for it */
- usb = usb_alloc_dev(hub, hub->bus);
- if (!usb) {
- err("couldn't allocate usb_device");
- goto out;
+ /* Disconnect any existing devices under this port */
+ if (hub->children[port])
+ usb_disconnect(&hub->children[port]);
+
+ /* Return now if nothing is connected */
+ if (!(portstatus & USB_PORT_STAT_CONNECTION)) {
+ if (portstatus & USB_PORT_STAT_ENABLE)
+ usb_hub_port_disable(hub, port);
+
+ return;
X }
X
- usb->slow = (portstatus & USB_PORT_STAT_LOW_SPEED) ? 1 : 0;
+ down(&usb_address0_sem);
X
- hub->children[port] = usb;
+ tempstr = kmalloc(1024, GFP_KERNEL);
+ portstr = kmalloc(1024, GFP_KERNEL);
+ if (portstr)
+ portstr[0] = 0;
+
+ for (i = 0; i < HUB_PROBE_TRIES; i++) {
+ struct usb_device *pdev, *cdev;
+
+ /* Allocate a new device struct */
+ dev = usb_alloc_dev(hub, hub->bus);
+ if (!dev) {
+ err("couldn't allocate usb_device");
+ break;
+ }
X
- /* Find a new device ID for it */
- usb_connect(usb);
+ hub->children[port] = dev;
X
- /* Run it through the hoops (find a driver, etc) */
- ret = usb_new_device(usb);
- if (ret) {
- /* Try resetting the device. Windows does this and it */
- /* gets some devices working correctly */
- usb_set_port_feature(hub, port + 1, USB_PORT_FEAT_RESET);
+ /* Reset the device */
+ if (usb_hub_port_reset(hub, port, dev, delay)) {
+ usb_free_dev(dev);
+ break;
+ }
X
- ret = usb_new_device(usb);
- if (ret) {
- usb_disconnect(&hub->children[port]);
+ /* Find a new device ID for it */
+ usb_connect(dev);
X
- /* Woops, disable the port */
- dbg("hub: disabling port %d", port + 1);
- usb_clear_port_feature(hub, port + 1,
- USB_PORT_FEAT_ENABLE);
+ /* Create a readable topology string */
+ cdev = dev;
+ pdev = dev->parent;
+ if (portstr && tempstr) {
+ while (pdev) {
+ int port;
+
+ for (port = 0; port < pdev->maxchild; port++)
+ if (pdev->children[port] == cdev)
+ break;
+
+ strcpy(tempstr, portstr);
+ if (!strlen(tempstr))
+ sprintf(portstr, "%d", port + 1);
+ else
+ sprintf(portstr, "%d/%s", port + 1, tempstr);
+
+ cdev = pdev;
+ pdev = pdev->parent;
+ }
X }
+
+ if (portstr)
+ info("USB new device connect on bus%d/%s, assigned device number %d",
+ dev->bus->busnum, portstr, dev->devnum);
+ else
+ info("USB new device connect on bus%d, assigned device number %d",
+ dev->bus->busnum, dev->devnum);
+
+ if (portstr)
+ kfree(portstr);
+ if (tempstr)
+ kfree(tempstr);
+
+ /* Run it through the hoops (find a driver, etc) */
+ if (!usb_new_device(dev)) {
+ up(&usb_address0_sem);
+ return;
+ }
+
+ /* Free the configuration if there was an error */
+ usb_free_dev(dev);
+
+ /* Switch to a long reset time */
+ delay = HUB_LONG_RESET_TIME;
X }
X
-out:
+ hub->children[port] = NULL;
+ usb_hub_port_disable(hub, port);
X up(&usb_address0_sem);
X }
X
X static void usb_hub_events(void)
X {
X unsigned long flags;
- int i;
X struct list_head *tmp;
X struct usb_device *dev;
X struct usb_hub *hub;
X struct usb_hub_status hubsts;
X unsigned short hubstatus, hubchange;
+ int i, ret;
X
X /*
X * We restart the list everytime to avoid a deadlock with
@@ -504,12 +648,26 @@
X
X spin_unlock_irqrestore(&hub_event_lock, flags);
X
+ if (hub->error) {
+ dbg("resetting hub %d for error %d", dev->devnum, hub->error);
+
+ if (usb_hub_reset(hub)) {
+ err("error resetting hub %d - disconnecting", dev->devnum);
+ usb_hub_disconnect(dev);
+ continue;
+ }
+


+ hub->nerrors = 0;

+ hub->error = 0;
+ }
+


X for (i = 0; i < hub->nports; i++) {

X struct usb_port_status portsts;
X unsigned short portstatus, portchange;
X
- if (usb_get_port_status(dev, i + 1, &portsts) < 0) {
- err("get_port_status failed");
+ ret = usb_get_port_status(dev, i + 1, &portsts);
+ if (ret < 0) {
+ err("get_port_status failed (err = %d)", ret);
X continue;
X }
X
@@ -519,27 +677,27 @@
X if (portchange & USB_PORT_STAT_C_CONNECTION) {
X dbg("port %d connection change", i + 1);
X
- usb_hub_port_connect_change(dev, i);
- }
-
- if (portchange & USB_PORT_STAT_C_ENABLE) {
+ usb_hub_port_connect_change(dev, i, &portsts);
+ } else if (portchange & USB_PORT_STAT_C_ENABLE) {
X dbg("port %d enable change, status %x", i + 1, portstatus);
X usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_ENABLE);
X
- // EM interference sometimes causes bad shielded USB devices to
- // be shutdown by the hub, this hack enables them again.
- // Works at least with mouse driver.
+ /*
+ * EM interference sometimes causes bad shielded USB devices to
+ * be shutdown by the hub, this hack enables them again.
+ * Works at least with mouse driver.
+ */
X if (!(portstatus & USB_PORT_STAT_ENABLE) &&
X (portstatus & USB_PORT_STAT_CONNECTION) && (dev->children[i])) {
X err("already running port %i disabled by hub (EMI?), re-enabling...",
X i + 1);
- usb_hub_port_connect_change(dev, i);
+ usb_hub_port_connect_change(dev, i, &portsts);
X }
X }
X
- if (portstatus & USB_PORT_STAT_SUSPEND) {
+ if (portchange & USB_PORT_STAT_C_SUSPEND) {
X dbg("port %d suspend change", i + 1);
- usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_SUSPEND);
+ usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_SUSPEND);
X }
X
X if (portchange & USB_PORT_STAT_C_OVERCURRENT) {
@@ -555,9 +713,9 @@
X } /* end for i */
X
X /* deal with hub status changes */
- if (usb_get_hub_status(dev, &hubsts) < 0) {
+ if (usb_get_hub_status(dev, &hubsts) < 0)
X err("get_hub_status failed");
- } else {
+ else {
X hubstatus = le16_to_cpup(&hubsts.wHubStatus);
X hubchange = le16_to_cpup(&hubsts.wHubChange);
X if (hubchange & HUB_CHANGE_LOCAL_POWER) {
@@ -566,7 +724,7 @@
X }
X if (hubchange & HUB_CHANGE_OVERCURRENT) {
X dbg("hub overcurrent change");
- wait_ms(500); //Cool down
+ wait_ms(500); /* Cool down */
X usb_clear_hub_feature(dev, C_HUB_OVER_CURRENT);
X usb_hub_power_on(hub);
X }
@@ -660,7 +818,7 @@
X }
X
X /*
- * Hub resources are freed for us by usb_deregister. It
+ * Hub resources are freed for us by usb_deregister. It calls
X * usb_driver_purge on every device which in turn calls that
X * devices disconnect function if it is using this driver.
X * The hub_disconnect function takes care of releasing the
@@ -701,23 +859,23 @@
X down(&usb_address0_sem);
X
X /* Send a reset to the device */
- usb_set_port_feature(parent, port + 1, USB_PORT_FEAT_RESET);
-
- wait_ms(200);
-
- usb_clear_port_feature(parent, port + 1, USB_PORT_FEAT_C_RESET);
+ if (usb_hub_port_reset(parent, port, dev, HUB_SHORT_RESET_TIME)) {
+ usb_hub_port_disable(parent, port);
+ up(&usb_address0_sem);
+ return(-ENODEV);
+ }
X
X /* Reprogram the Address */
X ret = usb_set_address(dev);
X if (ret < 0) {
X err("USB device not accepting new address (error=%d)", ret);
- clear_bit(dev->devnum, &dev->bus->devmap.devicemap);
- dev->devnum = -1;
+ usb_hub_port_disable(parent, port);
X up(&usb_address0_sem);
X return ret;
X }
X
- wait_ms(10); /* Let the SET_ADDRESS settle */
+ /* Let the SET_ADDRESS settle */
+ wait_ms(10);
X
X up(&usb_address0_sem);
X
@@ -768,30 +926,23 @@
X usb_set_maxpacket(dev);
X
X return 1;
- } else {
- ret = usb_set_configuration(dev,
- dev->actconfig->bConfigurationValue);
- if (ret < 0) {
- err("failed to set active configuration (error=%d)",
- ret);
- return ret;
- }
+ }
X
- for (i = 0; i < dev->actconfig->bNumInterfaces; i++) {
- struct usb_interface *intf =
- &dev->actconfig->interface[i];
- struct usb_interface_descriptor *as =
- &intf->altsetting[intf->act_altsetting];
+ ret = usb_set_configuration(dev, dev->actconfig->bConfigurationValue);
+ if (ret < 0) {
+ err("failed to set active configuration (error=%d)", ret);


+ return ret;
+ }
X

- ret = usb_set_interface(dev, as->bInterfaceNumber,
- as->bAlternateSetting);
- if (ret < 0) {
- err("failed to set active alternate setting for interface %d (error=%d)", i, ret);


- return ret;
- }
- }

+ for (i = 0; i < dev->actconfig->bNumInterfaces; i++) {
+ struct usb_interface *intf = &dev->actconfig->interface[i];
+ struct usb_interface_descriptor *as = &intf->altsetting[intf->act_altsetting];
X
- return 0;
+ ret = usb_set_interface(dev, as->bInterfaceNumber, as->bAlternateSetting);
+ if (ret < 0) {
+ err("failed to set active alternate setting for interface %d (error=%d)", i, ret);


+ return ret;
+ }
X }

X
X return 0;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/hub.h linux/drivers/usb/hub.h
--- v2.4.0-test8/linux/drivers/usb/hub.h Mon Jun 19 13:42:41 2000
+++ linux/drivers/usb/hub.h Tue Sep 19 15:33:36 2000
@@ -82,47 +82,32 @@
X __u16 wHubCharacteristics;
X __u8 bPwrOn2PwrGood;
X __u8 bHubContrCurrent;
+
X /* DeviceRemovable and PortPwrCtrlMask want to be variable-length
X bitmaps that hold max 256 entries, but for now they're ignored */
+ __u8 bitmap[0];
X } __attribute__ ((packed));
X
X struct usb_device;
X
-typedef enum {
- USB_PORT_UNPOWERED = 0, /* Default state */
- USB_PORT_POWERED, /* When we've put power to it */
- USB_PORT_ENABLED, /* When it's been enabled */
- USB_PORT_DISABLED, /* If it's been disabled */
- USB_PORT_ADMINDISABLED, /* Forced down */
-} usb_hub_port_state;
-
-struct usb_hub_port {
- usb_hub_port_state cstate; /* Configuration state */
-
- struct usb_device *child; /* Device attached to this port */
-
- struct usb_hub *parent; /* Parent hub */
-};
-
X struct usb_hub {
- /* Device structure */
X struct usb_device *dev;
X
- /* Interrupt polling pipe */
- struct urb *urb;
+ struct urb *urb; /* Interrupt polling pipe */
X
X char buffer[USB_MAXCHILDREN / 8];
X
- /* List of hubs */
+ int error;
+ int nerrors;
+
X struct list_head hub_list;
X
- /* Temporary event list */
X struct list_head event_list;
X
X /* Number of ports on the hub */
X int nports;
X
- struct usb_hub_port ports[0]; /* Dynamically allocated */
+ struct usb_hub_descriptor *descriptor;
X };
X
X #endif
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/microtek.c linux/drivers/usb/microtek.c
--- v2.4.0-test8/linux/drivers/usb/microtek.c Thu Sep 7 08:42:37 2000
+++ linux/drivers/usb/microtek.c Mon Sep 18 17:31:14 2000
@@ -98,10 +98,12 @@
X * 20000603 Version 0.2.1
X * 20000620 minor cosmetic changes
X * 20000620 Version 0.2.2
- * 20000822 Hopefully fixed deadlock in mts_remove_nolock()
- * 20000822 Fixed minor race in mts_transfer_cleanup()
- * 20000822 Fixed deadlock on submission error in queuecommand
- * 20000822 Version 0.2.3
+ * 20000822 Hopefully fixed deadlock in mts_remove_nolock()
+ * 20000822 Fixed minor race in mts_transfer_cleanup()
+ * 20000822 Fixed deadlock on submission error in queuecommand
+ * 20000822 Version 0.2.3
+ * 20000913 Reduced module size if debugging is off
+ * 20000913 Version 0.2.4
X */
X
X #include <linux/module.h>
@@ -151,7 +153,7 @@
X
X /* Internal driver stuff */
X
-#define MTS_VERSION "0.2.3"
+#define MTS_VERSION "0.2.4"
X #define MTS_NAME "microtek usb (rev " MTS_VERSION "): "
X
X #define MTS_WARNING(x...) \
@@ -198,6 +200,8 @@
X MTS_DEBUG_INT();\
X } while (0)
X
+#ifdef MTS_DO_DEBUG
+
X static inline void mts_debug_dump(struct mts_desc* desc) {
X MTS_DEBUG("desc at 0x%x: halted = %x%x, toggle = %x%x\n",
X (int)desc,(int)desc->usb_dev->halted[1],(int)desc->usb_dev->halted[0],
@@ -292,6 +296,23 @@
X srb->cmnd[0], srb->cmnd[1], srb->cmnd[2], srb->cmnd[3], srb->cmnd[4], srb->cmnd[5],
X srb->cmnd[6], srb->cmnd[7], srb->cmnd[8], srb->cmnd[9]);
X }
+
+#else
+
+static inline void mts_show_command(Scsi_Cmnd *srb)
+{
+ while (0) {}
+}
+
+static inline void mts_debug_dump(struct mts_desc* desc)
+{
+ while (0) {}


+}
+
+#endif
+
+
+

X
X static inline int mts_is_aborting(struct mts_desc* desc) {
X return (atomic_read(&desc->context.do_abort));
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/net1080.c linux/drivers/usb/net1080.c
--- v2.4.0-test8/linux/drivers/usb/net1080.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/net1080.c Tue Sep 19 08:31:53 2000
@@ -0,0 +1,1099 @@
+/*
+ * NetChip 1080 Driver (USB Host-to-Host Link)
+ * Copyright (C) 2000 by David Brownell <dbro...@users.sourceforge.net>
+ */
+
+/*
+ * This talks to the NetChip 1080, which can appear in "network cables"
+ * and other designs. This driver interoperates with the Win32 network
+ * drivers from NetChip, using the NetChip reference design.
+ *
+ * The IP-over-USB protocol here may be of interest. Embedded devices
+ * could implement it at the cost of two bulk endpoints, and whatever
+ * other system resources the desired IP-based applications need.
+ * Some Linux palmtops could support that today.
+ *
+ * STATUS:
+ *
+ * 13-sept-2000 experimental, new
+ *
+ * This doesn't yet do any network hotplugging, and there's no matching
+ * ifup policy script ... it should arrange bridging with "brctl", and
+ * should handle static and dynamic ("pump") setups.
+ *
+ * RX/TX queue sizes currently fixed at one due to URB unlink problems.
+ *
+ *-------------------------------------------------------------------------*/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kmod.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/random.h>
+#include <asm/unaligned.h>
+
+#define DEBUG // error path messages
+// #define VERBOSE // more; success messages
+#define USE_TTL // timeout our reads
+
+#if !defined (DEBUG) && defined (CONFIG_USB_DEBUG)
+# define DEBUG
+#endif
+#include <linux/usb.h>
+
+
+static const struct product {
+ char *name;
+ u16 idVendor;
+ u16 idProduct;
+} products [] = {
+ { "NetChip TurboCONNECT", 0x0525, 0x1080 }, // reference
+ // Belkin, ...
+ { 0, 0, 0 }, // END
+};
+
+static u8 node_id [ETH_ALEN];
+
+
+/*-------------------------------------------------------------------------
+ *
+ * NetChip protocol: ethernet framing, and only use bulk endpoints (01/81;
+ * not mailboxes 02/82 or status interrupt 83). Expects Ethernet bridging.
+ * Odd USB length == always short read.
+ * - nc_header
+ * - payload, in Ethernet framing (14 byte header etc)
+ * - (optional padding byte, if needed so length is odd)
+ * - nc_trailer
+ */
+
+struct nc_header {
+ u16 hdr_len; // sizeof nc_header (LE, all)
+ u16 packet_len; // packet size
+ u16 packet_id; // detects dropped packets
+#define NC_MIN_HEADER 6
+
+ // all else is optional, and must start with:
+ // u16 vendorId; // from usb-if
+ // u16 productId;
+};
+
+#define NC_PAD_BYTE ((unsigned char)0xAC)
+
+struct nc_trailer {
+ u16 packet_id;
+};
+
+// packetsize == f(mtu setting), with upper limit
+#define NC_MAX_PACKET(mtu) (sizeof (struct nc_header) \
+ + (mtu) \
+ + 1 \
+ + sizeof (struct nc_trailer))
+
+// zero means no timeout; else, how long a 64 byte bulk
+// read may be queued before HW flushes it.
+#define NC_READ_TTL ((u8)255) // ms
+
+
+/*-------------------------------------------------------------------------*/
+
+// list of all devices we manage
+static DECLARE_MUTEX (net1080_mutex);
+static LIST_HEAD (net1080_list);
+
+
+// Nineteen USB 1.1 max size bulk transactions per frame, max.
+#if 0
+#define RX_QLEN 4
+#define TX_QLEN 4
+
+#else
+// unlink_urbs() has probs on OHCI without test8-pre patches.
+#define RX_QLEN 1
+#define TX_QLEN 1
+#endif
+
+enum skb_state {
+ illegal = 0,
+ tx_start, tx_done,
+ rx_start, rx_done, rx_cleanup
+};
+
+struct skb_data { // skb->cb is one of these
+ struct urb *urb;
+ struct net1080 *dev;
+ enum skb_state state;
+ size_t length;
+};
+
+
+struct net1080 {
+ // housekeeping
+ struct usb_device *udev;
+ const struct product *prod_info;
+ struct semaphore mutex;
+ struct list_head dev_list;
+ wait_queue_head_t *wait;
+
+ // protocol/interface state
+ struct net_device net;
+ struct net_device_stats stats;
+ u16 packet_id;
+
+ // various kinds of pending driver work
+ struct sk_buff_head rxq;
+ struct sk_buff_head txq;
+ struct sk_buff_head done;
+ struct tasklet_struct bh;
+};
+
+#define mutex_lock(x) down(x)
+#define mutex_unlock(x) up(x)
+
+static void defer_bh (struct net1080 *dev, struct sk_buff *skb)
+{


+ unsigned long flags;
+

+ skb_unlink (skb);
+ spin_lock_irqsave (&dev->done.lock, flags);
+ __skb_queue_tail (&dev->done, skb);
+ if (dev->done.qlen == 1)
+ tasklet_schedule (&dev->bh);
+ spin_unlock_irqrestore (&dev->done.lock, flags);
+}
+
+/*-------------------------------------------------------------------------
+ *
+ * We ignore most registers and EEPROM contents.
+ */
+
+#define REG_USBCTL ((u8)0x04)
+#define REG_TTL ((u8)0x10)
+#define REG_STATUS ((u8)0x11)
+
+/*
+ * Vendor specific requests to read/write data
+ */
+
+#define REQUEST_REGISTER ((u8)0x10)
+#define REQUEST_EEPROM ((u8)0x11)
+
+#define CONTROL_TIMEOUT (500) /* msec */
+
+static int
+vendor_read (struct net1080 *dev, u8 req, u8 regnum, u16 *retval_ptr)
+{
+ int status = usb_control_msg (dev->udev,
+ usb_rcvctrlpipe (dev->udev, 0),
+ req,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0, regnum,
+ retval_ptr, sizeof *retval_ptr,
+ CONTROL_TIMEOUT);
+ if (status > 0)
+ status = 0;
+ if (!status)
+ le16_to_cpus (retval_ptr);
+ return status;
+}
+
+static inline int
+register_read (struct net1080 *dev, u8 regnum, u16 *retval_ptr)
+{
+ return vendor_read (dev, REQUEST_REGISTER, regnum, retval_ptr);
+}
+
+// without retval, this can become fully async (usable in_interrupt)
+static void
+vendor_write (struct net1080 *dev, u8 req, u8 regnum, u16 value)
+{
+ usb_control_msg (dev->udev,
+ usb_sndctrlpipe (dev->udev, 0),
+ req,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value, regnum,
+ 0, 0, // data is in setup packet
+ CONTROL_TIMEOUT);
+}
+
+static inline void
+register_write (struct net1080 *dev, u8 regnum, u16 value)
+{
+ vendor_write (dev, REQUEST_REGISTER, regnum, value);
+}
+
+
+#if 0
+static void dump_registers (struct net1080 *dev)
+{
+ u8 reg;
+ u16 value;
+
+ dbg ("%s registers:", dev->net.name);
+ for (reg = 0; reg < 0x20; reg++) {
+ int retval;
+
+ // reading some registers is trouble
+ if (reg >= 0x08 && reg <= 0xf)
+ continue;
+ if (reg >= 0x12 && reg <= 0x1e)
+ continue;
+
+ retval = register_read (dev, reg, &value);
+ if (retval < 0)
+ dbg ("%s reg [0x%x] ==> error %d",
+ dev->net.name, reg, retval);
+ else
+ dbg ("%s reg [0x%x] = 0x%x",
+ dev->net.name, reg, value);


+ }
+}
+#endif
+
+

+/*-------------------------------------------------------------------------
+ *
+ * Control register
+ */
+
+#define USBCTL_WRITABLE_MASK 0x1f0f
+// bits 15-13 reserved, r/o
+#define USBCTL_ENABLE_LANG (1 << 12)
+#define USBCTL_ENABLE_MFGR (1 << 11)
+#define USBCTL_ENABLE_PROD (1 << 10)
+#define USBCTL_ENABLE_SERIAL (1 << 9)
+#define USBCTL_ENABLE_DEFAULTS (1 << 8)
+// bits 7-4 reserved, r/o
+#define USBCTL_FLUSH_OTHER (1 << 3)
+#define USBCTL_FLUSH_THIS (1 << 2)
+#define USBCTL_DISCONN_OTHER (1 << 1)
+#define USBCTL_DISCONN_THIS (1 << 0)
+
+#ifdef DEBUG
+static void dump_usbctl (struct net1080 *dev, u16 usbctl)
+{
+ dbg ("%s: USB %d dev %d usbctl 0x%x:%s%s%s%s%s;"
+ " this%s%s;"
+ " other%s%s; r/o 0x%x",
+ dev->net.name,
+ dev->udev->bus->busnum, dev->udev->devnum,
+ usbctl,
+ (usbctl & USBCTL_ENABLE_LANG) ? " lang" : "",
+ (usbctl & USBCTL_ENABLE_MFGR) ? " mfgr" : "",
+ (usbctl & USBCTL_ENABLE_PROD) ? " prod" : "",
+ (usbctl & USBCTL_ENABLE_SERIAL) ? " serial" : "",
+ (usbctl & USBCTL_ENABLE_DEFAULTS) ? " defaults" : "",
+
+ (usbctl & USBCTL_FLUSH_OTHER) ? " FLUSH" : "",
+ (usbctl & USBCTL_DISCONN_OTHER) ? " DIS" : "",
+ (usbctl & USBCTL_FLUSH_THIS) ? " FLUSH" : "",
+ (usbctl & USBCTL_DISCONN_THIS) ? " DIS" : "",
+ usbctl & ~USBCTL_WRITABLE_MASK
+ );
+}
+#else
+static inline void dump_usbctl (struct net1080 *dev, u16 usbctl) {}
+#endif
+
+/*-------------------------------------------------------------------------
+ *
+ * Status register
+ */
+
+#define STATUS_PORT_A (1 << 15)
+
+#define STATUS_CONN_OTHER (1 << 14)
+#define STATUS_SUSPEND_OTHER (1 << 13)
+#define STATUS_MAILBOX_OTHER (1 << 12)
+#define STATUS_PACKETS_OTHER(n) (((n) >> 8) && 0x03)
+
+#define STATUS_CONN_THIS (1 << 6)
+#define STATUS_SUSPEND_THIS (1 << 5)
+#define STATUS_MAILBOX_THIS (1 << 4)
+#define STATUS_PACKETS_THIS(n) (((n) >> 0) && 0x03)
+
+#define STATUS_UNSPEC_MASK 0x0c8c
+#define STATUS_NOISE_MASK ((u16)~(0x0303|STATUS_UNSPEC_MASK))
+
+
+#ifdef DEBUG
+static void dump_status (struct net1080 *dev, u16 status)
+{
+ dbg ("%s: USB %d dev %d status 0x%x:"
+ " this (%c) PKT=%d%s%s%s;"
+ " other PKT=%d%s%s%s; unspec 0x%x",
+ dev->net.name,
+ dev->udev->bus->busnum, dev->udev->devnum,
+ status,
+
+ // XXX the packet counts don't seem right
+ // (1 at reset, not 0); maybe UNSPEC too
+
+ (status & STATUS_PORT_A) ? 'A' : 'B',
+ STATUS_PACKETS_THIS (status),
+ (status & STATUS_CONN_THIS) ? " CON" : "",
+ (status & STATUS_SUSPEND_THIS) ? " SUS" : "",
+ (status & STATUS_MAILBOX_THIS) ? " MBOX" : "",
+
+ STATUS_PACKETS_OTHER (status),
+ (status & STATUS_CONN_OTHER) ? " CON" : "",
+ (status & STATUS_SUSPEND_OTHER) ? " SUS" : "",
+ (status & STATUS_MAILBOX_OTHER) ? " MBOX" : "",
+
+ status & STATUS_UNSPEC_MASK
+ );
+}
+#else
+static inline void dump_status (struct net1080 *dev, u16 status) {}
+#endif
+
+/*-------------------------------------------------------------------------
+ *
+ * TTL register
+ */
+
+#define TTL_THIS(ttl) (0x00ff & ttl)
+#define TTL_OTHER(ttl) (0x00ff & (ttl >> 8))
+#define MK_TTL(this,other) ((u16)(((other)<<8)|(0x00ff&(this))))
+
+#ifdef DEBUG
+static void dump_ttl (struct net1080 *dev, u16 ttl)
+{
+ dbg ("%s: USB %d dev %d ttl 0x%x this = %d, other = %d",
+ dev->net.name,
+ dev->udev->bus->busnum, dev->udev->devnum,
+ ttl,
+
+ TTL_THIS (ttl),
+ TTL_OTHER (ttl)
+ );
+}
+#else
+static inline void dump_ttl (struct net1080 *dev, u16 ttl) {}
+#endif
+
+#define RUN_CONTEXT (in_irq () ? "in_irq" \
+ : (in_interrupt () ? "in_interrupt" : "can sleep"))
+
+/*-------------------------------------------------------------------------*/
+
+// ensure that the device is in a known state before using it.
+
+// preconditions:
+// caller owns the device mutex
+// caller has a process context
+
+static int net1080_reset (struct net1080 *dev)
+{
+ u16 usbctl, status, ttl;
+ int retval;
+
+ if ((retval = register_read (dev, REG_STATUS, &status)) < 0) {
+ dbg ("can't read dev %d status: %d", dev->udev->devnum, retval);
+ goto done;
+ }
+ dump_status (dev, status);
+
+ if ((retval = register_read (dev, REG_USBCTL, &usbctl)) < 0) {
+ dbg ("can't read USBCTL, %d", retval);
+ goto done;
+ }
+ dump_usbctl (dev, usbctl);
+
+ register_write (dev, REG_USBCTL,
+ USBCTL_FLUSH_THIS | USBCTL_FLUSH_OTHER);
+
+ if ((retval = register_read (dev, REG_TTL, &ttl)) < 0) {
+ dbg ("can't read TTL, %d", retval);
+ goto done;
+ }
+ dump_ttl (dev, ttl);
+
+#ifdef USE_TTL
+ // Have the chip flush reads that seem to be starving for read
+ // bandwidth ... or we're otherwise reading. Note, Win32 drivers
+ // may change our read TTL for us.
+
+ register_write (dev, REG_TTL,
+ MK_TTL (NC_READ_TTL, TTL_OTHER (ttl)) );
+ dbg ("%s: assigned TTL, %d ms", dev->net.name, NC_READ_TTL);
+#endif
+
+ info ("%s: %s, port %c on USB %d dev %d, peer %sconnected",
+ dev->net.name, dev->prod_info->name,
+ (status & STATUS_PORT_A) ? 'A' : 'B',
+ dev->udev->bus->busnum,
+ dev->udev->devnum,
+ (status & STATUS_CONN_OTHER) ? "" : "dis"
+ );
+ retval = 0;
+
+done:


+ return retval;
+}
+
+

+/*-------------------------------------------------------------------------
+ *
+ * Network Device Driver support (peer link to USB Host)
+ *
+ --------------------------------------------------------------------------*/
+
+static int net1080_change_mtu (struct net_device *net, int new_mtu)
+{
+ if ((new_mtu < 0) || NC_MAX_PACKET (new_mtu) > 8191)
+ return -EINVAL;
+ net->mtu = new_mtu;


+ return 0;
+}
+

+/*-------------------------------------------------------------------------*/
+
+static struct net_device_stats *net1080_get_stats (struct net_device *net)
+{
+ return &((struct net1080 *) net->priv)->stats;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void rx_complete (struct urb *urb);
+
+static void rx_submit (struct net1080 *dev, struct urb *urb, int flags)
+{
+ struct sk_buff *skb;
+ struct skb_data *entry;


+ int retval = 0;

+ unsigned long lockflags;
+
+ if ((skb = alloc_skb (NC_MAX_PACKET (dev->net.mtu), flags)) == 0) {
+ err ("no rx skb");
+ tasklet_schedule (&dev->bh);
+ usb_free_urb (urb);
+ return;
+ }
+
+ entry = (struct skb_data *) skb->cb;
+ entry->urb = urb;
+ entry->dev = dev;
+ entry->state = rx_start;
+ entry->length = 0;
+
+ FILL_BULK_URB (urb, dev->udev, usb_rcvbulkpipe (dev->udev, 1),
+ skb->data, skb->truesize, rx_complete, skb);
+ urb->transfer_flags |= USB_QUEUE_BULK;
+
+ spin_lock_irqsave (&dev->rxq.lock, lockflags);
+ if (!netif_queue_stopped (&dev->net)) {
+ if ((retval = usb_submit_urb (urb)) != 0) {
+ err ("%s rx submit, %d", dev->net.name, retval);
+ tasklet_schedule (&dev->bh);
+ } else {
+ __skb_queue_tail (&dev->rxq, skb);
+ }
+ } else {
+ dbg ("rx: stopped");
+ retval = -ENOLINK;
+ }
+ spin_unlock_irqrestore (&dev->rxq.lock, lockflags);
+ if (retval) {
+ dev_kfree_skb_any (skb);
+ usb_free_urb (urb);
+ }
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static void rx_complete (struct urb *urb)
+{
+ struct sk_buff *skb = (struct sk_buff *) urb->context;
+ struct skb_data *entry = (struct skb_data *) skb->cb;
+ struct net1080 *dev = entry->dev;
+ int urb_status = urb->status;
+
+ urb->dev = 0;
+ skb->len = urb->actual_length;
+ entry->state = rx_done;
+ entry->urb = 0;
+
+ if ((urb->transfer_flags & USB_ASYNC_UNLINK) != 0
+ || netif_queue_stopped (&dev->net)) {
+ dbg ("rx ... shutting down");
+ usb_free_urb (urb);
+ urb = 0;
+ }
+
+ switch (urb_status) {
+ // success
+ case 0:
+ if (skb->len & 0x01)
+ break;
+ entry->state = rx_cleanup;
+ dev->stats.rx_errors++;
+ dev->stats.rx_length_errors++;
+ dbg ("even rx len %d", skb->len);
+ break;
+
+ // hardware-reported interface shutdown ... which we
+ // typically see before khubd calls disconnect()
+ case -ETIMEDOUT: // usb-ohci
+ case -EILSEQ: // *uhci ... "crc"/timeout error
+ // netif_device_detach (&dev->net);
+ // FALLTHROUGH
+
+ // software-driven interface shutdown
+ case -ECONNRESET:
+ entry->state = rx_cleanup;
+ usb_free_urb (urb);
+ urb = 0;
+ dbg ("%s ... shutdown rx (%d)", dev->net.name, urb_status);
+ break;
+
+ // data overrun ... flush fifo?
+ case -EOVERFLOW:
+ dev->stats.rx_over_errors++;
+ // FALLTHROUGH
+
+ default:
+ entry->state = rx_cleanup;
+ dev->stats.rx_errors++;
+ err ("%s rx: status %d", dev->net.name, urb_status);
+ break;
+ }
+ defer_bh (dev, skb);
+
+ if (urb) {
+ if (!netif_queue_stopped (&dev->net)) {
+ rx_submit (dev, urb, GFP_ATOMIC);
+ return;
+ } else
+ usb_free_urb (urb);
+ }
+#ifdef VERBOSE
+ dbg ("no read resubmitted");
+#endif VERBOSE
+}
+
+/*-------------------------------------------------------------------------*/
+
+// unlink pending rx/tx; completion handlers do all other cleanup
+
+static int unlink_urbs (struct sk_buff_head *q)
+{
+ unsigned long flags;
+ struct sk_buff *skb;
+ struct skb_data *entry;
+ int retval;


+ int count = 0;
+

+ spin_lock_irqsave (&q->lock, flags);
+ for (skb = q->next; skb != (struct sk_buff *) q; skb = skb->next) {
+ entry = (struct skb_data *) skb->cb;
+ entry->urb->transfer_flags |= USB_ASYNC_UNLINK;
+ retval = usb_unlink_urb (entry->urb);
+ if (retval < 0)
+ dbg ("unlink urb err, %d", retval);
+ else
+ count++;
+ }
+ spin_unlock_irqrestore (&q->lock, flags);
+ return count;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+// precondition: never called in_interrupt
+
+static int net1080_stop (struct net_device *net)
+{
+ struct net1080 *dev = (struct net1080 *) net->priv;
+ int temp;
+ DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup);
+ DECLARE_WAITQUEUE (wait, current);
+
+ mutex_lock (&dev->mutex);
+
+ dbg ("%s stop stats: rx/tx %ld/%ld, errs %ld/%ld", net->name,
+ dev->stats.rx_packets, dev->stats.tx_packets,
+ dev->stats.rx_errors, dev->stats.tx_errors
+ );
+
+ netif_stop_queue(net);
+
+ // ensure there are no more active urbs
+ add_wait_queue (&unlink_wakeup, &wait);
+ dev->wait = &unlink_wakeup;
+ temp = unlink_urbs (&dev->txq) + unlink_urbs (&dev->rxq);
+
+ // maybe wait for deletions to finish.
+ if (temp) {


+ current->state = TASK_UNINTERRUPTIBLE;

+ schedule ();
+ dbg ("waited for %d urb completions", temp);
+ }
+ dev->wait = 0;
+ remove_wait_queue (&unlink_wakeup, &wait);
+
+ mutex_unlock (&dev->mutex);
+ MOD_DEC_USE_COUNT;


+ return 0;
+}
+

+/*-------------------------------------------------------------------------*/
+
+// posts a read, and enables write queing
+
+// precondition: never called in_interrupt
+
+static int net1080_open (struct net_device *net)
+{
+ struct net1080 *dev = (struct net1080 *) net->priv;
+ int retval;
+ u16 status;
+ int i;
+
+ MOD_INC_USE_COUNT;
+ mutex_lock (&dev->mutex);
+
+ // insist peer be connected -- is this the best place?
+ if ((retval = register_read (dev, REG_STATUS, &status)) != 0) {
+ dbg ("%s open: status read failed - %d", net->name, retval);
+ goto done;
+ }
+ if ((status & STATUS_CONN_OTHER) != STATUS_CONN_OTHER) {
+ retval = -ENOLINK;
+ dbg ("%s open: peer not connected", net->name);
+ goto done;
+ }
+
+ MOD_INC_USE_COUNT;
+ netif_start_queue (net);
+ for (i = 0; i < RX_QLEN; i++)
+ rx_submit (dev, usb_alloc_urb (0), GFP_KERNEL);
+
+ dbg ("%s open: started queueing (rx %d, tx %d)",
+ net->name, RX_QLEN, TX_QLEN);
+done:
+ mutex_unlock (&dev->mutex);
+ MOD_DEC_USE_COUNT;


+ return retval;
+}
+

+/*-------------------------------------------------------------------------*/
+
+static void tx_complete (struct urb *urb)
+{
+ struct sk_buff *skb = (struct sk_buff *) urb->context;
+ struct skb_data *entry = (struct skb_data *) skb->cb;
+ struct net1080 *dev = entry->dev;
+
+ urb->dev = 0;
+ entry->state = tx_done;
+ defer_bh (dev, skb);
+ netif_wake_queue (&dev->net);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static struct sk_buff *fixup_skb (struct sk_buff *skb)
+{
+ int padlen;
+ struct sk_buff *skb2;
+
+ padlen = ((skb->len + sizeof (struct nc_header)
+ + sizeof (struct nc_trailer)) & 0x01) ? 0 : 1;
+ if (!skb_cloned (skb)) {
+ int headroom = skb_headroom (skb);
+ int tailroom = skb_tailroom (skb);
+
+ if ((padlen + sizeof (struct nc_trailer)) <= tailroom
+ && sizeof (struct nc_header) <= headroom)
+ return skb;
+
+ if ((sizeof (struct nc_header) + padlen
+ + sizeof (struct nc_trailer)) <
+ (headroom + tailroom)) {
+ skb->data = memmove (skb->head
+ + sizeof (struct nc_header),
+ skb->data, skb->len);
+ skb->tail = skb->data + skb->len;
+ return skb;
+ }
+ }
+ skb2 = skb_copy_expand (skb,
+ sizeof (struct nc_header),
+ sizeof (struct nc_trailer) + padlen,
+ in_interrupt () ? GFP_ATOMIC : GFP_KERNEL);
+ dev_kfree_skb_any (skb);
+ return skb2;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int net1080_start_xmit (struct sk_buff *skb, struct net_device *net)
+{
+ struct net1080 *dev = (struct net1080 *) net->priv;
+ int length = skb->len;


+ int retval = 0;

+ struct urb *urb = 0;
+ struct skb_data *entry;
+ struct nc_header *header;
+ struct nc_trailer *trailer;


+ unsigned long flags;
+

+ if ((skb = fixup_skb (skb)) == 0) {
+ dbg ("can't fixup skb");
+ goto drop;
+ }
+ if ((urb = usb_alloc_urb (0)) == 0) {
+ dbg ("no urb");
+ goto drop;
+ }
+
+ entry = (struct skb_data *) skb->cb;
+ entry->urb = urb;
+ entry->dev = dev;
+ entry->state = tx_start;
+ entry->length = length;
+
+ header = (struct nc_header *) skb_push (skb, sizeof *header);
+ header->hdr_len = cpu_to_le16 (sizeof (*header));
+ header->packet_len = cpu_to_le16 (length);
+ if (!((skb->len + sizeof *trailer) & 0x01))
+ *skb_put (skb, 1) = NC_PAD_BYTE;
+ trailer = (struct nc_trailer *) skb_put (skb, sizeof *trailer);
+
+ FILL_BULK_URB (urb, dev->udev,
+ usb_sndbulkpipe (dev->udev, 1),
+ skb->data, skb->len, tx_complete, skb);
+ urb->transfer_flags |= USB_QUEUE_BULK;
+ // FIXME urb->timeout = ...;
+
+ spin_lock_irqsave (&dev->txq.lock, flags);
+ if (!netif_queue_stopped (&dev->net)) {
+ header->packet_id = cpu_to_le16 (dev->packet_id++);
+ put_unaligned (header->packet_id, &trailer->packet_id);
+
+ netif_stop_queue (net);
+ if ((retval = usb_submit_urb (urb)) != 0) {
+ netif_start_queue (net);
+ dbg ("%s tx: submit urb err %d", net->name, retval);
+ } else {
+ net->trans_start = jiffies;
+ __skb_queue_tail (&dev->txq, skb);
+ if (dev->txq.qlen < TX_QLEN)
+ netif_start_queue (net);
+ }
+ } else
+ retval = -ENOLINK;
+ spin_unlock_irqrestore (&dev->txq.lock, flags);
+
+ if (retval) {
+ dbg ("drop");
+drop:
+ dev->stats.tx_dropped++;
+ dev_kfree_skb_any (skb);
+ usb_free_urb (urb);
+#ifdef VERBOSE
+ } else {
+ dbg ("%s: tx %p len %d", net->name, skb, length);
+#endif
+ }


+ return retval;
+}
+
+

+/*-------------------------------------------------------------------------*/
+
+static void rx_process (struct net1080 *dev, struct sk_buff *skb)
+{
+ struct nc_header *header;
+ struct nc_trailer *trailer;
+
+ header = (struct nc_header *) skb->data;
+ le16_to_cpus (&header->hdr_len);
+ le16_to_cpus (&header->packet_len);
+ if (header->hdr_len < NC_MIN_HEADER) {
+ dev->stats.rx_frame_errors++;
+ dbg ("header too short, %d", header->hdr_len);
+ goto error;
+ } else if (header->hdr_len != sizeof *header) {
+ // out of band data for us?
+ dbg ("header OOB, %d bytes", header->hdr_len - NC_MIN_HEADER);
+ // switch (vendor/product ids) { ... }
+ }
+ skb_pull (skb, header->hdr_len);
+
+ trailer = (struct nc_trailer *)
+ (skb->data + skb->len - sizeof *trailer);
+ skb_trim (skb, skb->len - sizeof *trailer);
+
+ if ((header->packet_len & 0x01) == 0) {
+ if (skb->data [header->packet_len] != NC_PAD_BYTE) {
+ dev->stats.rx_frame_errors++;
+ dbg ("bad pad");
+ goto error;
+ }
+ skb_trim (skb, skb->len - 1);
+ }
+ if (skb->len != header->packet_len) {
+ dev->stats.rx_length_errors++;
+ dbg ("bad packet len %d (expected %d)",
+ skb->len, header->packet_len);
+ goto error;
+ }
+ if (header->packet_id != get_unaligned (&trailer->packet_id)) {
+ dev->stats.rx_fifo_errors++;
+ dbg ("(2+ dropped) rx packet_id mismatch 0x%x 0x%x",
+ header->packet_id, trailer->packet_id);
+ goto error;
+ }
+
+ if (skb->len) {
+ skb->dev = &dev->net;
+ skb->protocol = eth_type_trans (skb, &dev->net);
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
+
+#ifdef VERBOSE
+ dbg ("%s: rx %p len %d, type 0x%x, id 0x%x",
+ dev->net.name, skb, skb->len, skb->protocol,
+ le16_to_cpu (header->packet_id));
+#endif
+ netif_rx (skb);
+ } else {
+ dbg ("drop");
+error:
+ dev->stats.rx_errors++;
+ dev_kfree_skb (skb);
+ }
+}
+
+/*-------------------------------------------------------------------------*/
+
+// tasklet
+
+// We can have a state machine in this tasklet monitor the link state,
+// using async control messaging and calling attach/detach routines.
+
+// But then some listener ought to respond to the changes; do those
+// network attach/detach notifications get to userland somehow, such
+// as by calling "ifup usb0" and "ifdown usb0"?
+
+static void net1080_bh (unsigned long param)
+{
+ struct net1080 *dev = (struct net1080 *) param;
+ struct sk_buff *skb;
+ struct skb_data *entry;
+
+ while ((skb = skb_dequeue (&dev->done))) {
+ entry = (struct skb_data *) skb->cb;
+ switch (entry->state) {
+ case rx_done:
+ rx_process (dev, skb);
+ continue;
+ case tx_done:
+ if (entry->urb->status) {
+ // can this statistic become more specific?
+ dev->stats.tx_errors++;
+ dbg ("%s tx: err %d", dev->net.name,
+ entry->urb->status);
+ } else {
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += entry->length;
+ }
+ // FALLTHROUGH:
+ case rx_cleanup:
+ usb_free_urb (entry->urb);
+ dev_kfree_skb (skb);
+ continue;
+ default:
+ dbg ("%s: bogus skb state %d",
+ dev->net.name, entry->state);
+ }
+ }
+
+ // waiting for all pending urbs to complete?
+ if (dev->wait) {
+ if ((dev->txq.qlen + dev->rxq.qlen + dev->done.qlen) == 0) {
+ wake_up (dev->wait);
+ }
+
+ // or are we maybe short a few urbs?
+ } else if (!netif_queue_stopped (&dev->net)) {
+ if (dev->rxq.qlen < TX_QLEN) {
+ struct urb *urb;
+ int i;
+ for (i = 0; i < 3 && dev->rxq.qlen < TX_QLEN; i++) {
+ if ((urb = usb_alloc_urb (0)) != 0)
+ rx_submit (dev, urb, GFP_ATOMIC);
+ }
+ dbg ("%s: rxqlen now %d",
+ dev->net.name, dev->rxq.qlen);
+ }
+ }
+}
+
+/*-------------------------------------------------------------------------
+ *
+ * USB Device Driver support
+ *
+ --------------------------------------------------------------------------*/
+
+// precondition: never called in_interrupt
+
+static void net1080_disconnect (struct usb_device *udev, void *ptr)
+{
+ struct net1080 *dev = (struct net1080 *) ptr;
+
+ info ("%s: USB %d dev %d, %s, disconnected",
+ dev->net.name,
+ udev->bus->busnum, udev->devnum,
+ dev->prod_info->name);
+
+ unregister_netdev (&dev->net);
+
+ mutex_lock (&net1080_mutex);
+ mutex_lock (&dev->mutex);
+ list_del (&dev->dev_list);
+ mutex_unlock (&net1080_mutex);
+
+#ifdef DEBUG
+ memset (dev, 0x55, sizeof *dev);
+#endif
+ kfree (dev);
+ usb_dec_dev_use (udev);
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+// precondition: never called in_interrupt
+
+static void *net1080_probe (struct usb_device *udev, unsigned ifnum)
+{
+ int i;
+ struct net1080 *dev;
+ struct net_device *net;
+ struct usb_interface_descriptor *interface;
+ int retval;
+
+ for (i = 0; products [i].idVendor != 0; i++) {
+ if (products [i].idVendor != udev->descriptor.idVendor)
+ continue;
+ if (products [i].idProduct != udev->descriptor.idProduct)
+ continue;
+ break;
+ }
+ if (products [i].idVendor == 0)
+ return 0;
+
+ // sanity check; expect dedicated interface/devices for now.
+ interface = &udev->actconfig->interface [ifnum].altsetting[0];
+ if (udev->descriptor.bNumConfigurations != 1
+ || udev->config[0].bNumInterfaces != 1
+ || udev->config[0].bNumInterfaces != 1
+ || interface->bInterfaceClass != USB_CLASS_VENDOR_SPEC
+ || interface->bNumEndpoints != 5
+ ) {
+ dbg ("Bogus config info");


+ return 0;
+ }
+

+ // set up our own records
+ if (!(dev = kmalloc (sizeof *dev, GFP_KERNEL))) {
+ dbg ("can't kmalloc dev");
+ return 0;
+ }
+ memset (dev, 0, sizeof *dev);
+
+ init_MUTEX_LOCKED (&dev->mutex);
+ usb_inc_dev_use (udev);
+ dev->udev = udev;
+ dev->prod_info = &products [i];
+ INIT_LIST_HEAD (&dev->dev_list);
+ skb_queue_head_init (&dev->rxq);
+ skb_queue_head_init (&dev->txq);
+ skb_queue_head_init (&dev->done);
+ dev->bh.func = net1080_bh;
+ dev->bh.data = (unsigned long) dev;
+
+ // set up network interface records
+ net = &dev->net;
+ net->priv = dev;
+ strcpy (net->name, "usb%d");
+ memcpy (net->dev_addr, node_id, sizeof node_id);
+
+ ether_setup (net);
+ // net->flags |= IFF_POINTOPOINT;
+
+ net->change_mtu = net1080_change_mtu;
+ net->get_stats = net1080_get_stats;
+ net->hard_start_xmit = net1080_start_xmit;
+ net->open = net1080_open;
+ net->stop = net1080_stop;
+
+ register_netdev (&dev->net);
+
+ // ... talk to the device
+ // dump_registers (dev);
+
+ if ((retval = net1080_reset (dev)) < 0) {
+ err ("%s: init reset fail on USB %d dev %d - %d",
+ dev->net.name, udev->bus->busnum, udev->devnum, retval);
+ mutex_unlock (&dev->mutex);
+ net1080_disconnect (udev, dev);


+ return 0;
+ }
+

+ // ok, it's ready to go.
+ mutex_lock (&net1080_mutex);
+ list_add (&dev->dev_list, &net1080_list);
+ mutex_unlock (&dev->mutex);
+
+ // start as if the link is up
+ netif_device_attach (&dev->net);
+
+ mutex_unlock (&net1080_mutex);
+
+ return dev;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static struct usb_driver net1080_driver = {
+ name: "net1080",
+ probe: net1080_probe,
+ disconnect: net1080_disconnect,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static int __init net1080_init (void)
+{
+ // compiler should optimize this out
+ if (sizeof (((struct sk_buff *)0)->cb) < sizeof (struct skb_data))
+ BUG ();
+
+ if (usb_register (&net1080_driver) < 0)
+ return -1;
+
+ get_random_bytes (node_id, sizeof node_id);
+ node_id [0] &= 0x7f;


+
+ return 0;
+}

+module_init (net1080_init);
+
+static void __exit net1080_exit (void)
+{
+ usb_deregister (&net1080_driver);
+}
+module_exit (net1080_exit);
+
+MODULE_AUTHOR ("David Brownell <dbro...@users.sourceforge.net>");
+MODULE_DESCRIPTION ("NetChip 1080 Driver (USB Host-to-Host Link)");
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/ov511.c linux/drivers/usb/ov511.c
--- v2.4.0-test8/linux/drivers/usb/ov511.c Mon Aug 7 21:01:36 2000
+++ linux/drivers/usb/ov511.c Tue Sep 19 11:37:59 2000
@@ -30,7 +30,7 @@
X * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
X */
X
-static const char version[] = "1.20";
+static const char version[] = "1.25";


X
X #define __NO_VERSION__
X

@@ -59,11 +59,9 @@
X #define MAX_FRAME_SIZE (640 * 480 * 3)
X #define MAX_DATA_SIZE (MAX_FRAME_SIZE + sizeof(struct timeval))
X
-#define DEFAULT_WIDTH 640
-#define DEFAULT_HEIGHT 480
-
X #define GET_SEGSIZE(p) ((p) == VIDEO_PALETTE_GREY ? 256 : 384)
-#define GET_DEPTH(p) ((p) == VIDEO_PALETTE_GREY ? 8 : ((p) == VIDEO_PALETTE_YUV422 ? 8 : 24))
+#define GET_DEPTH(p) ((p) == VIDEO_PALETTE_GREY ? 8 : \
+ ((p) == VIDEO_PALETTE_YUV422 ? 16 : 24))
X
X /* PARAMETER VARIABLES: */
X static int autoadjust = 1; /* CCD dynamically changes exposure, etc... */
@@ -107,6 +105,13 @@
X /* Prevent apps from timing out if frame is not done in time */
X static int retry_sync = 0;
X
+/* Enable compression. This is for experimentation only; compressed images
+ * still cannot be decoded yet. */
+static int compress = 0;
+
+/* Display test pattern - doesn't work yet either */
+static int testpat = 0;
+
X MODULE_PARM(autoadjust, "i");
X MODULE_PARM_DESC(autoadjust, "CCD dynamically changes exposure");
X MODULE_PARM(debug, "i");
@@ -122,21 +127,28 @@
X MODULE_PARM(aperture, "i");
X MODULE_PARM_DESC(aperture, "Read the OV7610/7620 specs");
X MODULE_PARM(force_rgb, "i");
-MODULE_PARM_DESC(force_rgb, "Read RBG instead of BGR");
+MODULE_PARM_DESC(force_rgb, "Read RGB instead of BGR");
X MODULE_PARM(buf_timeout, "i");
X MODULE_PARM_DESC(buf_timeout, "Number of seconds before buffer deallocation");
X MODULE_PARM(cams, "i");
X MODULE_PARM_DESC(cams, "Number of simultaneous cameras");
X MODULE_PARM(retry_sync, "i");
X MODULE_PARM_DESC(retry_sync, "Prevent apps from timing out");
+MODULE_PARM(compress, "i");
+MODULE_PARM_DESC(compress, "Turn on compression (not functional yet)");
+MODULE_PARM(testpat, "i");
+MODULE_PARM_DESC(testpat, "Replace image with vertical bar testpattern (only partially working)");
X
-MODULE_AUTHOR("Mark McClelland <mmccl...@delphi.com> & Bret Wallach & Orion Sky Lawlor <ola...@acm.org> & Kevin Moore & Charl P. Botha <cpb...@ieee.org> & Claudio Matsuoka <cla...@conectiva.com>");
+MODULE_AUTHOR("Mark McClelland <m...@i.am> & Bret Wallach & Orion Sky Lawlor <ola...@acm.org> & Kevin Moore & Charl P. Botha <cpb...@ieee.org> & Claudio Matsuoka <cla...@conectiva.com>");
X MODULE_DESCRIPTION("OV511 USB Camera Driver");
X
X char kernel_version[] = UTS_RELEASE;
X
X static struct usb_driver ov511_driver;
X
+/* I know, I know, global variables suck. This is only a temporary hack */
+int output_offset;
+
X /**********************************************************************
X * List of known OV511-based cameras
X **********************************************************************/
@@ -645,7 +657,7 @@
X static void ov511_dump_i2c_regs(struct usb_device *dev)
X {
X PDEBUG(3, "I2C REGS");
- ov511_dump_i2c_range(dev, 0x00, 0x38);
+ ov511_dump_i2c_range(dev, 0x00, 0x7C);


X }
X
X #if 0

@@ -673,7 +685,7 @@
X PDEBUG(1, "I2C REGS");
X ov511_dump_reg_range(dev, 0x40, 0x49);
X PDEBUG(1, "SYSTEM CONTROL REGS");
- ov511_dump_reg_range(dev, 0x50, 0x53);
+ ov511_dump_reg_range(dev, 0x50, 0x55);
X ov511_dump_reg_range(dev, 0x5e, 0x5f);
X PDEBUG(1, "OmniCE REGS");
X ov511_dump_reg_range(dev, 0x70, 0x79);
@@ -797,15 +809,22 @@
X if (ov511_i2c_write(dev, OV7610_REG_COM_B, ret & 0xfe) < 0)
X return -EIO;
X #endif
- if (ov511->sensor == SEN_OV7610 || ov511->sensor == SEN_OV7620AE)
- if(ov511_i2c_write(dev, OV7610_REG_SAT, p->colour >> 8) < 0)
+ if (ov511->sensor == SEN_OV7610 || ov511->sensor == SEN_OV7620AE
+ || ov511->sensor == SEN_OV6620)
+ if (ov511_i2c_write(dev, OV7610_REG_SAT, p->colour >> 8) < 0)
X return -EIO;
X
- if (ov511->sensor == SEN_OV7610) {
- if(ov511_i2c_write(dev, OV7610_REG_CNT, p->contrast >> 8) < 0)
+ if (ov511->sensor == SEN_OV7610 || ov511->sensor == SEN_OV6620) {
+ if (ov511_i2c_write(dev, OV7610_REG_CNT, p->contrast >> 8) < 0)
X return -EIO;
X
- if(ov511_i2c_write(dev, OV7610_REG_BRT, p->brightness >> 8) < 0)
+ if (ov511_i2c_write(dev, OV7610_REG_RED, 0xFF - (p->hue >> 8)) < 0)
+ return -EIO;
+
+ if (ov511_i2c_write(dev, OV7610_REG_BLUE, p->hue >> 8) < 0)
+ return -EIO;
+
+ if (ov511_i2c_write(dev, OV7610_REG_BRT, p->brightness >> 8) < 0)
X return -EIO;
X } else if ((ov511->sensor == SEN_OV7620)
X || (ov511->sensor == SEN_OV7620AE)) {
@@ -816,7 +835,7 @@
X PDEBUG(1, "con=%d brt=%d", ov511_i2c_read(dev, OV7610_REG_CNT),
X ov511_i2c_read(dev, OV7610_REG_BRT));
X
- if(ov511_i2c_write(dev, OV7610_REG_CNT, p->contrast >> 8) < 0)
+ if (ov511_i2c_write(dev, OV7610_REG_CNT, p->contrast >> 8) < 0)
X return -EIO;
X #endif
X }
@@ -838,16 +857,19 @@
X if (ov511_stop(dev) < 0)
X return -EIO;
X
- if((ret = ov511_i2c_read(dev, OV7610_REG_SAT)) < 0) return -EIO;
+ if ((ret = ov511_i2c_read(dev, OV7610_REG_SAT)) < 0) return -EIO;
X p->colour = ret << 8;
X
- if((ret = ov511_i2c_read(dev, OV7610_REG_CNT)) < 0) return -EIO;
+ if ((ret = ov511_i2c_read(dev, OV7610_REG_CNT)) < 0) return -EIO;
X p->contrast = ret << 8;
X
- if((ret = ov511_i2c_read(dev, OV7610_REG_BRT)) < 0) return -EIO;
+ if ((ret = ov511_i2c_read(dev, OV7610_REG_BRT)) < 0) return -EIO;
X p->brightness = ret << 8;
X
- p->hue = 0x8000;
+ /* This may not be the best way to do it */
+ if ((ret = ov511_i2c_read(dev, OV7610_REG_BLUE)) < 0) return -EIO;
+ p->hue = ret << 8;
+
X p->whiteness = 105 << 8;
X
X /* Can we get these from frame[0]? -claudio? */
@@ -860,20 +882,23 @@


X return 0;
X }
X

-/* FIXME: 176x144, 160x140 */
X /* LNCNT values fixed by Lawrence Glaister <l...@jfm.bc.ca> */
X static struct mode_list mlist[] = {
- /* W H C PXCNT LNCNT PXDIV LNDIV M420 COMA COMC COML */
- { 640, 480, 0, 0x4f, 0x3b, 0x00, 0x00, 0x03, 0x24, 0x04, 0x9e },
- { 640, 480, 1, 0x4f, 0x3b, 0x00, 0x00, 0x03, 0x24, 0x04, 0x9e },
- { 320, 240, 0, 0x27, 0x1d, 0x00, 0x00, 0x03, 0x04, 0x24, 0x1e },
- { 320, 240, 1, 0x27, 0x1d, 0x00, 0x00, 0x03, 0x04, 0x24, 0x1e },
- { 352, 288, 0, 0x2b, 0x25, 0x00, 0x00, 0x03, 0x04, 0x04, 0x1e },
- { 352, 288, 1, 0x2b, 0x25, 0x00, 0x00, 0x03, 0x04, 0x04, 0x1e },
- { 384, 288, 0, 0x2f, 0x25, 0x00, 0x00, 0x03, 0x04, 0x04, 0x1e },
- { 384, 288, 1, 0x2f, 0x25, 0x00, 0x00, 0x03, 0x04, 0x04, 0x1e },
- { 448, 336, 0, 0x37, 0x29, 0x00, 0x00, 0x03, 0x04, 0x04, 0x1e },
- { 448, 336, 1 ,0x37, 0x29, 0x00, 0x00, 0x03, 0x04, 0x04, 0x1e },
+ /* W H C PXCNT LNCNT PXDIV LNDIV M420 COMA COML */
+ { 640, 480, 0, 0x4f, 0x3b, 0x00, 0x00, 0x03, 0x24, 0x9e },
+ { 640, 480, 1, 0x4f, 0x3b, 0x00, 0x00, 0x03, 0x24, 0x9e },
+ { 320, 240, 0, 0x27, 0x1d, 0x00, 0x00, 0x03, 0x04, 0x1e },
+ { 320, 240, 1, 0x27, 0x1d, 0x00, 0x00, 0x03, 0x04, 0x1e },
+ { 352, 288, 0, 0x2b, 0x25, 0x00, 0x00, 0x03, 0x04, 0x1e },
+ { 352, 288, 1, 0x2b, 0x25, 0x00, 0x00, 0x03, 0x04, 0x1e },
+ { 384, 288, 0, 0x2f, 0x25, 0x00, 0x00, 0x03, 0x04, 0x1e },
+ { 384, 288, 1, 0x2f, 0x25, 0x00, 0x00, 0x03, 0x04, 0x1e },
+ { 448, 336, 0, 0x37, 0x29, 0x00, 0x00, 0x03, 0x04, 0x1e },
+ { 448, 336, 1, 0x37, 0x29, 0x00, 0x00, 0x03, 0x04, 0x1e },
+ { 176, 144, 0, 0x15, 0x12, 0x00, 0x00, 0x03, 0x04, 0x1e },
+ { 176, 144, 1, 0x15, 0x12, 0x00, 0x00, 0x03, 0x04, 0x1e },
+ { 160, 120, 0, 0x13, 0x0e, 0x00, 0x00, 0x03, 0x04, 0x1e },
+ { 160, 120, 1, 0x13, 0x0e, 0x00, 0x00, 0x03, 0x04, 0x1e },
X { 0, 0 }
X };
X
@@ -883,7 +908,8 @@
X {
X int i;
X struct usb_device *dev = ov511->dev;
- int hwsbase = 0, hwebase = 0;
+ int hwsbase, hwebase, vwsbase, vwebase, hwsize, vwsize;
+ int hwscale = 0, vwscale = 0;
X
X PDEBUG(3, "width:%d, height:%d, mode:%d, sub:%d",
X width, height, mode, sub_flag);
@@ -895,7 +921,7 @@
X ov511_reg_write(dev, 0x16, 0x00);
X if (ov511->sensor == SEN_OV7610
X || ov511->sensor == SEN_OV7620AE) {
- /* these aren't valid on the OV7620 */
+ /* these aren't valid on the OV6620/OV7620 */
X ov511_i2c_write(dev, 0x0e, 0x44);
X }
X ov511_i2c_write(dev, 0x13, autoadjust ? 0x21 : 0x20);
@@ -907,7 +933,7 @@
X ov511_reg_write(dev, 0x16, 0x01);
X if (ov511->sensor == SEN_OV7610


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 092'
echo 'File patch-2.4.0-test9 is continued in part 093'
echo "093" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part093

#!/bin/sh -x
# this is part 093 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 093; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

X || ov511->sensor == SEN_OV7620AE) {

- /* not valid on the OV7620 */
+ /* not valid on the OV6620/OV7620 */
X ov511_i2c_write(dev, 0x0e, 0x04);
X }
X ov511_i2c_write(dev, 0x13, autoadjust ? 0x01 : 0x00);
@@ -923,27 +949,64 @@
X case SEN_OV7620AE:
X hwsbase = 0x38;
X hwebase = 0x3a;
+ vwsbase = vwebase = 0x05;
+ break;
+ case SEN_OV6620:
+ hwsbase = 0x38;
+ hwebase = 0x39;
+ vwsbase = 0x03;
+ vwebase = 0x04;
X break;
X case SEN_OV7620:
X hwsbase = 0x2c;
X hwebase = 0x2d;
+ vwsbase = vwebase = 0x05;
X break;
X default:
- hwsbase = 0;
- hwebase = 0;
- break;
+ err("Invalid sensor");


+ return -EINVAL;
+ }
+

+ /* Bit 5 of COM C register varies with sensor */
+ if (ov511->sensor == SEN_OV6620) {
+ if (width > 176 && height > 144) { /* CIF */
+ ov511_i2c_write(dev, 0x14, 0x04);
+ hwscale = 1;
+ vwscale = 1; /* The datasheet says 0; it's wrong */
+ hwsize = 352;
+ vwsize = 288;
+ } else { /* QCIF */
+ ov511_i2c_write(dev, 0x14, 0x24);
+ hwsize = 176;
+ vwsize = 144;
+ }
+ }
+ else {
+ if (width > 320 && height > 240) { /* VGA */
+ ov511_i2c_write(dev, 0x14, 0x04);
+ hwscale = 2;
+ vwscale = 1;
+ hwsize = 640;
+ vwsize = 480;
+ } else { /* QVGA */
+ ov511_i2c_write(dev, 0x14, 0x24);
+ hwscale = 1;
+ hwsize = 320;
+ vwsize = 240;
+ }
X }
X
+ /* FIXME! - This needs to be changed to support 160x120 and 6620!!! */
X if (sub_flag) {
- ov511_i2c_write(dev, 0x17, hwsbase+(ov511->subx>>2));
- ov511_i2c_write(dev, 0x18, hwebase+((ov511->subx+ov511->subw)>>2));
- ov511_i2c_write(dev, 0x19, 0x5+(ov511->suby>>1));
- ov511_i2c_write(dev, 0x1a, 0x5+((ov511->suby+ov511->subh)>>1));
+ ov511_i2c_write(dev, 0x17, hwsbase+(ov511->subx>>hwscale));
+ ov511_i2c_write(dev, 0x18, hwebase+((ov511->subx+ov511->subw)>>hwscale));
+ ov511_i2c_write(dev, 0x19, vwsbase+(ov511->suby>>vwscale));
+ ov511_i2c_write(dev, 0x1a, vwebase+((ov511->suby+ov511->subh)>>vwscale));
X } else {
X ov511_i2c_write(dev, 0x17, hwsbase);
- ov511_i2c_write(dev, 0x18, hwebase + (640>>2));
- ov511_i2c_write(dev, 0x19, 0x5);
- ov511_i2c_write(dev, 0x1a, 5 + (480>>1));
+ ov511_i2c_write(dev, 0x18, hwebase + (hwsize>>hwscale));
+ ov511_i2c_write(dev, 0x19, vwsbase);
+ ov511_i2c_write(dev, 0x1a, vwebase + (vwsize>>vwscale));
X }
X
X for (i = 0; mlist[i].width; i++) {
@@ -981,17 +1044,22 @@
X #ifdef OV511_GBR422
X ov511_i2c_write(dev, 0x12, mlist[i].common_A | 0x08);
X #else
- ov511_i2c_write(dev, 0x12, mlist[i].common_A);
+ ov511_i2c_write(dev, 0x12, mlist[i].common_A | (testpat?0x02:0x00));
X #endif
- ov511_i2c_write(dev, 0x14, mlist[i].common_C);
X
- /* 7620 doesn't have register 0x35, so play it safe */
- if (ov511->sensor != SEN_OV7620)
+ /* 7620/6620 don't have register 0x35, so play it safe */


+ if (ov511->sensor == SEN_OV7610 ||

+ ov511->sensor == SEN_OV7620AE)
X ov511_i2c_write(dev, 0x35, mlist[i].common_L);
X
X break;
X }
X
+ if (compress) {
+ ov511_reg_write(dev, 0x78, 0x03); // Turn on Y compression
+ ov511_reg_write(dev, 0x79, 0x00); // Disable LUTs
+ }
+
X if (ov511_restart(ov511->dev) < 0)
X return -EIO;
X
@@ -1028,6 +1096,16 @@
X *
X * To avoid floating point arithmetic, the color conversion
X * coefficients are scaled into 16.16 fixed-point integers.
+ * They were determined as follows:
+ *
+ * double brightness = 1.0; (0->black; 1->full scale)
+ * double saturation = 1.0; (0->greyscale; 1->full color)
+ * double fixScale = brightness * 256 * 256;
+ * int rvScale = (int)(1.402 * saturation * fixScale);
+ * int guScale = (int)(-0.344136 * saturation * fixScale);
+ * int gvScale = (int)(-0.714136 * saturation * fixScale);
+ * int buScale = (int)(1.772 * saturation * fixScale);
+ * int yScale = (int)(fixScale);
X */
X
X /* LIMIT: convert a 16.16 fixed-point value to a byte, with clipping. */
@@ -1037,14 +1115,11 @@
X ov511_move_420_block(int yTL, int yTR, int yBL, int yBR, int u, int v,
X int rowPixels, unsigned char * rgb)
X {
- const double brightness = 1.0; /* 0->black; 1->full scale */
- const double saturation = 1.0; /* 0->greyscale; 1->full color */
- const double fixScale = brightness * 256 * 256;
- const int rvScale = (int)(1.402 * saturation * fixScale);
- const int guScale = (int)(-0.344136 * saturation * fixScale);
- const int gvScale = (int)(-0.714136 * saturation * fixScale);
- const int buScale = (int)(1.772 * saturation * fixScale);
- const int yScale = (int)(fixScale);
+ const int rvScale = 91881;
+ const int guScale = -22553;
+ const int gvScale = -46801;
+ const int buScale = 116129;
+ const int yScale = 65536;
X int r, g, b;
X
X g = guScale * u + gvScale * v;
@@ -1104,6 +1179,9 @@
X
X #undef OV511_DUMPPIX
X
+/* #define this and OV511_DUMPPIX to disable parsing of UV data */
+#undef OV511_FORCE_MONO
+
X #ifdef OV511_GBR422
X static void
X ov511_parse_data_rgb24(unsigned char *pIn0, unsigned char *pOut0,
@@ -1234,6 +1312,8 @@
X }
X }
X #else
+
+#ifndef OV511_FORCE_MONO
X /* Just dump pix data straight out for debug */
X int i, j;
X
@@ -1246,95 +1326,124 @@
X }
X pOut0 += (iWidth - WDIV) * 3;
X }
+#else
+
+#if 1
+ /* This converts the Y data to "black-and-white" RGB data */
+ /* Useful for experimenting with compression */
+ int k, l, m;
+ unsigned char *pIn, *pOut, *pOut1;
+
+ pIn = pIn0 + 128;
+ pOut = pOut0 + iOutY;
+ for (k = 0; k < 4; k++) {
+ pOut1 = pOut;
+ for (l = 0; l < 8; l++) {
+ for (m = 0; m < 8; m++) {
+ *pOut1++ = *pIn;
+ *pOut1++ = *pIn;
+ *pOut1++ = *pIn++;
+ }
+ pOut1 += (iWidth - 8) * 3;
+ }
+ pOut += 8 * 3;
+ }
+#else
+ /* This will dump the Y channel data stream as-is */
+ int count;
+ unsigned char *pIn, *pOut;
+
+ pIn = pIn0 + 128;
+ pOut = pOut0 + output_offset;
+ for (count = 0; count < 256; count++) {
+ *pOut++ = *pIn;
+ *pOut++ = *pIn;
+ *pOut++ = *pIn++;
+ output_offset += 3;
+ }
+#endif
+
+#endif
+
X #endif
X }
X #endif
X
+/* This converts YUV420 segments to YUYV */
X static void
X ov511_parse_data_yuv422(unsigned char *pIn0, unsigned char *pOut0,
- int iOutY, int iOutUV, int iHalf, int iWidth)
+ int iOutY, int iOutUV, int iWidth)
X {
X int k, l, m;
- unsigned char *pIn;
- unsigned char *pOut, *pOut1;
+ unsigned char *pIn, *pOut, *pOut1;
X
- /* Just copy the Y's if in the first stripe */
- if (!iHalf) {
- pIn = pIn0 + 128;
- pOut = pOut0 + iOutY;
- for (k = 0; k < 4; k++) {
- pOut1 = pOut;
- for (l = 0; l < 8; l++) {
- for (m = 0; m < 8; m++) {
- *pOut1++ = (*pIn++) & 0xF0;
- }
- pOut1 += iWidth - 8;
+ pIn = pIn0 + 128;
+ pOut = pOut0 + iOutY;
+ for (k = 0; k < 4; k++) {
+ pOut1 = pOut;
+ for (l = 0; l < 8; l++) {
+ for (m = 0; m < 8; m++) {
+ *pOut1 = (*pIn++);
+ pOut1 += 2;
X }
- pOut += 8;
+ pOut1 += (iWidth - 8) * 2;
X }
+ pOut += 8 * 2;
X }
X
- /* Use the first half of VUs to calculate value */
X pIn = pIn0;
- pOut = pOut0 + iOutUV;
- for (l = 0; l < 4; l++) {
+ pOut = pOut0 + iOutUV + 1;
+ for (l = 0; l < 8; l++) {
X for (m=0; m<8; m++) {
- unsigned char *p00 = pOut;
- unsigned char *p01 = pOut+1;
- unsigned char *p10 = pOut+iWidth;
- unsigned char *p11 = pOut+iWidth+1;
- int v = *(pIn+64) - 128;
- int u = *pIn++ - 128;
- int uv = ((u >> 4) & 0x0C) + (v >> 6);
-
- *p00 |= uv;
- *p01 |= uv;
- *p10 |= uv;
- *p11 |= uv;
-
- pOut += 2;
+ int v = *(pIn+64);
+ int u = *pIn++;
+
+ *pOut = u;
+ *(pOut+2) = v;
+ *(pOut+iWidth) = u;
+ *(pOut+iWidth+2) = v;
+ pOut += 4;
X }
- pOut += (iWidth*2 - 16);
+ pOut += (iWidth*4 - 32);
X }
+}
X
- /* Just copy the other UV rows */
- for (l = 0; l < 4; l++) {
- for (m = 0; m < 8; m++) {
- int v = *(pIn + 64) - 128;
- int u = (*pIn++) - 128;
- int uv = ((u >> 4) & 0x0C) + (v >> 6);
- *(pOut) = uv;
- pOut += 2;
- }
- pOut += (iWidth*2 - 16);
+static void
+ov511_parse_data_yuv420(unsigned char *pIn0, unsigned char *pOut0,
+ int iOutY, int iOutUV, int iWidth, int iHeight)
+{
+ int k, l, m;
+ unsigned char *pIn;
+ unsigned char *pOut, *pOut1;
+ unsigned a = iWidth * iHeight;
+ unsigned w = iWidth / 2;
+
+ pIn = pIn0;
+ pOut = pOut0 + iOutUV + a;
+ for (k = 0; k < 8; k++) {
+ pOut1 = pOut;
+ for (l = 0; l < 8; l++) *pOut1++ = *pIn++;
+ pOut += w;
X }
X
- /* Calculate values if it's the second half */
- if (iHalf) {
- pIn = pIn0 + 128;
- pOut = pOut0 + iOutY;
- for (k = 0; k < 4; k++) {
- pOut1 = pOut;
- for (l=0; l<4; l++) {
- for (m=0; m<4; m++) {
- int y10 = *(pIn+8);
- int y00 = *pIn++;
- int y11 = *(pIn+8);
- int y01 = *pIn++;
- int uv = *pOut1;
+ pIn = pIn0 + 64;
+ pOut = pOut0 + iOutUV + a + a/4;
+ for (k = 0; k < 8; k++) {
+ pOut1 = pOut;
+ for (l = 0; l < 8; l++) *pOut1++ = *pIn++;
+ pOut += w;
+ }
X
- *pOut1 = (y00 & 0xF0) | uv;
- *(pOut1+1) = (y01 & 0xF0) | uv;
- *(pOut1+iWidth) = (y10 & 0xF0) | uv;
- *(pOut1+iWidth+1) = (y11 & 0xF0) | uv;
-
- pOut1 += 2;
- }
- pOut1 += (iWidth*2 - 8);
- pIn += 8;
- }
- pOut += 8;
+ pIn = pIn0 + 128;
+ pOut = pOut0 + iOutY;
+ for (k = 0; k < 4; k++) {
+ pOut1 = pOut;
+ for (l = 0; l < 8; l++) {
+ for (m = 0; m < 8; m++)
+ *pOut1++ =*pIn++;
+ pOut1 += iWidth - 8;
X }
+ pOut += 8;
X }
X }
X
@@ -1553,6 +1662,8 @@
X /* Frame start */
X PDEBUG(4, "Frame start, framenum = %d", ov511->curframe);
X
+ output_offset = 0;
+
X /* Check to see if it's a snapshot frame */
X /* FIXME?? Should the snapshot reset go here? Performance? */
X if (cdata[8] & 0x02) {
@@ -1633,8 +1744,12 @@
X iY & 1, frame->width);
X break;
X case VIDEO_PALETTE_YUV422:
- ov511_parse_data_yuv422(pData, pOut, iOutY, iOutUV,
- iY & 1, frame->width);
+ case VIDEO_PALETTE_YUYV:
+ ov511_parse_data_yuv422(pData, pOut, iOutY, iOutUV, frame->width);
+ break;
+ case VIDEO_PALETTE_YUV420:
+ ov511_parse_data_yuv420 (pData, pOut, iOutYP, iUV*HDIV*frame->width/2 + jUV*WDIV/4,
+ frame->width, frame->height);
X break;
X case VIDEO_PALETTE_YUV422P:
X ov511_parse_data_yuv422p (pData, pOut, iOutYP, iOutUVP/2,
@@ -1674,7 +1789,7 @@
X return;
X
X if (!ov511->streaming) {
- PDEBUG(2, "hmmm... not streaming, but got interrupt");
+ PDEBUG(4, "hmmm... not streaming, but got interrupt");
X return;
X }
X
@@ -1794,7 +1909,6 @@
X static int ov511_new_frame(struct usb_ov511 *ov511, int framenum)
X {
X struct ov511_frame *frame;
- int width, height;
X
X PDEBUG(4, "ov511->curframe = %d, framenum = %d", ov511->curframe,
X framenum);
@@ -1810,11 +1924,9 @@
X return 0;
X
X frame = &ov511->frame[framenum];
- width = frame->width;
- height = frame->height;
X
- PDEBUG (4, "framenum = %d, width = %d, height = %d", framenum, width,
- height);
+ PDEBUG (4, "framenum = %d, width = %d, height = %d", framenum,
+ frame->width, frame->height);
X
X frame->grabstate = FRAME_GRABBING;
X frame->scanstate = STATE_SCANNING;
@@ -1824,15 +1936,15 @@
X ov511->curframe = framenum;
X
X /* Make sure it's not too big */
- if (width > DEFAULT_WIDTH)
- width = DEFAULT_WIDTH;
+ if (frame->width > ov511->maxwidth)
+ frame->width = ov511->maxwidth;
X
- width &= ~7L; /* Multiple of 8 */
+ frame->width &= ~7L; /* Multiple of 8 */
X
- if (height > DEFAULT_HEIGHT)
- height = DEFAULT_HEIGHT;
+ if (frame->height > ov511->maxheight)
+ frame->height = ov511->maxheight;
X
- width &= ~3L; /* Multiple of 4 */
+ frame->height &= ~3L; /* Multiple of 4 */


X
X return 0;
X }

@@ -2006,22 +2118,24 @@
X
X PDEBUG(4, "ov511_close");
X
- down(&ov511->lock);
- ov511->user--;
+ down(&ov511->lock);
X
+ ov511->user--;
X ov511_stop_isoc(ov511);
X
- ov511_dealloc(ov511, 0);
+ if (ov511->dev)
+ ov511_dealloc(ov511, 0);
+
X up(&ov511->lock);
X
X if (!ov511->dev) {
+ ov511_dealloc(ov511, 1);
X video_unregister_device(&ov511->vdev);
X kfree(ov511);
X ov511 = NULL;
X }
X
X MOD_DEC_USE_COUNT;
-
X }
X
X static int ov511_init_done(struct video_device *dev)
@@ -2058,8 +2172,8 @@
X b.type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE;
X b.channels = 1;
X b.audios = 0;
- b.maxwidth = DEFAULT_WIDTH;
- b.maxheight = DEFAULT_HEIGHT;
+ b.maxwidth = ov511->maxwidth;
+ b.maxheight = ov511->maxheight;
X b.minwidth = 32;
X b.minheight = 16;
X
@@ -2126,6 +2240,8 @@
X if (p.palette != VIDEO_PALETTE_GREY &&
X p.palette != VIDEO_PALETTE_RGB24 &&
X p.palette != VIDEO_PALETTE_YUV422 &&
+ p.palette != VIDEO_PALETTE_YUYV &&
+ p.palette != VIDEO_PALETTE_YUV420 &&
X p.palette != VIDEO_PALETTE_YUV422P)
X return -EINVAL;
X
@@ -2198,9 +2314,9 @@
X return -EINVAL;
X if (vw.clipcount)
X return -EINVAL;
- if (vw.height != DEFAULT_HEIGHT)
+ if (vw.height != ov511->maxheight)
X return -EINVAL;
- if (vw.width != DEFAULT_WIDTH)
+ if (vw.width != ov511->maxwidth)
X return -EINVAL;
X #endif
X
@@ -2268,6 +2384,8 @@
X
X if (vm.format != VIDEO_PALETTE_RGB24 &&
X vm.format != VIDEO_PALETTE_YUV422 &&
+ vm.format != VIDEO_PALETTE_YUYV &&
+ vm.format != VIDEO_PALETTE_YUV420 &&
X vm.format != VIDEO_PALETTE_YUV422P &&
X vm.format != VIDEO_PALETTE_GREY)
X return -EINVAL;
@@ -2275,7 +2393,7 @@
X if ((vm.frame != 0) && (vm.frame != 1))
X return -EINVAL;
X
- if (vm.width > DEFAULT_WIDTH || vm.height > DEFAULT_HEIGHT)
+ if (vm.width > ov511->maxwidth || vm.height > ov511->maxheight)
X return -EINVAL;
X
X if (ov511->frame[vm.frame].grabstate == FRAME_GRABBING)
@@ -2392,14 +2510,14 @@
X return 0;
X }
X case VIDIOCKEY:
- return 0;
+ return 0;
X case VIDIOCCAPTURE:
X return -EINVAL;
X case VIDIOCSFBUF:
X return -EINVAL;
X case VIDIOCGTUNER:
X case VIDIOCSTUNER:
- return -EINVAL;
+ return -EINVAL;
X case VIDIOCGFREQ:
X case VIDIOCSFREQ:
X return -EINVAL;
@@ -2599,12 +2717,9 @@
X { OV511_I2C_BUS, 0x16, 0x06 },
X { OV511_I2C_BUS, 0x28, 0x24 },
X { OV511_I2C_BUS, 0x2b, 0xac },
- { OV511_I2C_BUS, 0x05, 0x00 },
- { OV511_I2C_BUS, 0x06, 0x00 },
X { OV511_I2C_BUS, 0x12, 0x00 },
X { OV511_I2C_BUS, 0x38, 0x81 },
X { OV511_I2C_BUS, 0x28, 0x24 }, /* 0c */
- { OV511_I2C_BUS, 0x05, 0x00 },
X { OV511_I2C_BUS, 0x0f, 0x85 }, /* lg's setting */
X { OV511_I2C_BUS, 0x15, 0x01 },
X { OV511_I2C_BUS, 0x20, 0x1c },
@@ -2612,7 +2727,6 @@
X { OV511_I2C_BUS, 0x24, 0x10 },
X { OV511_I2C_BUS, 0x25, 0x8a },
X { OV511_I2C_BUS, 0x27, 0xc2 },
- { OV511_I2C_BUS, 0x29, 0x03 }, /* 91 */
X { OV511_I2C_BUS, 0x2a, 0x04 },
X { OV511_I2C_BUS, 0x2c, 0xfe },
X { OV511_I2C_BUS, 0x30, 0x71 },
@@ -2634,14 +2748,12 @@
X { OV511_I2C_BUS, 0x2b, 0xac },
X { OV511_I2C_BUS, 0x12, 0x00 },
X { OV511_I2C_BUS, 0x28, 0x24 },
- { OV511_I2C_BUS, 0x05, 0x00 },
X { OV511_I2C_BUS, 0x0f, 0x85 }, /* lg's setting */
X { OV511_I2C_BUS, 0x15, 0x01 },
X { OV511_I2C_BUS, 0x23, 0x00 },
X { OV511_I2C_BUS, 0x24, 0x10 },
X { OV511_I2C_BUS, 0x25, 0x8a },
X { OV511_I2C_BUS, 0x27, 0xe2 },
- { OV511_I2C_BUS, 0x29, 0x03 },
X { OV511_I2C_BUS, 0x2a, 0x00 },
X { OV511_I2C_BUS, 0x2c, 0xfe },
X { OV511_I2C_BUS, 0x30, 0x71 },
@@ -2658,24 +2770,23 @@
X
X PDEBUG (4, "starting configuration");
X
- if(ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_WRITE,
- OV7610_I2C_WRITE_ID) < 0)
+ /* This looks redundant, but is necessary for WebCam 3 */
+ if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_WRITE,
+ OV7610_I2C_WRITE_ID) < 0)
X return -1;
X
- if(ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_READ,
- OV7610_I2C_READ_ID) < 0)
+ if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_READ,
+ OV7610_I2C_READ_ID) < 0)
X return -1;
X
X if (ov511_reset(dev, OV511_RESET_NOREGS) < 0)


X return -1;
-
+

X /* Reset the 76xx */
X if (ov511_i2c_write(dev, 0x12, 0x80) < 0) return -1;
X
-#if 1 /* Maybe this will fix detection problems? MM */
X /* Wait for it to initialize */
X schedule_timeout (1 + 150 * HZ / 1000);
-#endif
X
X for (i = 0, success = 0; i < i2c_detect_tries && !success; i++) {
X if ((ov511_i2c_read(dev, OV7610_REG_ID_HIGH) == 0x7F) &&
@@ -2693,12 +2804,34 @@
X }
X
X if (success) {
- PDEBUG(1, "I2C synced in %d attempt(s)", i);
+ PDEBUG(1, "I2C synced in %d attempt(s) (method 1)", i);
X } else {
- err("Failed to read sensor ID. You might not have an OV76xx,");
- err("or it may be not responding. Report this to");
- err("mmccl...@delphi.com");
- return -1;
+ /* Reset the 76xx */
+ if (ov511_i2c_write(dev, 0x12, 0x80) < 0) return -1;
+
+ /* Wait for it to initialize */
+ schedule_timeout (1 + 150 * HZ / 1000);
+
+ i = 0;
+ success = 0;
+ while (i <= i2c_detect_tries) {
+ if ((ov511_i2c_read(dev, OV7610_REG_ID_HIGH) == 0x7F) &&
+ (ov511_i2c_read(dev, OV7610_REG_ID_LOW) == 0xA2)) {
+ success = 1;
+ break;
+ } else {
+ i++;
+ }
+ }
+
+ if ((i == i2c_detect_tries) && (success == 0)) {
+ err("Failed to read sensor ID. You might not have an OV7610/20,");
+ err("or it may be not responding. Report this to");
+ err("m...@i.am");
+ return -1;
+ } else {
+ PDEBUG(1, "I2C synced in %d attempt(s) (method 2)", i+1);
+ }
X }
X
X /* Detect sensor if user didn't use override param */
@@ -2736,6 +2869,128 @@


X return -1;
X }
X

+ /* Set sensor-specific vars */
+ ov511->maxwidth = 640;
+ ov511->maxheight = 480;
+
+ if (aperture < 0) { /* go with the default */
+ if (ov511_i2c_write(dev, 0x26, 0xa2) < 0) return -1;
+ } else if (aperture <= 0xf) { /* user overrode default */
+ if (ov511_i2c_write(dev, 0x26, (aperture << 4) + 2) < 0)
+ return -1;
+ } else {
+ err("Invalid setting for aperture; legal value: 0 - 15");


+ return -1;
+ }
+

+ if (autoadjust) {
+ if (ov511_i2c_write(dev, 0x13, 0x01) < 0) return -1;
+ if (ov511_i2c_write(dev, 0x2d,
+ ov511->sensor==SEN_OV7620?0x91:0x93) < 0) return -1;
+ } else {
+ if (ov511_i2c_write(dev, 0x13, 0x00) < 0) return -1;
+ if (ov511_i2c_write(dev, 0x2d,
+ ov511->sensor==SEN_OV7620?0x81:0x83) < 0) return -1;
+ ov511_i2c_write(dev, 0x28, ov511_i2c_read(dev, 0x28) | 8);
+ }


+
+ return 0;
+}
+

+static int ov6xx0_configure(struct usb_ov511 *ov511)
+{
+ struct usb_device *dev = ov511->dev;
+ int i, success, rc;
+
+ static struct ov511_regvals aRegvalsNorm6x20[] = {
+ { OV511_I2C_BUS, 0x12, 0x80 }, /* reset */
+ { OV511_I2C_BUS, 0x11, 0x01 },
+ { OV511_I2C_BUS, 0x03, 0xd0 },
+ { OV511_I2C_BUS, 0x05, 0x7f },
+ { OV511_I2C_BUS, 0x07, 0xa8 },
+ { OV511_I2C_BUS, 0x0c, 0x24 },
+ { OV511_I2C_BUS, 0x0d, 0x24 },
+ { OV511_I2C_BUS, 0x10, 0xff }, /* ? */
+ { OV511_I2C_BUS, 0x14, 0x04 },
+ { OV511_I2C_BUS, 0x16, 0x06 }, /* ? */
+ { OV511_I2C_BUS, 0x19, 0x04 },
+ { OV511_I2C_BUS, 0x1a, 0x93 },
+ { OV511_I2C_BUS, 0x20, 0x28 },
+ { OV511_I2C_BUS, 0x27, 0xa2 },
+ { OV511_I2C_BUS, 0x28, 0x24 },
+ { OV511_I2C_BUS, 0x2a, 0x04 }, /* 84? */
+ { OV511_I2C_BUS, 0x2b, 0xac }, /* a8? */
+ { OV511_I2C_BUS, 0x2d, 0x95 },
+ { OV511_I2C_BUS, 0x33, 0x28 },
+ { OV511_I2C_BUS, 0x34, 0xc7 },
+ { OV511_I2C_BUS, 0x38, 0x8b },
+ { OV511_I2C_BUS, 0x3c, 0x5c },
+ { OV511_I2C_BUS, 0x3d, 0x80 },
+ { OV511_I2C_BUS, 0x3f, 0x00 },
+ { OV511_I2C_BUS, 0x4a, 0x80 }, /* undocumented */
+ { OV511_I2C_BUS, 0x4b, 0x80 }, /* undocumented */
+ { OV511_I2C_BUS, 0x4d, 0xd2 },
+ { OV511_I2C_BUS, 0x4e, 0xc1 },
+ { OV511_I2C_BUS, 0x4f, 0x04 },
+ { OV511_DONE_BUS, 0x0, 0x00 },
+ };
+
+ PDEBUG (4, "starting sensor configuration");
+
+ /* Reset the 6xx0 */
+ if (ov511_i2c_write(dev, 0x12, 0x80) < 0) return -1;
+
+ /* Wait for it to initialize */
+ schedule_timeout (1 + 150 * HZ / 1000);
+
+ for (i = 0, success = 0; i < i2c_detect_tries && !success; i++) {
+ if ((ov511_i2c_read(dev, OV7610_REG_ID_HIGH) == 0x7F) &&
+ (ov511_i2c_read(dev, OV7610_REG_ID_LOW) == 0xA2)) {
+ success = 1;
+ continue;
+ }
+
+ /* Reset the 6xx0 */
+ if (ov511_i2c_write(dev, 0x12, 0x80) < 0) return -1;
+ /* Wait for it to initialize */
+ schedule_timeout (1 + 150 * HZ / 1000);
+ /* Dummy read to sync I2C */
+ if (ov511_i2c_read(dev, 0x00) < 0) return -1;
+ }
+
+ if (success) {
+ PDEBUG(1, "I2C synced in %d attempt(s)", i);
+ } else {
+ err("Failed to read sensor ID. You might not have an OV6xx0,");
+ err("or it may be not responding. Report this to");
+ err("m...@i.am");


+ return -1;
+ }
+

+ /* Detect sensor if user didn't use override param */
+ if (sensor == 0) {
+ rc = ov511_i2c_read(dev, OV7610_REG_COM_I);
+
+ if (rc < 0) {
+ err("Error detecting sensor type");
+ return -1;
+ } else {
+ info("Sensor is an OV6xx0 (version %d)", rc & 3);
+ ov511->sensor = SEN_OV6620;
+ }
+ } else { /* sensor != 0; user overrode detection */
+ ov511->sensor = sensor;
+ info("Sensor set to type %d", ov511->sensor);
+ }
+
+ /* Set sensor-specific vars */
+ ov511->maxwidth = 352;
+ ov511->maxheight = 288;
+
+ PDEBUG(4, "Writing 6x20 registers");
+ if (ov511_write_regvals(dev, aRegvalsNorm6x20))
+ return -1;
+
X if (aperture < 0) { /* go with the default */
X if (ov511_i2c_write(dev, 0x26, 0xa2) < 0) return -1;
X } else if (aperture <= 0xf) { /* user overrode default */
@@ -2781,10 +3036,10 @@
X { OV511_REG_BUS, OV511_REG_DRAM_ENABLE_FLOW_CONTROL, 0x01 },
X { OV511_REG_BUS, OV511_REG_SYSTEM_SNAPSHOT, 0x02 },
X { OV511_REG_BUS, OV511_REG_SYSTEM_SNAPSHOT, 0x00 },
- { OV511_REG_BUS, OV511_REG_FIFO_BITMASK, 0x1f }, /* 0f */
- { OV511_REG_BUS, OV511_OMNICE_PREDICTION_HORIZ_Y, 0x3f },
- { OV511_REG_BUS, OV511_OMNICE_PREDICTION_HORIZ_UV, 0x3f },
- { OV511_REG_BUS, OV511_OMNICE_PREDICTION_VERT_Y, 0x01 },
+ { OV511_REG_BUS, OV511_REG_FIFO_BITMASK, 0x1f },
+ { OV511_REG_BUS, OV511_OMNICE_PREDICTION_HORIZ_Y, 0x08 },
+ { OV511_REG_BUS, OV511_OMNICE_PREDICTION_HORIZ_UV, 0x01 },
+ { OV511_REG_BUS, OV511_OMNICE_PREDICTION_VERT_Y, 0x08 },
X { OV511_REG_BUS, OV511_OMNICE_PREDICTION_VERT_UV, 0x01 },
X { OV511_REG_BUS, OV511_OMNICE_QUANTIZATION_HORIZ_Y, 0x01 },
X { OV511_REG_BUS, OV511_OMNICE_QUANTIZATION_HORIZ_UV, 0x01 },
@@ -2814,11 +3069,52 @@
X
X ov511->snap_enabled = snapshot;
X
+ /* Test for 76xx */
+ if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_WRITE,
+ OV7610_I2C_WRITE_ID) < 0)
+ goto error;
+
+ if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_READ,
+ OV7610_I2C_READ_ID) < 0)
+ goto error;
+
+ if (ov511_reset(dev, OV511_RESET_NOREGS) < 0)
+ goto error;
+
+ if (ov511_i2c_write(dev, 0x12, 0x80) < 0) {
+ /* Test for 6xx0 */
+ if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_WRITE,
+ OV6xx0_I2C_WRITE_ID) < 0)
+ goto error;
+
+ if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_READ,
+ OV6xx0_I2C_READ_ID) < 0)
+ goto error;
+
+ if (ov511_reset(dev, OV511_RESET_NOREGS) < 0)
+ goto error;
+
+ if (ov511_i2c_write(dev, 0x12, 0x80) < 0) {
+ err("Can't determine sensor slave IDs");


+ goto error;
+ }
+

+ if(ov6xx0_configure(ov511) < 0) {
+ err("failed to configure OV6xx0");
+ goto error;
+ }
+ } else {
+ if(ov76xx_configure(ov511) < 0) {
+ err("failed to configure OV76xx");


+ goto error;
+ }
+ }

+
X /* Set default sizes in case IOCTL (VIDIOCMCAPTURE) is not used
X * (using read() instead). */
X for (i = 0; i < OV511_NUMFRAMES; i++) {
- ov511->frame[i].width = DEFAULT_WIDTH;
- ov511->frame[i].height = DEFAULT_HEIGHT;
+ ov511->frame[i].width = ov511->maxwidth;
+ ov511->frame[i].height = ov511->maxheight;
X ov511->frame[i].depth = 24;
X ov511->frame[i].bytes_read = 0;
X ov511->frame[i].segment = 0;
@@ -2826,14 +3122,8 @@
X ov511->frame[i].segsize = GET_SEGSIZE(ov511->frame[i].format);
X }
X
- /* Initialize to DEFAULT_WIDTH, DEFAULT_HEIGHT, YUV4:2:0 */
-
- if(ov76xx_configure(ov511) < 0) {
- err("failed to configure OV76xx");
- goto error;
- }
-
- if (ov511_mode_init_regs(ov511, DEFAULT_WIDTH, DEFAULT_HEIGHT,
+ /* Initialize to max width/height, RGB24 */
+ if (ov511_mode_init_regs(ov511, ov511->maxwidth, ov511->maxheight,
X VIDEO_PALETTE_RGB24, 0) < 0)
X goto error;
X
@@ -2869,10 +3159,12 @@
X interface = &dev->actconfig->interface[ifnum].altsetting[0];
X
X /* Is it an OV511/OV511+? */
- if (dev->descriptor.idVendor != 0x05a9)
+ if (dev->descriptor.idVendor != 0x05a9
+ && dev->descriptor.idVendor != 0x0813)
X return NULL;
X if (dev->descriptor.idProduct != 0x0511
- && dev->descriptor.idProduct != 0xA511)
+ && dev->descriptor.idProduct != 0xA511
+ && dev->descriptor.idProduct != 0x0002)
X return NULL;
X
X /* Checking vendor/product should be enough, but what the hell */
@@ -2903,6 +3195,15 @@
X info("USB OV511+ camera found");
X ov511->bridge = BRG_OV511PLUS;
X break;
+ case 0x0002:
+ if (dev->descriptor.idVendor != 0x0813)
+ goto error;
+ info("Intel Play Me2Cam (OV511+) found");
+ ov511->bridge = BRG_OV511PLUS;
+ break;
+ default:
+ err("Unknown product ID");
+ goto error;
X }
X
X ov511->customid = ov511_reg_read(dev, OV511_REG_SYSTEM_CUSTOM_ID);
@@ -2929,7 +3230,7 @@
X
X if (clist[i].id == -1) {
X err("Camera type (%d) not recognized", ov511->customid);
- err("Please contact mmccl...@delphi.com to request");
+ err("Please contact m...@i.am to request");
X err("support for your camera.");
X }
X
@@ -2969,14 +3270,14 @@
X
X MOD_INC_USE_COUNT;
X
+ PDEBUG(3, "");
+
X /* We don't want people trying to open up the device */
X if (!ov511->user)
X video_unregister_device(&ov511->vdev);
+ else
+ PDEBUG(3, "Device open...deferring video_unregister_device");
X
- usb_driver_release_interface(&ov511_driver,
- &ov511->dev->actconfig->interface[ov511->iface]);
-
- ov511->dev = NULL;
X for (n = 0; n < OV511_NUMFRAMES; n++)
X ov511->frame[n].grabstate = FRAME_ERROR;
X
@@ -3001,15 +3302,17 @@
X }
X }
X
+ usb_driver_release_interface(&ov511_driver,
+ &ov511->dev->actconfig->interface[ov511->iface]);
+ ov511->dev = NULL;
+
X #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
X destroy_proc_ov511_cam(ov511);
X #endif
X
- /* FIXME - is this correct/safe? Should we acquire ov511->lock? */
- ov511_dealloc(ov511, 1);
-


X /* Free the memory */

X if (ov511 && !ov511->user) {
+ ov511_dealloc(ov511, 1);
X kfree(ov511);
X ov511 = NULL;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/ov511.h linux/drivers/usb/ov511.h
--- v2.4.0-test8/linux/drivers/usb/ov511.h Tue Jul 11 10:46:38 2000
+++ linux/drivers/usb/ov511.h Tue Sep 19 11:37:59 2000
@@ -183,6 +183,9 @@
X // FIXME - these can vary between specific models
X #define OV7610_I2C_WRITE_ID 0x42
X #define OV7610_I2C_READ_ID 0x43
+#define OV6xx0_I2C_WRITE_ID 0xC0
+#define OV6xx0_I2C_READ_ID 0xC1
+
X #define OV511_I2C_CLOCK_PRESCALER 0x03
X
X /* Prototypes */
@@ -203,6 +206,7 @@
X SEN_OV7610,
X SEN_OV7620,
X SEN_OV7620AE,
+ SEN_OV6620,
X };
X
X enum {
@@ -254,7 +258,7 @@
X int hdrheight; /* Height */
X
X int sub_flag; /* Sub-capture mode for this frame? */
- int format; /* Format for this frame */
+ unsigned int format; /* Format for this frame */
X int segsize; /* How big is each segment from the camera? */
X
X volatile int grabstate; /* State of grabbing */
@@ -285,6 +289,10 @@
X int desc;
X unsigned char iface;
X
+ /* Determined by sensor type */
+ int maxwidth;
+ int maxheight;
+
X int brightness;
X int colour;
X int contrast;
@@ -356,7 +364,6 @@
X u8 lndv; /* line divisor */
X u8 m420;
X u8 common_A;
- u8 common_C;
X u8 common_L;
X };
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/pegasus.c linux/drivers/usb/pegasus.c
--- v2.4.0-test8/linux/drivers/usb/pegasus.c Tue Aug 22 15:23:13 2000
+++ linux/drivers/usb/pegasus.c Mon Oct 2 14:20:39 2000
@@ -13,6 +13,12 @@
X ** from top-halves.
X ** v0.4.0 Control messages remained unurbified are now URBs.
X ** Now we can touch the HW at any time.
+** v0.4.9 Control urbs again use process context to wait. Argh...
+** Some long standing bugs (start_net) fixed. Also nasty
+** trick with resubmiting control urb from interrupt
+** context used. Please let me know how it behaves.
+** Pegasus II support added since this version.
+** TODO: suppressing HCD warnings spewage on disconnect.


X */
X
X /*

@@ -42,20 +48,65 @@


X #include <linux/usb.h>
X
X

-static const char *version = __FILE__ ": v0.4.3 2000/08/22 (C) 1999-2000 Petko Manolov (pet...@dce.bg)\n";
+static const char *version = __FILE__ ": v0.4.9 2000/09/14 (C) 1999-2000 Petko Manolov (pet...@dce.bg)";
X
X
-#define PEGASUS_USE_WAITQ
+#define PEGASUS_USE_INTR
X
X
+#define PEGASUS_II 0x80000000
+#define HAS_HOME_PNA 0x40000000
+
X #define PEGASUS_MTU 1500
X #define PEGASUS_MAX_MTU 1536
+
X #define EPROM_WRITE 0x01
X #define EPROM_READ 0x02
+#define EPROM_DONE 0x04
+#define EPROM_WR_ENABLE 0x10
+#define EPROM_LOAD 0x20
+
+#define MII_BMCR 0x00
+#define MII_BMSR 0x01
+#define BMSR_MEDIA 0x7808
+#define MII_ANLPA 0x05
+#define ANLPA_100TX_FD 0x0100
+#define ANLPA_100TX_HD 0x0080
+#define ANLPA_10T_FD 0x0040
+#define ANLPA_10T_HD 0x0020
+#define PHY_DONE 0x80
+#define PHY_READ 0x40
+#define PHY_WRITE 0x20
+#define DEFAULT_GPIO_RESET 0x24
+#define LINKSYS_GPIO_RESET 0x24
+#define DEFAULT_GPIO_SET 0x26
+
+#define PEGASUS_PRESENT 1
+#define PEGASUS_RUNNING 2
+#define CTRL_URB_RUNNING 4
+#define CTRL_URB_SLEEP 8
+#define ETH_REGS_CHANGE 0x40000000
+#define ETH_REGS_CHANGED 0x80000000
+
+#define RX_MULTICAST 2
+#define RX_PROMISCUOUS 4
+
+#define REG_TIMEOUT (HZ)
X #define PEGASUS_TX_TIMEOUT (HZ*10)
-#define PEGASUS_CTRL_TIMEOUT (HZ*5)
-#define PEGASUS_CTRL_WAIT (1<<31)
-#define PEGASUS_RUNNING 1
+
+#ifdef PEGASUS_USE_INTR
+ #define INTR_IVAL 0x80
+#else
+ #define INTR_IVAL 0
+#endif
+
+#define TX_UNDERRUN 0x80
+#define EXCESSIVE_COL 0x40
+#define LATE_COL 0x20
+#define NO_CARRIER 0x10
+#define LOSS_CARRIER 0x08
+#define JABBER_TIMEOUT 0x04
+
X #define PEGASUS_REQT_READ 0xc0
X #define PEGASUS_REQT_WRITE 0x40
X #define PEGASUS_REQ_GET_REGS 0xf0
@@ -64,12 +115,12 @@
X #define NUM_CTRL_URBS 0x10
X #define ALIGN(x) x __attribute__((aligned(L1_CACHE_BYTES)))
X
-
X enum pegasus_registers {
X EthCtrl0 = 0,
X EthCtrl1 = 1,
X EthCtrl2 = 2,
X EthID = 0x10,
+ Reg1d = 0x1d,
X EpromOffset = 0x20,
X EpromData = 0x21, /* 0x21 low, 0x22 high byte */
X EpromCtrl = 0x23,
@@ -80,348 +131,445 @@
X EthTxStat0 = 0x2b,
X EthTxStat1 = 0x2c,
X EthRxStat = 0x2d,
+ Reg7b = 0x7b,
X Gpio0 = 0x7e,
X Gpio1 = 0x7f,
+ Reg81 = 0x81,
X };
X
X
-struct pegasus;
-struct ctrl_urb_pool {
- struct pegasus *pegasus;
- struct urb urb;
- devrequest dr;
- __u8 busy;
-};
-
-
-struct pegasus {
+typedef struct pegasus {
X struct usb_device *usb;
X struct net_device *net;
X struct net_device_stats stats;
- int flags;
- struct urb rx_urb, tx_urb, intr_urb;
- struct ctrl_urb_pool ALIGN(ctrl[NUM_CTRL_URBS]);
+ unsigned flags;
+ unsigned features;
+ struct urb ctrl_urb, rx_urb, tx_urb, intr_urb;
+ devrequest dr;
X wait_queue_head_t ctrl_wait;
X struct semaphore ctrl_sem;
X unsigned char ALIGN(rx_buff[PEGASUS_MAX_MTU]);
X unsigned char ALIGN(tx_buff[PEGASUS_MAX_MTU]);
X unsigned char ALIGN(intr_buff[8]);
-};
+ __u8 eth_regs[4];
+ __u8 phy;
+ __u8 gpio_res;
+} pegasus_t;
X
X struct usb_eth_dev {
X char *name;
X __u16 vendor;
X __u16 device;
- void *private;
+ __u32 private; /* LSB is gpio reset value */
X };
X
X
X static int loopback = 0;
+static int mode = 0;
X static int multicast_filter_limit = 32;
X
X
X MODULE_AUTHOR("Petko Manolov <pet...@dce.bg>");
X MODULE_DESCRIPTION("ADMtek AN986 Pegasus USB Ethernet driver");
X MODULE_PARM(loopback, "i");
+MODULE_PARM(mode, "i");
X MODULE_PARM_DESC(loopback, "Enable MAC loopback mode (bit 0)");
+MODULE_PARM_DESC(mode, "Enable HomePNA mode (bit 0) - default = MII mode = 0");
X
X
X static struct usb_eth_dev usb_dev_id[] = {
- {"Billionton USB-100", 0x08dd, 0x0986, NULL},
- {"Corega FEter USB-TX", 0x7aa, 0x0004, NULL},
- {"MELCO/BUFFALO LUA-TX", 0x0411, 0x0001, NULL},
- {"D-Link DSB-650TX", 0x2001, 0x4001, NULL},
- {"D-Link DSB-650TX", 0x2001, 0x4002, NULL},
- {"D-Link DSB-650TX(PNA)", 0x2001, 0x4003, NULL},
- {"D-Link DSB-650", 0x2001, 0xabc1, NULL},
- {"D-Link DU-E10", 0x07b8, 0xabc1, NULL},
- {"D-Link DU-E100", 0x07b8, 0x4002, NULL},
- {"Linksys USB10TX", 0x066b, 0x2202, NULL},
- {"Linksys USB100TX", 0x066b, 0x2203, NULL},
- {"Linksys USB100TX", 0x066b, 0x2204, NULL},
- {"Linksys USB Ethernet Adapter", 0x066b, 0x2206, NULL},
- {"SMC 202 USB Ethernet", 0x0707, 0x0200, NULL},
- {"ADMtek AN986 \"Pegasus\" USB Ethernet (eval board)", 0x07a6, 0x0986, NULL},
- {"Accton USB 10/100 Ethernet Adapter", 0x083a, 0x1046, NULL},
- {"IO DATA USB ET/TX", 0x04bb, 0x0904, NULL},
- {"LANEED USB Ethernet LD-USB/TX", 0x056e, 0x4002, NULL},
- {"SOHOware NUB100 Ethernet", 0x15e8, 0x9100, NULL},
- {NULL, 0, 0, NULL}
+ {"Billionton USB-100", 0x08dd, 0x0986, DEFAULT_GPIO_RESET},
+ {"Corega FEter USB-TX", 0x7aa, 0x0004, DEFAULT_GPIO_RESET},
+ {"MELCO/BUFFALO LUA-TX", 0x0411, 0x0001, DEFAULT_GPIO_RESET},
+ {"D-Link DSB-650TX", 0x2001, 0x4001, LINKSYS_GPIO_RESET},
+ {"D-Link DSB-650TX", 0x2001, 0x4002, LINKSYS_GPIO_RESET},
+ {"D-Link DSB-650TX(PNA)", 0x2001, 0x4003, DEFAULT_GPIO_RESET},
+ {"D-Link DSB-650", 0x2001, 0xabc1, DEFAULT_GPIO_RESET},
+ {"D-Link DU-E10", 0x07b8, 0xabc1, DEFAULT_GPIO_RESET},
+ {"D-Link DU-E100", 0x07b8, 0x4002, DEFAULT_GPIO_RESET},
+ {"Linksys USB10TX", 0x066b, 0x2202, LINKSYS_GPIO_RESET},
+ {"Linksys USB100TX", 0x066b, 0x2203, LINKSYS_GPIO_RESET},
+ {"Linksys USB100TX", 0x066b, 0x2204, LINKSYS_GPIO_RESET},
+ {"Linksys USB Ethernet Adapter", 0x066b, 0x2206, LINKSYS_GPIO_RESET},
+ {"SMC 202 USB Ethernet", 0x0707, 0x0200, DEFAULT_GPIO_RESET},
+ {"ADMtek AN986 \"Pegasus\" USB Ethernet (eval board)", 0x07a6, 0x0986,
+ HAS_HOME_PNA | DEFAULT_GPIO_RESET},
+ {"Accton USB 10/100 Ethernet Adapter", 0x083a, 0x1046,
+ DEFAULT_GPIO_RESET},
+ {"IO DATA USB ET/TX", 0x04bb, 0x0904, DEFAULT_GPIO_RESET},
+ {"LANEED USB Ethernet LD-USB/TX", 0x056e, 0x4002, DEFAULT_GPIO_RESET},
+ {"SOHOware NUB100 Ethernet", 0x15e8, 0x9100, DEFAULT_GPIO_RESET},
+ {"ADMtek ADM8511 \"Pegasus II\" USB Ethernet", 0x07a6, 0x8511,
+ PEGASUS_II | DEFAULT_GPIO_RESET},
+ {NULL, 0, 0, 0}
X };
X
X
-static void pegasus_unlink_ctrl_urbs( struct pegasus *pegasus )
+static int update_eth_regs_async( pegasus_t * );
+/* Aargh!!! I _really_ hate such tweaks */
+static void ctrl_callback( urb_t *urb )
X {
- int i;
+ pegasus_t *pegasus = urb->context;
+
+ if ( !pegasus )
+ return;
X
- for ( i=0; i < NUM_CTRL_URBS; i++ ) {
- if ( pegasus->ctrl[i].urb.status == -EINPROGRESS )
- usb_unlink_urb( &pegasus->ctrl[i].urb );
+ switch ( urb->status ) {
+ case USB_ST_NOERROR:
+ if ( pegasus->flags & ETH_REGS_CHANGE ) {
+ pegasus->flags &= ~ETH_REGS_CHANGE;
+ pegasus->flags |= ETH_REGS_CHANGED;
+ update_eth_regs_async( pegasus );
+ return;
+ }
+ break;
+ case USB_ST_URB_PENDING:
+ return;
+ case USB_ST_URB_KILLED:
+ break;
+ default:
+ warn( __FUNCTION__ " status %d", urb->status);
+ }
+ pegasus->flags &= ~ETH_REGS_CHANGED;
+ if ( pegasus->flags & CTRL_URB_SLEEP ) {
+ pegasus->flags &= ~CTRL_URB_SLEEP;
+ wake_up_interruptible( &pegasus->ctrl_wait );
X }
X }
X
X
-static int pegasus_find_ctrl_urb( struct pegasus *pegasus )
+static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data)
X {
- int i=0;
-
- while( i < NUM_CTRL_URBS && (pegasus->ctrl[i].busy == 1 ||
- (pegasus->ctrl[i].urb.status == -EINPROGRESS)) )
- i++;
+ int ret;
X
- return i;
-}
-
-
-static void pegasus_ctrl_end( urb_t *urb )
-{
- struct ctrl_urb_pool *ctrl = urb->context;
- struct pegasus *pegasus = ctrl->pegasus;
+ if ( pegasus->flags & ETH_REGS_CHANGED ) {
+ pegasus->flags |= CTRL_URB_SLEEP;
+ interruptible_sleep_on( &pegasus->ctrl_wait );
+ }
+ pegasus->dr.requesttype = PEGASUS_REQT_READ;
+ pegasus->dr.request = PEGASUS_REQ_GET_REGS;
+ pegasus->dr.value = 0;
+ pegasus->dr.index = cpu_to_le16p(&indx);
+ pegasus->dr.length =
+ pegasus->ctrl_urb.transfer_buffer_length = cpu_to_le16p(&size);
X
+ FILL_CONTROL_URB( &pegasus->ctrl_urb, pegasus->usb,
+ usb_rcvctrlpipe(pegasus->usb,0),
+ (char *)&pegasus->dr,
+ data, size, ctrl_callback, pegasus );
X
- if ( !pegasus )
- return;
+ if ( (ret = usb_submit_urb( &pegasus->ctrl_urb )) ) {
+ err( __FUNCTION__ " BAD CTRLs %d", ret);
+ return ret;
+ }
+ pegasus->flags |= CTRL_URB_SLEEP;
+ interruptible_sleep_on( &pegasus->ctrl_wait );
X
- if ( urb->status )
- warn("ctrl_urb end status %d", urb->status);
- ctrl->busy = 0;
-#ifdef PEGASUS_USE_WAITQ
- wake_up_interruptible( &pegasus->ctrl_wait );
-#endif
+ return ret;
X }
X
X
-static int pegasus_get_registers( struct pegasus *pegasus, __u16 indx, __u16 size, void *data )
+static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data)
X {
- int ret, i;
- struct ctrl_urb_pool *ctrl;
-
- if ( (i = pegasus_find_ctrl_urb( pegasus )) == NUM_CTRL_URBS ) {
- return -1;
- }
+ int ret;
X
- ctrl = &pegasus->ctrl[i];
- ctrl->busy = 1;
- ctrl->pegasus = pegasus;
-
- ctrl->dr.requesttype = PEGASUS_REQT_READ;
- ctrl->dr.request = PEGASUS_REQ_GET_REGS;
- ctrl->dr.value = 0;
- ctrl->dr.index = cpu_to_le16p(&indx);
- ctrl->dr.length =
- ctrl->urb.transfer_buffer_length = cpu_to_le16p(&size);
+ if ( pegasus->flags & ETH_REGS_CHANGED ) {
+ pegasus->flags |= CTRL_URB_SLEEP ;
+ interruptible_sleep_on( &pegasus->ctrl_wait );
+ }
+ pegasus->dr.requesttype = PEGASUS_REQT_WRITE;
+ pegasus->dr.request = PEGASUS_REQ_SET_REGS;
+ pegasus->dr.value = 0;
+ pegasus->dr.index = cpu_to_le16p( &indx );
+ pegasus->dr.length =
+ pegasus->ctrl_urb.transfer_buffer_length = cpu_to_le16p( &size );
X
- FILL_CONTROL_URB( &ctrl->urb, pegasus->usb,
- usb_rcvctrlpipe(pegasus->usb,0),
- (char *)&ctrl->dr,
- data, size, pegasus_ctrl_end, ctrl );
+ FILL_CONTROL_URB( &pegasus->ctrl_urb, pegasus->usb,
+ usb_sndctrlpipe(pegasus->usb,0),
+ (char *)&pegasus->dr,
+ data, size, ctrl_callback, pegasus );
X
- if ( (ret = usb_submit_urb( &ctrl->urb )) )
- err( __FUNCTION__ " BAD CTRLs %d", ret);
-#ifdef PEGASUS_USE_WAITQ
+ if ( (ret = usb_submit_urb( &pegasus->ctrl_urb )) ) {
+ err( __FUNCTION__ " BAD CTRL %d", ret);
+ return ret;
+ }
+ pegasus->flags |= CTRL_URB_SLEEP;
X interruptible_sleep_on( &pegasus->ctrl_wait );
-#endif
+


X return ret;
X }
X

X
-static int pegasus_set_registers( struct pegasus *pegasus, __u16 indx, __u16 size, void *data )
+static int set_register( pegasus_t *pegasus, __u16 indx, __u8 data )
X {
- int ret, i;
- struct ctrl_urb_pool *ctrl;
-
- if ( (i = pegasus_find_ctrl_urb( pegasus )) == NUM_CTRL_URBS ) {
- return -1;
- }
+ int ret;
X
- ctrl = &pegasus->ctrl[i];
- ctrl->busy = 1;
- ctrl->pegasus = pegasus;
-
- ctrl->dr.requesttype = PEGASUS_REQT_WRITE;
- ctrl->dr.request = PEGASUS_REQ_SET_REGS;
- ctrl->dr.value = 0;
- ctrl->dr.index = cpu_to_le16p( &indx );
- ctrl->dr.length =
- ctrl->urb.transfer_buffer_length = cpu_to_le16p( &size );
+ if ( pegasus->flags & ETH_REGS_CHANGED ) {
+ pegasus->flags |= CTRL_URB_SLEEP;
+ interruptible_sleep_on( &pegasus->ctrl_wait );
+ }
+ pegasus->dr.requesttype = PEGASUS_REQT_WRITE;
+ pegasus->dr.request = PEGASUS_REQ_SET_REG;
+ pegasus->dr.value = data;
+ pegasus->dr.index = cpu_to_le16p( &indx );
+ pegasus->dr.length = pegasus->ctrl_urb.transfer_buffer_length = 1;
X
- FILL_CONTROL_URB( &ctrl->urb, pegasus->usb,
+ FILL_CONTROL_URB( &pegasus->ctrl_urb, pegasus->usb,
X usb_sndctrlpipe(pegasus->usb,0),
- (char *)&ctrl->dr,
- data, size, pegasus_ctrl_end, ctrl );
+ (char *)&pegasus->dr,
+ &data, 1, ctrl_callback, pegasus );
X
- if ( (ret = usb_submit_urb( &ctrl->urb )) )
+ if ( (ret = usb_submit_urb( &pegasus->ctrl_urb )) ) {
X err( __FUNCTION__ " BAD CTRL %d", ret);
-#ifdef PEGASUS_USE_WAITQ
+ return ret;
+ }
+ pegasus->flags |= CTRL_URB_SLEEP;
X interruptible_sleep_on( &pegasus->ctrl_wait );
-#endif
+

X return ret;
X }
X

X
-static int pegasus_set_register( struct pegasus *pegasus, __u16 indx,__u8 data )
+static int update_eth_regs_async( pegasus_t *pegasus )
X {
- int ret, i;
- struct ctrl_urb_pool *ctrl;
-
- if ( (i = pegasus_find_ctrl_urb( pegasus )) == NUM_CTRL_URBS ) {


- return -1;
- }
-

- ctrl = &pegasus->ctrl[i];
- ctrl->busy = 1;
- ctrl->pegasus = pegasus;
+ int ret;
X
- ctrl->dr.requesttype = PEGASUS_REQT_WRITE;
- ctrl->dr.request = PEGASUS_REQ_SET_REG;
- ctrl->dr.value = cpu_to_le16p( &data );
- ctrl->dr.index = cpu_to_le16p( &indx );
- ctrl->dr.length = ctrl->urb.transfer_buffer_length = 1;
+ pegasus->dr.requesttype = PEGASUS_REQT_WRITE;
+ pegasus->dr.request = PEGASUS_REQ_SET_REGS;
+ pegasus->dr.value = 0;
+ pegasus->dr.index = EthCtrl0;
+ pegasus->dr.length =
+ pegasus->ctrl_urb.transfer_buffer_length = 3;
X
- FILL_CONTROL_URB( &ctrl->urb, pegasus->usb,
+ FILL_CONTROL_URB( &pegasus->ctrl_urb, pegasus->usb,
X usb_sndctrlpipe(pegasus->usb,0),
- (char *)&ctrl->dr,
- &data, 1, pegasus_ctrl_end, ctrl );
+ (char *)&pegasus->dr,
+ pegasus->eth_regs, 3, ctrl_callback, pegasus );
+
+ if ( (ret = usb_submit_urb( &pegasus->ctrl_urb )) )
+ err( __FUNCTION__ " BAD CTRL %d, flags %x",ret,pegasus->flags );
X
- if ( (ret = usb_submit_urb( &ctrl->urb )) )
- err( __FUNCTION__ " BAD CTRL %d", ret);
-#ifdef PEGASUS_USE_WAITQ
- interruptible_sleep_on( &pegasus->ctrl_wait );
-#endif

X return ret;
X }
X

X
-static int pegasus_read_phy_word(struct pegasus *pegasus, __u8 index, __u16 *regdata)
+static int read_phy_word( pegasus_t *pegasus, __u8 phy, __u8 indx, __u16 *regd )
X {
- int i;
- __u8 data[4] = { 1, 0, 0, 0x40 + index };
+ int i;
+ __u8 data[4] = { phy, 0, 0, indx };
X
- pegasus_set_registers(pegasus, PhyAddr, 4, data);
- for (i = 0; i < 100; i++) {
- pegasus_get_registers(pegasus, PhyData, 3, data);
- if (data[2] & 0x80) {
- *regdata = *(__u16 *)(data);
- return 0;
- }
+ set_register( pegasus, PhyCtrl, 0 );
+ set_registers( pegasus, PhyAddr, sizeof(data), data );
+ set_register( pegasus, PhyCtrl, (indx | PHY_READ) );
+ for (i = 0; i < REG_TIMEOUT; i++) {
+ get_registers(pegasus, PhyCtrl, 1, data);
+ if ( data[0] & PHY_DONE )
+ break;
X }
- warn("read_phy_word() failed");
+ if ( i < REG_TIMEOUT ) {
+ get_registers( pegasus, PhyData, 2, regd );
+ return 0;
+ }
+ warn( __FUNCTION__ " failed" );
X

X return 1;
X }
X

X
-static int pegasus_write_phy_word(struct pegasus *pegasus, __u8 index, __u16 regdata)
+static int write_phy_word( pegasus_t *pegasus, __u8 phy, __u8 indx, __u16 regd )
X {
- int i;
- __u8 data[4] = { 1, regdata, regdata >> 8, 0x20 + index };
-
- pegasus_set_registers(pegasus, PhyAddr, 4, data);
- for (i = 0; i < 100; i++) {
- pegasus_get_registers(pegasus, PhyCtrl, 1, data);
- if (data[0] & 0x80)
- return 0;
+ int i;
+ __u8 data[4] = { phy, 0, 0, indx };
+
+ *(data + 1) = cpu_to_le16p( &regd );
+ set_register( pegasus, PhyCtrl, 0 );
+ set_registers( pegasus, PhyAddr, 4, data );
+ set_register( pegasus, PhyCtrl, (indx | PHY_WRITE) );
+ for (i = 0; i < REG_TIMEOUT; i++) {
+ get_registers(pegasus, PhyCtrl, 1, data);
+ if ( data[0] & PHY_DONE )
+ break;
X }
- warn("write_phy_word() failed");
+ if ( i < REG_TIMEOUT )
+ return 0;
+ warn( __FUNCTION__ " failed" );
X

X return 1;
X }
X

X
-static int pegasus_rw_eprom_word(struct pegasus *pegasus, __u8 index, __u16 *retdata, __u8 direction)
+static int read_eprom_word( pegasus_t *pegasus, __u8 index, __u16 *retdata )
X {
- int i;
- __u8 data[4] = { index, 0, 0, direction };
+ int i, tmp;
X
- pegasus_set_registers(pegasus, EpromOffset, 4, data);
- for (i = 0; i < 100; i++) {
- pegasus_get_registers(pegasus, EpromCtrl, 1, data);
- if (data[0] & 4) {
- pegasus_get_registers(pegasus, EpromData, 2, data);
- *retdata = *(__u16 *)data;
- return 0;
- }
+ set_register( pegasus, EpromCtrl, 0 );
+ set_register( pegasus, EpromOffset, index );
+ set_register( pegasus, EpromCtrl, EPROM_READ);
+ for ( i=0; i < REG_TIMEOUT; i++ ) {
+ get_registers( pegasus, EpromCtrl, 1, &tmp );
+ if ( tmp & EPROM_DONE )
+ break;
X }
- warn("pegasus_rw_eprom_word() failed");
-
- return 1;
+ if ( i < REG_TIMEOUT ) {
+ get_registers( pegasus, EpromData, 2, retdata );
+ return 0;
+ }
+ warn( __FUNCTION__ " failed" );


+
+ return -1;
+}
+
+

+static inline void enable_eprom_write( pegasus_t *pegasus )
+{
+ __u8 tmp;
+
+ get_registers( pegasus, EthCtrl2, 1, &tmp );
+ set_register( pegasus, EthCtrl2, tmp | EPROM_WR_ENABLE );
+}
+
+
+static inline void disable_eprom_write( pegasus_t *pegasus )
+{
+ __u8 tmp;
+
+ get_registers( pegasus, EthCtrl2, 1, &tmp );
+ set_register( pegasus, EpromCtrl, 0 );
+ set_register( pegasus, EthCtrl2, tmp & ~EPROM_WR_ENABLE );
+}
+
+
+static int write_eprom_word( pegasus_t *pegasus, __u8 index, __u16 data )
+{
+ int i, tmp;
+ __u8 d[4] = {0x3f, 0, 0, EPROM_WRITE};
+
+ set_registers( pegasus, EpromOffset, 4, d );
+ enable_eprom_write( pegasus );
+ set_register( pegasus, EpromOffset, index );
+ set_registers( pegasus, EpromData, 2, &data );
+ set_register( pegasus, EpromCtrl, EPROM_WRITE );
+
+ for ( i=0; i < REG_TIMEOUT; i++ ) {
+ get_registers( pegasus, EpromCtrl, 1, &tmp );
+ if ( tmp & EPROM_DONE )
+ break;
+ }
+ disable_eprom_write( pegasus );
+ if ( i < REG_TIMEOUT )
+ return 0;
+ warn( __FUNCTION__ " failed" );


+ return -1;
X }
X
X

-static int pegasus_get_node_id(struct pegasus *pegasus, __u8 *id)
+static void set_intr_interval( pegasus_t *pegasus )
+{
+ __u16 d;
+ __u8 tmp;
+
+ read_eprom_word( pegasus, 4, &d );
+ ((__u8 *)&d)[1] = INTR_IVAL;
+ write_eprom_word( pegasus, 4, d );
+ get_registers( pegasus, EthCtrl2, 1, &tmp );
+ set_register( pegasus, EthCtrl2, tmp | EPROM_LOAD );
+ udelay( 10000 );
+ set_register( pegasus, EthCtrl2, tmp );
+#ifdef PEGASUS_DUMP_EEPROM
+ { int i;
+ for ( i=0; i < 0x40; i++ ) {
+ read_eprom_word( pegasus, i, &d );
+ printk( "eepromword %02x-%04x, ", i, d );


+ }
+ printk( "\n" );

+ }
+#endif
+}
+
+

+static inline int get_node_id( pegasus_t *pegasus, __u8 *id )
X {
X int i;
+
X for (i = 0; i < 3; i++)
- if (pegasus_rw_eprom_word(pegasus, i, (__u16 *)&id[i*2], EPROM_READ))
+ if ( read_eprom_word( pegasus, i, (__u16 *)&id[i*2]) )
X return 1;


X return 0;
X }
X

X
-static int pegasus_reset_mac(struct pegasus *pegasus)
+static inline int reset_mac( pegasus_t *pegasus )
X {
- __u8 data = 0x8;
- int i;
+ __u8 data = 0x8;
+ int i;
X
- pegasus_set_register(pegasus, EthCtrl1, data);
- for (i = 0; i < 100; i++) {
- pegasus_get_registers(pegasus, EthCtrl1, 1, &data);
+ set_register(pegasus, EthCtrl1, data);
+ for (i = 0; i < REG_TIMEOUT; i++) {
+ get_registers(pegasus, EthCtrl1, 1, &data);
X if (~data & 0x08) {
X if (loopback & 1)
- return 0;
- pegasus_set_register(pegasus, Gpio0, 0x24);
- pegasus_set_register(pegasus, Gpio0, 0x27);
- return 0;
+ break;
+ if ( mode && (pegasus->features & HAS_HOME_PNA) )
+ set_register( pegasus, Gpio1, 0x34 );
+ else
+ set_register( pegasus, Gpio1, 0x26 );
+ set_register( pegasus, Gpio0, pegasus->features );
+ set_register( pegasus, Gpio0, DEFAULT_GPIO_SET );
+ break;
X }
X }
-
- return 1;
+ if ( i == REG_TIMEOUT )
+ return 1;


+ return 0;
X }
X

X
-static int pegasus_start_net(struct net_device *dev, struct usb_device *usb)
+static int start_net( struct net_device *dev, struct usb_device *usb )
X {
- __u16 partmedia, temp;
- __u8 node_id[6];
- __u8 data[4];
- struct pegasus *pegasus = dev->priv;
+ __u16 linkpart, bmsr;
+ __u8 node_id[6];
+ __u8 data[4];
+ pegasus_t *pegasus = dev->priv;
X
- if (pegasus_get_node_id(pegasus, node_id))
+ if ( get_node_id(pegasus, node_id) )
X return 1;
X
- pegasus_set_registers(pegasus, EthID, 6, node_id);
- memcpy(dev->dev_addr, node_id, 6);
- if (pegasus_read_phy_word(pegasus, 1, &temp))
+ set_registers( pegasus, EthID, sizeof(node_id), node_id );
+ memcpy( dev->dev_addr, node_id, sizeof(node_id) );
+ if ( read_phy_word(pegasus, pegasus->phy, MII_BMSR, &bmsr) )
X return 2;
-
- if ((~temp & 4) && !loopback) {
- warn("%s: link NOT established (0x%x) - check the cable.",
- dev->name, temp);
- }
-
- if (pegasus_read_phy_word(pegasus, 5, &partmedia))
+ if ( !(bmsr & 0x20) && !loopback )
+ warn( "%s: link NOT established (0x%x) - check the cable.",
+ dev->name, bmsr );
+ if ( read_phy_word(pegasus, pegasus->phy, MII_ANLPA, &linkpart) )
X return 4;
-
- if ((partmedia & 0x1f) != 1) {
- warn("party FAIL %x", partmedia);
- }
+ if ( !(linkpart & 1) )
+ warn( "link partner stat %x", linkpart );
X
X data[0] = 0xc9;
- data[1] = (partmedia & 0x100) ? 0x30 : ((partmedia & 0x80) ? 0x10 : 0);
+ data[1] = 0;
+ if ( linkpart & (ANLPA_100TX_FD | ANLPA_10T_FD) )
+ data[1] |= 0x20; /* set full duplex */
+ if ( linkpart & (ANLPA_100TX_FD | ANLPA_100TX_HD) )
+ data[1] |= 0x10; /* set 100 Mbps */
+ if ( mode )
+ data[1] = 0;
X data[2] = (loopback & 1) ? 0x09 : 0x01;
X
- pegasus_set_registers(pegasus, EthCtrl0, 3, data);
+ *(unsigned *)pegasus->eth_regs = *(unsigned *)data;
+
+ set_registers( pegasus, EthCtrl0, 3, data );
X

X return 0;
X }
X

X
-static void pegasus_read_bulk_callback( struct urb *urb )
+static void read_bulk_callback( struct urb *urb )
X {
- struct pegasus *pegasus = urb->context;
- struct net_device *net; /* = pegasus->net;*/
+ pegasus_t *pegasus = urb->context;
+ struct net_device *net;
X int count = urb->actual_length, res;
- int rx_status; /*= *(int *)(pegasus->rx_buff + count - 4);*/
+ int rx_status;
X struct sk_buff *skb;
X __u16 pkt_len;
X
@@ -436,26 +584,26 @@
X goto goon;
X }
X
- if (!count)
- goto goon;
-#if 0
- if (rx_status & 0x00010000)
+ if ( !count )
X goto goon;
-#endif
- if (rx_status & 0x000e0000) {
+
+ if ( rx_status & 0x000e0000 ) {
X
X dbg("%s: error receiving packet %x", net->name, rx_status & 0xe0000);
X pegasus->stats.rx_errors++;
- if(rx_status & 0x060000) pegasus->stats.rx_length_errors++;
- if(rx_status & 0x080000) pegasus->stats.rx_crc_errors++;
- if(rx_status & 0x100000) pegasus->stats.rx_frame_errors++;
+ if ( rx_status & 0x060000 )
+ pegasus->stats.rx_length_errors++;
+ if ( rx_status & 0x080000 )
+ pegasus->stats.rx_crc_errors++;
+ if ( rx_status & 0x100000 )
+ pegasus->stats.rx_frame_errors++;
X
X goto goon;
X }
X
X pkt_len = (rx_status & 0xfff) - 8;
X
- if(!(skb = dev_alloc_skb(pkt_len+2)))
+ if ( !(skb = dev_alloc_skb(pkt_len+2)) )
X goto goon;
X
X skb->dev = net;
@@ -469,36 +617,60 @@
X pegasus->stats.rx_bytes += pkt_len;
X
X goon:
+ pegasus->rx_urb.dev = pegasus->usb;
X if ( (res = usb_submit_urb(&pegasus->rx_urb)) )
- warn("(prb)failed rx_urb %d", res);
+ warn( __FUNCTION__ " failed submint rx_urb %d", res);
X }
X
X
-static void pegasus_irq_callback( urb_t *urb )
+static void write_bulk_callback( struct urb *urb )
X {
- __u8 *d = urb->transfer_buffer;
+ pegasus_t *pegasus = urb->context;
X
+ if ( !pegasus || !(pegasus->flags & PEGASUS_RUNNING) )
+ return;
+ if ( urb->status )
+ info("%s: TX status %d", pegasus->net->name, urb->status);
X
- if ( d[0] )
- dbg("txst0=0x%2x", d[0]);
+ netif_wake_queue(pegasus->net);
X }
X
X
-static void pegasus_write_bulk_callback(struct urb *urb)
+static void intr_callback( struct urb *urb )
X {
- struct pegasus *pegasus = urb->context;
+ pegasus_t *pegasus = urb->context;
+ struct net_device *net;
+ __u8 *d;
X
X if ( !pegasus )
X return;
-
- if (urb->status)
- info("%s: TX status %d", pegasus->net->name, urb->status);
- netif_wake_queue(pegasus->net);
+ d = urb->transfer_buffer;
+ net = pegasus->net;
+ if ( d[0] & 0xfc ) {
+ pegasus->stats.tx_errors++;
+ if ( d[0] & TX_UNDERRUN )
+ pegasus->stats.tx_fifo_errors++;
+ if ( d[0] & (EXCESSIVE_COL | JABBER_TIMEOUT) )
+ pegasus->stats.tx_aborted_errors++;
+ if ( d[0] & LATE_COL )
+ pegasus->stats.tx_window_errors++;
+ if ( d[0] & (NO_CARRIER | LOSS_CARRIER) )
+ pegasus->stats.tx_carrier_errors++;
+ }
+ switch ( urb->status ) {
+ case USB_ST_NOERROR:
+ break;
+ case USB_ST_URB_KILLED:
+ break;
+ default:
+ info("intr status %d", urb->status);
+ }
X }
X
-static void pegasus_tx_timeout(struct net_device *net)
+
+static void pegasus_tx_timeout( struct net_device *net )
X {
- struct pegasus *pegasus = net->priv;
+ pegasus_t *pegasus = net->priv;
X
X if ( !pegasus )
X return;
@@ -512,11 +684,11 @@
X }
X
X
-static int pegasus_start_xmit(struct sk_buff *skb, struct net_device *net)
+static int pegasus_start_xmit( struct sk_buff *skb, struct net_device *net )
X {
- struct pegasus *pegasus = net->priv;
- int count = ((skb->len+2) & 0x3f) ? skb->len+2 : skb->len+3;
- int res;
+ pegasus_t *pegasus = net->priv;
+ int count = ((skb->len+2) & 0x3f) ? skb->len+2 : skb->len+3;
+ int res;
X
X netif_stop_queue(net);
X if ( !(pegasus->flags & PEGASUS_RUNNING) )
@@ -527,6 +699,7 @@
X pegasus->tx_urb.transfer_buffer_length = count;
X pegasus->tx_urb.transfer_flags |= USB_ASYNC_UNLINK;
X
+ pegasus->tx_urb.dev = pegasus->usb;
X if ((res = usb_submit_urb(&pegasus->tx_urb))) {
X warn("failed tx_urb %d", res);
X pegasus->stats.tx_errors++;
@@ -543,77 +716,76 @@
X }
X
X
-static struct net_device_stats *pegasus_netdev_stats(struct net_device *dev)
+static struct net_device_stats *pegasus_netdev_stats( struct net_device *dev )
X {
- return &((struct pegasus *)dev->priv)->stats;
+ return &((pegasus_t *)dev->priv)->stats;
X }
X
X
-static inline void pegasus_stop_net( struct pegasus *pegasus )
+static inline void stop_net( pegasus_t *pegasus )
X {
- int tmp;
+ int tmp=0;
X
- pegasus_get_registers( pegasus, EthCtrl0, 1, &tmp );
- pegasus_set_register( pegasus, EthCtrl0, tmp & 0x3f );
+ set_registers( pegasus, EthCtrl0, 2, &tmp );
X }
X
X
X static int pegasus_open(struct net_device *net)
X {
- struct pegasus *pegasus = (struct pegasus *)net->priv;
- int res;
+ pegasus_t *pegasus = (pegasus_t *)net->priv;
+ int res;
X
- if ((res = pegasus_start_net(net, pegasus->usb))) {
+ if ((res = start_net(net, pegasus->usb))) {
X err("can't start_net() - %d", res);


X return -EIO;
X }
-

- if ((res = usb_submit_urb(&pegasus->rx_urb)))
- warn("(open)failed rx_urb %d", res);
-
- if ((res = usb_submit_urb(&pegasus->intr_urb)))
- warn("(open)failed intr_urb %d", res);
-
- netif_start_queue(net);
+ pegasus->rx_urb.dev = pegasus->usb;
+ if ( (res = usb_submit_urb(&pegasus->rx_urb)) )
+ warn( __FUNCTION__ " failed rx_urb %d", res );
+#ifdef PEGASUS_USE_INTR
+ pegasus->intr_urb.dev = pegasus->usb;
+ if ( (res = usb_submit_urb(&pegasus->intr_urb)) )
+ warn( __FUNCTION__ " failed intr_urb %d", res);
+#endif
+ netif_start_queue( net );
X pegasus->flags |= PEGASUS_RUNNING;
X

X return 0;
X }
X

X
-static int pegasus_close(struct net_device *net)
+static int pegasus_close( struct net_device *net )
X {
- struct pegasus *pegasus = net->priv;
+ pegasus_t *pegasus = net->priv;
X
+ stop_net( pegasus );
X pegasus->flags &= ~PEGASUS_RUNNING;
- pegasus_stop_net( pegasus );
-
X netif_stop_queue(net);
X
- usb_unlink_urb(&pegasus->rx_urb);
- usb_unlink_urb(&pegasus->tx_urb);
- usb_unlink_urb(&pegasus->intr_urb);
- pegasus_unlink_ctrl_urbs( pegasus );
+ usb_unlink_urb( &pegasus->rx_urb );
+ usb_unlink_urb( &pegasus->tx_urb );
+ usb_unlink_urb( &pegasus->ctrl_urb );
+ usb_unlink_urb( &pegasus->intr_urb );
X

X return 0;
X }
X

X
-static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
+static int pegasus_ioctl( struct net_device *net, struct ifreq *rq, int cmd )
X {
X __u16 *data = (__u16 *)&rq->ifr_data;
- struct pegasus *pegasus = net->priv;
+ pegasus_t *pegasus = net->priv;
X
X switch(cmd) {
X case SIOCDEVPRIVATE:
- data[0] = 1;
+ data[0] = pegasus->phy;
X case SIOCDEVPRIVATE+1:
- pegasus_read_phy_word(pegasus, data[1] & 0x1f, &data[3]);
+ read_phy_word(pegasus, data[0], data[1]&0x1f, &data[3]);
X return 0;
X case SIOCDEVPRIVATE+2:
- if (!capable(CAP_NET_ADMIN))
+ if ( !capable(CAP_NET_ADMIN) )
X return -EPERM;
- pegasus_write_phy_word(pegasus, data[1] & 0x1f, data[2]);
+ write_phy_word(pegasus, pegasus->phy, data[1] & 0x1f, data[2]);
X return 0;
X default:
X return -EOPNOTSUPP;
@@ -621,36 +793,29 @@
X }
X
X
-static void pegasus_set_rx_mode(struct net_device *net)
+static void pegasus_set_multicast( struct net_device *net )
X {
-#ifndef PEGASUS_USE_WAITQ
- struct pegasus *pegasus = net->priv;
- __u8 tmp;
-#endif
+ pegasus_t *pegasus = net->priv;
X
X netif_stop_queue(net);
X
X if (net->flags & IFF_PROMISC) {
-#ifndef PEGASUS_USE_WAITQ
- pegasus_get_registers(pegasus, EthCtrl2, 1, &tmp);
- pegasus_set_register(pegasus, EthCtrl2, tmp | 4);
-#endif
+ pegasus->eth_regs[EthCtrl2] |= RX_PROMISCUOUS;
X info("%s: Promiscuous mode enabled", net->name);
X } else if ((net->mc_count > multicast_filter_limit) ||
X (net->flags & IFF_ALLMULTI)) {
-#ifndef PEGASUS_USE_WAITQ
- pegasus_set_register(pegasus, EthCtrl0, 0xfa);
- pegasus_set_register(pegasus, EthCtrl2, 0);
-#endif
+ pegasus->eth_regs[EthCtrl0] |= RX_MULTICAST;
+ pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS;
X info("%s set allmulti", net->name);
X } else {
-#ifndef PEGASUS_USE_WAITQ
- pegasus_get_registers(pegasus, EthCtrl2, 1, &tmp);
- pegasus_set_register(pegasus, EthCtrl2, tmp & ~4);
-#endif
+ pegasus->eth_regs[EthCtrl0] &= ~RX_MULTICAST;
+ pegasus->eth_regs[EthCtrl2] &= ~RX_PROMISCUOUS;
X info("%s: set Rx mode", net->name);
X }
X
+ pegasus->flags |= ETH_REGS_CHANGE;
+ ctrl_callback( &pegasus->ctrl_urb );
+
X netif_wake_queue(net);
X }
X
@@ -669,10 +834,38 @@
X }
X
X
-static void * pegasus_probe(struct usb_device *dev, unsigned int ifnum)
+static __u8 mii_phy_probe( pegasus_t *pegasus )
+{
+ int i;
+ __u16 tmp;
+
+ for ( i=0; i < 32; i++ ) {
+ read_phy_word( pegasus, i, MII_BMSR, &tmp );
+ if ( tmp == 0 || tmp == 0xffff || (tmp & BMSR_MEDIA) == 0 )
+ continue;
+ else
+ return i;
+ }


+
+ return 0;
+}
+
+

+static inline void setup_pegasus_II( pegasus_t *pegasus )
+{
+ set_register( pegasus, Reg1d, 0 );
+ set_register( pegasus, Reg7b, 2 );
+ if ( pegasus->features & HAS_HOME_PNA )
+ set_register( pegasus, Reg81, 6 );
+ else
+ set_register( pegasus, Reg81, 2 );
+}
+
+
+static void * pegasus_probe( struct usb_device *dev, unsigned int ifnum )


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 093'
echo 'File patch-2.4.0-test9 is continued in part 094'
echo "094" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part094

#!/bin/sh -x
# this is part 094 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 094; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

X {
X struct net_device *net;
- struct pegasus *pegasus;
+ pegasus_t *pegasus;
X int dev_indx;
X
X if ( (dev_indx = check_device_ids(dev->descriptor.idVendor, dev->descriptor.idProduct)) == -1 ) {
@@ -698,34 +891,50 @@
X net->tx_timeout = pegasus_tx_timeout;
X net->do_ioctl = pegasus_ioctl;
X net->hard_start_xmit = pegasus_start_xmit;
- net->set_multicast_list = pegasus_set_rx_mode;
+ net->set_multicast_list = pegasus_set_multicast;
X net->get_stats = pegasus_netdev_stats;
X net->mtu = PEGASUS_MTU;
X
X init_MUTEX( &pegasus-> ctrl_sem );
X init_waitqueue_head( &pegasus->ctrl_wait );
X
+ usb_inc_dev_use (dev);
X pegasus->usb = dev;
X pegasus->net = net;
X
X FILL_BULK_URB( &pegasus->rx_urb, dev, usb_rcvbulkpipe(dev, 1),
X pegasus->rx_buff, PEGASUS_MAX_MTU,
- pegasus_read_bulk_callback, pegasus );
+ read_bulk_callback, pegasus );
X FILL_BULK_URB( &pegasus->tx_urb, dev, usb_sndbulkpipe(dev, 2),
X pegasus->tx_buff, PEGASUS_MAX_MTU,
- pegasus_write_bulk_callback, pegasus );
+ write_bulk_callback, pegasus );
X FILL_INT_URB( &pegasus->intr_urb, dev, usb_rcvintpipe(dev, 3),
- pegasus->intr_buff, 8, pegasus_irq_callback,
- pegasus, 128 );
+ pegasus->intr_buff, 8, intr_callback,
+ pegasus, INTR_IVAL );
X
- if (pegasus_reset_mac(pegasus)) {
+ pegasus->features = usb_dev_id[dev_indx].private;
+ if ( reset_mac(pegasus) ) {
X err("can't reset MAC");
+ unregister_netdev( pegasus->net );
X kfree(pegasus);
X pegasus = NULL;
X return NULL;
X }
-
- info( "%s: %s\n", net->name, usb_dev_id[dev_indx].name );
+
+ if ( pegasus->features & PEGASUS_II ) {
+ info( "setup Pegasus II specific registers" );
+ setup_pegasus_II( pegasus );
+ }
+
+ pegasus->phy = mii_phy_probe( pegasus );
+ if ( !pegasus->phy ) {
+ warn( "can't locate MII phy, using default" );
+ pegasus->phy = 1;
+ }
+
+ set_intr_interval( pegasus );
+
+ info( "%s: %s", net->name, usb_dev_id[dev_indx].name );
X
X MOD_INC_USE_COUNT;
X
@@ -733,24 +942,22 @@
X }
X
X
-static void pegasus_disconnect(struct usb_device *dev, void *ptr)
+static void pegasus_disconnect( struct usb_device *dev, void *ptr )
X {
X struct pegasus *pegasus = ptr;
X
- if (!pegasus) {
+ if ( !pegasus ) {
X warn("unregistering non-existant device");
X return;
X }
X

+ stop_net( pegasus );
X pegasus->flags &= ~PEGASUS_RUNNING;

- unregister_netdev(pegasus->net);
-


- usb_unlink_urb(&pegasus->rx_urb);
- usb_unlink_urb(&pegasus->tx_urb);
- usb_unlink_urb(&pegasus->intr_urb);
- pegasus_unlink_ctrl_urbs( pegasus );

+ netif_stop_queue( pegasus->net );
+ unregister_netdev( pegasus->net );
X
- kfree(pegasus);
+ usb_dec_dev_use (pegasus->usb);
+ kfree( pegasus );
X pegasus = NULL;
X
X MOD_DEC_USE_COUNT;
@@ -766,13 +973,13 @@
X int __init pegasus_init(void)
X {
X info( "%s", version );
- return usb_register(&pegasus_driver);
+ return usb_register( &pegasus_driver );
X }
X
X void __exit pegasus_exit(void)
X {
- usb_deregister(&pegasus_driver);
+ usb_deregister( &pegasus_driver );
X }
X
-module_init(pegasus_init);
-module_exit(pegasus_exit);
+module_init( pegasus_init );
+module_exit( pegasus_exit );
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/scanner.c linux/drivers/usb/scanner.c
--- v2.4.0-test8/linux/drivers/usb/scanner.c Mon Jun 19 13:42:42 2000
+++ linux/drivers/usb/scanner.c Tue Sep 19 17:47:06 2000
@@ -199,6 +199,14 @@
X * - Fixed HP S20 ID's...again..sigh. Thanks to Ruud
X * Linders <rlin...@xs4all.nl>.
X *
+ * 0.4.4
+ * - Added addtional Mustek ID's (BearPaw 1200, 600 CU, 1200 USB,
+ * and 1200 UB. Thanks to Henning Meier-Geinitz <henn...@gmx.de>.
+ * - Added the Vuego Scan Brisa 340U ID's. Apparently this scanner is
+ * marketed by Acer Peripherals as a cheap 300 dpi model. Thanks to
+ * David Gundersen <gund...@paradise.net.nz>.
+ * - Added the Epson Expression1600 ID's. Thanks to Karl Heinz
+ * Kremer <k...@khk.net>.
X *
X * TODO
X *
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/scanner.h linux/drivers/usb/scanner.h
--- v2.4.0-test8/linux/drivers/usb/scanner.h Mon Jun 19 13:42:42 2000
+++ linux/drivers/usb/scanner.h Tue Sep 19 17:47:06 2000
@@ -106,6 +106,7 @@
X /* Acer */
X { 0x04a5, 0x2060 }, /* Prisa Acerscan 620U & 640U (!) */
X { 0x04a5, 0x2040 }, /* Prisa AcerScan 620U (!) */
+ { 0x04a5, 0x2022 }, /* Vuego Scan Brisa 340U */
X /* Agfa */
X { 0x06bd, 0x0001 }, /* SnapScan 1212U */
X { 0x06bd, 0x2061 }, /* Another SnapScan 1212U (?) */
@@ -120,6 +121,7 @@
X { 0x03f0, 0x0105 }, /* 4200C */
X { 0x03f0, 0x0102 }, /* PhotoSmart S20 */
X { 0x03f0, 0x0401 }, /* 5200C */
+ { 0x03f0, 0x0701 }, /* 5300C */
X { 0x03f0, 0x0201 }, /* 6200C */
X { 0x03f0, 0x0601 }, /* 6300C */
X /* iVina */
@@ -134,6 +136,10 @@
X { 0x05da, 0x80ac }, /* ScanMaker V6UL - SpicyU */
X /* Mustek */
X { 0x055f, 0x0001 }, /* 1200 CU */
+ { 0x0400, 0x1000 }, /* BearPaw 1200 */
+ { 0x055f, 0x0002 }, /* 600 CU */
+ { 0x055f, 0x0003 }, /* 1200 USB */
+ { 0x055f, 0x0006 }, /* 1200 UB */
X /* Primax/Colorado */
X { 0x0461, 0x0300 }, /* G2-300 #1 */
X { 0x0461, 0x0380 }, /* G2-600 #1 */
@@ -151,15 +157,19 @@
X { 0x04b8, 0x0101 }, /* Perfection 636U and 636Photo */
X { 0x04b8, 0x0103 }, /* Perfection 610 */
X { 0x04b8, 0x0104 }, /* Perfection 1200U and 1200Photo */
+ { 0x04b8, 0x0107 }, /* Expression 1600 */
X /* Umax */
X { 0x1606, 0x0010 }, /* Astra 1220U */
X { 0x1606, 0x0002 }, /* Astra 1236U */
X { 0x1606, 0x0030 }, /* Astra 2000U */
X { 0x1606, 0x0230 }, /* Astra 2200U */
X /* Visioneer */
- { 0x04a7, 0x0221 }, /* OneTouch 5300 */
- { 0x04a7, 0x0221 }, /* OneTouch 7600 duplicate ID (!) */
- { 0x04a7, 0x0231 }, /* 6100 */
+ { 0x04a7, 0x0221 }, /* OneTouch 5300 USB */
+ { 0x04a7, 0x0211 }, /* OneTouch 7600 USB */
+ { 0x04a7, 0x0231 }, /* 6100 USB */
+ { 0x04a7, 0x0311 }, /* 6200 EPP/USB */
+ { 0x04a7, 0x0321 }, /* OneTouch 8100 EPP/USB */
+ { 0x04a7, 0x0331 }, /* OneTouch 8600 EPP/USB */
X };
X
X /* Forward declarations */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/serial/ftdi_sio.c linux/drivers/usb/serial/ftdi_sio.c
--- v2.4.0-test8/linux/drivers/usb/serial/ftdi_sio.c Tue Sep 5 13:42:52 2000
+++ linux/drivers/usb/serial/ftdi_sio.c Mon Sep 18 15:23:25 2000
@@ -12,6 +12,9 @@
X *
X * See Documentation/usb/usb-serial.txt for more information on using this driver
X *
+ * (09/11/2000) gkh
+ * Removed DEBUG #ifdefs with call to usb_serial_debug_data
+ *
X * (07/19/2000) gkh
X * Added module_init and module_exit functions to handle the fact that this
X * driver is a loadable module now.
@@ -331,26 +334,9 @@
X first_byte = port->write_urb->transfer_buffer;
X *first_byte = 1 | ((count-data_offset) << 2) ;
X
-#ifdef CONFIG_USB_SERIAL_DEBUG
X dbg("Bytes: %d, Control Byte: 0o%03o",count, first_byte[0]);
-
- if (count) {
- int i;
- printk (KERN_DEBUG __FILE__ ": data written - length = %d, data = ", count);
- for (i = 0; i < count; ++i) {
- printk ( "0x%02x ", first_byte[i]);
- if (first_byte[i] > ' ' && first_byte[i] < '~') {
- printk( "%c ", first_byte[i]);
- } else {
- printk( " ");
- }
- }
-
-
- printk ( "\n");
- }
-
-#endif
+ usb_serial_debug_data (__FILE__, __FUNCTION__, count, first_byte);
+
X /* send the data out the bulk port */
X port->write_urb->transfer_buffer_length = count;
X
@@ -429,23 +415,11 @@
X return;
X }
X
-#ifdef CONFIG_USB_SERIAL_DEBUG
X if (urb->actual_length > 2) {
- printk (KERN_DEBUG __FILE__ ": data read - length = %d, data = ", urb->actual_length);
- for (i = 0; i < urb->actual_length; ++i) {
- printk ( "0x%.2x ", data[i]);
- if (data[i] > ' ' && data[i] < '~') {
- printk( "%c ", data[i]);
- } else {
- printk( " ");
- }
- }
- printk ( "\n");
+ usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
X } else {
X dbg("Just status");
X }
-#endif
-
X
X if (urb->actual_length > data_offset) {
X for (i = data_offset ; i < urb->actual_length ; ++i) {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/serial/usb-serial.h linux/drivers/usb/serial/usb-serial.h
--- v2.4.0-test8/linux/drivers/usb/serial/usb-serial.h Tue Sep 5 13:19:08 2000
+++ linux/drivers/usb/serial/usb-serial.h Mon Sep 18 15:23:25 2000
@@ -11,6 +11,10 @@
X *
X * See Documentation/usb/usb-serial.txt for more information on using this driver
X *
+ * (09/11/2000) gkh
+ * Added usb_serial_debug_data function to help get rid of #DEBUG in the
+ * drivers.
+ *
X * (08/28/2000) gkh
X * Added port_lock to port structure.
X *
@@ -204,6 +208,18 @@
X return port->serial;
X }
X
+
+static inline void usb_serial_debug_data (const char *file, const char *function, int size, const unsigned char *data)
+{
+#ifdef CONFIG_USB_SERIAL_DEBUG
+ int i;
+ printk (KERN_DEBUG "%s: %s - length = %d, data = ", file, function, size);
+ for (i = 0; i < size; ++i) {
+ printk ("%.2x ", data[i]);
+ }
+ printk ("\n");
+#endif
+}
X
X #endif /* ifdef __LINUX_USB_SERIAL_H */
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/serial/usbserial.c linux/drivers/usb/serial/usbserial.c
--- v2.4.0-test8/linux/drivers/usb/serial/usbserial.c Tue Sep 5 13:19:08 2000
+++ linux/drivers/usb/serial/usbserial.c Mon Sep 18 15:23:25 2000
@@ -15,6 +15,9 @@
X *
X * See Documentation/usb/usb-serial.txt for more information on using this driver
X *
+ * (09/11/2000) gkh
+ * Removed DEBUG #ifdefs with call to usb_serial_debug_data
+ *
X * (08/28/2000) gkh
X * Added port_lock to port structure.
X * Added locks for SMP safeness to generic driver
@@ -766,16 +769,7 @@
X spin_lock_irqsave (&port->port_lock, flags);
X count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
X
-#ifdef DEBUG
- {
- int i;
- printk (KERN_DEBUG __FILE__ ": " __FUNCTION__ " - length = %d, data = ", count);
- for (i = 0; i < count; ++i) {
- printk ("%.2x ", buf[i]);
- }
- printk ("\n");
- }
-#endif
+ usb_serial_debug_data (__FILE__, __FUNCTION__, count, buf);
X
X if (from_user) {
X copy_from_user(port->write_urb->transfer_buffer, buf, count);
@@ -854,15 +848,7 @@
X return;
X }
X
-#ifdef DEBUG
- if (urb->actual_length) {
- printk (KERN_DEBUG __FILE__ ": " __FUNCTION__ "- length = %d, data = ", urb->actual_length);
- for (i = 0; i < urb->actual_length; ++i) {
- printk ("%.2x ", data[i]);
- }
- printk ("\n");
- }
-#endif
+ usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
X
X tty = port->tty;
X if (urb->actual_length) {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/serial/visor.c linux/drivers/usb/serial/visor.c
--- v2.4.0-test8/linux/drivers/usb/serial/visor.c Tue Sep 5 13:42:52 2000
+++ linux/drivers/usb/serial/visor.c Mon Sep 18 15:23:25 2000
@@ -11,6 +11,17 @@
X *
X * See Documentation/usb/usb-serial.txt for more information on using this driver
X *
+ * (09/11/2000) gkh
+ * Got rid of always calling kmalloc for every urb we wrote out to the
+ * device.
+ * Added visor_read_callback so we can keep track of bytes in and out for
+ * those people who like to know the speed of their device.
+ * Removed DEBUG #ifdefs with call to usb_serial_debug_data
+ *
+ * (09/06/2000) gkh
+ * Fixed oops in visor_exit. Need to uncomment usb_unlink_urb call _after_
+ * the host controller drivers set urb->dev = NULL when the urb is finished.
+ *
X * (08/28/2000) gkh
X * Added locks for SMP safeness.
X *
@@ -71,6 +82,7 @@
X
X #include "visor.h"
X
+#define MIN(a,b) (((a)<(b))?(a):(b))
X
X /* function prototypes for a handspring visor */
X static int visor_open (struct usb_serial_port *port, struct file *filp);
@@ -82,7 +94,8 @@
X static void visor_shutdown (struct usb_serial *serial);
X static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
X static void visor_set_termios (struct usb_serial_port *port, struct termios *old_termios);
-static void visor_write_bulk_callback (struct urb *urb);
+static void visor_write_bulk_callback (struct urb *urb);
+static void visor_read_bulk_callback (struct urb *urb);
X
X /* All of the device info needed for the Handspring Visor */
X static __u16 handspring_vendor_id = HANDSPRING_VENDOR_ID;
@@ -108,12 +121,17 @@
X set_termios: visor_set_termios,
X write: visor_write,
X write_bulk_callback: visor_write_bulk_callback,
+ read_bulk_callback: visor_read_bulk_callback,
X };
X
X
-#define NUM_URBS 24
+#define NUM_URBS 24
+#define URB_TRANSFER_BUFFER_SIZE 64
X static struct urb *write_urb_pool[NUM_URBS];
X static spinlock_t write_urb_pool_lock;
+static int bytes_in;
+static int bytes_out;
+
X
X /******************************************************************************
X * Handspring Visor specific driver functions
@@ -134,6 +152,8 @@
X
X if (!port->active) {
X port->active = 1;
+ bytes_in = 0;
+ bytes_out = 0;
X
X /*Start reading from the device*/
X if (usb_submit_urb(port->read_urb))
@@ -181,78 +201,79 @@
X usb_unlink_urb (port->read_urb);
X port->active = 0;
X port->open_count = 0;
- }
X
+ }
X spin_unlock_irqrestore (&port->port_lock, flags);
+
+ /* Uncomment the following line if you want to see some statistics in your syslog */
+ /* info ("Bytes In = %d Bytes Out = %d", bytes_in, bytes_out); */
X }
X
X
X static int visor_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count)
X {
X struct usb_serial *serial = port->serial;
- struct urb *urb = NULL;
- unsigned char *buffer = NULL;
+ struct urb *urb;
+ const unsigned char *current_position = buf;
+ unsigned long flags;
X int status;
X int i;
- unsigned long flags;
+ int bytes_sent = 0;
+ int transfer_size;
X
X dbg(__FUNCTION__ " - port %d", port->number);
X
- if (count == 0) {
- dbg(__FUNCTION__ " - write request of 0 bytes");


- return 0;
- }
-

- /* try to find a free urb in our list of them */
- spin_lock_irqsave (&write_urb_pool_lock, flags);
- for (i = 0; i < NUM_URBS; ++i) {
- if (write_urb_pool[i]->status != -EINPROGRESS) {
- urb = write_urb_pool[i];
- break;
+ usb_serial_debug_data (__FILE__, __FUNCTION__, count, buf);
+
+ while (count > 0) {
+ /* try to find a free urb in our list of them */
+ urb = NULL;
+ spin_lock_irqsave (&write_urb_pool_lock, flags);
+ for (i = 0; i < NUM_URBS; ++i) {
+ if (write_urb_pool[i]->status != -EINPROGRESS) {
+ urb = write_urb_pool[i];
+ break;
+ }
X }
+ spin_unlock_irqrestore (&write_urb_pool_lock, flags);
+ if (urb == NULL) {
+ dbg (__FUNCTION__ " - no more free urbs");
+ goto exit;
+ }
+ if (urb->transfer_buffer == NULL) {
+ urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
+ if (urb->transfer_buffer == NULL) {
+ err(__FUNCTION__" no more kernel memory...");
+ goto exit;
+ }
+ }
+
+ transfer_size = MIN (count, URB_TRANSFER_BUFFER_SIZE);
+ if (from_user)
+ copy_from_user (urb->transfer_buffer, current_position, transfer_size);
+ else
+ memcpy (urb->transfer_buffer, current_position, transfer_size);
+
+ count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
+
+ /* build up our urb */
+ FILL_BULK_URB (urb, serial->dev, usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),
+ urb->transfer_buffer, transfer_size, visor_write_bulk_callback, port);


+ urb->transfer_flags |= USB_QUEUE_BULK;
+

+ /* send it down the pipe */
+ status = usb_submit_urb(urb);
+ if (status)
+ dbg(__FUNCTION__ " - usb_submit_urb(write bulk) failed with status = %d", status);
+
+ current_position += transfer_size;
+ bytes_sent += transfer_size;
+ count -= transfer_size;
+ bytes_out += transfer_size;
X }
- spin_unlock_irqrestore (&write_urb_pool_lock, flags);
- if (urb == NULL) {
- dbg (__FUNCTION__ " - no free urbs");


- return 0;
- }
-

- count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
-
-#ifdef DEBUG
- printk (KERN_DEBUG __FILE__ ": " __FUNCTION__ " - length = %d, data = ", count);
- for (i = 0; i < count; ++i) {
- printk ("%.2x ", buf[i]);
- }
- printk ("\n");
-#endif
X
- if (urb->transfer_buffer != NULL)
- kfree(urb->transfer_buffer);
- buffer = kmalloc (count, GFP_KERNEL);
- if (buffer == NULL) {
- err(__FUNCTION__" no more kernel memory...");


- return 0;
- }
-

- if (from_user) {
- copy_from_user(buffer, buf, count);
- }
- else {
- memcpy (buffer, buf, count);
- }
-
- /* build up our urb */
- FILL_BULK_URB (urb, serial->dev, usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),
- buffer, count, visor_write_bulk_callback, port);
- urb->transfer_flags |= USB_QUEUE_BULK;
-
- /* send it down the pipe */
- status = usb_submit_urb(urb);
- if (status)
- dbg(__FUNCTION__ " - usb_submit_urb(write bulk) failed with status = %d", status);
-
- return (count);
+exit:
+ return bytes_sent;
X }
X
X
@@ -277,6 +298,41 @@
X }
X
X
+static void visor_read_bulk_callback (struct urb *urb)
+{
+ struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+ struct tty_struct *tty;
+ unsigned char *data = urb->transfer_buffer;
+ int i;
+
+ if (port_paranoia_check (port, __FUNCTION__))
+ return;
+
+ dbg(__FUNCTION__ " - port %d", port->number);
+
+ if (urb->status) {
+ dbg(__FUNCTION__ " - nonzero read bulk status received: %d", urb->status);
+ return;
+ }
+
+ usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
+
+ tty = port->tty;
+ if (urb->actual_length) {
+ for (i = 0; i < urb->actual_length ; ++i) {
+ tty_insert_flip_char(tty, data[i], 0);
+ }
+ tty_flip_buffer_push(tty);
+ bytes_in += urb->actual_length;
+ }
+
+ /* Continue trying to always read */
+ if (usb_submit_urb(urb))
+ dbg(__FUNCTION__ " - failed resubmitting read urb");
+ return;
+}
+
+
X static void visor_throttle (struct usb_serial_port *port)


X {
X unsigned long flags;

@@ -372,7 +428,7 @@
X kfree (transfer_buffer);
X
X /* continue on with initialization */
- return (0);


+ return 0;
X }
X
X

@@ -466,20 +522,27 @@
X
X static int __init visor_init (void)
X {
+ struct urb *urb;
X int i;
X
X usb_serial_register (&handspring_device);
X
- /* create our write urb pool */
+ /* create our write urb pool and transfer buffers */
X spin_lock_init (&write_urb_pool_lock);
X for (i = 0; i < NUM_URBS; ++i) {
- struct urb *urb = usb_alloc_urb(0);
+ urb = usb_alloc_urb(0);
+ write_urb_pool[i] = urb;
X if (urb == NULL) {
X err("No more urbs???");
X continue;
X }
+
X urb->transfer_buffer = NULL;
- write_urb_pool[i] = urb;
+ urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
+ if (!urb->transfer_buffer) {
+ err (__FUNCTION__ " - out of memory for urb buffers.");
+ continue;


+ }
X }
X
X return 0;

@@ -496,10 +559,15 @@
X spin_lock_irqsave (&write_urb_pool_lock, flags);
X
X for (i = 0; i < NUM_URBS; ++i) {
- usb_unlink_urb(write_urb_pool[i]);
- if (write_urb_pool[i]->transfer_buffer)
- kfree(write_urb_pool[i]->transfer_buffer);
- usb_free_urb (write_urb_pool[i]);
+ if (write_urb_pool[i]) {
+ /* FIXME - uncomment the following usb_unlink_urb call when
+ * the host controllers get fixed to set urb->dev = NULL after
+ * the urb is finished. Otherwise this call oopses. */
+ /* usb_unlink_urb(write_urb_pool[i]); */
+ if (write_urb_pool[i]->transfer_buffer)
+ kfree(write_urb_pool[i]->transfer_buffer);
+ usb_free_urb (write_urb_pool[i]);
+ }
X }
X
X spin_unlock_irqrestore (&write_urb_pool_lock, flags);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/serial/whiteheat.c linux/drivers/usb/serial/whiteheat.c
--- v2.4.0-test8/linux/drivers/usb/serial/whiteheat.c Thu Sep 7 08:36:40 2000
+++ linux/drivers/usb/serial/whiteheat.c Mon Sep 18 15:23:25 2000
@@ -11,6 +11,9 @@
X *
X * See Documentation/usb/usb-serial.txt for more information on using this driver
X *
+ * (09/11/2000) gkh
+ * Removed DEBUG #ifdefs with call to usb_serial_debug_data
+ *
X * (07/19/2000) gkh
X * Added module_init and module_exit functions to handle the fact that this
X * driver is a loadable module now.
@@ -130,11 +133,6 @@
X *****************************************************************************/
X static void command_port_write_callback (struct urb *urb)
X {
-#ifdef DEBUG
- int i;
- unsigned char *data = urb->transfer_buffer;
-#endif
-
X dbg (__FUNCTION__);
X
X if (urb->status) {
@@ -142,15 +140,7 @@
X return;
X }
X
-#ifdef DEBUG
- if (urb->actual_length) {
- printk (KERN_DEBUG __FILE__ ": " __FUNCTION__ " - length = %d, data = ", urb->actual_length);
- for (i = 0; i < urb->actual_length; ++i) {
- printk ("%.2x ", data[i]);
- }
- printk ("\n");
- }
-#endif
+ usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, urb->transfer_buffer);
X
X return;
X }
@@ -160,9 +150,6 @@
X {
X struct whiteheat_private *info = (struct whiteheat_private *)urb->context;
X unsigned char *data = urb->transfer_buffer;
-#ifdef DEBUG
- int i;
-#endif
X
X dbg (__FUNCTION__);
X
@@ -171,15 +158,7 @@
X return;
X }
X
-#ifdef DEBUG
- if (urb->actual_length) {
- printk (KERN_DEBUG __FILE__ ": " __FUNCTION__ " - length = %d, data = ", urb->actual_length);
- for (i = 0; i < urb->actual_length; ++i) {
- printk ("%.2x ", data[i]);
- }
- printk ("\n");
- }
-#endif
+ usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
X
X /* right now, if the command is COMMAND_COMPLETE, just flip the bit saying the command finished */
X /* in the future we're going to have to pay attention to the actual command that completed */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/storage/Makefile linux/drivers/usb/storage/Makefile
--- v2.4.0-test8/linux/drivers/usb/storage/Makefile Mon Aug 28 16:59:14 2000
+++ linux/drivers/usb/storage/Makefile Fri Sep 8 16:39:12 2000
@@ -21,7 +21,7 @@
X usb-storage-obj-$(CONFIG_USB_STORAGE_DPCM) += dpcm.o
X
X usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \
- $(usb-storage-obj-y)
+ initializers.o $(usb-storage-obj-y)
X
X # Extract lists of the multi-part drivers.
X # The 'int-*' lists are the intermediate files used to build the multi's.
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/storage/debug.c linux/drivers/usb/storage/debug.c
--- v2.4.0-test8/linux/drivers/usb/storage/debug.c Mon Aug 28 16:59:14 2000
+++ linux/drivers/usb/storage/debug.c Fri Sep 8 16:39:12 2000
@@ -1,7 +1,7 @@
X /* Driver for USB Mass Storage compliant devices
X * Debugging Functions Source Code File
X *
- * $Id: debug.c,v 1.3 2000/08/25 00:13:51 mdharm Exp $
+ * $Id: debug.c,v 1.4 2000/09/04 02:12:47 groovyjava Exp $
X *
X * Current development and maintenance by:
X * (c) 1999, 2000 Matthew Dharm (mdhar...@one-eyed-alien.net)
@@ -206,5 +206,162 @@
X sg[i].address[14],
X sg[i].address[15]);
X }
+}
+
+void usb_stor_show_sense(
+ unsigned char key,
+ unsigned char asc,
+ unsigned char ascq) {
+
+ char *keys[] = {
+ "No Sense",
+ "Recovered Error",
+ "Not Ready",
+ "Medium Error",
+ "Hardware Error",
+ "Illegal Request",
+ "Unit Attention",
+ "Data Protect",
+ "Blank Check",
+ "Vendor Specific",
+ "Copy Aborted",
+ "Aborted Command",
+ "(Obsolete)",
+ "Volume Overflow",
+ "Miscompare"
+ };
+
+ unsigned short qual = asc;
+
+ char *what = 0;
+ char *keystr = 0;
+
+ qual <<= 8;
+ qual |= ascq;
+
+ if (key>0x0E)
+ keystr = "(Unknown Key)";
+ else
+ keystr = keys[key];
+
+ switch (qual) {
+
+ case 0x0000: what="no additional sense information"; break;
+ case 0x0001: what="filemark detected"; break;
+ case 0x0002: what="end of partition/medium detected"; break;
+ case 0x0003: what="setmark detected"; break;
+ case 0x0004: what="beginning of partition/medium detected"; break;
+ case 0x0005: what="end of data detected"; break;
+ case 0x0006: what="I/O process terminated"; break;
+ case 0x0011: what="audio play operation in progress"; break;
+ case 0x0012: what="audio play operation paused"; break;
+ case 0x0013: what="audio play operation stopped due to error"; break;
+ case 0x0014: what="audio play operation successfully completed"; break;
+ case 0x0015: what="no current audio status to return"; break;
+ case 0x0016: what="operation in progress"; break;
+ case 0x0017: what="cleaning requested"; break;
+ case 0x0100: what="no index/sector signal"; break;
+ case 0x0200: what="no seek complete"; break;
+ case 0x0300: what="peripheral device write fault"; break;
+ case 0x0301: what="no write current"; break;
+ case 0x0302: what="excessive write errors"; break;
+ case 0x0400: what="LUN not ready, cause not reportable"; break;
+ case 0x0401: what="LUN in process of becoming ready"; break;
+ case 0x0402: what="LUN not ready, initializing cmd. required"; break;
+ case 0x0403: what="LUN not ready, manual intervention required"; break;
+ case 0x0404: what="LUN not ready, format in progress"; break;
+ case 0x0405: what="LUN not ready, rebuild in progress"; break;
+ case 0x0406: what="LUN not ready, recalculation in progress"; break;
+ case 0x0407: what="LUN not ready, operation in progress"; break;
+ case 0x0408: what="LUN not ready, long write in progress"; break;
+ case 0x0500: what="LUN doesn't respond to selection"; break;
+ case 0x0A00: what="error log overflow"; break;
+ case 0x0C04: what="compression check miscompare error"; break;
+ case 0x0C05: what="data expansion occurred during compression"; break;
+ case 0x0C06: what="block not compressible"; break;
+ case 0x1102: what="error too long to correct"; break;
+ case 0x1106: what="CIRC unrecovered error"; break;
+ case 0x1107: what="data resynchronization error"; break;
+ case 0x110D: what="decompression CRC error"; break;
+ case 0x110E: what="can't decompress using declared algorithm"; break;
+ case 0x110F: what="error reading UPC/EAN number"; break;
+ case 0x1110: what="error reading ISRC number"; break;
+ case 0x1200: what="address mark not found for ID field"; break;
+ case 0x1300: what="address mark not found for data field"; break;
+ case 0x1403: what="end of data not found"; break;
+ case 0x1404: what="block sequence error"; break;
+ case 0x1600: what="data sync mark error"; break;
+ case 0x1601: what="data sync error: data rewritten"; break;
+ case 0x1602: what="data sync error: recommend rewrite"; break;
+ case 0x1603: what="data sync error: data auto-reallocated"; break;
+ case 0x1604: what="data sync error: recommend reassignment"; break;
+ case 0x1900: what="defect list error"; break;
+ case 0x1901: what="defect list not available"; break;
+ case 0x1902: what="defect list error in primary list"; break;
+ case 0x1903: what="defect list error in grown list"; break;
+ case 0x1C00: what="defect list not found"; break;
+ case 0x2400: what="invalid field in CDB"; break;
+ case 0x2703: what="associated write protect"; break;
+ case 0x2903: what="bus device reset function occurred"; break;
+ case 0x2904: what="device internal reset"; break;
+ case 0x2B00: what="copy can't execute since host can't disconnect";
+ break;
+ case 0x2C00: what="command sequence error"; break;
+ case 0x2C03: what="current program area is not empty"; break;
+ case 0x2C04: what="current program area is empty"; break;
+ case 0x2F00: what="commands cleared by another initiator"; break;
+ case 0x3001: what="can't read medium: unknown format"; break;
+ case 0x3002: what="can't read medium: incompatible format"; break;
+ case 0x3003: what="cleaning cartridge installed"; break;
+ case 0x3004: what="can't write medium: unknown format"; break;
+ case 0x3005: what="can't write medium: incompatible format"; break;
+ case 0x3006: what="can't format medium: incompatible medium"; break;
+ case 0x3007: what="cleaning failure"; break;
+ case 0x3008: what="can't write: application code mismatch"; break;
+ case 0x3009: what="current session not fixated for append"; break;
+ case 0x3201: what="defect list update failure"; break;
+ case 0x3400: what="enclosure failure"; break;
+ case 0x3500: what="enclosure services failure"; break;
+ case 0x3502: what="enclosure services unavailable"; break;
+ case 0x3503: what="enclosure services transfer failure"; break;
+ case 0x3504: what="enclosure services transfer refused"; break;
+ case 0x3B0F: what="end of medium reached"; break;
+ case 0x3F02: what="changed operating definition"; break;
+ case 0x4100: what="data path failure (should use 40 NN)"; break;
+ case 0x4A00: what="command phase error"; break;
+ case 0x4B00: what="data phase error"; break;
+ case 0x5100: what="erase failure"; break;
+ case 0x5200: what="cartridge fault"; break;
+ case 0x6300: what="end of user area encountered on this track"; break;
+ case 0x6600: what="automatic document feeder cover up"; break;
+ case 0x6601: what="automatic document feeder lift up"; break;
+ case 0x6602: what="document jam in auto doc feeder"; break;
+ case 0x6603: what="document miss feed auto in doc feeder"; break;
+ case 0x6700: what="configuration failure"; break;
+ case 0x6701: what="configuration of incapable LUN's failed"; break;
+ case 0x6702: what="add logical unit failed"; break;
+ case 0x6706: what="attachment of logical unit failed"; break;
+ case 0x6707: what="creation of logical unit failed"; break;
+ case 0x6900: what="data loss on logical unit"; break;
+ case 0x6E00: what="command to logical unit failed"; break;
+ case 0x7100: what="decompression exception long algorithm ID"; break;
+ case 0x7204: what="empty or partially written reserved track"; break;
+ case 0x7300: what="CD control error"; break;
+
+ default:
+ if (asc==0x40) {
+ US_DEBUGP("%s: diagnostic failure on component"
+ " %02X\n", keystr, ascq);
+ return;
+ }
+ if (asc==0x70) {
+ US_DEBUGP("%s: decompression exception short"
+ " algorithm ID of %02X\n", keystr, ascq);
+ return;
+ }
+ what = "(unknown ASC/ASCQ)";
+ }
+
+ US_DEBUGP("%s: %s\n", keystr, what);
X }
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/storage/debug.h linux/drivers/usb/storage/debug.h
--- v2.4.0-test8/linux/drivers/usb/storage/debug.h Mon Aug 28 16:59:14 2000
+++ linux/drivers/usb/storage/debug.h Mon Oct 2 11:02:34 2000
@@ -1,7 +1,7 @@
X /* Driver for USB Mass Storage compliant devices
X * Debugging Functions Header File
X *
- * $Id: debug.h,v 1.4 2000/08/25 00:13:51 mdharm Exp $
+ * $Id: debug.h,v 1.5 2000/09/04 02:12:47 groovyjava Exp $
X *
X * Current development and maintenance by:
X * (c) 1999, 2000 Matthew Dharm (mdhar...@one-eyed-alien.net)
@@ -55,6 +55,8 @@
X #ifdef CONFIG_USB_STORAGE_DEBUG
X void usb_stor_show_command(Scsi_Cmnd *srb);
X void usb_stor_print_Scsi_Cmnd( Scsi_Cmnd* cmd );
+void usb_stor_show_sense( unsigned char key,
+ unsigned char asc, unsigned char ascq );
X #define US_DEBUGP(x...) printk( KERN_DEBUG USB_STORAGE ## x )
X #define US_DEBUGPX(x...) printk( ## x )
X #define US_DEBUG(x) x
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/storage/freecom.c linux/drivers/usb/storage/freecom.c
--- v2.4.0-test8/linux/drivers/usb/storage/freecom.c Tue Sep 5 12:56:51 2000
+++ linux/drivers/usb/storage/freecom.c Mon Oct 2 11:54:51 2000
@@ -1,6 +1,6 @@
X /* Driver for Freecom USB/IDE adaptor
X *
- * $Id: freecom.c,v 1.7 2000/08/25 00:13:51 mdharm Exp $
+ * $Id: freecom.c,v 1.12 2000/09/22 01:16:17 mdharm Exp $
X *
X * Freecom v0.1:
X *
@@ -33,6 +33,7 @@
X #include "usb.h"
X #include "debug.h"
X #include "freecom.h"
+#include "linux/hdreg.h"
X
X static void pdump (void *, int);
X
@@ -54,6 +55,18 @@
X __u8 Timeout; /* Timeout in seconds. */
X __u32 Count; /* Number of bytes to transfer. */
X __u8 Pad[58];
+} __attribute__ ((packed));
+
+struct freecom_ide_out {
+ __u8 Type; /* Type + IDE register. */
+ __u8 Pad;
+ __u16 Value; /* Value to write. */
+ __u8 Pad2[60];
+};
+
+struct freecom_ide_in {
+ __u8 Type; /* Type | IDE register. */
+ __u8 Pad[63];
X };
X
X struct freecom_status {
@@ -63,17 +76,182 @@
X __u8 Pad[60];
X };
X
+/* Freecom stuffs the interrupt status in the INDEX_STAT bit of the ide
+ * register. */
+#define FCM_INT_STATUS INDEX_STAT
+
X /* These are the packet types. The low bit indicates that this command
X * should wait for an interrupt. */
X #define FCM_PACKET_ATAPI 0x21
+#define FCM_PACKET_STATUS 0x20
X
X /* Receive data from the IDE interface. The ATAPI packet has already
X * waited, so the data should be immediately available. */
-#define FCM_PACKET_INPUT 0x90
+#define FCM_PACKET_INPUT 0x81
+
+/* Send data to the IDE interface. */
+#define FCM_PACKET_OUTPUT 0x01
+
+/* Write a value to an ide register. Or the ide register to write after
+ * munging the addres a bit. */
+#define FCM_PACKET_IDE_WRITE 0x40
+#define FCM_PACKET_IDE_READ 0xC0
X
X /* All packets (except for status) are 64 bytes long. */
X #define FCM_PACKET_LENGTH 64
X
+/*
+ * Transfer an entire SCSI command's worth of data payload over the bulk
+ * pipe.
+ *
+ * Note that this uses us_transfer_partial to achieve it's goals -- this
+ * function simply determines if we're going to use scatter-gather or not,
+ * and acts appropriately. For now, it also re-interprets the error codes.
+ */
+static void us_transfer_freecom(Scsi_Cmnd *srb, struct us_data* us, int transfer_amount)
+{
+ int i;
+ int result = -1;
+ struct scatterlist *sg;
+ unsigned int total_transferred = 0;
+
+ /* was someone foolish enough to request more data than available
+ * buffer space? */
+ if (transfer_amount > srb->request_bufflen)
+ transfer_amount = srb->request_bufflen;
+
+ /* are we scatter-gathering? */
+ if (srb->use_sg) {
+
+ /* loop over all the scatter gather structures and
+ * make the appropriate requests for each, until done
+ */
+ sg = (struct scatterlist *) srb->request_buffer;
+ for (i = 0; i < srb->use_sg; i++) {
+
+ /* transfer the lesser of the next buffer or the
+ * remaining data */
+ if (transfer_amount - total_transferred >=
+ sg[i].length) {
+ result = us_transfer_partial(us, sg[i].address,
+ sg[i].length);
+ total_transferred += sg[i].length;
+ } else
+ result = us_transfer_partial(us, sg[i].address,
+ transfer_amount - total_transferred);
+
+ /* if we get an error, end the loop here */


+ if (result)
+ break;

+ }
+ }
+ else
+ /* no scatter-gather, just make the request */
+ result = us_transfer_partial(us, srb->request_buffer,
+ transfer_amount);
+
+ /* return the result in the data structure itself */
+ srb->result = result;
+}
+
+
+/* Write a value to an ide register. */
+static int
+freecom_ide_write (struct us_data *us, int reg, int value)
+{
+ freecom_udata_t extra = (freecom_udata_t) us->extra;
+ struct freecom_ide_out *ideout =
+ (struct freecom_ide_out *) extra->buffer;
+ int opipe;
+ int result, partial;
+
+ printk (KERN_DEBUG "IDE out 0x%02x <- 0x%02x\n", reg, value);
+
+ /* Get handles for both transports. */
+ opipe = usb_sndbulkpipe (us->pusb_dev, us->ep_out);
+
+ if (reg < 0 || reg > 8)
+ return USB_STOR_TRANSPORT_ERROR;
+ if (reg < 8)
+ reg |= 0x20;
+ else
+ reg = 0x0e;
+
+ ideout->Type = FCM_PACKET_IDE_WRITE | reg;
+ ideout->Pad = 0;
+ ideout->Value = cpu_to_le16 (value);
+ memset (ideout->Pad2, 0, sizeof (ideout->Pad2));
+
+ result = usb_stor_bulk_msg (us, ideout, opipe,
+ FCM_PACKET_LENGTH, &partial);
+ if (result != 0) {
+ if (result == -ENOENT)
+ return US_BULK_TRANSFER_ABORTED;
+ else
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
+/* Read a value from an ide register. */
+static int
+freecom_ide_read (struct us_data *us, int reg, int *value)
+{
+ freecom_udata_t extra = (freecom_udata_t) us->extra;
+ struct freecom_ide_in *idein =
+ (struct freecom_ide_in *) extra->buffer;
+ __u8 *buffer = extra->buffer;
+ int ipipe, opipe;
+ int result, partial;
+ int desired_length;
+
+ /* Get handles for both transports. */
+ opipe = usb_sndbulkpipe (us->pusb_dev, us->ep_out);
+ ipipe = usb_rcvbulkpipe (us->pusb_dev, us->ep_in);
+
+ if (reg < 0 || reg > 8)
+ return USB_STOR_TRANSPORT_ERROR;
+ if (reg < 8)
+ reg |= 0x10;
+ else
+ reg = 0x0e;
+
+ idein->Type = FCM_PACKET_IDE_READ | reg;
+ memset (idein->Pad, 0, sizeof (idein->Pad));
+
+ result = usb_stor_bulk_msg (us, idein, opipe,
+ FCM_PACKET_LENGTH, &partial);
+ if (result != 0) {
+ if (result == -ENOENT)
+ return US_BULK_TRANSFER_ABORTED;
+ else
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ desired_length = 1;
+ if (reg == 0x10)
+ desired_length = 2;
+
+ result = usb_stor_bulk_msg (us, buffer, ipipe,
+ desired_length, &partial);
+ if (result != 0) {
+ if (result == -ENOENT)
+ return US_BULK_TRANSFER_ABORTED;
+ else
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ if (desired_length == 1)
+ *value = buffer[0];
+ else
+ *value = le16_to_cpu (*(__u16 *) buffer);
+
+ printk (KERN_DEBUG "IDE in 0x%02x -> 0x%02x\n", reg, *value);
+
+ return USB_STOR_TRANSPORT_GOOD;


+}
+
X static int

X freecom_readdata (Scsi_Cmnd *srb, struct us_data *us,
X int ipipe, int opipe, int count)
@@ -83,6 +261,7 @@
X (struct freecom_xfer_wrap *) extra->buffer;
X int result, partial;
X int offset;
+ int this_read;
X __u8 *buffer = extra->buffer;
X
X fxfr->Type = FCM_PACKET_INPUT | 0x00;
@@ -111,6 +290,9 @@
X result, partial);
X
X /* Now transfer all of our blocks. */
+ printk (KERN_DEBUG "Start of read\n");
+ us_transfer_freecom(srb, us, count);
+#if 0
X if (srb->use_sg) {
X US_DEBUGP ("Need to implement scatter-gather\n");
X return USB_STOR_TRANSPORT_ERROR;
@@ -118,6 +300,14 @@
X offset = 0;
X
X while (offset < count) {
+#if 0
+ this_read = count - offset;
+ if (this_read > 64)
+ this_read = 64;
+#else
+ this_read = 64;
+#endif
+
X printk (KERN_DEBUG "Start of read\n");
X /* Use the given buffer directly, but only if there
X * is space for an entire packet. */
@@ -125,7 +315,7 @@
X if (offset + 64 <= srb->request_bufflen) {
X result = usb_stor_bulk_msg (
X us, srb->request_buffer+offset,
- ipipe, 64, &partial);
+ ipipe, this_read, &partial);
X printk (KERN_DEBUG "Read111 = %d, %d\n",
X result, partial);
X pdump (srb->request_buffer+offset,
@@ -133,7 +323,7 @@
X } else {
X result = usb_stor_bulk_msg (
X us, buffer,
- ipipe, 64, &partial);
+ ipipe, this_read, &partial);
X printk (KERN_DEBUG "Read112 = %d, %d\n",
X result, partial);
X memcpy (srb->request_buffer+offset,
@@ -156,14 +346,118 @@
X return USB_STOR_TRANSPORT_ERROR;
X }
X
- offset += 64;
+ offset += this_read;
X }
X }
+#endif
X
X printk (KERN_DEBUG "freecom_readdata done!\n");
X return USB_STOR_TRANSPORT_GOOD;
X }
X
+static int
+freecom_writedata (Scsi_Cmnd *srb, struct us_data *us,
+ int ipipe, int opipe, int count)
+{
+ freecom_udata_t extra = (freecom_udata_t) us->extra;
+ struct freecom_xfer_wrap *fxfr =
+ (struct freecom_xfer_wrap *) extra->buffer;
+ int result, partial;
+ int offset;
+ int this_write;
+ __u8 *buffer = extra->buffer;
+
+ fxfr->Type = FCM_PACKET_OUTPUT | 0x00;
+ fxfr->Timeout = 0; /* Short timeout for debugging. */
+ fxfr->Count = cpu_to_le32 (count);
+ memset (fxfr->Pad, 0, sizeof (fxfr->Pad));
+
+ printk (KERN_DEBUG "Write data Freecom! (c=%d)\n", count);
+
+ /* Issue the transfer command. */
+ result = usb_stor_bulk_msg (us, fxfr, opipe,
+ FCM_PACKET_LENGTH, &partial);
+ if (result != 0) {
+ US_DEBUGP ("Freecom writedata xpot failure: r=%d, p=%d\n",
+ result, partial);
+
+ /* -ENOENT -- we canceled this transfer */
+ if (result == -ENOENT) {
+ US_DEBUGP("us_transfer_partial(): transfer aborted\n");
+ return US_BULK_TRANSFER_ABORTED;
+ }
+
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+ printk (KERN_DEBUG "Done issuing write request: %d %d\n",
+ result, partial);
+
+ /* Now transfer all of our blocks. */
+ printk (KERN_DEBUG "Start of write\n");
+ us_transfer_freecom(srb, us, count);
+#if 0
+ if (srb->use_sg) {
+ US_DEBUGP ("Need to implement scatter-gather\n");
+ return USB_STOR_TRANSPORT_ERROR;
+ } else {
+ offset = 0;
+
+ while (offset < count) {
+#if 1
+ this_write = count - offset;
+ if (this_write > 64)
+ this_write = 64;
+#else
+ this_write = 64;
+#endif
+
+ printk (KERN_DEBUG "Start of write\n");
+ /* Use the given buffer directly, but only if there
+ * is space for an entire packet. */
+
+ if (offset + 64 <= srb->request_bufflen) {
+ result = usb_stor_bulk_msg (
+ us, srb->request_buffer+offset,
+ opipe, this_write, &partial);
+ printk (KERN_DEBUG "Write111 = %d, %d\n",
+ result, partial);
+ pdump (srb->request_buffer+offset,
+ partial);
+ } else {
+ result = usb_stor_bulk_msg (
+ us, buffer,
+ opipe, this_write, &partial);
+ printk (KERN_DEBUG "Write112 = %d, %d\n",
+ result, partial);
+ memcpy (buffer,
+ srb->request_buffer+offset,
+ srb->request_bufflen - offset);
+ pdump (srb->request_buffer+offset,
+ srb->request_bufflen - offset);
+ }
+
+ if (result != 0) {
+ US_DEBUGP ("Freecom writeblock r=%d, p=%d\n",
+ result, partial);
+
+ /* -ENOENT -- we canceled this transfer */
+ if (result == -ENOENT) {
+ US_DEBUGP("us_transfer_partial(): transfer aborted\n");
+ return US_BULK_TRANSFER_ABORTED;
+ }
+
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ offset += this_write;
+ }
+ }
+#endif
+
+ printk (KERN_DEBUG "freecom_writedata done!\n");
+ return USB_STOR_TRANSPORT_GOOD;
+}
+
X /*
X * Transport for the Freecom USB/IDE adaptor.
X *
@@ -178,17 +472,6 @@
X int length;
X freecom_udata_t extra;
X
- /* Allocate a buffer for us. The upper usb transport code will
- * free this for us when cleaning up. */
- if (us->extra == NULL) {
- us->extra = kmalloc (sizeof (struct freecom_udata),
- GFP_KERNEL);
- if (us->extra == NULL) {
- printk (KERN_WARNING USB_STORAGE "Out of memory\n");
- return USB_STOR_TRANSPORT_ERROR;
- }
- }
-
X extra = (freecom_udata_t) us->extra;
X
X fcb = (struct freecom_cb_wrap *) extra->buffer;
@@ -208,7 +491,7 @@
X #endif
X
X /* The ATAPI Command always goes out first. */
- fcb->Type = FCM_PACKET_ATAPI;
+ fcb->Type = FCM_PACKET_ATAPI | 0x00;
X fcb->Timeout = 0;
X memcpy (fcb->Atapi, srb->cmnd, 12);
X memset (fcb->Filler, 0, sizeof (fcb->Filler));
@@ -247,10 +530,54 @@
X }
X
X pdump ((void *) fst, partial);
+
+ /* while we haven't recieved the IRQ */
+ while (!(fst->Status & 0x2)) {
+ /* send a command to re-fetch the status */
+ US_DEBUGP("Re-attempting to get status...\n");
+
+ fcb->Type = FCM_PACKET_STATUS;
+ fcb->Timeout = 0;
+ memset (fcb->Atapi, 0, 12);
+ memset (fcb->Filler, 0, sizeof (fcb->Filler));
+
+ /* Send it out. */
+ result = usb_stor_bulk_msg (us, fcb, opipe,
+ FCM_PACKET_LENGTH, &partial);
+
+ /* The Freecom device will only fail if there is something wrong in
+ * USB land. It returns the status in its own registers, which
+ * come back in the bulk pipe. */
+ if (result != 0) {
+ US_DEBUGP ("freecom xport failure: r=%d, p=%d\n",
+ result, partial);
+
+ /* -ENOENT -- we canceled this transfer */
+ if (result == -ENOENT) {
+ US_DEBUGP("us_transfer_partial(): transfer aborted\n");
+ return US_BULK_TRANSFER_ABORTED;
+ }
+
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+
+ /* actually get the status info */
+ result = usb_stor_bulk_msg (us, fst, ipipe,
+ FCM_PACKET_LENGTH, &partial);
+ printk (KERN_DEBUG "bar Status result %d %d\n", result, partial);
+ /* -ENOENT -- we canceled this transfer */
+ if (result == -ENOENT) {
+ US_DEBUGP("us_transfer_partial(): transfer aborted\n");
+ return US_BULK_TRANSFER_ABORTED;
+ }
+
+ pdump ((void *) fst, partial);
+ }
+
X if (partial != 4 || result != 0) {
X return USB_STOR_TRANSPORT_ERROR;
X }
- if ((fst->Reason & 1) != 0) {
+ if ((fst->Status & 1) != 0) {
X printk (KERN_DEBUG "operation failed\n");
X return USB_STOR_TRANSPORT_FAILED;
X }
@@ -274,9 +601,70 @@
X
X switch (us->srb->sc_data_direction) {
X case SCSI_DATA_READ:
+ /* Make sure that the status indicates that the device
+ * wants data as well. */
+ if ((fst->Status & DRQ_STAT) == 0 || (fst->Reason & 3) != 2) {
+ printk (KERN_DEBUG "SCSI wants data, drive doesn't have any\n");
+ return USB_STOR_TRANSPORT_FAILED;
+ }
X result = freecom_readdata (srb, us, ipipe, opipe, length);
X if (result != USB_STOR_TRANSPORT_GOOD)
X return result;
+
+ printk (KERN_DEBUG "FCM: Waiting for status\n");
+ result = usb_stor_bulk_msg (us, fst, ipipe,
+ FCM_PACKET_LENGTH, &partial);
+ pdump ((void *) fst, partial);
+ if (result == -ENOENT) {
+ US_DEBUGP ("freecom_transport: transfer aborted\n");
+ return US_BULK_TRANSFER_ABORTED;
+ }
+ if (partial != 4 || result != 0)
+ return USB_STOR_TRANSPORT_ERROR;
+ if ((fst->Status & ERR_STAT) != 0) {
+ printk (KERN_DEBUG "operation failed\n");
+ return USB_STOR_TRANSPORT_FAILED;
+ }
+ if ((fst->Reason & 3) != 3) {
+ printk (KERN_DEBUG "Drive seems still hungry\n");
+ return USB_STOR_TRANSPORT_FAILED;
+ }
+ printk (KERN_DEBUG "Transfer happy\n");
+ break;
+
+ case SCSI_DATA_WRITE:
+ /* Make sure the status indicates that the device wants to
+ * send us data. */
+ /* !!IMPLEMENT!! */
+ result = freecom_writedata (srb, us, ipipe, opipe, length);
+ if (result != USB_STOR_TRANSPORT_GOOD)
+ return result;
+
+#if 1
+ printk (KERN_DEBUG "FCM: Waiting for status\n");
+ result = usb_stor_bulk_msg (us, fst, ipipe,
+ FCM_PACKET_LENGTH, &partial);
+ if (result == -ENOENT) {
+ US_DEBUGP ("freecom_transport: transfer aborted\n");
+ return US_BULK_TRANSFER_ABORTED;
+ }
+ if (partial != 4 || result != 0)
+ return USB_STOR_TRANSPORT_ERROR;
+ if ((fst->Status & ERR_STAT) != 0) {
+ printk (KERN_DEBUG "operation failed\n");
+ return USB_STOR_TRANSPORT_FAILED;
+ }
+ if ((fst->Reason & 3) != 3) {
+ printk (KERN_DEBUG "Drive seems still hungry\n");
+ return USB_STOR_TRANSPORT_FAILED;
+ }
+#endif
+ printk (KERN_DEBUG "Transfer happy\n");
+ break;
+
+
+ case SCSI_DATA_NONE:
+ /* Easy, do nothing. */
X break;
X
X default:
@@ -310,6 +698,69 @@
X srb->sc_data_direction);
X
X return USB_STOR_TRANSPORT_ERROR;
+}
+
+int
+freecom_init (struct us_data *us)
+{
+ int result, value;
+ int counter;
+ char buffer[33];
+
+ /* Allocate a buffer for us. The upper usb transport code will
+ * free this for us when cleaning up. */
+ if (us->extra == NULL) {
+ us->extra = kmalloc (sizeof (struct freecom_udata),
+ GFP_KERNEL);
+ if (us->extra == NULL) {
+ printk (KERN_WARNING USB_STORAGE "Out of memory\n");
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+ }
+
+ result = usb_stor_control_msg(us, usb_rcvctrlpipe(us->pusb_dev, 0),
+ 0x4c, 0xc0, 0x4346, 0x0, buffer, 0x20);
+ buffer[32] = '\0';
+ US_DEBUGP("String returned from FC init is: %s\n", buffer);
+
+ result = freecom_ide_write (us, 0x06, 0xA0);
+ if (result != USB_STOR_TRANSPORT_GOOD)
+ return result;
+ result = freecom_ide_write (us, 0x01, 0x00);
+ if (result != USB_STOR_TRANSPORT_GOOD)
+ return result;
+
+ counter = 50;
+ do {
+ result = freecom_ide_read (us, 0x07, &value);
+ if (result != USB_STOR_TRANSPORT_GOOD)
+ return result;
+ if (counter-- < 0) {
+ printk (KERN_WARNING USB_STORAGE "Timeout in freecom");
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+ } while ((value & 0x80) != 0);
+
+ result = freecom_ide_write (us, 0x07, 0x08);
+ if (result != USB_STOR_TRANSPORT_GOOD)
+ return result;
+
+ counter = 50;
+ do {
+ result = freecom_ide_read (us, 0x07, &value);
+ if (result != USB_STOR_TRANSPORT_GOOD)
+ return result;
+ if (counter-- < 0) {
+ printk (KERN_WARNING USB_STORAGE "Timeout in freecom");
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+ } while ((value & 0x80) != 0);
+
+ result = freecom_ide_write (us, 0x08, 0x08);
+ if (result != USB_STOR_TRANSPORT_GOOD)
+ return result;
+
+ return USB_STOR_TRANSPORT_GOOD;
X }
X
X int usb_stor_freecom_reset(struct us_data *us)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/storage/freecom.h linux/drivers/usb/storage/freecom.h
--- v2.4.0-test8/linux/drivers/usb/storage/freecom.h Mon Aug 28 16:59:14 2000
+++ linux/drivers/usb/storage/freecom.h Fri Sep 8 16:39:12 2000
@@ -1,6 +1,6 @@
X /* Driver for Freecom USB/IDE adaptor
X *
- * $Id: freecom.h,v 1.3 2000/08/25 00:13:51 mdharm Exp $
+ * $Id: freecom.h,v 1.4 2000/08/29 14:49:15 dlbrown Exp $
X *
X * Freecom v0.1:
X *
@@ -31,5 +31,6 @@
X
X extern int freecom_transport(Scsi_Cmnd *srb, struct us_data *us);
X extern int usb_stor_freecom_reset(struct us_data *us);
+extern int freecom_init (struct us_data *us);
X
X #endif
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/storage/initializers.c linux/drivers/usb/storage/initializers.c
--- v2.4.0-test8/linux/drivers/usb/storage/initializers.c Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/storage/initializers.c Fri Sep 8 16:39:12 2000
@@ -0,0 +1,60 @@
+/* Special Initializers for certain USB Mass Storage devices
+ *
+ * $Id: initializers.c,v 1.2 2000/09/06 22:35:57 mdharm Exp $
+ *
+ * Current development and maintenance by:
+ * (c) 1999, 2000 Matthew Dharm (mdhar...@one-eyed-alien.net)
+ *
+ * This driver is based on the 'USB Mass Storage Class' document. This
+ * describes in detail the protocol used to communicate with such
+ * devices. Clearly, the designers had SCSI and ATAPI commands in
+ * mind when they created this document. The commands are all very
+ * similar to commands in the SCSI-II and ATAPI specifications.
+ *
+ * It is important to note that in a number of cases this class
+ * exhibits class-specific exemptions from the USB specification.
+ * Notably the usage of NAK, STALL and ACK differs from the norm, in
+ * that they are used to communicate wait, failed and OK on commands.
+ *
+ * Also, for certain devices, the interrupt endpoint is used to convey
+ * status of a command.
+ *
+ * Please see http://www.one-eyed-alien.net/~mdharm/linux-usb for more
+ * information about this driver.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *


+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU

+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "initializers.h"
+#include "debug.h"
+
+/* This places the Shuttle/SCM USB<->SCSI bridge devices in multi-target
+ * mode */
+int usb_stor_euscsi_init(struct us_data *us)
+{
+ unsigned char data = 0x1;
+ int result;
+
+ US_DEBUGP("Attempting to init eUSCSI bridge...\n");
+ result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev, 0),
+ 0x0C, USB_RECIP_INTERFACE | USB_TYPE_VENDOR,
+ 0x01, 0x0, &data, 0x1, 5*HZ);
+ US_DEBUGP("-- result is %d\n", result);
+ US_DEBUGP("-- data afterwards is %d\n", data);


+
+ return 0;
+}
+
+

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/storage/initializers.h linux/drivers/usb/storage/initializers.h
--- v2.4.0-test8/linux/drivers/usb/storage/initializers.h Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/storage/initializers.h Mon Oct 2 11:02:34 2000
@@ -0,0 +1,44 @@
+/* Header file for Special Initializers for certain USB Mass Storage devices
+ *
+ * $Id: initializers.h,v 1.1 2000/08/29 23:07:02 mdharm Exp $
+ *
+ * Current development and maintenance by:
+ * (c) 1999, 2000 Matthew Dharm (mdhar...@one-eyed-alien.net)
+ *
+ * This driver is based on the 'USB Mass Storage Class' document. This
+ * describes in detail the protocol used to communicate with such
+ * devices. Clearly, the designers had SCSI and ATAPI commands in
+ * mind when they created this document. The commands are all very
+ * similar to commands in the SCSI-II and ATAPI specifications.
+ *
+ * It is important to note that in a number of cases this class
+ * exhibits class-specific exemptions from the USB specification.
+ * Notably the usage of NAK, STALL and ACK differs from the norm, in
+ * that they are used to communicate wait, failed and OK on commands.
+ *
+ * Also, for certain devices, the interrupt endpoint is used to convey
+ * status of a command.
+ *
+ * Please see http://www.one-eyed-alien.net/~mdharm/linux-usb for more
+ * information about this driver.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *


+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU

+ * General Public License for more details.
+ *


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 094'
echo 'File patch-2.4.0-test9 is continued in part 095'
echo "095" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part095

#!/bin/sh -x
# this is part 095 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 095; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+

+#include "usb.h"


+
+/* This places the Shuttle/SCM USB<->SCSI bridge devices in multi-target
+ * mode */

+int usb_stor_euscsi_init(struct us_data *us);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/storage/protocol.c linux/drivers/usb/storage/protocol.c
--- v2.4.0-test8/linux/drivers/usb/storage/protocol.c Mon Aug 28 16:59:14 2000
+++ linux/drivers/usb/storage/protocol.c Fri Sep 8 16:39:12 2000
@@ -1,6 +1,6 @@


X /* Driver for USB Mass Storage compliant devices
X *

- * $Id: protocol.c,v 1.5 2000/08/25 00:13:51 mdharm Exp $
+ * $Id: protocol.c,v 1.6 2000/09/01 22:03:55 mdharm Exp $
X *


X * Current development and maintenance by:
X * (c) 1999, 2000 Matthew Dharm (mdhar...@one-eyed-alien.net)

@@ -170,7 +170,7 @@
X usb_stor_invoke_transport(srb, us);
X
X /* Fix the MODE_SENSE data if we translated the command */
- if ((old_cmnd == MODE_SENSE) && (srb->result == GOOD))
+ if ((old_cmnd == MODE_SENSE) && (status_byte(srb->result) == GOOD))
X usb_stor_scsiSense10to6(srb);
X
X /* fix the INQUIRY data if necessary */
@@ -265,7 +265,7 @@
X usb_stor_invoke_transport(srb, us);
X
X /* Fix the MODE_SENSE data if we translated the command */
- if ((old_cmnd == MODE_SENSE) && (srb->result == GOOD))
+ if ((old_cmnd == MODE_SENSE) && (status_byte(srb->result) == GOOD))
X usb_stor_scsiSense10to6(srb);
X
X /* Fix the data for an INQUIRY, if necessary */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/storage/scsiglue.c linux/drivers/usb/storage/scsiglue.c
--- v2.4.0-test8/linux/drivers/usb/storage/scsiglue.c Mon Aug 28 16:59:14 2000
+++ linux/drivers/usb/storage/scsiglue.c Mon Oct 2 12:07:51 2000


@@ -1,7 +1,7 @@
X /* Driver for USB Mass Storage compliant devices

X * SCSI layer glue code
X *
- * $Id: scsiglue.c,v 1.9 2000/08/25 00:13:51 mdharm Exp $
+ * $Id: scsiglue.c,v 1.13 2000/09/28 21:54:30 mdharm Exp $
X *


X * Current development and maintenance by:
X * (c) 1999, 2000 Matthew Dharm (mdhar...@one-eyed-alien.net)

@@ -112,7 +112,7 @@
X {
X struct us_data *us = (struct us_data *)psh->hostdata[0];
X
- US_DEBUGP("us_release() called for host %s\n", us->htmplt.name);
+ US_DEBUGP("release() called for host %s\n", us->htmplt.name);
X
X /* Kill the control threads
X *
@@ -124,9 +124,7 @@
X wake_up(&(us->wqh));
X down(&(us->notify));
X
- /* free the data structure we were using */
- US_DEBUGP("-- freeing URB\n");
- kfree(us->current_urb);
+ /* remove the pointer to the data structure we were using */
X (struct us_data*)psh->hostdata[0] = NULL;
X
X /* we always have a successful release */
@@ -189,12 +187,6 @@
X return SUCCESS;
X }
X
- /* This is a sanity check that we should never hit */
- if (in_interrupt()) {
- printk(KERN_ERR "usb-storage: command_abort() called from an interrupt!!! BAD!!! BAD!! BAD!!\n");
- return FAILED;
- }
-
X /* if we have an urb pending, let's wake the control thread up */
X if (us->current_urb->status == -EINPROGRESS) {
X /* cancel the URB */
@@ -213,18 +205,62 @@
X return FAILED;
X }
X
-/* FIXME: this doesn't do anything right now */
+/* This invokes the transport reset mechanism to reset the state of the
+ * device */
+static int device_reset( Scsi_Cmnd *srb )
+{
+ struct us_data *us = (struct us_data *)srb->host->hostdata[0];
+
+ US_DEBUGP("device_reset() called\n" );
+ return us->transport_reset(us);
+}
+
+/* This resets the device port, and simulates the device
+ * disconnect/reconnect for all drivers which have claimed other
+ * interfaces. */
X static int bus_reset( Scsi_Cmnd *srb )
X {
- // struct us_data *us = (struct us_data *)srb->host->hostdata[0];
+ struct us_data *us = (struct us_data *)srb->host->hostdata[0];
+ int i;
X
- printk(KERN_CRIT "usb-storage: bus_reset() requested but not implemented\n" );
- US_DEBUGP("Bus reset requested\n");
- // us->transport_reset(us);
- return FAILED;
+ /* we use the usb_reset_device() function to handle this for us */
+ US_DEBUGP("bus_reset() called\n");
+
+ /* attempt to reset the port */
+ if (usb_reset_device(us->pusb_dev) < 0)
+ return FAILED;
+
+ /* FIXME: This needs to lock out driver probing while it's working
+ * or we can have race conditions */
+ for (i = 0; i < us->pusb_dev->actconfig->bNumInterfaces; i++) {


+ struct usb_interface *intf =

+ &us->pusb_dev->actconfig->interface[i];
+
+ /* if this is an unclaimed interface, skip it */
+ if (!intf->driver) {
+ continue;
+ }
+
+ US_DEBUGP("Examinging driver %s...", intf->driver->name);
+ /* skip interfaces which we've claimed */
+ if (intf->driver == &usb_storage_driver) {
+ US_DEBUGPX("skipping ourselves.\n");
+ continue;
+ }
+
+ /* simulate a disconnect and reconnect for all interfaces */
+ US_DEBUGPX("simulating disconnect/reconnect.\n");
+ down(&intf->driver->serialize);
+ intf->driver->disconnect(us->pusb_dev, intf->private_data);
+ intf->driver->probe(us->pusb_dev, i);
+ up(&intf->driver->serialize);
+ }
+
+ US_DEBUGP("bus_reset() complete\n");
+ return SUCCESS;
X }
X
-/* FIXME: This doesn't actually reset anything */
+/* FIXME: This doesn't do anything right now */
X static int host_reset( Scsi_Cmnd *srb )
X {
X printk(KERN_CRIT "usb-storage: host_reset() requested but not implemented\n" );
@@ -261,9 +297,11 @@
X us = us->next;
X }
X
+ /* release our lock on the data structures */
+ up(&us_list_semaphore);
+
X /* if we couldn't find it, we return an error */
X if (!us) {
- up(&us_list_semaphore);
X return -ESRCH;
X }
X
@@ -282,9 +320,6 @@
X /* show the GUID of the device */
X SPRINTF(" GUID: " GUID_FORMAT "\n", GUID_ARGS(us->guid));
X
- /* release our lock on the data structures */
- up(&us_list_semaphore);
-
X /*
X * Calculate start of next buffer, and return value.
X */
@@ -313,7 +348,7 @@
X queuecommand: queuecommand,
X
X eh_abort_handler: command_abort,
- eh_device_reset_handler:bus_reset,
+ eh_device_reset_handler:device_reset,
X eh_bus_reset_handler: bus_reset,
X eh_host_reset_handler: host_reset,
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/storage/shuttle_usbat.c linux/drivers/usb/storage/shuttle_usbat.c
--- v2.4.0-test8/linux/drivers/usb/storage/shuttle_usbat.c Mon Aug 28 16:59:14 2000
+++ linux/drivers/usb/storage/shuttle_usbat.c Sun Oct 1 19:42:40 2000
@@ -1,18 +1,6 @@
X /* Driver for SCM Microsystems USB-ATAPI cable
X *
- * $Id: shuttle_usbat.c,v 1.4 2000/08/25 00:13:51 mdharm Exp $
- *
- * SCM driver v0.2:
- *
- * Removed any reference to maxlen for bulk transfers.
- * Changed scm_bulk_transport to allow for transfers without commands.
- * Changed hp8200e transport to use the request_bufflen field in the
- * SCSI command for the length of the transfer, rather than calculating
- * it ourselves based on the command.
- *
- * SCM driver v0.1:
- *
- * First release - hp8200e.
+ * $Id: shuttle_usbat.c,v 1.10 2000/09/24 00:03:08 groovyjava Exp $


X *
X * Current development and maintenance by:

X * (c) 2000 Robert Baruch (auto...@dol.net)
@@ -30,8 +18,8 @@
X * as well. This driver is only guaranteed to work with the ATAPI
X * translation.
X *
- * The only peripherals that I know of (as of 14 Jul 2000) that uses this
- * device is the Hewlett-Packard 8200e CD-Writer Plus.
+ * The only peripheral that I know of (as of 8 Sep 2000) that uses this
+ * device is the Hewlett-Packard 8200e/8210e CD-Writer Plus.
X *
X * This program is free software; you can redistribute it and/or modify it
X * under the terms of the GNU General Public License as published by the
@@ -64,10 +52,12 @@
X extern int usb_stor_bulk_msg(struct us_data *us, void *data, int pipe,
X unsigned int len, unsigned int *act_len);
X
-#define short_pack(b1,b2) ( ((u16)(b1)) | ( ((u16)(b2))<<8 ) )
+#define short_pack(LSB,MSB) ( ((u16)(LSB)) | ( ((u16)(MSB))<<8 ) )
X #define LSB_of(s) ((s)&0xFF)
X #define MSB_of(s) ((s)>>8)
X
+int transferred = 0;
+
X /*
X * Send a control message and wait for the response.
X *
@@ -98,16 +88,6 @@
X
X int result;
X
- // If data is going to be sent or received with the URB,
- // then allocate a buffer for it. If data is to be sent,
- // copy the data into the buffer.
-/*
- if (xfer_len > 0) {
- buffer = kmalloc(xfer_len, GFP_KERNEL);
- if (!(command[0] & USB_DIR_IN))
- memcpy(buffer, xfer_data, xfer_len);
- }
-*/
X // Send the URB to the device and wait for a response.
X
X /* Why are request and request type reversed in this call? */
@@ -117,16 +97,6 @@
X xfer_data, xfer_len);
X
X
- // If data was sent or received with the URB, free the buffer we
- // allocated earlier, but not before reading the data out of the
- // buffer if we wanted to receive data.
-/*
- if (xfer_len > 0) {
- if (command[0] & USB_DIR_IN)
- memcpy(xfer_data, buffer, xfer_len);
- kfree(buffer);
- }
-*/
X // Check the return code for the command.
X
X if (result < 0) {
@@ -192,7 +162,7 @@
X if (result == -EPIPE) {
X US_DEBUGP("usbat_raw_bulk():"
X " output pipe stalled\n");
- return USB_STOR_TRANSPORT_FAILED;
+ return US_BULK_TRANSFER_SHORT;
X }
X
X /* the catch-all case */
@@ -206,7 +176,8 @@
X return US_BULK_TRANSFER_SHORT;
X }
X
- US_DEBUGP("Transfered %d of %d bytes\n", act_len, len);
+ US_DEBUGP("Transferred %s %d of %d bytes\n",
+ direction==SCSI_DATA_READ ? "in" : "out", act_len, len);
X
X return US_BULK_TRANSFER_GOOD;
X }
@@ -225,68 +196,18 @@
X
X int result = USB_STOR_TRANSPORT_GOOD;
X int transferred = 0;
- unsigned char execute[8] = {
- 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- };
X int i;
X struct scatterlist *sg;
- char string[64];
- int pipe;
X
-/*
- if (command_len != 0) {
-
- // Fix up the command's data length
-
- command[6] = len&0xFF;
- command[7] = (len>>8)&0xFF;
-
-
-
- result = usbat_send_control(us,
- execute,
- command,
- command_len);
-
- if (result != USB_STOR_TRANSPORT_GOOD)
- return result;
- }
-*/
X if (len==0)
X return USB_STOR_TRANSPORT_GOOD;
X
-
X /* transfer the data payload for the command, if there is any */
X
-
X if (command_len != 0)
X direction = (command[0]&0x80) ? SCSI_DATA_READ :
X SCSI_DATA_WRITE;
X
- if (direction == SCSI_DATA_WRITE) {
-
- /* Debug-print the first 48 bytes of the write transfer */
-
- if (!use_sg) {
- string[0] = 0;
- for (i=0; i<len && i<48; i++) {
- sprintf(string+strlen(string), "%02X ",
- data[i]);
- if ((i%16)==15) {
- US_DEBUGP("%s\n", string);
- string[0] = 0;
- }
- }
- if (string[0]!=0)
- US_DEBUGP("%s\n", string);
- }
- }
-
-
- US_DEBUGP("SCM data %s transfer %d sg buffers %d\n",
- ( direction==SCSI_DATA_READ ? "in" : "out"),
- len, use_sg);
-
X if (!use_sg)
X result = usbat_raw_bulk(us, direction, data, len);
X else {
@@ -311,9 +232,6 @@
X unsigned char *content) {
X
X int result;
- unsigned char command[8] = {
- 0xC0, access, reg, 0x00, 0x00, 0x00, 0x00, 0x00
- };
X
X result = usbat_send_control(us,
X usb_rcvctrlpipe(us->pusb_dev,0),
@@ -324,8 +242,6 @@
X content,
X 1);
X
- // result = usbat_send_control(us, command, content, 1);
-
X return result;
X }
X
@@ -335,9 +251,6 @@
X unsigned char content) {
X
X int result;
- unsigned char command[8] = {
- 0x40, access|0x01, reg, content, 0x00, 0x00, 0x00, 0x00
- };
X
X result = usbat_send_control(us,
X usb_sndctrlpipe(us->pusb_dev,0),
@@ -348,8 +261,6 @@
X NULL,
X 0);
X
- // result = usbat_send_control(us, command, NULL, 0);
-
X return result;
X }
X
@@ -376,8 +287,6 @@
X command,
X 8);
X
- // result = usbat_bulk_transport(us, command, 8, 0, NULL, 0, 0);
-
X return result;
X }
X
@@ -409,9 +318,6 @@
X result = usbat_bulk_transport(us,
X NULL, 0, SCSI_DATA_READ, content, len, use_sg);
X
- // result = usbat_bulk_transport(us,
- // command, 8, 0, content, len, use_sg);
-
X return result;
X }
X
@@ -420,40 +326,47 @@
X * an error condition.
X */
X
-int usbat_wait_not_busy(struct us_data *us) {
+int usbat_wait_not_busy(struct us_data *us, int minutes) {
X
X int i;
X int result;
X unsigned char status;
X
X /* Synchronizing cache on a CDR could take a heck of a long time,
- but probably not more than 15 minutes or so */
+ * but probably not more than 10 minutes or so. On the other hand,
+ * doing a full blank on a CDRW at speed 1 will take about 75
+ * minutes!
+ */
+
+ for (i=0; i<1200+minutes*60; i++) {
X
- for (i=0; i<500; i++) {
X result = usbat_read(us, USBAT_ATA, 0x17, &status);
- US_DEBUGP("SCM: Write ATA data status is %02X\n", status);
+
X if (result!=USB_STOR_TRANSPORT_GOOD)
X return result;
X if (status&0x01) // check condition
X return USB_STOR_TRANSPORT_FAILED;
X if (status&0x20) // device fault
X return USB_STOR_TRANSPORT_FAILED;
- if ((status&0x80)!=0x80) // not busy
- break;
- if (i<5)
- wait_ms(100);
- else if (i<20)
- wait_ms(500);
- else if (i<49)
- wait_ms(1000);
- else if (i<499)
- wait_ms(2000);
- }
X
- if (i==500)
- return USB_STOR_TRANSPORT_FAILED;
+ if ((status&0x80)!=0x80) { // not busy
+ US_DEBUGP("Waited not busy for %d steps\n", i);
+ return USB_STOR_TRANSPORT_GOOD;
+ }
X
- return USB_STOR_TRANSPORT_GOOD;
+ if (i<500)
+ wait_ms(10); // 5 seconds
+ else if (i<700)
+ wait_ms(50); // 10 seconds
+ else if (i<1200)
+ wait_ms(100); // 50 seconds
+ else
+ wait_ms(1000); // X minutes
+ }
+
+ US_DEBUGP("Waited not busy for %d minutes, timing out.\n",
+ minutes);
+ return USB_STOR_TRANSPORT_FAILED;
X }
X
X int usbat_write_block(struct us_data *us,
@@ -461,7 +374,8 @@
X unsigned char reg,
X unsigned char *content,
X unsigned short len,
- int use_sg) {
+ int use_sg,
+ int minutes) {
X
X int result;
X unsigned char command[8] = {
@@ -487,115 +401,157 @@


X if (result != USB_STOR_TRANSPORT_GOOD)
X return result;

X
- // result = usbat_bulk_transport(us,
- // command, 8, 0, content, len, use_sg);
-
- return usbat_wait_not_busy(us);
+ return usbat_wait_not_busy(us, minutes);
X }
X
-int usbat_write_block_test(struct us_data *us,
+int usbat_rw_block_test(struct us_data *us,
X unsigned char access,
X unsigned char *registers,
X unsigned char *data_out,
X unsigned short num_registers,
X unsigned char data_reg,
X unsigned char status_reg,
- unsigned char qualifier,
X unsigned char timeout,
+ unsigned char qualifier,
+ int direction,
X unsigned char *content,
X unsigned short len,
- int use_sg) {
+ int use_sg,
+ int minutes) {
X
X int result;
X
X // Not really sure the 0x07, 0x17, 0xfc, 0xe7 is necessary here,
- // but that's what came out of the trace.
+ // but that's what came out of the trace every single time.
X
X unsigned char command[16] = {
X 0x40, access|0x07, 0x07, 0x17, 0xfc, 0xe7,
X LSB_of(num_registers*2), MSB_of(num_registers*2),
- 0x40, access|0x05, data_reg, status_reg,
- qualifier, timeout, LSB_of(len), MSB_of(len)
+ (direction==SCSI_DATA_WRITE ? 0x40 : 0xC0),
+ access|(direction==SCSI_DATA_WRITE ? 0x05 : 0x04),
+ data_reg, status_reg,
+ timeout, qualifier, LSB_of(len), MSB_of(len)
X };
+
X int i;
X unsigned char data[num_registers*2];
- int transferred;
- struct scatterlist *sg;
- char string[64];
+ unsigned char status;
X
X for (i=0; i<num_registers; i++) {
X data[i<<1] = registers[i];
X data[1+(i<<1)] = data_out[i];
X }
X
- result = usbat_send_control(us,
- usb_sndctrlpipe(us->pusb_dev,0),
- 0x80,
- 0x40,
- 0,
- 0,
- command,
- 16);
-
- if (result != USB_STOR_TRANSPORT_GOOD)
- return result;
+ for (i=0; i<20; i++) {
X
- result = usbat_bulk_transport(us,
- NULL, 0, SCSI_DATA_WRITE, data, num_registers*2, 0);
+ /*
+ * The first time we send the full command, which consists
+ * of downloading the SCSI command followed by downloading
+ * the data via a write-and-test. Any other time we only
+ * send the command to download the data -- the SCSI command
+ * is still 'active' in some sense in the device.
+ *
+ * We're only going to try sending the data 10 times. After
+ * that, we just return a failure.
+ */
+
+ result = usbat_send_control(us,
+ usb_sndctrlpipe(us->pusb_dev,0),
+ 0x80,
+ 0x40,
+ 0,
+ 0,
+ (i==0 ? command : command+8),
+ (i==0 ? 16 : 8));
X
- // result = usbat_bulk_transport(us,
- // command, 16, 0, data, num_registers*2, 0);


+ if (result != USB_STOR_TRANSPORT_GOOD)
+ return result;

X
- if (result!=USB_STOR_TRANSPORT_GOOD)
- return result;
+ if (i==0) {
X
- // transferred = 0;
+ result = usbat_bulk_transport(us,
+ NULL, 0, SCSI_DATA_WRITE,
+ data, num_registers*2, 0);
X
- US_DEBUGP("Transfer out %d bytes, sg buffers %d\n",
- len, use_sg);
+ if (result!=USB_STOR_TRANSPORT_GOOD)
+ return result;
X
- result = usbat_bulk_transport(us,
- NULL, 0, SCSI_DATA_WRITE, content, len, use_sg);
+ }
X
-/*
- if (!use_sg) {
X
- // Debug-print the first 48 bytes of the transfer
+ //US_DEBUGP("Transfer %s %d bytes, sg buffers %d\n",
+ // direction == SCSI_DATA_WRITE ? "out" : "in",
+ // len, use_sg);
+
+ result = usbat_bulk_transport(us,
+ NULL, 0, direction, content, len, use_sg);
+
+ /*
+ * If we get a stall on the bulk download, we'll retry
+ * the bulk download -- but not the SCSI command because
+ * in some sense the SCSI command is still 'active' and
+ * waiting for the data. Don't ask me why this should be;
+ * I'm only following what the Windoze driver did.
+ *
+ * Note that a stall for the test-and-read/write command means
+ * that the test failed. In this case we're testing to make
+ * sure that the device is error-free
+ * (i.e. bit 0 -- CHK -- of status is 0). The most likely
+ * hypothesis is that the USBAT chip somehow knows what
+ * the device will accept, but doesn't give the device any
+ * data until all data is received. Thus, the device would
+ * still be waiting for the first byte of data if a stall
+ * occurs, even if the stall implies that some data was
+ * transferred.
+ */
+
+ if (result == US_BULK_TRANSFER_SHORT) {
+
+ /*
+ * If we're reading and we stalled, then clear
+ * the bulk output pipe only the first time.
+ */
+
+ if (direction==SCSI_DATA_READ && i==0)
+ usb_clear_halt(us->pusb_dev,
+ usb_sndbulkpipe(us->pusb_dev,
+ us->ep_out));
+ /*
+ * Read status: is the device angry, or just busy?
+ */
+
+ result = usbat_read(us, USBAT_ATA,
+ direction==SCSI_DATA_WRITE ? 0x17 : 0x0E,
+ &status);
X
- string[0] = 0;
- for (i=0; i<len && i<48; i++) {
- sprintf(string+strlen(string), "%02X ",
- content[i]);
- if ((i%16)==15) {
- US_DEBUGP("%s\n", string);
- string[0] = 0;
- }
- }
- if (string[0]!=0)
- US_DEBUGP("%s\n", string);
+ if (result!=USB_STOR_TRANSPORT_GOOD)
+ return result;
+ if (status&0x01) // check condition
+ return USB_STOR_TRANSPORT_FAILED;
+ if (status&0x20) // device fault
+ return USB_STOR_TRANSPORT_FAILED;
X
- result = usbat_raw_bulk(us, SCSI_DATA_WRITE, content, len);
+ US_DEBUGP("Redoing %s\n",
+ direction==SCSI_DATA_WRITE ? "write" : "read");
X
- } else {
+ } else if (result != US_BULK_TRANSFER_GOOD)
+ return result;
+ else
+ return usbat_wait_not_busy(us, minutes);
X
- sg = (struct scatterlist *)content;
- for (i=0; i<use_sg && transferred<len; i++) {
- result = usbat_raw_bulk(us, SCSI_DATA_WRITE,
- sg[i].address,
- len-transferred > sg[i].length ?
- sg[i].length : len-transferred);
- if (result!=US_BULK_TRANSFER_GOOD)
- break;
- transferred += sg[i].length;
- }
X }
-*/
- if (result!=USB_STOR_TRANSPORT_GOOD)
- return result;
X
- return usbat_wait_not_busy(us);
+ US_DEBUGP("Bummer! %s bulk data 20 times failed.\n",
+ direction==SCSI_DATA_WRITE ? "Writing" : "Reading");
+
+ return USB_STOR_TRANSPORT_FAILED;
X }
X
+/*
+ * Write data to multiple registers at once. Not meant for large
+ * transfers of data!
+ */
+
X int usbat_multiple_write(struct us_data *us,
X unsigned char access,
X unsigned char *registers,
@@ -630,21 +586,15 @@
X result = usbat_bulk_transport(us,
X NULL, 0, SCSI_DATA_WRITE, data, num_registers*2, 0);
X
- // result = usbat_bulk_transport(us, cmd, 8, 0,
- // data, num_registers*2, 0);
-
X if (result!=USB_STOR_TRANSPORT_GOOD)
X return result;
X
- return usbat_wait_not_busy(us);
+ return usbat_wait_not_busy(us, 0);
X }
X
X int usbat_read_user_io(struct us_data *us,
X unsigned char *data_flags) {
X
- unsigned char command[8] = {
- 0xC0, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- };
X int result;
X
X result = usbat_send_control(us,
@@ -656,8 +606,6 @@
X data_flags,
X 1);
X
- // result = usbat_send_control(us, command, data_flags, 1);
-
X return result;
X }
X
@@ -665,9 +613,6 @@
X unsigned char enable_flags,
X unsigned char data_flags) {
X
- unsigned char command[8] = {
- 0x40, 0x82, enable_flags, data_flags, 0x00, 0x00, 0x00, 0x00
- };
X int result;
X
X result = usbat_send_control(us,
@@ -679,8 +624,138 @@
X NULL,
X 0);
X
- // result = usbat_send_control(us, command, NULL, 0);


+ return result;
+}
+

+/*
+ * Squeeze a potentially huge (> 65535 byte) read10 command into
+ * a little ( <= 65535 byte) ATAPI pipe
+ */
+
+int usbat_handle_read10(struct us_data *us,
+ unsigned char *registers,
+ unsigned char *data,
+ Scsi_Cmnd *srb) {
+
+ int result = USB_STOR_TRANSPORT_GOOD;
+ unsigned char *buffer;
+ unsigned int len;
+ unsigned int sector;
+ unsigned int amount;
+ struct scatterlist *sg = NULL;
+ int sg_segment = 0;
+ int sg_offset = 0;
+
+ US_DEBUGP("handle_read10: transfersize %d\n",
+ srb->transfersize);
+
+ if (srb->request_bufflen < 0x10000) {
+
+ result = usbat_rw_block_test(us, USBAT_ATA,
+ registers, data, 19,
+ 0x10, 0x17, 0xFD, 0x30,
+ SCSI_DATA_READ,
+ srb->request_buffer,
+ srb->request_bufflen, srb->use_sg, 1);
+


+ return result;
+ }
+

+ /*
+ * Since we're requesting more data than we can handle in
+ * a single read command (max is 64k-1), we will perform
+ * multiple reads, but each read must be in multiples of
+ * a sector. Luckily the sector size is in srb->transfersize
+ * (see linux/drivers/scsi/sr.c).
+ */
+
+ if (data[7+0] == GPCMD_READ_CD) {
+ len = short_pack(data[7+9], data[7+8]);
+ len <<= 16;
+ len |= data[7+7];
+ srb->transfersize = srb->request_bufflen/len;
+ }
+
+
+ len = (65535/srb->transfersize) * srb->transfersize;
+ US_DEBUGP("Max read is %d bytes\n", len);
+ buffer = kmalloc(len, GFP_KERNEL);
+ if (buffer == NULL) // bloody hell!
+ return USB_STOR_TRANSPORT_FAILED;
+ sector = short_pack(data[7+3], data[7+2]);
+ sector <<= 16;
+ sector |= short_pack(data[7+5], data[7+4]);
+ transferred = 0;
+
+ if (srb->use_sg) {
+ sg = (struct scatterlist *)srb->request_buffer;
+ sg_segment = 0; // for keeping track of where we are in
+ sg_offset = 0; // the scatter/gather list
+ }
+
+ while (transferred != srb->request_bufflen) {
+
+ if (len > srb->request_bufflen - transferred)
+ len = srb->request_bufflen - transferred;
+
+ data[3] = len&0xFF; // (cylL) = expected length (L)
+ data[4] = (len>>8)&0xFF; // (cylH) = expected length (H)
+
+ // Fix up the SCSI command sector and num sectors
+
+ data[7+2] = MSB_of(sector>>16); // SCSI command sector
+ data[7+3] = LSB_of(sector>>16);
+ data[7+4] = MSB_of(sector&0xFFFF);
+ data[7+5] = LSB_of(sector&0xFFFF);
+ if (data[7+0] == GPCMD_READ_CD)
+ data[7+6] = 0;
+ data[7+7] = MSB_of(len / srb->transfersize); // SCSI command
+ data[7+8] = LSB_of(len / srb->transfersize); // num sectors
+
+ result = usbat_rw_block_test(us, USBAT_ATA,
+ registers, data, 19,
+ 0x10, 0x17, 0xFD, 0x30,
+ SCSI_DATA_READ,
+ buffer,
+ len, 0, 1);
+
+ if (result != USB_STOR_TRANSPORT_GOOD)
+ break;
+
+ // Transfer the received data into the srb buffer
+
+ if (!srb->use_sg) {
+ memcpy(srb->request_buffer+transferred, buffer, len);
+ } else {
+ amount = 0;
+ while (amount<len) {
+ if (len - amount >=
+ sg[sg_segment].length-sg_offset) {
+ memcpy(sg[sg_segment].address + sg_offset,
+ buffer + amount,
+ sg[sg_segment].length - sg_offset);
+ amount +=
+ sg[sg_segment].length-sg_offset;
+ sg_segment++;
+ sg_offset=0;
+ } else {
+ memcpy(sg[sg_segment].address + sg_offset,
+ buffer + amount,
+ len - amount);
+ sg_offset += (len - amount);
+ amount = len;
+ }
+ }
+ }
X
+ // Update the amount transferred and the sector number
+
+ transferred += len;
+ sector += len / srb->transfersize;
+
+ } // while transferred != srb->request_bufflen
+
+ kfree(buffer);
X return result;
X }
X
@@ -870,102 +945,8 @@
X int i;
X char string[64];
X
- /* This table tells us:
- X = command not supported
- L = return length in cmnd[4] (8 bits).
- H = return length in cmnd[7] and cmnd[8] (16 bits).
- D = return length in cmnd[6] to cmnd[9] (32 bits).
- B = return length/blocksize in cmnd[6] to cmnd[8].
- T = return length in cmnd[6] to cmnd[8] (24 bits).
- 0-9 = fixed return length
- W = 24 bytes
- h = return length/2048 in cmnd[7-8].
- */
-
- static char *lengths =
-
- /* 0123456789ABCDEF 0123456789ABCDEF */
-
- "0XXL0XXXXXXXXXXX" "XXLXXXXXXXX0XX0X" /* 00-1F */
- "XXXXX8XXhXH0XXX0" "XXXXX0XXXXXXXXXX" /* 20-3F */
- "XXHHL0X0XXH0XX0X" "XHH00HXX0TH0H0XX" /* 40-5F */
- "XXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXX" /* 60-7F */
- "XXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXX" /* 80-9F */
- "X0XXX0XXDXDXXXXX" "XXXXXXXXX000XHBX" /* A0-BF */
- "XXXXXXXXXXXXXXXX" "XXXXXXXXXXXXXXXX" /* C0-DF */
- "XDXXXXXXXXXXXXXX" "XXW00HXXXXXXXXXX"; /* E0-FF */
-
-/* if (us->flags & US_FL_NEED_INIT) {
- US_DEBUGP("8200e: initializing\n");
- init_8200e(us);
- us->flags &= ~US_FL_NEED_INIT;
- } */
-
X len = srb->request_bufflen;
X
-/* if (srb->sc_data_direction == SCSI_DATA_WRITE)
- len = srb->request_bufflen;
- else {
-
- switch (lengths[srb->cmnd[0]]) {
-
- case 'L':
- len = srb->cmnd[4];
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- len = lengths[srb->cmnd[0]]-'0';
- break;
- case 'H':
- len = (((unsigned int)srb->cmnd[7])<<8) | srb->cmnd[8];
- break;
- case 'h':
- len = (((unsigned int)srb->cmnd[7])<<8) | srb->cmnd[8];
- len <<= 11; // *2048
- break;
- case 'T':
- len = (((unsigned int)srb->cmnd[6])<<16) |
- (((unsigned int)srb->cmnd[7])<<8) |
- srb->cmnd[8];
- break;
- case 'D':
- len = (((unsigned int)srb->cmnd[6])<<24) |
- (((unsigned int)srb->cmnd[7])<<16) |
- (((unsigned int)srb->cmnd[8])<<8) |
- srb->cmnd[9];
- break;
- case 'W':
- len = 24;
- break;
- case 'B':
- // Let's try using the command structure's
- // request_bufflen here
- len = srb->request_bufflen;
- break;
- default:
- US_DEBUGP("Error: UNSUPPORTED COMMAND %02X\n",
- srb->cmnd[0]);
- return USB_STOR_TRANSPORT_ERROR;
- }
- } */
-
- if (len > 0xFFFF) {
- US_DEBUGP("Error: len = %08X... what do I do now?\n",
- len);


- return USB_STOR_TRANSPORT_ERROR;
- }
-

- // US_DEBUGP("XXXXXXXXXXXXXXXX req_bufflen %d, len %d, bufflen %d\n",
- // srb->request_bufflen, len, srb->bufflen);
-
X /* Send A0 (ATA PACKET COMMAND).
X Note: I guess we're never going to get any of the ATA
X commands... just ATA Packet Commands.
@@ -986,20 +967,41 @@
X data[5] = 0xB0; // (device sel) = slave
X data[6] = 0xA0; // (command) = ATA PACKET COMMAND
X
- if (srb->sc_data_direction == SCSI_DATA_WRITE) {
+ for (i=7; i<19; i++) {
+ registers[i] = 0x10;
+ data[i] = (i-7 >= srb->cmd_len) ? 0 : srb->cmnd[i-7];
+ }
X
- for (i=7; i<19; i++) {
- registers[i] = 0x10;
- data[i] = (i-7 >= srb->cmd_len) ? 0 : srb->cmnd[i-7];
- }
+ if (srb->cmnd[0] == TEST_UNIT_READY)
+ transferred = 0;
+
+ if (srb->sc_data_direction == SCSI_DATA_WRITE) {
X
- result = usbat_write_block_test(us, USBAT_ATA,
+ result = usbat_rw_block_test(us, USBAT_ATA,
X registers, data, 19,
X 0x10, 0x17, 0xFD, 0x30,
+ SCSI_DATA_WRITE,
X srb->request_buffer,
- len, srb->use_sg);
+ len, srb->use_sg, 10);
+
+ if (result == USB_STOR_TRANSPORT_GOOD) {
+ transferred += len;
+ US_DEBUGP("Wrote %08X bytes\n", transferred);
+ }
X
X return result;
+
+ } else if (srb->cmnd[0] == READ_10 ||
+ srb->cmnd[0] == GPCMD_READ_CD) {
+
+ return usbat_handle_read10(us, registers, data, srb);
+
+ }
+
+ if (len > 0xFFFF) {
+ US_DEBUGP("Error: len = %08X... what do I do now?\n",
+ len);
+ return USB_STOR_TRANSPORT_ERROR;
X }
X
X if ( (result = usbat_multiple_write(us,
@@ -1010,8 +1012,15 @@
X
X // Write the 12-byte command header.
X
+ // If the command is BLANK then set the timer for 75 minutes.
+ // Otherwise set it for 10 minutes.
+
+ // NOTE: THE 8200 DOCUMENTATION STATES THAT BLANKING A CDRW
+ // AT SPEED 4 IS UNRELIABLE!!!
+
X if ( (result = usbat_write_block(us,
- USBAT_ATA, 0x10, srb->cmnd, 12, 0)) !=
+ USBAT_ATA, 0x10, srb->cmnd, 12, 0,
+ srb->cmnd[0]==GPCMD_BLANK ? 75 : 10)) !=
X USB_STOR_TRANSPORT_GOOD) {
X return result;
X }
@@ -1060,8 +1069,6 @@
X US_DEBUGP("%s\n", string);
X }
X }
-
- // US_DEBUGP("Command result %d\n", result);
X
X return result;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/storage/shuttle_usbat.h linux/drivers/usb/storage/shuttle_usbat.h
--- v2.4.0-test8/linux/drivers/usb/storage/shuttle_usbat.h Mon Aug 28 16:59:14 2000
+++ linux/drivers/usb/storage/shuttle_usbat.h Sun Oct 1 19:42:40 2000
@@ -1,7 +1,7 @@
X /* Driver for SCM Microsystems USB-ATAPI cable
X * Header File
X *
- * $Id: shuttle_usbat.h,v 1.4 2000/08/25 00:13:51 mdharm Exp $
+ * $Id: shuttle_usbat.h,v 1.5 2000/09/17 14:44:52 groovyjava Exp $


X *
X * Current development and maintenance by:

X * (c) 2000 Robert Baruch (auto...@dol.net)
@@ -63,7 +63,7 @@
X int use_sg);
X extern int usbat_write_block(struct us_data *us, unsigned char access,
X unsigned char reg, unsigned char *content, unsigned short len,
- int use_sg);
+ int use_sg, int minutes);
X extern int usbat_multiple_write(struct us_data *us, unsigned char access,
X unsigned char *registers, unsigned char *data_out,
X unsigned short num_registers);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/storage/transport.c linux/drivers/usb/storage/transport.c
--- v2.4.0-test8/linux/drivers/usb/storage/transport.c Mon Aug 28 16:59:14 2000
+++ linux/drivers/usb/storage/transport.c Sun Oct 1 19:42:40 2000
@@ -1,6 +1,6 @@


X /* Driver for USB Mass Storage compliant devices
X *

- * $Id: transport.c,v 1.18 2000/08/25 00:13:51 mdharm Exp $
+ * $Id: transport.c,v 1.27 2000/09/28 21:54:30 mdharm Exp $
X *


X * Current development and maintenance by:
X * (c) 1999, 2000 Matthew Dharm (mdhar...@one-eyed-alien.net)

@@ -43,6 +43,8 @@
X * with this program; if not, write to the Free Software Foundation, Inc.,
X * 675 Mass Ave, Cambridge, MA 02139, USA.
X */
+
+#include <linux/config.h>
X #include "transport.h"
X #include "protocol.h"
X #include "usb.h"
@@ -680,7 +682,7 @@
X need_auto_sense = 1;
X }
X if (result == USB_STOR_TRANSPORT_ERROR) {
- /* FIXME: we need to invoke a transport reset here */
+ us->transport_reset(us);
X US_DEBUGP("-- transport indicates transport failure\n");
X need_auto_sense = 0;
X srb->result = DID_ERROR << 16;
@@ -742,8 +744,15 @@
X /* issue the auto-sense command */
X temp_result = us->transport(us->srb, us);
X if (temp_result != USB_STOR_TRANSPORT_GOOD) {
- /* FIXME: we need to invoke a transport reset here */
X US_DEBUGP("-- auto-sense failure\n");
+
+ /* we skip the reset if this happens to be a
+ * multi-target device, since failure of an
+ * auto-sense is perfectly valid
+ */
+ if (!(us->flags & US_FL_SCM_MULT_TARG)) {
+ us->transport_reset(us);
+ }
X srb->result = DID_ERROR << 16;
X return;
X }
@@ -754,9 +763,15 @@
X srb->sense_buffer[2] & 0xf,
X srb->sense_buffer[12],
X srb->sense_buffer[13]);
+#ifdef CONFIG_USB_STORAGE_DEBUG
+ usb_stor_show_sense(
+ srb->sense_buffer[2] & 0xf,
+ srb->sense_buffer[12],
+ srb->sense_buffer[13]);
+#endif
X
X /* set the result so the higher layers expect this data */
- srb->result = CHECK_CONDITION;
+ srb->result = CHECK_CONDITION << 1;
X
X /* we're done here, let's clean up */
X srb->request_buffer = old_request_buffer;
@@ -767,15 +782,15 @@
X
X /* If things are really okay, then let's show that */
X if ((srb->sense_buffer[2] & 0xf) == 0x0)
- srb->result = GOOD;
+ srb->result = GOOD << 1;
X } else /* if (need_auto_sense) */
- srb->result = GOOD;
+ srb->result = GOOD << 1;
X
X /* Regardless of auto-sense, if we _know_ we have an error
X * condition, show that in the result code
X */
X if (result == USB_STOR_TRANSPORT_FAILED)
- srb->result = CHECK_CONDITION;
+ srb->result = CHECK_CONDITION << 1;
X
X /* If we think we're good, then make sure the sense data shows it.
X * This is necessary because the auto-sense for some devices always
@@ -822,6 +837,9 @@
X {
X int result;
X
+ /* Set up for status notification */
+ us->ip_wanted = 1;
+
X /* COMMAND STAGE */
X /* let's send the command via the control pipe */
X result = usb_stor_control_msg(us, usb_sndctrlpipe(us->pusb_dev,0),
@@ -832,6 +850,9 @@
X /* check the return code for the command */
X US_DEBUGP("Call to usb_stor_control_msg() returned %d\n", result);
X if (result < 0) {
+ /* Reset flag for status notification */
+ us->ip_wanted = 0;
+
X /* if the command was aborted, indicate that */
X if (result == -ENOENT)
X return USB_STOR_TRANSPORT_ABORTED;
@@ -850,9 +871,6 @@


X return USB_STOR_TRANSPORT_ERROR;
X }
X

- /* Set up for status notification */
- us->ip_wanted = 1;
-
X /* DATA STAGE */
X /* transfer the data payload for this command, if one exists*/
X if (us_transfer_length(srb)) {
@@ -860,8 +878,12 @@
X US_DEBUGP("CBI data stage result is 0x%x\n", srb->result);
X
X /* if it was aborted, we need to indicate that */
- if (srb->result == USB_STOR_TRANSPORT_ABORTED)
+ if (srb->result == USB_STOR_TRANSPORT_ABORTED) {
+ /* we need to reset the state of this semaphore */
+ down(&(us->ip_waitq));
+
X return USB_STOR_TRANSPORT_ABORTED;
+ }
X }
X
X /* STATUS STAGE */
@@ -1038,7 +1060,7 @@
X /* send it to out endpoint */
X US_DEBUGP("Bulk command S 0x%x T 0x%x Trg %d LUN %d L %d F %d CL %d\n",
X le32_to_cpu(bcb.Signature), bcb.Tag,
- (bcb.Lun >> 4), (bcb.Lun & 0xFF),
+ (bcb.Lun >> 4), (bcb.Lun & 0x0F),
X bcb.DataTransferLength, bcb.Flags, bcb.Length);
X result = usb_stor_bulk_msg(us, &bcb, pipe, US_BULK_CB_WRAP_LEN,
X &partial);
@@ -1137,8 +1159,9 @@
X return USB_STOR_TRANSPORT_FAILED;
X
X case US_BULK_STAT_PHASE:
- /* phase error */
- usb_stor_Bulk_reset(us);
+ /* phase error -- note that a transport reset will be
+ * invoked by the invoke_transport() function
+ */


X return USB_STOR_TRANSPORT_ERROR;
X }
X

@@ -1167,8 +1190,15 @@
X USB_TYPE_CLASS | USB_RECIP_INTERFACE,
X 0, us->ifnum, cmd, sizeof(cmd), HZ*5);
X
+ if (result < 0) {
+ US_DEBUGP("CB[I] soft reset failed %d\n", result);
+ return FAILED;
+ }
+
X /* long wait for reset */
+ set_current_state(TASK_UNINTERRUPTIBLE);
X schedule_timeout(HZ*6);
+ set_current_state(TASK_RUNNING);
X
X US_DEBUGP("CB_reset: clearing endpoint halt\n");
X clear_halt(us->pusb_dev,
@@ -1177,7 +1207,8 @@
X usb_rcvbulkpipe(us->pusb_dev, us->ep_out));
X
X US_DEBUGP("CB_reset done\n");
- return 0;
+ /* return a result code based on the result of the control message */
+ return SUCCESS;
X }
X
X /* This issues a Bulk-only Reset to the device in question, including
@@ -1195,16 +1226,20 @@
X USB_TYPE_CLASS | USB_RECIP_INTERFACE,
X 0, us->ifnum, NULL, 0, HZ*5);
X
- if (result < 0)
- US_DEBUGP("Bulk hard reset failed %d\n", result);
+ if (result < 0) {
+ US_DEBUGP("Bulk soft reset failed %d\n", result);
+ return FAILED;
+ }
+
+ /* long wait for reset */
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(HZ*6);
+ set_current_state(TASK_RUNNING);
X
X clear_halt(us->pusb_dev,
X usb_rcvbulkpipe(us->pusb_dev, us->ep_in));
X clear_halt(us->pusb_dev,
X usb_sndbulkpipe(us->pusb_dev, us->ep_out));
-
- /* long wait for reset */
- schedule_timeout(HZ*6);
-
- return result;
+ US_DEBUGP("Bulk soft reset completed\n");
+ return SUCCESS;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/storage/transport.h linux/drivers/usb/storage/transport.h
--- v2.4.0-test8/linux/drivers/usb/storage/transport.h Mon Aug 28 16:59:14 2000
+++ linux/drivers/usb/storage/transport.h Mon Oct 2 11:02:34 2000


@@ -1,7 +1,7 @@
X /* Driver for USB Mass Storage compliant devices

X * Transport Functions Header File
X *
- * $Id: transport.h,v 1.11 2000/08/25 00:13:51 mdharm Exp $
+ * $Id: transport.h,v 1.12 2000/09/08 21:20:06 mdharm Exp $
X *


X * Current development and maintenance by:
X * (c) 1999, 2000 Matthew Dharm (mdhar...@one-eyed-alien.net)

@@ -41,8 +41,8 @@
X #ifndef _TRANSPORT_H_
X #define _TRANSPORT_H_
X
-#include <linux/blk.h>
X #include <linux/config.h>
+#include <linux/blk.h>
X #include "usb.h"
X #include "scsi.h"
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/storage/usb.c linux/drivers/usb/storage/usb.c
--- v2.4.0-test8/linux/drivers/usb/storage/usb.c Tue Sep 5 12:56:51 2000
+++ linux/drivers/usb/storage/usb.c Sun Oct 1 19:42:40 2000
@@ -1,6 +1,6 @@


X /* Driver for USB Mass Storage compliant devices
X *

- * $Id: usb.c,v 1.33 2000/08/25 00:13:51 mdharm Exp $
+ * $Id: usb.c,v 1.46 2000/09/25 23:25:12 mdharm Exp $
X *


X * Current development and maintenance by:
X * (c) 1999, 2000 Matthew Dharm (mdhar...@one-eyed-alien.net)

@@ -49,6 +49,7 @@
X #include "transport.h"
X #include "protocol.h"
X #include "debug.h"
+#include "initializers.h"
X #ifdef CONFIG_USB_STORAGE_HP8200e
X #include "shuttle_usbat.h"
X #endif
@@ -94,7 +95,7 @@
X
X static void * storage_probe(struct usb_device *dev, unsigned int ifnum);
X static void storage_disconnect(struct usb_device *dev, void *ptr);
-static struct usb_driver storage_driver = {
+struct usb_driver usb_storage_driver = {
X name: "usb-storage",
X probe: storage_probe,
X disconnect: storage_disconnect,
@@ -206,7 +207,7 @@
X */
X if (us->srb->sc_data_direction == SCSI_DATA_UNKNOWN) {
X US_DEBUGP("UNKNOWN data direction\n");
- us->srb->result = DID_ERROR;
+ us->srb->result = DID_ERROR << 16;
X set_current_state(TASK_INTERRUPTIBLE);
X us->srb->scsi_done(us->srb);
X us->srb = NULL;
@@ -242,7 +243,7 @@
X /* handle those devices which can't do a START_STOP */
X if ((us->srb->cmnd[0] == START_STOP) &&
X (us->flags & US_FL_START_STOP)) {
- us->srb->result = GOOD;
+ us->srb->result = GOOD << 1;
X
X set_current_state(TASK_INTERRUPTIBLE);
X us->srb->scsi_done(us->srb);
@@ -264,12 +265,12 @@
X memcpy(us->srb->request_buffer,
X usb_stor_sense_notready,
X sizeof(usb_stor_sense_notready));
- us->srb->result = GOOD;
+ us->srb->result = GOOD << 1;
X } else {
X memcpy(us->srb->sense_buffer,
X usb_stor_sense_notready,
X sizeof(usb_stor_sense_notready));
- us->srb->result = CHECK_CONDITION;
+ us->srb->result = CHECK_CONDITION << 1;
X }
X } else { /* !us->pusb_dev */
X /* we've got a command, let's do it! */
@@ -328,46 +329,34 @@
X * restriction. However, if the flag is not present, then you
X * are free to use as many characters as you like.
X */
-
-int euscsi_init(struct us_data *us)
-{
- unsigned char bar = 0x1;
- int result;
-
- US_DEBUGP("Attempting to init eUSCSI bridge...\n");
- result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev, 0),
- 0x0C, USB_RECIP_INTERFACE | USB_TYPE_VENDOR,
- 0x01, 0x0, &bar, 0x1, 5*HZ);
- US_DEBUGP("-- result is %d\n", result);
- US_DEBUGP("-- bar afterwards is %d\n", bar);
-}
-
X static struct us_unusual_dev us_unusual_dev_list[] = {
X
+ { 0x03ee, 0x0000, 0x0000, 0x0245,
+ "Mitsumi",
+ "CD-R/RW Drive",
+ US_SC_8020, US_PR_CBI, NULL, 0},
+
X { 0x03f0, 0x0107, 0x0200, 0x0200,
X "HP",
X "CD-Writer+",
- US_SC_8070, US_PR_CB, NULL,
- 0},
+ US_SC_8070, US_PR_CB, NULL, 0},
X
X #ifdef CONFIG_USB_STORAGE_HP8200e
X { 0x03f0, 0x0207, 0x0001, 0x0001,
X "HP",
X "CD-Writer+ 8200e",
- US_SC_8070, US_PR_SCM_ATAPI, init_8200e,
- US_FL_SINGLE_LUN},
+ US_SC_8070, US_PR_SCM_ATAPI, init_8200e, 0},
X #endif
X
X { 0x04e6, 0x0001, 0x0200, 0x0200,
X "Matshita",
X "LS-120",
- US_SC_8020, US_PR_CB, NULL,
- US_FL_SINGLE_LUN},
+ US_SC_8020, US_PR_CB, NULL, 0},
X
X { 0x04e6, 0x0002, 0x0100, 0x0100,
X "Shuttle",
X "eUSCSI Bridge",
- US_SC_SCSI, US_PR_BULK, euscsi_init,
+ US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init,
X US_FL_SCM_MULT_TARG },
X
X #ifdef CONFIG_USB_STORAGE_SDDR09
@@ -392,39 +381,42 @@
X US_SC_SCSI, US_PR_CB, NULL,
X US_FL_SINGLE_LUN},
X
+ { 0x04e6, 0x0007, 0x0100, 0x0200,
+ "Sony",
+ "Hifd",
+ US_SC_SCSI, US_PR_CB, NULL,
+ US_FL_SINGLE_LUN},
+
X { 0x04e6, 0x0009, 0x0200, 0x0200,
X "Shuttle",
- "ATA/ATAPI Bridge",
- US_SC_8020, US_PR_CB, NULL,
- US_FL_SINGLE_LUN},
+ "eUSB ATA/ATAPI Adapter",
+ US_SC_8020, US_PR_CB, NULL, 0},
X
- { 0x04e6, 0x000A, 0x0200, 0x0200,
+ { 0x04e6, 0x000a, 0x0200, 0x0200,
X "Shuttle",
- "Compact Flash Reader",
- US_SC_8020, US_PR_CB, NULL,
- US_FL_SINGLE_LUN},
+ "eUSB CompactFlash Adapter",
+ US_SC_8020, US_PR_CB, NULL, 0},
X
X { 0x04e6, 0x000B, 0x0100, 0x0100,
X "Shuttle",
X "eUSCSI Bridge",
- US_SC_SCSI, US_PR_BULK, euscsi_init,
+ US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init,
X US_FL_SCM_MULT_TARG },
X
X { 0x04e6, 0x000C, 0x0100, 0x0100,
X "Shuttle",
X "eUSCSI Bridge",
- US_SC_SCSI, US_PR_BULK, euscsi_init,
+ US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init,
X US_FL_SCM_MULT_TARG },
X
X { 0x04e6, 0x0101, 0x0200, 0x0200,
X "Shuttle",
X "CD-RW Device",
- US_SC_8020, US_PR_CB, NULL,
- US_FL_SINGLE_LUN},
+ US_SC_8020, US_PR_CB, NULL, 0},
X
- { 0x054c, 0x0010, 0x0210, 0x0210,
+ { 0x054c, 0x0010, 0x0106, 0x0210,
X "Sony",
- "DSC-S30/S70",
+ "DSC-S30/S70/505V/F505",
X US_SC_SCSI, US_PR_CB, NULL,
X US_FL_SINGLE_LUN | US_FL_START_STOP | US_FL_MODE_XLATE },
X
@@ -449,26 +441,35 @@
X { 0x059f, 0xa601, 0x0200, 0x0200,
X "LaCie",
X "USB Hard Disk",
- US_SC_RBC, US_PR_CB, NULL,
- 0 },
+ US_SC_RBC, US_PR_CB, NULL, 0 },
X
X { 0x05ab, 0x0031, 0x0100, 0x0100,
X "In-System",
- "USB/IDE Bridge",
- US_SC_8070, US_PR_BULK, NULL,
- 0 },
+ "USB/IDE Bridge (ATAPI ONLY!)",
+ US_SC_8070, US_PR_BULK, NULL, 0 },
X
- { 0x0693, 0x0005, 0x0100, 0x0100,
- "Hagiwara",
- "Flashgate",
- US_SC_SCSI, US_PR_BULK, NULL,
- 0 },
+ { 0x0644, 0x0000, 0x0100, 0x0100,
+ "TEAC",
+ "Floppy Drive",
+ US_SC_UFI, US_PR_CB, NULL, 0 },
+
+#ifdef CONFIG_USB_STORAGE_SDDR09
+ { 0x066b, 0x0105, 0x0100, 0x0100,
+ "Olympus",
+ "Camedia MAUSB-2",
+ US_SC_SCSI, US_PR_EUSB_SDDR09, NULL,
+ US_FL_SINGLE_LUN | US_FL_START_STOP },
+#endif
X
X { 0x0693, 0x0002, 0x0100, 0x0100,
X "Hagiwara",
X "FlashGate SmartMedia",
- US_SC_SCSI, US_PR_BULK, NULL,
- 0 },
+ US_SC_SCSI, US_PR_BULK, NULL, 0 },
+
+ { 0x0693, 0x0005, 0x0100, 0x0100,
+ "Hagiwara",
+ "Flashgate",
+ US_SC_SCSI, US_PR_BULK, NULL, 0 },
X
X { 0x0781, 0x0001, 0x0200, 0x0200,
X "Sandisk",
@@ -493,20 +494,20 @@
X { 0x07af, 0x0004, 0x0100, 0x0100,
X "Microtech",
X "USB-SCSI-DB25",
- US_SC_SCSI, US_PR_BULK, euscsi_init,
+ US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init,
X US_FL_SCM_MULT_TARG },
X
X #ifdef CONFIG_USB_STORAGE_FREECOM
X { 0x07ab, 0xfc01, 0x0921, 0x0921,
X "Freecom",
X "USB-IDE",
- US_SC_8070, US_PR_FREECOM, NULL, US_FL_SINGLE_LUN },
+ US_SC_QIC, US_PR_FREECOM, freecom_init, 0},
X #endif
X
X { 0x07af, 0x0005, 0x0100, 0x0100,
X "Microtech",
X "USB-SCSI-HD50",
- US_SC_SCSI, US_PR_BULK, euscsi_init,
+ US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init,
X US_FL_SCM_MULT_TARG },
X
X #ifdef CONFIG_USB_STORAGE_DPCM
@@ -613,7 +614,9 @@
X unsigned int flags;
X struct us_unusual_dev *unusual_dev;
X struct us_data *ss = NULL;
+#ifdef CONFIG_USB_STORAGE_SDDR09
X int result;
+#endif
X
X /* these are temporary copies -- we test on these, then put them
X * in the us-data structure
@@ -716,6 +719,7 @@
X }
X
X /* At this point, we're committed to using the device */
+ usb_inc_dev_use(dev);
X
X /* clear the GUID and fetch the strings */
X GUID_CLEAR(guid);
@@ -740,9 +744,6 @@
X dev->descriptor.idProduct, "0");
X }
X
- /* lock access to the data structures */
- down(&us_list_semaphore);
-
X /*
X * Now check if we have seen this GUID before
X * We're looking for a device with a matching GUID that isn't
@@ -775,8 +776,14 @@
X if ((ss->protocol == US_PR_CBI) && usb_stor_allocate_irq(ss))
X return NULL;
X
- /* Re-Initialize the device if it needs it */
+ /* allocate the URB we're going to use */
+ ss->current_urb = usb_alloc_urb(0);
+ if (!ss->current_urb) {
+ kfree(ss);
+ return NULL;
+ }
X
+ /* Re-Initialize the device if it needs it */
X if (unusual_dev && unusual_dev->initFunction)
X (unusual_dev->initFunction)(ss);
X
@@ -787,7 +794,6 @@
X if ((ss = (struct us_data *)kmalloc(sizeof(struct us_data),
X GFP_KERNEL)) == NULL) {
X printk(KERN_WARNING USB_STORAGE "Out of memory\n");
- up(&us_list_semaphore);
X return NULL;
X }
X memset(ss, 0, sizeof(struct us_data));
@@ -892,7 +898,7 @@
X ss->transport_name = "EUSB/SDDR09";
X ss->transport = sddr09_transport;
X ss->transport_reset = usb_stor_CB_reset;
- ss->max_lun = 1;
+ ss->max_lun = 0;
X break;
X #endif
X
@@ -916,7 +922,6 @@
X
X default:
X ss->transport_name = "Unknown";
- up(&us_list_semaphore);
X kfree(ss->current_urb);
X kfree(ss);
X return NULL;
@@ -937,16 +942,19 @@
X case US_SC_8020:
X ss->protocol_name = "8020i";
X ss->proto_handler = usb_stor_ATAPI_command;
+ ss->max_lun = 0;
X break;
X
X case US_SC_QIC:
X ss->protocol_name = "QIC-157";
X ss->proto_handler = usb_stor_qic157_command;
+ ss->max_lun = 0;
X break;
X
X case US_SC_8070:
X ss->protocol_name = "8070i";
X ss->proto_handler = usb_stor_ATAPI_command;
+ ss->max_lun = 0;
X break;
X
X case US_SC_SCSI:
@@ -961,7 +969,6 @@
X
X default:
X ss->protocol_name = "Unknown";
- up(&us_list_semaphore);
X kfree(ss->current_urb);
X kfree(ss);
X return NULL;
@@ -994,7 +1001,7 @@
X /* Just before we start our control thread, initialize
X * the device if it needs initialization */
X if (unusual_dev && unusual_dev->initFunction)
- (unusual_dev->initFunction)(ss);
+ unusual_dev->initFunction(ss);
X
X /* start up our control thread */
X ss->pid = kernel_thread(usb_stor_control_thread, ss,
@@ -1014,13 +1021,16 @@
X ss->htmplt.module = THIS_MODULE;
X scsi_register_module(MODULE_SCSI_HA, &(ss->htmplt));
X
+ /* lock access to the data structures */
+ down(&us_list_semaphore);
+
X /* put us in the list */
X ss->next = us_list;
X us_list = ss;
- }
X
- /* release the data structure lock */
- up(&us_list_semaphore);
+ /* release the data structure lock */
+ up(&us_list_semaphore);
+ }
X
X printk(KERN_DEBUG
X "WARNING: USB Mass Storage data integrity not assured\n");
@@ -1051,18 +1061,26 @@
X /* release the IRQ, if we have one */
X down(&(ss->irq_urb_sem));
X if (ss->irq_urb) {
- US_DEBUGP("-- releasing irq handle\n");
+ US_DEBUGP("-- releasing irq URB\n");
X result = usb_unlink_urb(ss->irq_urb);
- ss->irq_urb = NULL;
X US_DEBUGP("-- usb_unlink_urb() returned %d\n", result);
X usb_free_urb(ss->irq_urb);
+ ss->irq_urb = NULL;
X }
X up(&(ss->irq_urb_sem));
X
+ /* free up the main URB for this device */
+ US_DEBUGP("-- releasing main URB\n");
+ result = usb_unlink_urb(ss->current_urb);
+ US_DEBUGP("-- usb_unlink_urb() returned %d\n", result);
+ usb_free_urb(ss->current_urb);
+ ss->current_urb = NULL;
+
X /* mark the device as gone */
+ usb_dec_dev_use(ss->pusb_dev);
X ss->pusb_dev = NULL;
X
- /* lock access to the device data structure */
+ /* unlock access to the device data structure */
X up(&(ss->dev_semaphore));
X }
X
@@ -1078,7 +1096,7 @@
X my_host_number = 0;
X
X /* register the driver, return -1 if error */
- if (usb_register(&storage_driver) < 0)
+ if (usb_register(&usb_storage_driver) < 0)
X return -1;
X
X /* we're all set */
@@ -1096,46 +1114,47 @@
X * This eliminates races with probes and disconnects
X */
X US_DEBUGP("-- calling usb_deregister()\n");
- usb_deregister(&storage_driver) ;
+ usb_deregister(&usb_storage_driver) ;
X
- /* lock access to the data structures */
- down(&us_list_semaphore);
-
X /* While there are still virtual hosts, unregister them
- *
- * Note that the us_release() routine will destroy the local data
- * structure. So we have to peel these off the top of the list
- * and keep updating the head pointer as we go.
+ * Note that it's important to do this completely before removing
+ * the structures because of possible races with the /proc
+ * interface
+ */
+ for (next = us_list; next; next = next->next) {
+ US_DEBUGP("-- calling scsi_unregister_module()\n");
+ scsi_unregister_module(MODULE_SCSI_HA, &(next->htmplt));
+ }
+
+ /* While there are still structures, free them. Note that we are
+ * now race-free, since these structures can no longer be accessed
+ * from either the SCSI command layer or the /proc interface
X */
X while (us_list) {
X /* keep track of where the next one is */
X next = us_list->next;
X
- US_DEBUGP("-- calling scsi_unregister_module()\n");
- scsi_unregister_module(MODULE_SCSI_HA, &(us_list->htmplt));
-
- /* Now that scsi_unregister_module is done with the host
- * template, we can free the us_data structure (the host
- * template is inline in this structure). */
-
X /* If there's extra data in the us_data structure then
X * free that first */
-
X if (us_list->extra) {
- if (us_list->extra_destructor)
- (*us_list->extra_destructor)(
- us_list->extra);
+ /* call the destructor routine, if it exists */
+ if (us_list->extra_destructor) {
+ US_DEBUGP("-- calling extra_destructor()\n");
+ us_list->extra_destructor(us_list->extra);
+ }
+
+ /* destroy the extra data */
+ US_DEBUGP("-- freeing the data structure\n");
X kfree(us_list->extra);
X }
+
+ /* free the structure itself */
X kfree (us_list);
X
X /* advance the list pointer */
X us_list = next;
X }
-
- /* unlock the data structures */
- up(&us_list_semaphore);
X }
X
-module_init(usb_stor_init) ;
-module_exit(usb_stor_exit) ;
+module_init(usb_stor_init);
+module_exit(usb_stor_exit);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/storage/usb.h linux/drivers/usb/storage/usb.h
--- v2.4.0-test8/linux/drivers/usb/storage/usb.h Mon Aug 28 16:59:14 2000
+++ linux/drivers/usb/storage/usb.h Mon Oct 2 11:02:34 2000


@@ -1,7 +1,7 @@
X /* Driver for USB Mass Storage compliant devices

X * Main Header File
X *
- * $Id: usb.h,v 1.8 2000/08/25 00:13:51 mdharm Exp $
+ * $Id: usb.h,v 1.9 2000/09/25 23:25:12 mdharm Exp $
X *


X * Current development and maintenance by:
X * (c) 1999, 2000 Matthew Dharm (mdhar...@one-eyed-alien.net)

@@ -112,6 +112,7 @@
X typedef int (*trans_cmnd)(Scsi_Cmnd*, struct us_data*);
X typedef int (*trans_reset)(struct us_data*);
X typedef void (*proto_cmnd)(Scsi_Cmnd*, struct us_data*);
+typedef void (*extra_data_destructor)(void *); /* extra data destructor */
X
X /* we allocate one of these for every device that we remember */
X struct us_data {
@@ -178,16 +179,17 @@
X struct semaphore queue_exclusion; /* to protect data structs */
X struct us_unusual_dev *unusual_dev; /* If unusual device */
X void *extra; /* Any extra data */
- void (*extra_destructor)(void *); /* extra data destructor */
+ extra_data_destructor extra_destructor;/* extra data destructor */
X };
X
X /* The list of structures and the protective lock for them */
X extern struct us_data *us_list;
X extern struct semaphore us_list_semaphore;
X
-/* Function to fill an inquiry response. See usb.c for details */
+/* The structure which defines our driver */
+struct usb_driver usb_storage_driver;
X
+/* Function to fill an inquiry response. See usb.c for details */
X extern void fill_inquiry_response(struct us_data *us,
X unsigned char *data, unsigned int data_len);
-
X #endif
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/uhci.c linux/drivers/usb/uhci.c
--- v2.4.0-test8/linux/drivers/usb/uhci.c Thu Sep 7 08:39:00 2000
+++ linux/drivers/usb/uhci.c Tue Sep 19 17:47:06 2000
@@ -493,8 +493,6 @@
X
X urb->hcpriv = urbp;
X
- usb_inc_dev_use(urb->dev);
-
X return urbp;
X }
X
@@ -556,8 +554,6 @@
X urb->hcpriv = NULL;
X kmem_cache_free(uhci_up_cachep, urbp);
X
- usb_dec_dev_use(urb->dev);
-
X unlock:
X spin_unlock_irqrestore(&urb->lock, flags);


X }
@@ -572,7 +568,7 @@
X

X spin_lock_irqsave(&uhci->framelist_lock, flags);
X
- if (!urbp->fsbr) {
+ if ((!(urb->transfer_flags & USB_NO_FSBR)) && (!urbp->fsbr)) {
X urbp->fsbr = 1;
X if (!uhci->fsbr++)
X uhci->skel_term_qh.link = virt_to_bus(&uhci->skel_hs_control_qh) | UHCI_PTR_QH;
@@ -591,7 +587,7 @@
X
X spin_lock_irqsave(&uhci->framelist_lock, flags);
X
- if (urbp->fsbr) {
+ if ((!(urb->transfer_flags & USB_NO_FSBR)) && urbp->fsbr) {
X urbp->fsbr = 0;
X if (!--uhci->fsbr)
X uhci->skel_term_qh.link = UHCI_PTR_TERM;
@@ -739,8 +735,6 @@
X
X uhci_add_urb_list(uhci, urb);
X
- usb_inc_dev_use(urb->dev);
-
X return -EINPROGRESS;
X }
X
@@ -1316,10 +1310,13 @@
X if (u && !(urb->transfer_flags & USB_QUEUE_BULK))
X return -ENXIO;
X
+ usb_inc_dev_use(urb->dev);
X spin_lock_irqsave(&urb->lock, flags);
X
X if (!uhci_alloc_urb_priv(urb)) {
X spin_unlock_irqrestore(&urb->lock, flags);
+ usb_dec_dev_use(urb->dev);
+


X return -ENOMEM;
X }
X

@@ -1329,17 +1326,16 @@
X break;
X case PIPE_INTERRUPT:
X if (urb->bandwidth == 0) { /* not yet checked/allocated */
- bustime = usb_check_bandwidth (urb->dev, urb);
+ bustime = usb_check_bandwidth(urb->dev, urb);
X if (bustime < 0)
X ret = bustime;
X else {
X ret = uhci_submit_interrupt(urb);
X if (ret == -EINPROGRESS)
- usb_claim_bandwidth (urb->dev, urb, bustime, 0);
+ usb_claim_bandwidth(urb->dev, urb, bustime, 0);
X }
- } else { /* bandwidth is already set */
+ } else /* bandwidth is already set */
X ret = uhci_submit_interrupt(urb);
- }
X break;
X case PIPE_BULK:
X ret = uhci_submit_bulk(urb, u);
@@ -1350,7 +1346,7 @@
X ret = -EINVAL;
X break;
X }
- bustime = usb_check_bandwidth (urb->dev, urb);
+ bustime = usb_check_bandwidth(urb->dev, urb);
X if (bustime < 0) {
X ret = bustime;
X break;
@@ -1358,10 +1354,9 @@
X
X ret = uhci_submit_isochronous(urb);
X if (ret == -EINPROGRESS)
- usb_claim_bandwidth (urb->dev, urb, bustime, 1);
- } else { /* bandwidth is already set */
+ usb_claim_bandwidth(urb->dev, urb, bustime, 1);
+ } else /* bandwidth is already set */
X ret = uhci_submit_isochronous(urb);
- }
X break;
X }
X
@@ -1371,8 +1366,10 @@
X
X if (ret == -EINPROGRESS)
X ret = 0;
- else
+ else {
X uhci_unlink_generic(urb);
+ usb_dec_dev_use(urb->dev);
+ }
X
X return ret;
X }
@@ -1384,6 +1381,7 @@
X */
X static void uhci_transfer_result(struct urb *urb)
X {
+ struct usb_device *dev = urb->dev;
X struct urb *turb;
X int proceed = 0, is_ring = 0;
X int ret = -EINVAL;
@@ -1420,22 +1418,23 @@
X /* Release bandwidth for Interrupt or Isoc. transfers */
X /* Spinlock needed ? */
X if (urb->bandwidth)
- usb_release_bandwidth (urb->dev, urb, 1);
+ usb_release_bandwidth(urb->dev, urb, 1);
X uhci_unlink_generic(urb);
X break;
X case PIPE_INTERRUPT:
X /* Interrupts are an exception */
- urb->complete(urb);
- if (urb->interval)
+ if (urb->interval) {
+ urb->complete(urb);
X uhci_reset_interrupt(urb);
- else {
- /* Release bandwidth for Interrupt or Isoc. transfers */
- /* Spinlock needed ? */
- if (urb->bandwidth)
- usb_release_bandwidth (urb->dev, urb, 0);
- uhci_unlink_generic(urb);
+ return;
X }
- return; /* <-- Note the return */
+
+ /* Release bandwidth for Interrupt or Isoc. transfers */
+ /* Spinlock needed ? */
+ if (urb->bandwidth)
+ usb_release_bandwidth(urb->dev, urb, 0);
+ uhci_unlink_generic(urb);
+ break;
X }
X
X if (urb->next) {
@@ -1453,7 +1452,7 @@
X is_ring = 1;
X }
X
- if (urb->complete && (!proceed || (urb->transfer_flags & USB_URB_EARLY_COMPLETE))) {
+ if (urb->complete && !proceed) {
X urb->complete(urb);
X if (!proceed && is_ring)
X uhci_submit_urb(urb);
@@ -1468,9 +1467,12 @@
X turb = turb->next;
X } while (turb && turb != urb->next);
X
- if (urb->complete && !(urb->transfer_flags & USB_URB_EARLY_COMPLETE))
+ if (urb->complete)
X urb->complete(urb);
X }
+
+ /* We decrement the usage count after we're done with everything */
+ usb_dec_dev_use(dev);
X }
X
X static int uhci_unlink_generic(struct urb *urb)


@@ -1494,6 +1496,8 @@
X

X uhci_destroy_urb_priv(urb);
X
+ urb->dev = NULL;
+


X return 0;
X }
X

@@ -1520,10 +1524,10 @@
X if (urb->bandwidth) {
X switch (usb_pipetype(urb->pipe)) {
X case PIPE_INTERRUPT:
- usb_release_bandwidth (urb->dev, urb, 0);
+ usb_release_bandwidth(urb->dev, urb, 0);
X break;
X case PIPE_ISOCHRONOUS:
- usb_release_bandwidth (urb->dev, urb, 1);
+ usb_release_bandwidth(urb->dev, urb, 1);
X break;
X default:
X break;


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 095'
echo 'File patch-2.4.0-test9 is continued in part 096'
echo "096" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part096

#!/bin/sh -x
# this is part 096 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 096; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/usb-core.c linux/drivers/usb/usb-core.c
--- v2.4.0-test8/linux/drivers/usb/usb-core.c Thu Sep 7 08:39:00 2000
+++ linux/drivers/usb/usb-core.c Mon Sep 18 15:23:30 2000
@@ -12,7 +12,6 @@
X
X #include <linux/version.h>
X #include <linux/kernel.h>


-#include <linux/config.h>
X #include <linux/init.h>

X #include <linux/usb.h>
X
@@ -25,13 +24,6 @@
X int usb_major_init(void);
X void usb_major_cleanup(void);
X
-
-/*
- * HCI drivers
- */
-
-int uhci_init(void);
-int ohci_hcd_init(void);
X
X /*
X * Cleanup
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/usb-ohci.c linux/drivers/usb/usb-ohci.c
--- v2.4.0-test8/linux/drivers/usb/usb-ohci.c Thu Sep 7 08:39:00 2000
+++ linux/drivers/usb/usb-ohci.c Tue Oct 3 09:24:40 2000
@@ -2,6 +2,7 @@
X * URB OHCI HCD (Host Controller Driver) for USB.
X *
X * (C) Copyright 1999 Roman Weissgaerber <wei...@vienna.at>
+ * (C) Copyright 2000 David Brownell <dav...@pacbell.net>
X *
X * [ Initialisation is based on Linus' ]
X * [ uhci code and gregs ohci fragments ]
@@ -11,6 +12,14 @@
X *
X * History:
X *
+ * 2000/09/26 fixed races in removing the private portion of the urb
+ * 2000/09/07 disable bulk and control lists when unlinking the last
+ * endpoint descriptor in order to avoid unrecoverable errors on
+ * the Lucent chips.
+ * 2000/08/29 use bandwidth claiming hooks (thanks Randy!), fix some
+ * urb unlink probs, indentation fixes
+ * 2000/08/11 various oops fixes mostly affecting iso and cleanup from
+ * device unplugs.
X * 2000/06/28 use PCI hotplug framework, for better power management
X * and for Cardbus support (David Brownell)
X * 2000/earlier: fixes for NEC/Lucent chips; suspend/resume handling
@@ -73,8 +82,9 @@
X
X /* For initializing controller (mask in an HCFS mode too) */
X #define OHCI_CONTROL_INIT \
- (OHCI_CTRL_CBSR & 0x3) \
- | OHCI_CTRL_BLE | OHCI_CTRL_CLE | OHCI_CTRL_IE | OHCI_CTRL_PLE
+ (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
+
+#define OHCI_UNLINK_TIMEOUT (HZ / 10)
X
X static LIST_HEAD (ohci_hcd_list);
X static spinlock_t usb_ed_lock = SPIN_LOCK_UNLOCKED;
@@ -83,23 +93,55 @@
X * URB support functions
X *-------------------------------------------------------------------------*/
X
-/* free the private part of an URB */
-
-static void urb_rm_priv (urb_t * urb)
+/* free HCD-private data associated with this URB */
+
+static void urb_free_priv (urb_priv_t * urb_priv)
X {
- urb_priv_t * urb_priv = urb->hcpriv;
X int i;
-
- if (!urb_priv) return;
-
+
X for (i = 0; i < urb_priv->length; i++) {
X if (urb_priv->td [i]) {
X OHCI_FREE (urb_priv->td [i]);
X }
X }
- kfree (urb->hcpriv);
- urb->hcpriv = NULL;
X
+ kfree (urb_priv);
+}
+
+static void urb_rm_priv_locked (urb_t * urb)
+{
+ urb_priv_t * urb_priv = urb->hcpriv;
+
+ if (urb_priv) {
+ urb->hcpriv = NULL;
+
+ /* Release int/iso bandwidth */
+ if (urb->bandwidth) {
+ switch (usb_pipetype(urb->pipe)) {
+ case PIPE_INTERRUPT:
+ usb_release_bandwidth (urb->dev, urb, 0);
+ break;
+ case PIPE_ISOCHRONOUS:
+ usb_release_bandwidth (urb->dev, urb, 1);
+ break;
+ default:


+ break;
+ }
+ }
+

+ urb_free_priv (urb_priv);
+ usb_dec_dev_use (urb->dev);


+ urb->dev = NULL;
+ }

+}
+
+static void urb_rm_priv (urb_t * urb)


+{
+ unsigned long flags;
+

+ spin_lock_irqsave (&usb_ed_lock, flags);
+ urb_rm_priv_locked (urb);
+ spin_unlock_irqrestore (&usb_ed_lock, flags);
X }
X
X /*-------------------------------------------------------------------------*/
@@ -347,15 +389,15 @@
X unsigned long flags;
X int i;
X
+ if (!urb_priv)
+ return -1; /* urb already unlinked */
+
X /* just to be sure */
X if (!urb->complete) {
X urb_rm_priv (urb);
- usb_dec_dev_use (urb->dev);


X return -1;
X }
X

- if (!urb_priv) return -1; /* urb already unlinked */
-
X #ifdef DEBUG
X urb_print (urb, "RET", usb_pipeout (urb->pipe));
X #endif
@@ -389,7 +431,6 @@
X
X } else { /* unlink URB, call complete */
X urb_rm_priv (urb);
- usb_dec_dev_use (urb->dev);
X urb->complete (urb);
X }
X break;
@@ -397,7 +438,6 @@
X case PIPE_BULK:
X case PIPE_CONTROL: /* unlink URB, call complete */
X urb_rm_priv (urb);
- usb_dec_dev_use (urb->dev);
X urb->complete (urb);
X break;
X }
@@ -416,9 +456,10 @@
X unsigned int pipe = urb->pipe;
X int i, size = 0;
X unsigned long flags;
+ int bustime = 0;
X
X if (!urb->dev || !urb->dev->bus)
- return -EINVAL;
+ return -ENODEV;
X
X if (urb->hcpriv) /* urb already in use */
X return -EINVAL;
@@ -433,7 +474,7 @@
X urb_print (urb, "SUB", usb_pipein (pipe));
X #endif
X
- /* a request to the virtual root hub */
+ /* handle a request to the virtual root hub */
X if (usb_pipedevice (pipe) == ohci->rh.devnum)
X return rh_submit_urb (urb);
X
@@ -457,6 +498,10 @@
X break;
X case PIPE_ISOCHRONOUS: /* number of packets from URB */
X size = urb->number_of_packets;
+ if (size <= 0) {
+ usb_dec_dev_use (urb->dev);
+ return -EINVAL;
+ }
X for (i = 0; i < urb->number_of_packets; i++) {
X urb->iso_frame_desc[i].actual_length = 0;
X urb->iso_frame_desc[i].status = -EXDEV;
@@ -468,11 +513,10 @@
X break;
X case PIPE_INTERRUPT: /* one TD */
X size = 1;


-
X break;
X }
X

- /* allocate the private part or the URB */
+ /* allocate the private part of the URB */
X urb_priv = kmalloc (sizeof (urb_priv_t) + size * sizeof (td_t *),
X in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
X if (!urb_priv) {
@@ -482,43 +526,59 @@
X memset (urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (td_t *));
X
X /* fill the private part of the URB */
- urb->hcpriv = urb_priv;
X urb_priv->length = size;
- urb_priv->td_cnt = 0;
- urb_priv->state = 0;
X urb_priv->ed = ed;
-
+
X /* allocate the TDs */
X for (i = 0; i < size; i++) {
X OHCI_ALLOC (urb_priv->td[i], sizeof (td_t));
X if (!urb_priv->td[i]) {
+ urb_free_priv (urb_priv);
X usb_dec_dev_use (urb->dev);
- urb_rm_priv (urb);


X return -ENOMEM;
X }
X }

- spin_lock_irqsave (&usb_ed_lock, flags);
+
X if (ed->state == ED_NEW || (ed->state & ED_DEL)) {
- urb_rm_priv(urb);
+ urb_free_priv (urb_priv);
X usb_dec_dev_use (urb->dev);
- spin_unlock_irqrestore(&usb_ed_lock, flags);


X return -EINVAL;
X }
X

- /* for ISOC transfers calculate start frame index */
- if (urb->transfer_flags & USB_ISO_ASAP) {
- urb->start_frame = ((ed->state == ED_OPER)? (ed->last_iso + 1):
- (le16_to_cpu (ohci->hcca.frame_no) + 10)) & 0xffff;
- }
- urb->status = USB_ST_URB_PENDING;
+ /* allocate and claim bandwidth if needed; ISO
+ * needs start frame index if it was't provided.
+ */
+ switch (usb_pipetype (pipe)) {
+ case PIPE_ISOCHRONOUS:
+ if (urb->transfer_flags & USB_ISO_ASAP) {
+ urb->start_frame = ((ed->state == ED_OPER)
+ ? (ed->last_iso + 1)
+ : (le16_to_cpu (ohci->hcca.frame_no) + 10)) & 0xffff;
+ }
+ /* FALLTHROUGH */
+ case PIPE_INTERRUPT:
+ if (urb->bandwidth == 0) {
+ bustime = usb_check_bandwidth (urb->dev, urb);
+ }
+ if (bustime < 0) {
+ urb_free_priv (urb_priv);
+ usb_dec_dev_use (urb->dev);
+ return bustime;
+ }
+ usb_claim_bandwidth (urb->dev, urb, bustime, usb_pipeisoc (urb->pipe));
+ }
+
+ spin_lock_irqsave (&usb_ed_lock, flags);
X urb->actual_length = 0;
-
- if (ed->state != ED_OPER) /* link the ed into a chain if is not already */
+ urb->hcpriv = urb_priv;
+ urb->status = USB_ST_URB_PENDING;
+
+ /* link the ed into a chain if is not already */
+ if (ed->state != ED_OPER)
X ep_link (ohci, ed);
-
- urb->status = USB_ST_URB_PENDING;
- td_submit_urb (urb); /* fill the TDs and link it to the ed */
X
+ /* fill the TDs and link it to the ed */
+ td_submit_urb (urb);
X spin_unlock_irqrestore (&usb_ed_lock, flags);
X
X return 0;
@@ -528,7 +588,7 @@
X
X /* deactivate all TDs and remove the private part of the URB */
X /* interrupt callers must use async unlink mode */
-
+
X static int sohci_unlink_urb (urb_t * urb)


X {
X unsigned long flags;

@@ -545,16 +605,14 @@
X #ifdef DEBUG
X urb_print (urb, "UNLINK", 1);
X #endif
-
- if (usb_pipedevice (urb->pipe) == ohci->rh.devnum) {
- usb_dec_dev_use(urb->dev);
- return rh_unlink_urb (urb); /* a request to the virtual root hub */
- }
X
- if (urb->hcpriv) {
- /* URB active? */
- if (urb->status == USB_ST_URB_PENDING && !ohci->disabled) {
- urb_priv_t * urb_priv = urb->hcpriv;
+ /* handle a request to the virtual root hub */
+ if (usb_pipedevice (urb->pipe) == ohci->rh.devnum)
+ return rh_unlink_urb (urb);
+
+ if (urb->hcpriv && (urb->status == USB_ST_URB_PENDING)) {
+ if (!ohci->disabled) {
+ urb_priv_t * urb_priv;
X
X /* interrupt code may not sleep; it must use
X * async status return to unlink pending urbs.
@@ -566,40 +624,50 @@
X return -EWOULDBLOCK;
X }
X
-
X /* flag the urb and its TDs for deletion in some
X * upcoming SF interrupt delete list processing
X */
- urb_priv->state = URB_DEL;
-
X spin_lock_irqsave (&usb_ed_lock, flags);
+ urb_priv = urb->hcpriv;
+
+ if (!urb_priv || (urb_priv->state == URB_DEL)) {
+ spin_unlock_irqrestore (&usb_ed_lock, flags);


+ return 0;
+ }
+

+ urb_priv->state = URB_DEL;
X ep_rm_ed (urb->dev, urb_priv->ed);
X urb_priv->ed->state |= ED_URB_DEL;
- spin_unlock_irqrestore (&usb_ed_lock, flags);
X
X if (!(urb->transfer_flags & USB_ASYNC_UNLINK)) {
X DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup);
X DECLARE_WAITQUEUE (wait, current);
+ int timeout = OHCI_UNLINK_TIMEOUT;
X
- usb_dec_dev_use (urb->dev);
- /* wait until all TDs are deleted */
X add_wait_queue (&unlink_wakeup, &wait);
X urb_priv->wait = &unlink_wakeup;
- current->state = TASK_UNINTERRUPTIBLE;
- schedule ();
+ spin_unlock_irqrestore (&usb_ed_lock, flags);
+
+ /* wait until all TDs are deleted */
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ while (timeout && (urb->status == USB_ST_URB_PENDING))
+ timeout = schedule_timeout (timeout);
X remove_wait_queue (&unlink_wakeup, &wait);
- urb->status = -ENOENT;
- urb_priv->wait = 0;
+ if (urb->status == USB_ST_URB_PENDING) {
+ err ("unlink URB timeout");
+ return -ETIMEDOUT;
+ }
X } else {
X /* usb_dec_dev_use done in dl_del_list() */
X urb->status = -EINPROGRESS;
+ spin_unlock_irqrestore (&usb_ed_lock, flags);
X }
X } else {
- usb_dec_dev_use (urb->dev);
X urb_rm_priv (urb);
- if (urb->complete && (urb->transfer_flags & USB_ASYNC_UNLINK)) {
- urb->complete (urb);
- urb->status = 0;
+ if (urb->transfer_flags & USB_ASYNC_UNLINK) {
+ urb->status = -ECONNRESET;
+ if (urb->complete)
+ urb->complete (urb);
X } else
X urb->status = -ENOENT;
X }
@@ -683,14 +751,19 @@
X } else if (!in_interrupt ()) {
X DECLARE_WAIT_QUEUE_HEAD (freedev_wakeup);
X DECLARE_WAITQUEUE (wait, current);
+ int timeout = OHCI_UNLINK_TIMEOUT;
X
X /* SF interrupt handler calls dl_del_list */
X add_wait_queue (&freedev_wakeup, &wait);
X dev->wait = &freedev_wakeup;
- current->state = TASK_UNINTERRUPTIBLE;
- schedule ();
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ while (timeout && dev->ed_cnt)
+ timeout = schedule_timeout (timeout);
X remove_wait_queue (&freedev_wakeup, &wait);
-
+ if (dev->ed_cnt) {
+ err ("free device %d timeout", usb_dev->devnum);
+ return -ETIMEDOUT;
+ }
X } else {
X /* likely some interface's driver has a refcount bug */
X err ("bus %s devnum %d deletion in interrupt",
@@ -790,7 +863,7 @@
X ed->state = ED_OPER;
X
X switch (ed->type) {
- case CTRL:
+ case PIPE_CONTROL:
X ed->hwNextED = 0;
X if (ohci->ed_controltail == NULL) {
X writel (virt_to_bus (ed), &ohci->regs->ed_controlhead);
@@ -798,10 +871,15 @@
X ohci->ed_controltail->hwNextED = cpu_to_le32 (virt_to_bus (ed));
X }
X ed->ed_prev = ohci->ed_controltail;
+ if (!ohci->ed_controltail && !ohci->ed_rm_list[0] &&
+ !ohci->ed_rm_list[1]) {
+ ohci->hc_control |= OHCI_CTRL_CLE;
+ writel (ohci->hc_control, &ohci->regs->control);
+ }
X ohci->ed_controltail = edi;
X break;
X
- case BULK:
+ case PIPE_BULK:
X ed->hwNextED = 0;
X if (ohci->ed_bulktail == NULL) {
X writel (virt_to_bus (ed), &ohci->regs->ed_bulkhead);
@@ -809,10 +887,15 @@
X ohci->ed_bulktail->hwNextED = cpu_to_le32 (virt_to_bus (ed));
X }
X ed->ed_prev = ohci->ed_bulktail;
+ if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] &&
+ !ohci->ed_rm_list[1]) {
+ ohci->hc_control |= OHCI_CTRL_BLE;
+ writel (ohci->hc_control, &ohci->regs->control);
+ }
X ohci->ed_bulktail = edi;
X break;
X
- case INT:
+ case PIPE_INTERRUPT:
X load = ed->int_load;
X interval = ep_2_n_interval (ed->int_period);
X ed->int_interval = interval;
@@ -833,7 +916,7 @@
X #endif
X break;
X
- case ISO:
+ case PIPE_ISOCHRONOUS:
X ed->hwNextED = 0;
X ed->int_interval = 1;
X if (ohci->ed_isotail != NULL) {
@@ -873,24 +956,33 @@
X int inter;
X int interval;
X __u32 * ed_p;
-
-
+
+ ed->hwINFO |= cpu_to_le32 (OHCI_ED_SKIP);
+
X switch (ed->type) {
- case CTRL:
+ case PIPE_CONTROL:
X if (ed->ed_prev == NULL) {
+ if (!ed->hwNextED) {
+ ohci->hc_control &= ~OHCI_CTRL_CLE;
+ writel (ohci->hc_control, &ohci->regs->control);
+ }
X writel (le32_to_cpup (&ed->hwNextED), &ohci->regs->ed_controlhead);
X } else {
X ed->ed_prev->hwNextED = ed->hwNextED;
X }
- if(ohci->ed_controltail == ed) {
+ if (ohci->ed_controltail == ed) {
X ohci->ed_controltail = ed->ed_prev;
X } else {
X ((ed_t *) bus_to_virt (le32_to_cpup (&ed->hwNextED)))->ed_prev = ed->ed_prev;
X }
X break;
X
- case BULK:
+ case PIPE_BULK:
X if (ed->ed_prev == NULL) {
+ if (!ed->hwNextED) {
+ ohci->hc_control &= ~OHCI_CTRL_BLE;
+ writel (ohci->hc_control, &ohci->regs->control);
+ }
X writel (le32_to_cpup (&ed->hwNextED), &ohci->regs->ed_bulkhead);
X } else {
X ed->ed_prev->hwNextED = ed->hwNextED;
@@ -902,7 +994,7 @@
X }
X break;
X
- case INT:
+ case PIPE_INTERRUPT:
X int_branch = ed->int_branch;
X interval = ed->int_interval;
X
@@ -924,7 +1016,7 @@
X #endif
X break;
X
- case ISO:
+ case PIPE_ISOCHRONOUS:
X if (ohci->ed_isotail == ed)
X ohci->ed_isotail = ed->ed_prev;
X if (ed->hwNextED != 0)
@@ -969,16 +1061,17 @@
X td_t * td;
X ed_t * ed_ret;
X volatile ed_t * ed;

+ unsigned long flags;
X

X
- spin_lock (&usb_ed_lock);
+ spin_lock_irqsave (&usb_ed_lock, flags);
X
X ed = ed_ret = &(usb_to_ohci (usb_dev)->ed[(usb_pipeendpoint (pipe) << 1) |
X (usb_pipecontrol (pipe)? 0: usb_pipeout (pipe))]);
X
X if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) {
X /* pending delete request */
- spin_unlock (&usb_ed_lock);
+ spin_unlock_irqrestore (&usb_ed_lock, flags);


X return NULL;
X }
X

@@ -987,7 +1080,7 @@
X OHCI_ALLOC (td, sizeof (*td)); /* dummy td; end of td list for ed */
X if (!td) {
X /* out of memory */
- spin_unlock (&usb_ed_lock);
+ spin_unlock_irqrestore (&usb_ed_lock, flags);
X return NULL;
X }
X ed->hwTailP = cpu_to_le32 (virt_to_bus (td));
@@ -1006,12 +1099,12 @@
X | usb_pipeslow (pipe) << 13
X | usb_maxpacket (usb_dev, pipe, usb_pipeout (pipe)) << 16);
X
- if (ed->type == INT && ed->state == ED_UNLINK) {
+ if (ed->type == PIPE_INTERRUPT && ed->state == ED_UNLINK) {
X ed->int_period = interval;
X ed->int_load = load;
X }
X
- spin_unlock(&usb_ed_lock);
+ spin_unlock_irqrestore (&usb_ed_lock, flags);
X return ed_ret;
X }
X
@@ -1029,28 +1122,29 @@
X if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL))
X return;
X
- ed->hwINFO |= cpu_to_le32 (OHCI_ED_SKIP);
+ ed->hwINFO |= cpu_to_le32 (OHCI_ED_SKIP);
X
X if (!ohci->disabled) {
- /* enable SOF interrupt */
- writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
- writel (OHCI_INTR_SF, &ohci->regs->intrenable);
+ switch (ed->type) {
+ case PIPE_CONTROL: /* stop control list */
+ ohci->hc_control &= ~OHCI_CTRL_CLE;
+ writel (ohci->hc_control, &ohci->regs->control);
+ break;
+ case PIPE_BULK: /* stop bulk list */
+ ohci->hc_control &= ~OHCI_CTRL_BLE;
+ writel (ohci->hc_control, &ohci->regs->control);

+ break;
+ }
X }
X

X frame = le16_to_cpu (ohci->hcca.frame_no) & 0x1;
X ed->ed_rm_list = ohci->ed_rm_list[frame];
X ohci->ed_rm_list[frame] = ed;
X
- if (ohci->disabled)
- return;
-
- switch (ed->type) {
- case CTRL: /* stop CTRL list */
- writel (ohci->hc_control &= ~OHCI_CTRL_CLE, &ohci->regs->control);
- break;
- case BULK: /* stop BULK list */
- writel (ohci->hc_control &= ~OHCI_CTRL_BLE, &ohci->regs->control);
- break;
+ if (!ohci->disabled) {
+ /* enable SOF interrupt */
+ writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
+ writel (OHCI_INTR_SF, &ohci->regs->intrenable);
X }
X }
X
@@ -1072,25 +1166,30 @@
X
X td_pt = urb_priv->td [index];
X /* fill the old dummy TD */
- td = urb_priv->td [index] = (td_t *) bus_to_virt (le32_to_cpup (&urb_priv->ed->hwTailP) & 0xfffffff0);
+ td = urb_priv->td [index] = (td_t *)
+ bus_to_virt (le32_to_cpup (&urb_priv->ed->hwTailP) & 0xfffffff0);
X td->ed = urb_priv->ed;
+ td->next_dl_td = NULL;
X td->index = index;
X td->urb = urb;
X td->hwINFO = cpu_to_le32 (info);
- if ((td->ed->type & 3) == PIPE_ISOCHRONOUS) {
- td->hwCBP = cpu_to_le32 (((!data || !len)?
- 0 : virt_to_bus (data)) & 0xFFFFF000);
+ if ((td->ed->type) == PIPE_ISOCHRONOUS) {
+ td->hwCBP = cpu_to_le32 (((!data || !len)
+ ? 0
+ : virt_to_bus (data)) & 0xFFFFF000);
X td->ed->last_iso = info & 0xffff;
X } else {
- td->hwCBP = cpu_to_le32 (((!data || !len)? 0 : virt_to_bus (data)));
+ td->hwCBP = cpu_to_le32 (((!data || !len)
+ ? 0
+ : virt_to_bus (data)));
X }
- td->hwBE = cpu_to_le32 ((!data || !len )? 0: virt_to_bus (data + len - 1));
+ td->hwBE = cpu_to_le32 ((!data || !len )
+ ? 0
+ : virt_to_bus (data + len - 1));
X td->hwNextTD = cpu_to_le32 (virt_to_bus (td_pt));
X td->hwPSW [0] = cpu_to_le16 ((virt_to_bus (data) & 0x0FFF) | 0xE000);
X td_pt->hwNextTD = 0;
X td->ed->hwTailP = td->hwNextTD;
-
- td->next_dl_td = NULL; //td_pt;
X }
X
X /*-------------------------------------------------------------------------*/
@@ -1215,6 +1314,27 @@
X }
X }
X
+/* handle an urb that is being unlinked */
+
+static void dl_del_urb (urb_t * urb)
+{
+ wait_queue_head_t * wait_head = ((urb_priv_t *)(urb->hcpriv))->wait;
+
+ urb_rm_priv_locked (urb);
+
+ if (urb->transfer_flags & USB_ASYNC_UNLINK) {
+ urb->status = -ECONNRESET;
+ if (urb->complete)
+ urb->complete (urb);
+ } else {
+ urb->status = -ENOENT;
+
+ /* unblock sohci_unlink_urb */
+ if (wait_head)
+ wake_up (wait_head);
+ }
+}
+
X /*-------------------------------------------------------------------------*/
X
X /* replies to the request have to be on a FIFO basis so
@@ -1276,6 +1396,7 @@
X int ctrl = 0, bulk = 0;
X
X spin_lock_irqsave (&usb_ed_lock, flags);
+
X for (ed = ohci->ed_rm_list[frame]; ed != NULL; ed = ed->ed_rm_list) {
X
X tdTailP = bus_to_virt (le32_to_cpup (&ed->hwTailP) & 0xfffffff0);
@@ -1290,22 +1411,13 @@
X td_next = bus_to_virt (le32_to_cpup (&td->hwNextTD) & 0xfffffff0);
X if ((urb_priv->state == URB_DEL) || (ed->state & ED_DEL)) {
X tdINFO = le32_to_cpup (&td->hwINFO);
- if (TD_CC_GET (tdINFO) < 0xE) dl_transfer_length (td);
+ if (TD_CC_GET (tdINFO) < 0xE)
+ dl_transfer_length (td);
X *td_p = td->hwNextTD | (*td_p & cpu_to_le32 (0x3));
- /* URB is done; clean up */
- if (++(urb_priv->td_cnt) == urb_priv->length) {
- void *condition = urb_priv->wait;
X
- urb_rm_priv (urb);
- if (urb->transfer_flags & USB_ASYNC_UNLINK) {
- usb_dec_dev_use (urb->dev);
- urb->status = -ECONNRESET;
- urb->complete (urb);
- } else if (condition) {
- /* unblock sohci_unlink_urb */
- wake_up (condition);
- }
- }
+ /* URB is done; clean up */
+ if (++(urb_priv->td_cnt) == urb_priv->length)
+ dl_del_urb (urb);
X } else {
X td_p = &td->hwNextTD;
X }
@@ -1317,31 +1429,54 @@
X ed->hwINFO = cpu_to_le32 (OHCI_ED_SKIP);
X ed->state = ED_NEW;
X /* if all eds are removed wake up sohci_free_dev */
- if (!--dev->ed_cnt && dev->wait)
- wake_up (dev->wait);
- }
- else {
+ if (!--dev->ed_cnt) {
+ wait_queue_head_t *wait_head = dev->wait;


+
+ dev->wait = 0;

+ if (wait_head)
+ wake_up (wait_head);
+ }
+ } else {
X ed->state &= ~ED_URB_DEL;
- ed->hwINFO &= ~cpu_to_le32 (OHCI_ED_SKIP);
+ tdHeadP = bus_to_virt (le32_to_cpup (&ed->hwHeadP) & 0xfffffff0);
+
+ if (tdHeadP == tdTailP) {
+ if (ed->state == ED_OPER)
+ ep_unlink(ohci, ed);
+ OHCI_FREE (tdTailP);
+ ed->hwINFO = cpu_to_le32 (OHCI_ED_SKIP);
+ ed->state = ED_NEW;
+ --(usb_to_ohci (ohci->dev[edINFO & 0x7F]))->ed_cnt;
+ } else
+ ed->hwINFO &= ~cpu_to_le32 (OHCI_ED_SKIP);
X }
-
- if ((ed->type & 3) == CTRL) ctrl |= 1;
- if ((ed->type & 3) == BULK) bulk |= 1;
+
+ switch (ed->type) {
+ case PIPE_CONTROL:
+ ctrl = 1;
+ break;
+ case PIPE_BULK:
+ bulk = 1;
+ break;
+ }
X }
X
- /* maybe reenable CTRL and BULK lists */
+ /* maybe reenable control and bulk lists */
X if (!ohci->disabled) {
- if (ctrl) /* reset CTRL list */
+ if (ctrl) /* reset control list */
X writel (0, &ohci->regs->ed_controlcurrent);
- if (bulk) /* reset BULK list */
+ if (bulk) /* reset bulk list */
X writel (0, &ohci->regs->ed_bulkcurrent);
X if (!ohci->ed_rm_list[!frame]) {
- ohci->hc_control |= OHCI_CTRL_CLE | OHCI_CTRL_BLE;
+ if (ohci->ed_controltail)
+ ohci->hc_control |= OHCI_CTRL_CLE;
+ if (ohci->ed_bulktail)
+ ohci->hc_control |= OHCI_CTRL_BLE;
X writel (ohci->hc_control, &ohci->regs->control);
X }
X }
- ohci->ed_rm_list[frame] = NULL;
X
+ ohci->ed_rm_list[frame] = NULL;
X spin_unlock_irqrestore (&usb_ed_lock, flags);
X }
X
@@ -1375,17 +1510,25 @@
X
X /* error code of transfer */
X cc = TD_CC_GET (tdINFO);
- if( cc == TD_CC_STALL) usb_endpoint_halt(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe));
+ if (cc == TD_CC_STALL)
+ usb_endpoint_halt(urb->dev,
+ usb_pipeendpoint(urb->pipe),
+ usb_pipeout(urb->pipe));
X
- if (!(urb->transfer_flags & USB_DISABLE_SPD) && (cc == TD_DATAUNDERRUN))
- cc = TD_CC_NOERROR;
+ if (!(urb->transfer_flags & USB_DISABLE_SPD)
+ && (cc == TD_DATAUNDERRUN))
+ cc = TD_CC_NOERROR;
+
X if (++(urb_priv->td_cnt) == urb_priv->length) {
- if (urb_priv->state != URB_DEL && !(ed->state & ED_DEL) && ed->state != ED_NEW) {
+ if ((ed->state & (ED_OPER | ED_UNLINK))
+ && (urb_priv->state != URB_DEL)) {
X urb->status = cc_to_error[cc];
X sohci_return_urb (urb);
X } else {
- urb_rm_priv (urb);
- }
+ spin_lock_irqsave (&usb_ed_lock, flags);
+ dl_del_urb (urb);
+ spin_unlock_irqrestore (&usb_ed_lock, flags);
+ }
X }
X
X spin_lock_irqsave (&usb_ed_lock, flags);
@@ -1393,13 +1536,13 @@
X edHeadP = le32_to_cpup (&ed->hwHeadP) & 0xfffffff0;
X edTailP = le32_to_cpup (&ed->hwTailP);
X
- if((edHeadP == edTailP) && (ed->state == ED_OPER))
- ep_unlink (ohci, ed); /* unlink eds if they are not busy */
-
- }
- spin_unlock_irqrestore (&usb_ed_lock, flags);
+ /* unlink eds if they are not busy */
+ if ((edHeadP == edTailP) && (ed->state == ED_OPER))
+ ep_unlink (ohci, ed);
+ }
+ spin_unlock_irqrestore (&usb_ed_lock, flags);
X
- td_list = td_list_next;
+ td_list = td_list_next;
X }
X }
X
@@ -1530,7 +1673,7 @@
X
X /* ignore timers firing during PM suspend, etc */
X if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER)
- return;
+ goto out;
X
X if(ohci->rh.send) {
X len = rh_send_irq (ohci, urb->transfer_buffer, urb->transfer_buffer_length);
@@ -1539,9 +1682,11 @@
X #ifdef DEBUG
X urb_print (urb, "RET-t(rh)", usb_pipeout (urb->pipe));
X #endif
- if (urb->complete) urb->complete (urb);
+ if (urb->complete)
+ urb->complete (urb);
X }
- }
+ }
+ out:
X rh_init_int_timer (urb);
X }
X
@@ -1594,7 +1739,6 @@
X __u16 wLength;
X
X if (usb_pipeint(pipe)) {
-
X ohci->rh.urb = urb;
X ohci->rh.send = 1;
X ohci->rh.interval = urb->interval;
@@ -1765,9 +1909,11 @@
X urb_print (urb, "RET(rh)", usb_pipeout (urb->pipe));
X #endif
X
+ urb->hcpriv = NULL;
+ usb_dec_dev_use (usb_dev);


+ urb->dev = NULL;

X if (urb->complete)
X urb->complete (urb);
- usb_dec_dev_use (urb->dev);


X return 0;
X }
X

@@ -1780,6 +1926,17 @@
X if (ohci->rh.urb == urb) {
X ohci->rh.send = 0;
X del_timer (&ohci->rh.rh_int_timer);
+ ohci->rh.urb = NULL;
+
+ urb->hcpriv = NULL;
+ usb_dec_dev_use(urb->dev);


+ urb->dev = NULL;

+ if (urb->transfer_flags & USB_ASYNC_UNLINK) {
+ urb->status = -ECONNRESET;
+ if (urb->complete)
+ urb->complete (urb);
+ } else
+ urb->status = -ENOENT;


X }
X return 0;
X }

@@ -2290,6 +2447,12 @@
X
X ohci->disabled = 0;
X ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
+ if (!ohci->ed_rm_list[0] & !ohci->ed_rm_list[1]) {
+ if (ohci->ed_controltail)
+ ohci->hc_control |= OHCI_CTRL_CLE;
+ if (ohci->ed_bulktail)
+ ohci->hc_control |= OHCI_CTRL_BLE;
+ }
X writel (ohci->hc_control, &ohci->regs->control);
X #ifdef CONFIG_PMAC_PBOOK
X enable_irq (ohci->irq);
@@ -2386,7 +2549,6 @@


X return ret;
X }
X

-
X /*-------------------------------------------------------------------------*/
X
X static void __exit ohci_hcd_cleanup (void)
@@ -2401,6 +2563,5 @@
X module_exit (ohci_hcd_cleanup);
X
X
-
-MODULE_AUTHOR ("Roman Weissgaerber <wei...@vienna.at>");
+MODULE_AUTHOR ("Roman Weissgaerber <wei...@vienna.at>, David Brownell");
X MODULE_DESCRIPTION ("USB OHCI Host Controller Driver");
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/usb-ohci.h linux/drivers/usb/usb-ohci.h
--- v2.4.0-test8/linux/drivers/usb/usb-ohci.h Sun Aug 13 15:59:10 2000
+++ linux/drivers/usb/usb-ohci.h Tue Oct 3 09:24:40 2000
@@ -1,10 +1,10 @@
- /*
+/*
X * URB OHCI HCD (Host Controller Driver) for USB.
X *
- *(C) Copyright 1999 Roman Weissgaerber <wei...@vienna.at>
+ * (C) Copyright 1999 Roman Weissgaerber <wei...@vienna.at>
+ * (C) Copyright 2000 David Brownell <dav...@pacbell.net>
X *
X * usb-ohci.h
- *
X */
X
X
@@ -40,7 +40,7 @@
X #define ED_UNLINK 0x01
X #define ED_OPER 0x02
X #define ED_DEL 0x04
-#define ED_URB_DEL 0x08
+#define ED_URB_DEL 0x08
X
X /* usb_ohci_ed */
X typedef struct ed {
@@ -107,7 +107,7 @@
X __u32 hwBE; /* Memory Buffer End Pointer */
X __u16 hwPSW[MAXPSW];
X
- __u8 type;
+ __u8 unused;
X __u8 index;
X struct ed * ed;
X struct td * next_dl_td;
@@ -115,18 +115,6 @@
X } td_t;
X
X
-/* TD types */
-#define BULK 0x03
-#define INT 0x01
-#define CTRL 0x02
-#define ISO 0x00
-
-#define SEND 0x01
-#define ST_ADDR 0x02
-#define ADD_LEN 0x04
-#define DEL 0x08
-
-
X #define OHCI_ED_SKIP (1 << 14)
X
X /*
@@ -347,7 +335,7 @@
X __u16 length; // number of tds associated with this request
X __u16 td_cnt; // number of tds already serviced
X int state;
- void * wait;
+ wait_queue_head_t * wait;
X td_t * td[0]; // list pointer to all corresponding TDs associated with this request
X
X } urb_priv_t;
@@ -372,8 +360,8 @@
X struct list_head ohci_hcd_list; /* list of all ohci_hcd */
X
X struct ohci * next; // chain of uhci device contexts
- struct list_head urb_list; // list of all pending urbs
- spinlock_t urb_list_lock; // lock to keep consistency
+ // struct list_head urb_list; // list of all pending urbs
+ // spinlock_t urb_list_lock; // lock to keep consistency
X
X int ohci_int_load[32]; /* load of the 32 Interrupt Chains (for load balancing)*/
X ed_t * ed_rm_list[2]; /* lists of all endpoints to be removed */
@@ -398,7 +386,7 @@
X struct ohci_device {
X ed_t ed[NUM_EDS];
X int ed_cnt;
- void * wait;
+ wait_queue_head_t * wait;
X };
X
X // #define ohci_to_usb(ohci) ((ohci)->usb)
@@ -418,7 +406,7 @@
X static int rh_unlink_urb(urb_t * urb);
X static int rh_init_int_timer(urb_t * urb);
X
-#ifdef DEBUG
+#ifdef OHCI_VERBOSE_DEBUG
X #define OHCI_FREE(x) kfree(x); printk("OHCI FREE: %d: %4x\n", -- __ohci_free_cnt, (unsigned int) x)
X #define OHCI_ALLOC(x,size) (x) = kmalloc(size, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); printk("OHCI ALLO: %d: %4x\n", ++ __ohci_free_cnt,(unsigned int) x)
X static int __ohci_free_cnt = 0;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/usb-uhci.c linux/drivers/usb/usb-uhci.c
--- v2.4.0-test8/linux/drivers/usb/usb-uhci.c Thu Sep 7 08:39:00 2000
+++ linux/drivers/usb/usb-uhci.c Tue Oct 3 09:24:40 2000
@@ -12,7 +12,7 @@
X * (C) Copyright 1999 Johannes Erdfelt
X * (C) Copyright 1999 Randy Dunlap
X *
- * $Id: usb-uhci.c,v 1.237 2000/08/08 14:58:17 acher Exp $
+ * $Id: usb-uhci.c,v 1.239 2000/09/19 20:15:12 acher Exp $
X */
X
X #include <linux/config.h>
@@ -48,7 +48,7 @@
X /* This enables an extra UHCI slab for memory debugging */
X #define DEBUG_SLAB
X
-#define VERSTR "$Revision: 1.237 $ time " __TIME__ " " __DATE__
+#define VERSTR "$Revision: 1.239 $ time " __TIME__ " " __DATE__
X
X #include <linux/usb.h>
X #include "usb-uhci.h"
@@ -141,6 +141,9 @@
X {
X int flags;
X
+ if (urb->transfer_flags & USB_NO_FSBR)
+ return;
+
X spin_lock_irqsave (&s->qh_lock, flags);
X s->chain_end->hw.qh.head&=~UHCI_PTR_TERM;
X mb();
@@ -153,8 +156,10 @@
X {
X int flags;
X
- spin_lock_irqsave (&s->qh_lock, flags);
+ if (urb->transfer_flags & USB_NO_FSBR)
+ return;
X
+ spin_lock_irqsave (&s->qh_lock, flags);
X if (((urb_priv_t*)urb->hcpriv)->use_loop) {
X s->loop_usage--;
X
@@ -1029,12 +1034,30 @@
X }
X }
X /*-------------------------------------------------------------------*/
+// Release bandwidth for Interrupt or Isoc. transfers
+_static void uhci_release_bandwidth(urb_t *urb)
+{
+ if (urb->bandwidth) {
+ switch (usb_pipetype(urb->pipe)) {
+ case PIPE_INTERRUPT:
+ usb_release_bandwidth (urb->dev, urb, 0);
+ break;
+ case PIPE_ISOCHRONOUS:
+ usb_release_bandwidth (urb->dev, urb, 1);
+ break;
+ default:


+ break;
+ }
+ }
+}

+/*-------------------------------------------------------------------*/
X // unlinks an urb by dequeuing its qh, waits some frames and forgets it
X _static int uhci_unlink_urb_sync (uhci_t *s, urb_t *urb)
X {
X uhci_desc_t *qh;
X urb_priv_t *urb_priv;
X unsigned long flags=0;
+ struct usb_device *usb_dev;
X
X spin_lock_irqsave (&s->urb_list_lock, flags);
X
@@ -1050,6 +1073,7 @@
X if (!in_interrupt())
X spin_unlock(&urb->lock);
X
+ uhci_release_bandwidth(urb);
X spin_unlock_irqrestore (&s->urb_list_lock, flags);
X
X urb->status = -ENOENT; // mark urb as killed
@@ -1080,11 +1104,13 @@
X #else
X kfree (urb->hcpriv);
X #endif
+ usb_dev = urb->dev;
X if (urb->complete) {
X dbg("unlink_urb: calling completion");


+ urb->dev = NULL;

X urb->complete ((struct urb *) urb);
X }
- usb_dec_dev_use (urb->dev);
+ usb_dec_dev_use (usb_dev);
X }
X else {
X if (!in_interrupt())
@@ -1148,6 +1174,7 @@
X
X if (urb->complete) {
X spin_unlock(&s->urb_list_lock);


+ urb->dev = NULL;

X urb->complete ((struct urb *) urb);
X spin_lock(&s->urb_list_lock);
X }
@@ -1242,6 +1269,7 @@
X if (!in_interrupt())
X spin_lock(&urb->lock);
X
+ uhci_release_bandwidth(urb);
X ret = uhci_unlink_urb_async(s, urb);
X
X if (!in_interrupt())
@@ -1543,6 +1571,7 @@


X int ret = 0;

X unsigned long flags;
X urb_t *bulk_urb=NULL;
+ int bustime;
X
X if (!urb->dev || !urb->dev->bus)
X return -ENODEV;
@@ -1612,11 +1641,39 @@
X else {
X spin_unlock_irqrestore (&s->urb_list_lock, flags);
X switch (usb_pipetype (urb->pipe)) {
- case PIPE_ISOCHRONOUS:
- ret = uhci_submit_iso_urb (urb);
+ case PIPE_ISOCHRONOUS:
+ if (urb->bandwidth == 0) { /* not yet checked/allocated */
+ if (urb->number_of_packets <= 0) {
+ ret = -EINVAL;
+ break;
+ }
+
+ bustime = usb_check_bandwidth (urb->dev, urb);
+ if (bustime < 0) {
+ ret = bustime;
+ break;
+ }
+
+ ret = uhci_submit_iso_urb(urb);
+ if (ret == 0)
+ usb_claim_bandwidth (urb->dev, urb, bustime, 1);


+ } else { /* bandwidth is already set */

+ ret = uhci_submit_iso_urb(urb);
+ }


X break;
X case PIPE_INTERRUPT:

- ret = uhci_submit_int_urb (urb);
+ if (urb->bandwidth == 0) { /* not yet checked/allocated */
+ bustime = usb_check_bandwidth (urb->dev, urb);
+ if (bustime < 0)
+ ret = bustime;
+ else {
+ ret = uhci_submit_int_urb(urb);
+ if (ret == 0)
+ usb_claim_bandwidth (urb->dev, urb, bustime, 0);
+ }


+ } else { /* bandwidth is already set */

+ ret = uhci_submit_int_urb(urb);
+ }
X break;
X case PIPE_CONTROL:
X ret = uhci_submit_control_urb (urb);
@@ -2029,6 +2086,7 @@
X
X urb->actual_length = len;
X urb->status = stat;
+ urb->dev=NULL;
X if (urb->complete)
X urb->complete (urb);
X return 0;
@@ -2431,7 +2489,6 @@


X int ret = 0;

X urb_t *urb;
X
-
X urb=list_entry (p, urb_t, urb_list);
X //dbg("process_urb: found queued urb: %p", urb);
X

@@ -2455,6 +2512,17 @@
X

X if (urb->status != -EINPROGRESS) {
X int proceed = 0;
+ struct usb_device *usb_dev;
+
+ usb_dev=urb->dev;
+
+ /* Release bandwidth for Interrupt or Iso transfers */
+ if (urb->bandwidth) {
+ if (usb_pipetype(urb->pipe)==PIPE_ISOCHRONOUS)
+ usb_release_bandwidth (urb->dev, urb, 1);
+ else if (usb_pipetype(urb->pipe)==PIPE_INTERRUPT && urb->interval)
+ usb_release_bandwidth (urb->dev, urb, 0);
+ }
X
X dbg("dequeued urb: %p", urb);
X dequeue_urb (s, urb);
@@ -2488,9 +2556,12 @@
X // In case you need the current URB status for your completion handler (before resubmit)
X if (urb->complete && (!proceed )) {
X dbg("process_transfer: calling early completion");


+ urb->dev = NULL;

X urb->complete ((struct urb *) urb);
- if (!proceed && is_ring && (urb->status != -ENOENT))
+ if (!proceed && is_ring && (urb->status != -ENOENT)) {
+ urb->dev=usb_dev;
X uhci_submit_urb (urb);
+ }
X }
X
X if (proceed && urb->next) {
@@ -2506,11 +2577,13 @@
X
X if (urb->complete) {
X dbg("process_transfer: calling completion");
+ urb->dev=NULL;
X urb->complete ((struct urb *) urb);
X }
X }
-
- usb_dec_dev_use (urb->dev);
+
+ urb->dev=NULL; // Just in case no completion was called
+ usb_dec_dev_use (usb_dev);
X spin_unlock(&urb->lock);
X spin_lock(&s->urb_list_lock);
X }


@@ -2842,6 +2915,7 @@
X

X if(!urb_priv_kmem) {
X err("kmem_cache_create for urb_priv_t failed (out of memory)");
+ kmem_cache_destroy(uhci_desc_kmem);
X return -ENOMEM;
X }
X #endif
@@ -2876,6 +2950,15 @@
X i++;
X }
X
+#ifdef DEBUG_SLAB
+ if (retval < 0 ) {
+ if (kmem_cache_destroy(urb_priv_kmem))
+ err("urb_priv_kmem remained");
+ if (kmem_cache_destroy(uhci_desc_kmem))
+ err("uhci_desc_kmem remained");
+ }
+#endif
+
X return retval;
X }
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/usb/usb.c linux/drivers/usb/usb.c
--- v2.4.0-test8/linux/drivers/usb/usb.c Tue Sep 5 13:41:53 2000
+++ linux/drivers/usb/usb.c Tue Oct 3 09:24:40 2000
@@ -25,19 +25,7 @@
X #include <linux/bitops.h>
X #include <linux/malloc.h>
X #include <linux/interrupt.h> /* for in_interrupt() */
-
-
-#if defined(CONFIG_KMOD) && defined(CONFIG_HOTPLUG)
X #include <linux/kmod.h>
-#include <linux/sched.h>
-#include <asm/uaccess.h>
-
-#define __KERNEL_SYSCALLS__
-#include <linux/unistd.h>
-
-/* waitpid() call glue uses this */
-static int errno;
-#endif
X
X
X #ifdef CONFIG_USB_DEBUG
@@ -47,6 +35,11 @@
X #endif
X #include <linux/usb.h>
X
+#define DEVNUM_ROUND_ROBIN /***** OPTION *****/
+#ifdef DEVNUM_ROUND_ROBIN
+static int devnum_next = 1;
+#endif
+
X static const int usb_bandwidth_option =
X #ifdef CONFIG_USB_BANDWIDTH
X 1;
@@ -187,6 +180,19 @@


X return NULL;
X }
X

+struct usb_endpoint_descriptor *usb_epnum_to_ep_desc(struct usb_device *dev, unsigned epnum)
+{
+ int i, j, k;
+


+ for (i = 0; i < dev->actconfig->bNumInterfaces; i++)

+ for (j = 0; j < dev->actconfig->interface[i].num_altsetting; j++)
+ for (k = 0; k < dev->actconfig->interface[i].altsetting[j].bNumEndpoints; k++)
+ if (epnum == dev->actconfig->interface[i].altsetting[j].endpoint[k].bEndpointAddress)
+ return &dev->actconfig->interface[i].altsetting[j].endpoint[k];


+
+ return NULL;
+}

+
X /*
X * usb_calc_bus_time:
X *
@@ -284,7 +290,7 @@
X dev->bus->bandwidth_int_reqs++;
X urb->bandwidth = bustime;
X
- dbg("bw_alloc increased by %d to %d for %d requesters",
+ dbg("bandwidth alloc increased by %d to %d for %d requesters",
X bustime,
X dev->bus->bandwidth_allocated,
X dev->bus->bandwidth_int_reqs + dev->bus->bandwidth_isoc_reqs);
@@ -303,7 +309,7 @@
X else
X dev->bus->bandwidth_int_reqs--;
X
- dbg("bw_alloc reduced by %d to %d for %d requesters",
+ dbg("bandwidth alloc reduced by %d to %d for %d requesters",
X urb->bandwidth,
X dev->bus->bandwidth_allocated,
X dev->bus->bandwidth_int_reqs + dev->bus->bandwidth_isoc_reqs);
@@ -504,40 +510,6 @@
X * (normally /sbin/hotplug) when USB devices get added or removed.
X */
X
-static int exec_helper (void *arg)
-{
- void **params = (void **) arg;
- char *path = (char *) params [0];
- char **argv = (char **) params [1];
- char **envp = (char **) params [2];
- return exec_usermodehelper (path, argv, envp);
-}
-
-int call_usermodehelper (char *path, char **argv, char **envp)
-{
- void *params [3] = { path, argv, envp };
- int pid, pid2, retval;
- mm_segment_t fs;
-
- if ((pid = kernel_thread (exec_helper, (void *) params, 0)) < 0) {
- err ("failed fork of %s, errno = %d", argv [0], -pid);


- return -1;
- }
-

- /* set signal mask? */
- fs = get_fs ();
- set_fs (KERNEL_DS); /* retval is in kernel space. */
- pid2 = waitpid (pid, &retval, __WCLONE); /* "errno" gets assigned */
- set_fs (fs);
- /* restore signal mask? */
-
- if (pid2 != pid) {
- err ("waitpid(%d) failed, returned %d\n", pid, pid2);
- return -1;
- }
- return retval;
-}
-
X static int to_bcd (char *buf, __u16 *bcdValue)
X {


X int retval = 0;

@@ -700,7 +672,8 @@
X value = call_usermodehelper (argv [0], argv, envp);
X kfree (buf);
X kfree (envp);
- dbg ("kusbd policy returned 0x%x", value);
+ if (value != 0)
+ dbg ("kusbd policy returned 0x%x", value);
X }
X
X #else
@@ -737,7 +710,7 @@
X dbg("unhandled interfaces on device");
X
X if (!claimed) {
- warn("USB device %d (prod/vend 0x%x/0x%x) is not claimed by any active driver.",
+ warn("USB device %d (vend/prod 0x%x/0x%x) is not claimed by any active driver.",
X dev->devnum,
X dev->descriptor.idVendor,
X dev->descriptor.idProduct);
@@ -1237,7 +1210,7 @@
X config->interface = (struct usb_interface *)
X kmalloc(config->bNumInterfaces *
X sizeof(struct usb_interface), GFP_KERNEL);
- dbg("kmalloc IF %p, numif %i",config->interface,config->bNumInterfaces);
+ dbg("kmalloc IF %p, numif %i", config->interface, config->bNumInterfaces);
X if (!config->interface) {
X err("out of memory");
X return -1;
@@ -1455,8 +1428,6 @@
X
X info("USB disconnect on device %d", dev->devnum);
X
- call_policy ("remove", dev);
-
X if (dev->actconfig) {
X for (i = 0; i < dev->actconfig->bNumInterfaces; i++) {
X struct usb_interface *interface = &dev->actconfig->interface[i];
@@ -1477,6 +1448,9 @@
X usb_disconnect(child);
X }
X
+ /* Let policy agent unload modules etc */
+ call_policy ("remove", dev);
+
X /* Free the device number and remove the /proc/bus/usb entry */
X if (dev->devnum > 0) {
X clear_bit(dev->devnum, &dev->bus->devmap.devicemap);
@@ -1498,10 +1472,22 @@
X int devnum;
X // FIXME needs locking for SMP!!
X /* why? this is called only from the hub thread,
- * which hopefully doesn't run on multiple CPU's simulatenously 8-)
+ * which hopefully doesn't run on multiple CPU's simultaneously 8-)
X */
X dev->descriptor.bMaxPacketSize0 = 8; /* Start off at 8 bytes */
+#ifndef DEVNUM_ROUND_ROBIN
X devnum = find_next_zero_bit(dev->bus->devmap.devicemap, 128, 1);
+#else /* round_robin alloc of devnums */
+ /* Try to allocate the next devnum beginning at devnum_next. */
+ devnum = find_next_zero_bit(dev->bus->devmap.devicemap, 128, devnum_next);
+ if (devnum >= 128)
+ devnum = find_next_zero_bit(dev->bus->devmap.devicemap, 128, 1);
+
+ devnum_next = devnum + 1;
+ if (devnum_next >= 128)
+ devnum_next = 1;
+#endif /* round_robin alloc of devnums */
+
X if (devnum < 128) {
X set_bit(devnum, dev->bus->devmap.devicemap);
X dev->devnum = devnum;
@@ -1898,8 +1884,6 @@


X {
X int err;
X

- info("USB new device connect, assigned device number %d", dev->devnum);
-
X /* USB v1.1 5.5.3 */
X /* We read the first 8 bytes from the device descriptor to get to */
X /* the bMaxPacketSize0 field. Then we set the maximum packet size */


@@ -1909,7 +1893,8 @@
X

X err = usb_set_address(dev);
X if (err < 0) {
- err("USB device not accepting new address (error=%d)", err);
+ err("USB device not accepting new address=%d (error=%d)",
+ dev->devnum, err);
X clear_bit(dev->devnum, &dev->bus->devmap.devicemap);
X dev->devnum = -1;
X return 1;
@@ -1922,7 +1907,7 @@
X if (err < 0)
X err("USB device not responding, giving up (error=%d)", err);
X else
- err("USB device descriptor short read (expected %i, got %i)",8,err);
+ err("USB device descriptor short read (expected %i, got %i)", 8, err);
X clear_bit(dev->devnum, &dev->bus->devmap.devicemap);
X dev->devnum = -1;
X return 1;
@@ -1935,7 +1920,8 @@
X if (err < 0)
X err("unable to get device descriptor (error=%d)", err);
X else
- err("USB device descriptor short read (expected %i, got %i)", sizeof(dev->descriptor), err);
+ err("USB device descriptor short read (expected %i, got %i)",
+ sizeof(dev->descriptor), err);
X
X clear_bit(dev->devnum, &dev->bus->devmap.devicemap);
X dev->devnum = -1;


@@ -1944,7 +1930,8 @@
X

X err = usb_get_configuration(dev);
X if (err < 0) {
- err("unable to get configuration (error=%d)", err);
+ err("unable to get device %d configuration (error=%d)",
+ dev->devnum, err);
X usb_destroy_configuration(dev);
X clear_bit(dev->devnum, &dev->bus->devmap.devicemap);
X dev->devnum = -1;
@@ -1954,7 +1941,8 @@
X /* we set the default configuration here */
X err = usb_set_configuration(dev, dev->config[0].bConfigurationValue);
X if (err) {
- err("failed to set default configuration (error=%d)", err);
+ err("failed to set device %d default configuration (error=%d)",
+ dev->devnum, err);
X clear_bit(dev->devnum, &dev->bus->devmap.devicemap);
X dev->devnum = -1;
X return 1;
@@ -2048,6 +2036,7 @@
X * then these symbols need to be exported for the modules to use.
X */
X EXPORT_SYMBOL(usb_ifnum_to_if);
+EXPORT_SYMBOL(usb_epnum_to_ep_desc);
X
X EXPORT_SYMBOL(usb_register);
X EXPORT_SYMBOL(usb_deregister);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/video/Config.in linux/drivers/video/Config.in
--- v2.4.0-test8/linux/drivers/video/Config.in Wed Aug 9 14:11:11 2000
+++ linux/drivers/video/Config.in Mon Sep 18 15:15:22 2000
@@ -30,7 +30,7 @@
X if [ "$CONFIG_ARCH_ACORN" = "y" ]; then
X bool ' Acorn VIDC support' CONFIG_FB_ACORN
X fi
- tristate ' Cyber2000 support' CONFIG_FB_CYBER2000
+ dep_tristate ' Cyber2000 support' CONFIG_FB_CYBER2000 $CONFIG_PCI
X if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
X bool ' SA-1100 LCD support' CONFIG_FB_SA1100
X fi
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/video/Makefile linux/drivers/video/Makefile
--- v2.4.0-test8/linux/drivers/video/Makefile Sun Aug 6 11:23:41 2000
+++ linux/drivers/video/Makefile Sun Sep 17 09:48:04 2000
@@ -46,7 +46,10 @@
X
X # Add fbmon.o back into obj-$(CONFIG_FB) in 2.5.x
X obj-$(CONFIG_FB) += fbmem.o fbcmap.o modedb.o fbcon.o fonts.o
+# Only include macmodes.o if we have FB support and are PPC
+ifeq ($(CONFIG_FB),y)
X obj-$(CONFIG_PPC) += macmodes.o
+endif
X
X obj-$(CONFIG_FB_ACORN) += acornfb.o
X obj-$(CONFIG_FB_AMIGA) += amifb.o
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/video/acornfb.c linux/drivers/video/acornfb.c
--- v2.4.0-test8/linux/drivers/video/acornfb.c Sun Aug 13 10:04:17 2000
+++ linux/drivers/video/acornfb.c Mon Sep 18 15:15:22 2000
@@ -1,7 +1,11 @@
X /*
- * linux/drivers/video/acornfb.c
+ * linux/drivers/video/acornfb.c
X *
- * Copyright (C) 1998-2000 Russell King
+ * Copyright (C) 1998-2000 Russell King
+ *


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

X *
X * Frame buffer code for Acorn platforms
X *
@@ -97,6 +101,8 @@
X
X #ifdef HAS_VIDC
X
+#define MAX_SIZE 480*1024
+
X /* CTL VIDC Actual
X * 24.000 0 8.000
X * 25.175 0 8.392
@@ -335,6 +341,8 @@
X #ifdef HAS_VIDC20
X #include <asm/arch/acornfb.h>
X
+#define MAX_SIZE 2*1024*1024
+
X /* VIDC20 has a different set of rules from the VIDC:
X * hcr : must be multiple of 4
X * hswr : must be even
@@ -1561,7 +1569,7 @@
X if (current_par.montype == -1 || current_par.montype > NR_MONTYPES)
X current_par.montype = 4;
X
- if (current_par.montype > 0) {
+ if (current_par.montype >= 0) {
X fb_info.monspecs = monspecs[current_par.montype];
X fb_info.monspecs.dpms = current_par.dpms;
X }
@@ -1603,8 +1611,13 @@
X } else if (current_par.dram_size)
X size = current_par.dram_size;
X else
- size = (init_var.xres * init_var.yres *
- init_var.bits_per_pixel) / 8;
+ size = MAX_SIZE;
+
+ /*
+ * Limit maximum screen size.
+ */
+ if (size > MAX_SIZE)
+ size = MAX_SIZE;
X
X size = PAGE_ALIGN(size);
X
@@ -1640,13 +1653,6 @@
X }
X #endif
X #if defined(HAS_VIDC)
-#define MAX_SIZE 480*1024
- /*
- * Limit maximum screen size.
- */
- if (size > MAX_SIZE)
- size = MAX_SIZE;
-
X /*
X * Free unused pages
X */
@@ -1661,17 +1667,41 @@
X * find it, then we can't restore it if we change
X * the resolution, so we disable this feature.
X */
- rc = fb_find_mode(&init_var, &fb_info, NULL, modedb,
- sizeof(modedb) / sizeof(*modedb),
- &acornfb_default_mode, DEFAULT_BPP);
+ do {
+ rc = fb_find_mode(&init_var, &fb_info, NULL, modedb,
+ sizeof(modedb) / sizeof(*modedb),
+ &acornfb_default_mode, DEFAULT_BPP);
+ /*
+ * If we found an exact match, all ok.
+ */
+ if (rc == 1)
+ break;
+
+ rc = fb_find_mode(&init_var, &fb_info, NULL, NULL, 0,
+ &acornfb_default_mode, DEFAULT_BPP);
+ /*
+ * If we found an exact match, all ok.
+ */
+ if (rc == 1)
+ break;
+
+ rc = fb_find_mode(&init_var, &fb_info, NULL, modedb,
+ sizeof(modedb) / sizeof(*modedb),
+ &acornfb_default_mode, DEFAULT_BPP);
+ if (rc)
+ break;
+
+ rc = fb_find_mode(&init_var, &fb_info, NULL, NULL, 0,
+ &acornfb_default_mode, DEFAULT_BPP);
+ } while (0);
X
X /*
X * If we didn't find an exact match, try the
X * generic database.
X */
- if (rc != 1 && fb_find_mode(&init_var, &fb_info, NULL, NULL, 0,
- &acornfb_default_mode, DEFAULT_BPP)) {
+ if (rc == 0) {
X printk("Acornfb: no valid mode found\n");
+ return -EINVAL;
X }
X
X h_sync = 1953125000 / init_var.pixclock;
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/video/acornfb.h linux/drivers/video/acornfb.h
--- v2.4.0-test8/linux/drivers/video/acornfb.h Fri May 12 11:21:20 2000
+++ linux/drivers/video/acornfb.h Mon Sep 18 15:15:22 2000
@@ -1,16 +1,20 @@
X /*
- * linux/drivers/video/acornfb.h
+ * linux/drivers/video/acornfb.h
X *
- * Copyright (C) 1998,1999 Russell King
+ * Copyright (C) 1998,1999 Russell King
X *
- * Frame buffer code for Acorn platforms


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Frame buffer code for Acorn platforms
X */
X #if defined(HAS_VIDC20)
-#include <asm/iomd.h>
+#include <asm/hardware/iomd.h>
X #define VIDC_PALETTE_SIZE 256
X #define VIDC_NAME "VIDC20"
X #elif defined(HAS_VIDC)
-#include <asm/memc.h>
+#include <asm/hardware/memc.h>
X #define VIDC_PALETTE_SIZE 16
X #define VIDC_NAME "VIDC"
X #endif
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/video/aty.h linux/drivers/video/aty.h
--- v2.4.0-test8/linux/drivers/video/aty.h Tue Jun 20 14:14:51 2000
+++ linux/drivers/video/aty.h Sun Sep 17 09:48:04 2000
@@ -461,6 +461,7 @@
X #define VERTEX_2_SECONDARY_T 0x0738 /* Dword offset 1_CE */
X #define VERTEX_2_SECONDARY_W 0x073C /* Dword offset 1_CF */
X
+#define GTC_3D_RESET_DELAY 3 /* 3D engine reset delay in ms */
X
X /* CRTC control values (mostly CRTC_GEN_CNTL) */
X
@@ -747,7 +748,8 @@
X #define GI_CHIP_ID 0x4749 /* RAGE PRO, BGA, PCI33 only */
X #define GP_CHIP_ID 0x4750 /* RAGE PRO, PQFP, PCI33, full 3D */
X #define GQ_CHIP_ID 0x4751 /* RAGE PRO, PQFP, PCI33, limited 3D */
-#define LN_CHIP_ID 0x4c4d /* RAGE Mobility AGP */
+#define LM_CHIP_ID 0x4c4d /* RAGE Mobility PCI */
+#define LN_CHIP_ID 0x4c4e /* RAGE Mobility AGP */
X
X
X /* Mach64 major ASIC revisions */
@@ -998,5 +1000,12 @@
X #define LCD_LT_GIO 0x07
X #define LCD_POWER_MANAGEMENT 0x08
X #define LCD_ZVGPIO 0x09
+#define LCD_MISC_CNTL 0x14
+
+/* Values in LCD_MISC_CNTL */
+#define BIAS_MOD_LEVEL_MASK 0x0000ff00
+#define BIAS_MOD_LEVEL_SHIFT 8
+#define BLMOD_EN 0x00010000
+#define BIASMOD_EN 0x00020000
X
X #endif /* REGMACH64_H */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/video/aty128.h linux/drivers/video/aty128.h
--- v2.4.0-test8/linux/drivers/video/aty128.h Tue Jun 20 14:14:51 2000
+++ linux/drivers/video/aty128.h Sun Sep 17 09:48:04 2000
@@ -43,6 +43,7 @@
X #define OVR_CLR 0x0230
X #define OVR_WID_LEFT_RIGHT 0x0234
X #define OVR_WID_TOP_BOTTOM 0x0238
+#define LVDS_GEN_CNTL 0x02d0
X #define DDA_CONFIG 0x02e0
X #define DDA_ON_OFF 0x02e4
X #define VGA_DDA_CONFIG 0x02e8
@@ -267,7 +268,8 @@
X #define DAC_BLANKING 0x00000004
X #define DAC_RANGE_CNTL 0x00000003
X #define DAC_RANGE_CNTL 0x00000003
-#define PALETTE_ACCESS_CNTL 0x00000020
+#define DAC_PALETTE_ACCESS_CNTL 0x00000020
+#define DAC_PDWN 0x00008000
X
X /* GEN_RESET_CNTL bit constants */
X #define SOFT_RESET_GUI 0x00000001
@@ -339,5 +341,12 @@
X #define DP_SRC_RECT 0x00000200
X #define DP_SRC_HOST 0x00000300
X #define DP_SRC_HOST_BYTEALIGN 0x00000400
+
+/* LVDS_GEN_CNTL constants */
+#define LVDS_BL_MOD_LEVEL_MASK 0x0000ff00
+#define LVDS_BL_MOD_LEVEL_SHIFT 8
+#define LVDS_BL_MOD_EN 0x00010000
+#define LVDS_DIGION 0x00040000
+#define LVDS_BLON 0x00080000
X
X #endif /* REG_RAGE128_H */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/video/aty128fb.c linux/drivers/video/aty128fb.c
--- v2.4.0-test8/linux/drivers/video/aty128fb.c Wed Jul 26 11:08:40 2000
+++ linux/drivers/video/aty128fb.c Sun Sep 17 09:48:04 2000
@@ -55,6 +55,15 @@
X #endif
X #endif
X
+#ifdef CONFIG_ADB_PMU
+#include <linux/adb.h>
+#include <linux/pmu.h>
+#endif
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+#include <asm/backlight.h>
+#endif
+
X #ifdef CONFIG_FB_COMPAT_XPMAC
X #include <asm/vc_ioctl.h>
X #endif
@@ -211,13 +220,8 @@
X #endif
X
X #ifdef CONFIG_PPC
-#ifdef CONFIG_NVRAM_NOT_DEFINED
-static int default_vmode __initdata = VMODE_640_480_60;
+static int default_vmode __initdata = VMODE_1024_768_60;
X static int default_cmode __initdata = CMODE_8;
-#else
-static int default_vmode __initdata = VMODE_NVRAM;
-static int default_cmode __initdata = CMODE_NVRAM;
-#endif
X #endif
X
X #ifdef CONFIG_MTRR
@@ -419,6 +423,15 @@
X fb_rasterimg: aty128fb_rasterimg,
X };
X
+#ifdef CONFIG_PMAC_BACKLIGHT
+static int aty128_set_backlight_enable(int on, int level, void* data);
+static int aty128_set_backlight_level(int level, void* data);
+
+static struct backlight_controller aty128_backlight_controller = {
+ aty128_set_backlight_enable,
+ aty128_set_backlight_level
+};
+#endif /* CONFIG_PMAC_BACKLIGHT */
X
X /*
X * Functions to read from/write to the mmio registers
@@ -1712,15 +1725,8 @@
X if (!mac_find_mode(&var, &info->fb_info, mode_option, 8))
X var = default_var;
X } else {
-#ifdef CONFIG_NVRAM
- if (default_vmode == VMODE_NVRAM)
- default_vmode = nvram_read_byte(NV_VMODE);
-
- if (default_cmode == CMODE_NVRAM)
- default_cmode = nvram_read_byte(NV_CMODE);
-#endif
X if (default_vmode <= 0 || default_vmode > VMODE_MAX)
- default_vmode = VMODE_640_480_60;
+ default_vmode = VMODE_1024_768_60;
X
X if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
X default_cmode = CMODE_8;
@@ -1772,6 +1778,12 @@
X if (register_framebuffer(&info->fb_info) < 0)
X return 0;
X
+#ifdef CONFIG_PMAC_BACKLIGHT
+ /* Could be extended to Rage128Pro LVDS output too */
+ if (info->chip_gen == rage_M3)
+ register_backlight_controller(&aty128_backlight_controller, info, "ati");
+#endif /* CONFIG_PMAC_BACKLIGHT */
+
X printk(KERN_INFO "fb%d: %s frame buffer device on %s\n",
X GET_FB_IDX(info->fb_info.node), aty128fb_name, name);
X
@@ -1916,6 +1928,11 @@
X }
X #endif /* CONFIG_MTRR */
X
+#ifdef CONFIG_FB_COMPAT_XPMAC
+ if (!console_fb_info)
+ console_fb_info = &info->fb_info;
+#endif


+
X return 0;
X

X err_out:
@@ -2136,6 +2153,11 @@
X struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
X u8 state = 0;
X
+#ifdef CONFIG_PMAC_BACKLIGHT
+ if ((_machine == _MACH_Pmac) && blank)
+ set_backlight_enable(0);
+#endif /* CONFIG_PMAC_BACKLIGHT */
+
X if (blank & VESA_VSYNC_SUSPEND)
X state |= 2;
X if (blank & VESA_HSYNC_SUSPEND)
@@ -2144,6 +2166,11 @@
X state |= 4;
X
X aty_st_8(CRTC_EXT_CNTL+1, state);
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+ if ((_machine == _MACH_Pmac) && !blank)
+ set_backlight_enable(1);
+#endif /* CONFIG_PMAC_BACKLIGHT */
X }
X
X
@@ -2199,7 +2226,7 @@
X int i;
X
X if (info->chip_gen == rage_M3)
- aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & ~PALETTE_ACCESS_CNTL);
+ aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & ~DAC_PALETTE_ACCESS_CNTL);
X
X for (i=16; i<256; i++) {
X aty_st_8(PALETTE_INDEX, i);
@@ -2208,7 +2235,7 @@
X }
X
X if (info->chip_gen == rage_M3) {
- aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | PALETTE_ACCESS_CNTL);
+ aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | DAC_PALETTE_ACCESS_CNTL);
X
X for (i=16; i<256; i++) {
X aty_st_8(PALETTE_INDEX, i);
@@ -2221,7 +2248,7 @@
X /* initialize palette */
X
X if (info->chip_gen == rage_M3)
- aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & ~PALETTE_ACCESS_CNTL);
+ aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & ~DAC_PALETTE_ACCESS_CNTL);
X
X if (info->current_par.crtc.bpp == 16)
X aty_st_8(PALETTE_INDEX, (regno << 3));
@@ -2230,7 +2257,7 @@
X col = (red << 16) | (green << 8) | blue;
X aty_st_le32(PALETTE_DATA, col);
X if (info->chip_gen == rage_M3) {
- aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | PALETTE_ACCESS_CNTL);
+ aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | DAC_PALETTE_ACCESS_CNTL);
X if (info->current_par.crtc.bpp == 16)
X aty_st_8(PALETTE_INDEX, (regno << 3));
X else
@@ -2282,6 +2309,38 @@
X }
X }
X
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+static int backlight_conv[] = {
+ 0xff, 0xc0, 0xb5, 0xaa, 0x9f, 0x94, 0x89, 0x7e,
+ 0x73, 0x68, 0x5d, 0x52, 0x47, 0x3c, 0x31, 0x24
+};
+
+static int
+aty128_set_backlight_enable(int on, int level, void* data)
+{
+ struct fb_info_aty128 *info = (struct fb_info_aty128 *)data;
+ unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL);
+
+ reg |= LVDS_BL_MOD_EN | LVDS_BLON;
+ if (on && level > BACKLIGHT_OFF) {
+ reg &= ~LVDS_BL_MOD_LEVEL_MASK;
+ reg |= (backlight_conv[level] << LVDS_BL_MOD_LEVEL_SHIFT);
+ } else {
+ reg &= ~LVDS_BL_MOD_LEVEL_MASK;
+ reg |= (backlight_conv[0] << LVDS_BL_MOD_LEVEL_SHIFT);
+ }
+ aty_st_le32(LVDS_GEN_CNTL, reg);


+
+ return 0;
+}
+

+static int
+aty128_set_backlight_level(int level, void* data)
+{
+ return aty128_set_backlight_enable(1, level, data);
+}
+#endif /* CONFIG_PMAC_BACKLIGHT */
X
X /*
X * Accelerated functions
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/video/atyfb.c linux/drivers/video/atyfb.c
--- v2.4.0-test8/linux/drivers/video/atyfb.c Tue Aug 29 14:09:15 2000
+++ linux/drivers/video/atyfb.c Sun Sep 17 09:48:05 2000
@@ -20,6 +20,8 @@
X * This file is subject to the terms and conditions of the GNU General Public
X * License. See the file COPYING in the main directory of this archive for
X * more details.
+ *
+ * Many thanks to Nitya from ATI devrel for support and patience !
X */
X
X /******************************************************************************
@@ -73,6 +75,10 @@
X #ifdef CONFIG_NVRAM
X #include <linux/nvram.h>
X #endif
+#ifdef CONFIG_PMAC_BACKLIGHT
+#include <asm/backlight.h>
+#endif
+
X #ifdef __sparc__
X #include <asm/pbm.h>
X #include <asm/fbio.h>
@@ -286,6 +292,15 @@
X static struct fb_info_aty* first_display = NULL;
X #endif
X
+#ifdef CONFIG_PMAC_BACKLIGHT
+static int aty_set_backlight_enable(int on, int level, void* data);
+static int aty_set_backlight_level(int level, void* data);
+
+static struct backlight_controller aty_backlight_controller = {
+ aty_set_backlight_enable,
+ aty_set_backlight_level
+};
+#endif /* CONFIG_PMAC_BACKLIGHT */
X
X /*
X * Frame buffer device API
@@ -556,6 +571,8 @@
X { 0x4749, 0x4749, "3D RAGE PRO (BGA, PCI)" },
X { 0x4750, 0x4750, "3D RAGE PRO (PQFP, PCI)" },
X { 0x4751, 0x4751, "3D RAGE PRO (PQFP, PCI, limited 3D)" },


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 096'
echo 'File patch-2.4.0-test9 is continued in part 097'
echo "097" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part097

#!/bin/sh -x
# this is part 097 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 097; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ { 0x4c4d, 0x4c4d, "3D RAGE Mobility (PCI)" },
+ { 0x4c4e, 0x4c4e, "3D RAGE Mobility (AGP)" },
X };
X
X static const char *aty_gx_ram[8] __initdata = {
@@ -567,48 +584,51 @@
X };
X
X
-static inline u32 aty_ld_le32(unsigned int regindex,
+static inline u32 aty_ld_le32(int regindex,
X const struct fb_info_aty *info)
X {
-#if defined(__powerpc__)
- unsigned long temp;
- u32 val;
+ /* Hack for bloc 1, should be cleanly optimized by compiler */
+ if (regindex >= 0x400)
+ regindex -= 0x800;
X
- temp = info->ati_regbase;
- asm volatile("lwbrx %0,%1,%2;eieio" : "=r"(val) : "b" (regindex), "r" (temp));
- return val;
-#elif defined(__mc68000__)
+#if defined(__mc68000__)
X return le32_to_cpu(*((volatile u32 *)(info->ati_regbase+regindex)));
X #else
X return readl (info->ati_regbase + regindex);
X #endif
X }
X
-static inline void aty_st_le32(unsigned int regindex, u32 val,
+static inline void aty_st_le32(int regindex, u32 val,
X const struct fb_info_aty *info)
X {
-#if defined(__powerpc__)
- unsigned long temp;
+ /* Hack for bloc 1, should be cleanly optimized by compiler */
+ if (regindex >= 0x400)
+ regindex -= 0x800;
X
- temp = info->ati_regbase;
- asm volatile("stwbrx %0,%1,%2;eieio" : : "r" (val), "b" (regindex), "r" (temp) :
- "memory");
-#elif defined(__mc68000__)
+#if defined(__mc68000__)
X *((volatile u32 *)(info->ati_regbase+regindex)) = cpu_to_le32(val);
X #else
X writel (val, info->ati_regbase + regindex);
X #endif
X }
X
-static inline u8 aty_ld_8(unsigned int regindex,
+static inline u8 aty_ld_8(int regindex,
X const struct fb_info_aty *info)
X {
+ /* Hack for bloc 1, should be cleanly optimized by compiler */
+ if (regindex >= 0x400)
+ regindex -= 0x800;
+
X return readb (info->ati_regbase + regindex);
X }
X
-static inline void aty_st_8(unsigned int regindex, u8 val,
+static inline void aty_st_8(int regindex, u8 val,
X const struct fb_info_aty *info)
X {
+ /* Hack for bloc 1, should be cleanly optimized by compiler */
+ if (regindex >= 0x400)
+ regindex -= 0x800;
+
X writeb (val, info->ati_regbase + regindex);
X }
X
@@ -675,6 +695,16 @@
X BUS_FIFO_ERR_ACK, info);
X }
X
+static void reset_GTC_3D_engine(const struct fb_info_aty *info)
+{
+ aty_st_le32(SCALE_3D_CNTL, 0xc0, info);
+ mdelay(GTC_3D_RESET_DELAY);
+ aty_st_le32(SETUP_CNTL, 0x00, info);
+ mdelay(GTC_3D_RESET_DELAY);
+ aty_st_le32(SCALE_3D_CNTL, 0x00, info);
+ mdelay(GTC_3D_RESET_DELAY);
+}
+
X static void init_engine(const struct atyfb_par *par, struct fb_info_aty *info)
X {
X u32 pitch_value;
@@ -688,6 +718,13 @@
X pitch_value = pitch_value * 3;
X }
X
+ /* On GTC (RagePro), we need to reset the 3D engine before */
+ if (Gx == LB_CHIP_ID || Gx == LD_CHIP_ID || Gx == LI_CHIP_ID ||
+ Gx == LP_CHIP_ID || Gx == GB_CHIP_ID || Gx == GD_CHIP_ID ||
+ Gx == GI_CHIP_ID || Gx == GP_CHIP_ID || Gx == GQ_CHIP_ID ||
+ Gx == LM_CHIP_ID || Gx == LN_CHIP_ID)
+ reset_GTC_3D_engine(info);
+
X /* Reset engine, enable, and clear any engine errors */
X reset_engine(info);
X /* Ensure that vga page pointers are set to zero - the upper */
@@ -2494,6 +2531,9 @@
X } else if ((Gx == VT_CHIP_ID) || (Gx == VU_CHIP_ID)) {
X aty_st_le32(DAC_CNTL, 0x87010184, info);
X aty_st_le32(BUS_CNTL, 0x680000f9, info);
+ } else if ((Gx == LN_CHIP_ID) || (Gx == LM_CHIP_ID)) {
+ aty_st_le32(DAC_CNTL, 0x80010102, info);
+ aty_st_le32(BUS_CNTL, 0x7b33a040, info);
X } else {
X /* GT */
X aty_st_le32(DAC_CNTL, 0x86010102, info);
@@ -3375,6 +3415,10 @@
X /* Rage LT */
X pll = 230;
X mclk = 63;
+ } else if ((Gx == LN_CHIP_ID) || (Gx == LM_CHIP_ID)) {
+ /* Rage mobility M1 */
+ pll = 230;
+ mclk = 50;
X } else {
X /* other RAGE */
X pll = 135;
@@ -3545,13 +3589,15 @@
X info->fb_info.blank = &atyfbcon_blank;
X info->fb_info.flags = FBINFO_FLAG_DEFAULT;
X
-#ifdef CONFIG_PPC
+#ifdef CONFIG_PMAC_BACKLIGHT
X if (Gx == LI_CHIP_ID && machine_is_compatible("PowerBook1,1")) {
X /* these bits let the 101 powerbook wake up from sleep -- paulus */
X aty_st_lcd(LCD_POWER_MANAGEMENT, aty_ld_lcd(LCD_POWER_MANAGEMENT, info)
X | (USE_F32KHZ | TRISTATE_MEM_EN), info);
X }
-#endif /* CONFIG_PPC */
+ if ((Gx == LN_CHIP_ID) || (Gx == LM_CHIP_ID))
+ register_backlight_controller(&aty_backlight_controller, info, "ati");
+#endif /* CONFIG_PMAC_BACKLIGHT */
X
X #ifdef MODULE
X var = default_var;
@@ -3580,6 +3626,9 @@
X default_vmode = VMODE_1024_768_60;
X else if (machine_is_compatible("iMac"))
X default_vmode = VMODE_1024_768_75;
+ else if (machine_is_compatible("PowerBook2,1"))
+ /* iBook with 800x600 LCD */
+ default_vmode = VMODE_800_600_60;
X else
X default_vmode = VMODE_640_480_67;
X sense = read_aty_sense(info);
@@ -4216,10 +4265,10 @@
X struct fb_info_aty *info = (struct fb_info_aty *)fb;
X u8 gen_cntl;
X
-#ifdef CONFIG_ADB_PMU
+#ifdef CONFIG_PMAC_BACKLIGHT
X if ((_machine == _MACH_Pmac) && blank)
- pmu_enable_backlight(0);
-#endif


+ set_backlight_enable(0);
+#endif /* CONFIG_PMAC_BACKLIGHT */

X
X gen_cntl = aty_ld_8(CRTC_GEN_CNTL, info);
X if (blank > 0)
@@ -4241,10 +4290,10 @@
X gen_cntl &= ~(0x4c);
X aty_st_8(CRTC_GEN_CNTL, gen_cntl, info);
X
-#ifdef CONFIG_ADB_PMU
+#ifdef CONFIG_PMAC_BACKLIGHT
X if ((_machine == _MACH_Pmac) && !blank)
- pmu_enable_backlight(1);
-#endif


+ set_backlight_enable(1);
+#endif /* CONFIG_PMAC_BACKLIGHT */
X }
X
X

@@ -4954,6 +5003,40 @@
X return result;
X }
X #endif /* CONFIG_PMAC_PBOOK */


+
+#ifdef CONFIG_PMAC_BACKLIGHT
+static int backlight_conv[] = {

+ 0x00, 0x3f, 0x4c, 0x59, 0x66, 0x73, 0x80, 0x8d,
+ 0x9a, 0xa7, 0xb4, 0xc1, 0xcf, 0xdc, 0xe9, 0xff
+};
+
+static int
+aty_set_backlight_enable(int on, int level, void* data)
+{
+ struct fb_info_aty *info = (struct fb_info_aty *)data;
+ unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, info);
+
+ reg |= (BLMOD_EN | BIASMOD_EN);


+ if (on && level > BACKLIGHT_OFF) {

+ reg &= ~BIAS_MOD_LEVEL_MASK;
+ reg |= (backlight_conv[level] << BIAS_MOD_LEVEL_SHIFT);
+ } else {
+ reg &= ~BIAS_MOD_LEVEL_MASK;
+ reg |= (backlight_conv[0] << BIAS_MOD_LEVEL_SHIFT);
+ }
+ aty_st_lcd(LCD_MISC_CNTL, reg, info);


+
+ return 0;
+}
+
+static int

+aty_set_backlight_level(int level, void* data)
+{
+ return aty_set_backlight_enable(1, level, data);
+}


+
+#endif /* CONFIG_PMAC_BACKLIGHT */

+
X
X #ifdef MODULE
X int __init init_module(void)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/video/chipsfb.c linux/drivers/video/chipsfb.c
--- v2.4.0-test8/linux/drivers/video/chipsfb.c Fri Aug 4 18:06:34 2000
+++ linux/drivers/video/chipsfb.c Sun Sep 17 09:48:05 2000
@@ -35,6 +35,9 @@
X #include <asm/io.h>
X #include <asm/prom.h>
X #include <asm/pci-bridge.h>


+#ifdef CONFIG_PMAC_BACKLIGHT
+#include <asm/backlight.h>
+#endif

X #include <linux/adb.h>
X #include <linux/pmu.h>
X
@@ -245,7 +248,9 @@
X // used to disable backlight only for blank > 1, but it seems
X // useful at blank = 1 too (saves battery, extends backlight life)
X if (blank) {
- pmu_enable_backlight(0);
+#ifdef CONFIG_PMAC_BACKLIGHT


+ set_backlight_enable(0);
+#endif /* CONFIG_PMAC_BACKLIGHT */

X /* get the palette from the chip */
X for (i = 0; i < 256; ++i) {
X out_8(p->io_base + 0x3c7, i);
@@ -262,7 +267,9 @@
X out_8(p->io_base + 0x3c9, 0);
X }
X } else {
- pmu_enable_backlight(1);
+#ifdef CONFIG_PMAC_BACKLIGHT


+ set_backlight_enable(1);
+#endif /* CONFIG_PMAC_BACKLIGHT */

X for (i = 0; i < 256; ++i) {
X out_8(p->io_base + 0x3c8, i);
X udelay(1);
@@ -673,8 +680,10 @@
X /* Clear the entire framebuffer */
X memset(p->frame_buffer, 0, 0x100000);
X
+#ifdef CONFIG_PMAC_BACKLIGHT
X /* turn on the backlight */
- pmu_enable_backlight(1);


+ set_backlight_enable(1);
+#endif /* CONFIG_PMAC_BACKLIGHT */
X

X init_chips(p);
X }
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/video/controlfb.c linux/drivers/video/controlfb.c
--- v2.4.0-test8/linux/drivers/video/controlfb.c Fri Aug 4 18:06:34 2000
+++ linux/drivers/video/controlfb.c Sun Sep 17 09:48:05 2000
@@ -122,6 +122,8 @@
X struct fb_info *info);
X static int control_set_cmap(struct fb_cmap *cmap, int kspc, int con,
X struct fb_info *info);
+static int control_mmap(struct fb_info *info, struct file *file,
+ struct vm_area_struct *vma);
X
X
X static int controlfb_getcolreg(u_int regno, u_int *red, u_int *green,
@@ -171,6 +173,7 @@
X fb_get_cmap: control_get_cmap,
X fb_set_cmap: control_set_cmap,
X fb_pan_display: control_pan_display,
+ fb_mmap: control_mmap,
X };
X
X
@@ -327,6 +330,48 @@


X return 0;
X }
X

+/* Private mmap since we want to have a different caching on the framebuffer
+ * for controlfb.
+ * Note there's no locking in here; it's done in fb_mmap() in fbmem.c.
+ */
+static int control_mmap(struct fb_info *info, struct file *file,
+ struct vm_area_struct *vma)
+{
+ struct fb_ops *fb = info->fbops;
+ struct fb_fix_screeninfo fix;
+ struct fb_var_screeninfo var;
+ unsigned long off, start;
+ u32 len;
+
+ fb->fb_get_fix(&fix, PROC_CONSOLE(info), info);
+ off = vma->vm_pgoff << PAGE_SHIFT;
+
+ /* frame buffer memory */
+ start = fix.smem_start;
+ len = PAGE_ALIGN((start & ~PAGE_MASK)+fix.smem_len);
+ if (off >= len) {
+ /* memory mapped io */
+ off -= len;
+ fb->fb_get_var(&var, PROC_CONSOLE(info), info);
+ if (var.accel_flags)
+ return -EINVAL;
+ start = fix.mmio_start;
+ len = PAGE_ALIGN((start & ~PAGE_MASK)+fix.mmio_len);
+ pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE|_PAGE_GUARDED;
+ } else {
+ /* framebuffer */
+ pgprot_val(vma->vm_page_prot) |= _PAGE_WRITETHRU;
+ }
+ start &= PAGE_MASK;
+ vma->vm_pgoff = off >> PAGE_SHIFT;
+ if (io_remap_page_range(vma->vm_start, off,
+ vma->vm_end - vma->vm_start, vma->vm_page_prot))
+ return -EAGAIN;


+
+ return 0;
+}
+
+

X /******************** End of controlfb_ops implementation ********************/
X /* (new one that is) */
X
@@ -466,11 +511,6 @@
X }
X }
X
-#ifdef CONFIG_FB_COMPAT_XPMAC
-extern struct vc_mode display_info;
-extern struct fb_info *console_fb_info;
-#endif /* CONFIG_FB_COMPAT_XPMAC */
-
X static inline int control_vram_reqd(int video_mode, int color_mode)
X {
X return (control_reg_init[video_mode-1]->vres
@@ -483,12 +523,14 @@
X struct adb_request req;
X int i;
X
+#ifdef CONFIG_ADB_CUDA
X for (i = 0; i < 3; ++i) {


X cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,

X 0x50, i + 1, params[i]);
X while (!req.complete)
X cuda_poll();
X }
+#endif
X }
X
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/video/cyber2000fb.c linux/drivers/video/cyber2000fb.c
--- v2.4.0-test8/linux/drivers/video/cyber2000fb.c Sun Aug 6 11:25:46 2000
+++ linux/drivers/video/cyber2000fb.c Mon Sep 18 15:15:22 2000


@@ -1,7 +1,11 @@
X /*

- * Linux/drivers/video/cyber2000fb.c
+ * linux/drivers/video/cyber2000fb.c


X *
- * Copyright (C) 1998-2000 Russell King
+ * Copyright (C) 1998-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X *

X * Integraphics CyberPro 2000, 2010 and 5000 frame buffer device
X *
@@ -268,9 +272,9 @@
X if (regno >= NR_PALETTE)
X return 1;
X
- red >>= 10;
- green >>= 10;
- blue >>= 10;
+ red >>= 8;
+ green >>= 8;
+ blue >>= 8;
X
X cfb->palette[regno].red = red;
X cfb->palette[regno].green = green;
@@ -706,6 +710,7 @@
X int err;
X
X hw->width = var->xres_virtual;
+ hw->palette_ctrl = 0x06;
X
X switch (var->bits_per_pixel) {
X #ifdef FBCON_HAS_CFB8
@@ -713,7 +718,6 @@
X hw->pixformat = PIXFORMAT_8BPP;
X hw->visualid = VISUALID_256;
X hw->pitch = hw->width >> 3;
- hw->palette_ctrl = 0x04;
X break;
X #endif
X #ifdef FBCON_HAS_CFB16
@@ -722,14 +726,14 @@
X hw->pixformat = PIXFORMAT_16BPP;
X hw->visualid = VISUALID_64K;
X hw->pitch = hw->width >> 2;
- hw->palette_ctrl = 0x14;
+ hw->palette_ctrl |= 0x10;
X break;
X #endif
X case 15:/* DIRECTCOLOUR, 32k */
X hw->pixformat = PIXFORMAT_16BPP;
X hw->visualid = VISUALID_32K;
X hw->pitch = hw->width >> 2;
- hw->palette_ctrl = 0x14;
+ hw->palette_ctrl |= 0x10;


X break;
X
X #endif

@@ -739,7 +743,7 @@
X hw->visualid = VISUALID_16M;
X hw->width *= 3;
X hw->pitch = hw->width >> 3;
- hw->palette_ctrl = 0x14;
+ hw->palette_ctrl |= 0x10;
X break;
X #endif
X default:
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/video/cyber2000fb.h linux/drivers/video/cyber2000fb.h
--- v2.4.0-test8/linux/drivers/video/cyber2000fb.h Tue Jun 20 14:14:51 2000
+++ linux/drivers/video/cyber2000fb.h Mon Sep 18 15:15:22 2000
@@ -1,5 +1,11 @@
X /*
- * linux/drivers/video/cyber2000fb.h
+ * linux/drivers/video/cyber2000fb.h
+ *


+ * Copyright (C) 1998-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X *

X * Integraphics Cyber2000 frame buffer device
X */
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/video/fbcon.c linux/drivers/video/fbcon.c
--- v2.4.0-test8/linux/drivers/video/fbcon.c Mon Jul 24 18:24:26 2000
+++ linux/drivers/video/fbcon.c Sun Oct 1 20:35:16 2000
@@ -143,7 +143,7 @@
X * if dispsw->cursor is NULL, use Atari alike software cursor
X */
X
-static int cursor_drawn = 0;
+static int cursor_drawn;
X
X #define CURSOR_DRAW_DELAY (1)
X
@@ -154,8 +154,8 @@
X #define MAC_CURSOR_BLINK_RATE (32)
X #define DEFAULT_CURSOR_BLINK_RATE (20)
X
-static int vbl_cursor_cnt = 0;
-static int cursor_on = 0;
+static int vbl_cursor_cnt;
+static int cursor_on;
X static int cursor_blink_rate;
X
X static inline void cursor_undrawn(void)
@@ -218,7 +218,7 @@
X /*
X * On the Macintoy, there may or may not be a working VBL int. We need to probe
X */
-static int vbl_detected = 0;
+static int vbl_detected;
X
X static void fbcon_vbl_detect(int irq, void *dummy, struct pt_regs *fp)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/video/fbmem.c linux/drivers/video/fbmem.c
--- v2.4.0-test8/linux/drivers/video/fbmem.c Sun Aug 6 11:25:46 2000
+++ linux/drivers/video/fbmem.c Sun Oct 1 20:35:16 2000
@@ -286,10 +286,10 @@
X
X
X struct fb_info *registered_fb[FB_MAX];
-int num_registered_fb = 0;
+int num_registered_fb;
X extern int fbcon_softback_size;
X
-static int first_fb_vc = 0;
+static int first_fb_vc;
X static int last_fb_vc = MAX_NR_CONSOLES-1;
X static int fbcon_is_default = 1;
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/video/matrox/matroxfb_base.c linux/drivers/video/matrox/matroxfb_base.c
--- v2.4.0-test8/linux/drivers/video/matrox/matroxfb_base.c Tue Aug 29 14:09:15 2000
+++ linux/drivers/video/matrox/matroxfb_base.c Sun Oct 1 20:35:16 2000
@@ -1286,43 +1286,43 @@
X };
X
X /* initialized by setup, see explanation at end of file (search for MODULE_PARM_DESC) */
-static unsigned int mem = 0; /* "matrox:mem:xxxxxM" */
+static unsigned int mem; /* "matrox:mem:xxxxxM" */
X static int option_precise_width = 1; /* cannot be changed, option_precise_width==0 must imply noaccel */
-static int inv24 = 0; /* "matrox:inv24" */
+static int inv24; /* "matrox:inv24" */
X static int cross4MB = -1; /* "matrox:cross4MB" */
-static int disabled = 0; /* "matrox:disabled" */
-static int noaccel = 0; /* "matrox:noaccel" */
-static int nopan = 0; /* "matrox:nopan" */
-static int no_pci_retry = 0; /* "matrox:nopciretry" */
-static int novga = 0; /* "matrox:novga" */
-static int nobios = 0; /* "matrox:nobios" */
+static int disabled; /* "matrox:disabled" */
+static int noaccel; /* "matrox:noaccel" */
+static int nopan; /* "matrox:nopan" */
+static int no_pci_retry; /* "matrox:nopciretry" */
+static int novga; /* "matrox:novga" */
+static int nobios; /* "matrox:nobios" */
X static int noinit = 1; /* "matrox:init" */
-static int inverse = 0; /* "matrox:inverse" */
+static int inverse; /* "matrox:inverse" */
X static int hwcursor = 1; /* "matrox:nohwcursor" */
X static int blink = 1; /* "matrox:noblink" */
-static int sgram = 0; /* "matrox:sgram" */
+static int sgram; /* "matrox:sgram" */
X #ifdef CONFIG_MTRR
X static int mtrr = 1; /* "matrox:nomtrr" */
X #endif
-static int grayscale = 0; /* "matrox:grayscale" */
-static unsigned int fastfont = 0; /* "matrox:fastfont:xxxxx" */
+static int grayscale; /* "matrox:grayscale" */
+static unsigned int fastfont; /* "matrox:fastfont:xxxxx" */
X static int dev = -1; /* "matrox:dev:xxxxx" */
X static unsigned int vesa = ~0; /* "matrox:vesa:xxxxx" */
X static int depth = -1; /* "matrox:depth:xxxxx" */
-static unsigned int xres = 0; /* "matrox:xres:xxxxx" */
-static unsigned int yres = 0; /* "matrox:yres:xxxxx" */
+static unsigned int xres; /* "matrox:xres:xxxxx" */
+static unsigned int yres; /* "matrox:yres:xxxxx" */
X static unsigned int upper = ~0; /* "matrox:upper:xxxxx" */
X static unsigned int lower = ~0; /* "matrox:lower:xxxxx" */
-static unsigned int vslen = 0; /* "matrox:vslen:xxxxx" */
+static unsigned int vslen; /* "matrox:vslen:xxxxx" */
X static unsigned int left = ~0; /* "matrox:left:xxxxx" */
X static unsigned int right = ~0; /* "matrox:right:xxxxx" */
-static unsigned int hslen = 0; /* "matrox:hslen:xxxxx" */
-static unsigned int pixclock = 0; /* "matrox:pixclock:xxxxx" */
+static unsigned int hslen; /* "matrox:hslen:xxxxx" */
+static unsigned int pixclock; /* "matrox:pixclock:xxxxx" */
X static int sync = -1; /* "matrox:sync:xxxxx" */
-static unsigned int fv = 0; /* "matrox:fv:xxxxx" */
-static unsigned int fh = 0; /* "matrox:fh:xxxxxk" */
-static unsigned int maxclk = 0; /* "matrox:maxclk:xxxxM" */
-static int dfp = 0; /* "matrox:dfp */
+static unsigned int fv; /* "matrox:fv:xxxxx" */
+static unsigned int fh; /* "matrox:fh:xxxxxk" */
+static unsigned int maxclk; /* "matrox:maxclk:xxxxM" */
+static int dfp; /* "matrox:dfp */
X static int memtype = -1; /* "matrox:memtype:xxx" */
X static char fontname[64]; /* "matrox:font:xxxxx" */
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/video/offb.c linux/drivers/video/offb.c
--- v2.4.0-test8/linux/drivers/video/offb.c Fri Aug 4 18:06:34 2000
+++ linux/drivers/video/offb.c Sun Sep 17 09:48:05 2000
@@ -43,6 +43,15 @@
X
X static int currcon = 0;
X
+/* Supported palette hacks */
+enum {
+ cmap_unknown,
+ cmap_m64, /* ATI Mach64 */
+ cmap_r128, /* ATI Rage128 */
+ cmap_M3A, /* ATI Rage Mobility M3 Head A */
+ cmap_M3B /* ATI Rage Mobility M3 Head B */
+};
+
X struct fb_info_offb {
X struct fb_info info;
X struct fb_fix_screeninfo fix;
@@ -51,7 +60,7 @@
X struct { u_char red, green, blue, pad; } palette[256];
X volatile unsigned char *cmap_adr;
X volatile unsigned char *cmap_data;
- int is_rage_128;
+ int cmap_type;
X union {
X #ifdef FBCON_HAS_CFB16
X u16 cfb16[16];
@@ -408,21 +417,27 @@
X fix->type = FB_TYPE_PACKED_PIXELS;
X fix->type_aux = 0;
X
- info->is_rage_128 = 0;
+ info->cmap_type = cmap_unknown;
X if (depth == 8)
X {
X /* XXX kludge for ati */
- if (strncmp(name, "ATY,Rage128", 11) == 0) {
- if (dp) {
+ if (dp && !strncmp(name, "ATY,Rage128", 11)) {
X unsigned long regbase = dp->addrs[2].address;
- info->cmap_adr = ioremap(regbase, 0x1FFF) + 0x00b0;
- info->cmap_data = info->cmap_adr + 4;
- info->is_rage_128 = 1;
- }
- } else if (strncmp(name, "ATY,", 4) == 0) {
+ info->cmap_adr = ioremap(regbase, 0x1FFF);
+ info->cmap_type = cmap_r128;
+ } else if (dp && !strncmp(name, "ATY,RageM3pA", 12)) {
+ unsigned long regbase = dp->parent->addrs[2].address;
+ info->cmap_adr = ioremap(regbase, 0x1FFF);
+ info->cmap_type = cmap_M3A;
+ } else if (dp && !strncmp(name, "ATY,RageM3pB", 12)) {
+ unsigned long regbase = dp->parent->addrs[2].address;
+ info->cmap_adr = ioremap(regbase, 0x1FFF);
+ info->cmap_type = cmap_M3B;
+ } else if (!strncmp(name, "ATY,", 4)) {
X unsigned long base = address & 0xff000000UL;
X info->cmap_adr = ioremap(base + 0x7ff000, 0x1000) + 0xcc0;
X info->cmap_data = info->cmap_adr + 1;
+ info->cmap_type = cmap_m64;
X }
X fix->visual = info->cmap_adr ? FB_VISUAL_PSEUDOCOLOR
X : FB_VISUAL_STATIC_PSEUDOCOLOR;
@@ -580,7 +595,7 @@
X display_info.cmap_data_address = 0;
X display_info.disp_reg_address = 0;
X /* XXX kludge for ati */
- if (strncmp(name, "ATY,", 4) == 0) {
+ if (info->cmap_type == cmap_m64) {
X unsigned long base = address & 0xff000000UL;
X display_info.disp_reg_address = base + 0x7ffc00;
X display_info.cmap_adr_address = base + 0x7ffcc0;
@@ -628,11 +643,32 @@
X
X if (blank)
X for (i = 0; i < 256; i++) {
- *info2->cmap_adr = i;
- mach_eieio();
- for (j = 0; j < 3; j++) {
- *info2->cmap_data = 0;
- mach_eieio();
+ switch(info2->cmap_type) {
+ case cmap_m64:
+ *info2->cmap_adr = i;
+ mach_eieio();
+ for (j = 0; j < 3; j++) {
+ *info2->cmap_data = 0;
+ mach_eieio();
+ }
+ break;
+ case cmap_M3A:
+ /* Clear PALETTE_ACCESS_CNTL in DAC_CNTL */
+ out_le32((unsigned *)(info2->cmap_adr + 0x58),
+ in_le32((unsigned *)(info2->cmap_adr + 0x58)) & ~0x20);
+ case cmap_r128:
+ /* Set palette index & data */
+ out_8(info2->cmap_adr + 0xb0, i);
+ out_le32((unsigned *)(info2->cmap_adr + 0xb4), 0);
+ break;
+ case cmap_M3B:
+ /* Set PALETTE_ACCESS_CNTL in DAC_CNTL */
+ out_le32((unsigned *)(info2->cmap_adr + 0x58),
+ in_le32((unsigned *)(info2->cmap_adr + 0x58)) | 0x20);
+ /* Set palette index & data */
+ out_8(info2->cmap_adr + 0xb0, i);
+ out_le32((unsigned *)(info2->cmap_adr + 0xb4), 0);
+ break;
X }
X }
X else
@@ -682,18 +718,36 @@
X info2->palette[regno].green = green;
X info2->palette[regno].blue = blue;
X
- *info2->cmap_adr = regno;/* On some chipsets, add << 3 in 15 bits */
- mach_eieio();
- if (info2->is_rage_128) {
- out_le32((unsigned int *)info2->cmap_data,
- (red << 16 | green << 8 | blue));
- } else {
+ switch(info2->cmap_type) {
+ case cmap_m64:
+ *info2->cmap_adr = regno;
+ mach_eieio();
X *info2->cmap_data = red;
- mach_eieio();
- *info2->cmap_data = green;
- mach_eieio();
- *info2->cmap_data = blue;
- mach_eieio();
+ mach_eieio();
+ *info2->cmap_data = green;
+ mach_eieio();
+ *info2->cmap_data = blue;
+ mach_eieio();
+ break;
+ case cmap_M3A:
+ /* Clear PALETTE_ACCESS_CNTL in DAC_CNTL */
+ out_le32((unsigned *)(info2->cmap_adr + 0x58),
+ in_le32((unsigned *)(info2->cmap_adr + 0x58)) & ~0x20);
+ case cmap_r128:
+ /* Set palette index & data */
+ out_8(info2->cmap_adr + 0xb0, regno);
+ out_le32((unsigned *)(info2->cmap_adr + 0xb4),
+ (red << 16 | green << 8 | blue));
+ break;
+ case cmap_M3B:
+ /* Set PALETTE_ACCESS_CNTL in DAC_CNTL */
+ out_le32((unsigned *)(info2->cmap_adr + 0x58),
+ in_le32((unsigned *)(info2->cmap_adr + 0x58)) | 0x20);
+ /* Set palette index & data */
+ out_8(info2->cmap_adr + 0xb0, regno);
+ out_le32((unsigned *)(info2->cmap_adr + 0xb4),
+ (red << 16 | green << 8 | blue));
+ break;
X }
X
X if (regno < 16)
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/video/riva/fbdev.c linux/drivers/video/riva/fbdev.c
--- v2.4.0-test8/linux/drivers/video/riva/fbdev.c Mon Jul 31 11:21:37 2000
+++ linux/drivers/video/riva/fbdev.c Mon Sep 18 14:57:01 2000
@@ -582,7 +582,7 @@
X
X riva_boards = riva_board_list_add(riva_boards, rinfo);
X
- pd->driver_data = rinfo;
+ pci_set_drvdata (pd, rinfo);
X
X printk ("PCI Riva NV%d framebuffer ver %s (%s, %dMB @ 0x%lX)\n",
X rinfo->riva.Architecture,
@@ -610,7 +610,7 @@
X
X static void __devexit rivafb_remove_one (struct pci_dev *pd)
X {
- struct rivafb_info *board = pd->driver_data;
+ struct rivafb_info *board = pci_get_drvdata (pd);
X
X if (!board)
X return;
@@ -630,6 +630,8 @@
X board->base1_region_size);
X
X kfree (board);
+
+ pci_set_drvdata (pd, NULL);
X }
X
X
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/video/sa1100fb.c linux/drivers/video/sa1100fb.c
--- v2.4.0-test8/linux/drivers/video/sa1100fb.c Sun Aug 13 09:54:15 2000
+++ linux/drivers/video/sa1100fb.c Mon Sep 18 15:15:22 2000
@@ -43,7 +43,17 @@
X *
X * 2000/08/09:
X * XP860 support added
- * Kunihiko IMAI <???>
+ * Kunihiko IMAI <im...@vasara.co.jp>
+ *
+ * 2000/08/19:
+ * Allows standard options to be passed on the kernel command line
+ * for most common passive displays.
+ * Mark Huang <mhu...@livetoy.com>
+ *
+ * 2000/08/29:
+ * s/save_flags_cli/local_irq_save/
+ * remove unneeded extra save_flags_cli in
+ * sa1100fb_enable_lcd_controller


X */
X
X #include <linux/config.h>

@@ -164,6 +174,7 @@
X /* Shadows for LCD controller registers */
X struct sa1100fb_lcd_reg {
X Address dbar1;
+ Address dbar2;
X Word lccr0;
X Word lccr1;
X Word lccr2;
@@ -667,6 +678,16 @@
X init_var.grayscale = 0;
X init_var.sync = 0;
X init_var.pixclock = 171521;
+ } else if (machine_is_cerf()) {
+ current_par.max_xres = 320;
+ current_par.max_yres = 240;
+ current_par.max_bpp = 8;
+ init_var.red.length = 4;
+ init_var.green.length = 4;
+ init_var.blue.length = 4;
+ init_var.grayscale = 0;
+ init_var.sync = 0;
+ init_var.pixclock = 171521;
X } else if (machine_is_bitsy()) {
X current_par.max_xres = 320;
X current_par.max_yres = 240;
@@ -784,8 +805,8 @@
X u_int required_pages;
X u_int extra_pages;
X u_int order;
+ struct page *page;
X char *allocated_region;
- struct page *page;
X
X if (VideoMemRegion != NULL)
X return -EINVAL;
@@ -885,10 +906,11 @@
X DPRINTK("activating\n");
X
X /* Disable interrupts and save status */
- save_flags_cli(flags); // disable the interrupts and save flags
+ local_irq_save(flags); // disable the interrupts and save flags
X
X /* Reset the LCD Controller's DMA address if it has changed */
X lcd_shadow.dbar1 = (Address)current_par.p_palette_base;
+ lcd_shadow.dbar2 = (Address)(current_par.p_screen_base + (current_par.xres * current_par.yres * current_par.bits_per_pixel / 8 / 2));
X
X DPRINTK("Configuring xres = %d, yres = %d\n",var->xres, var->yres);
X
@@ -945,6 +967,22 @@
X LCCR3_OutEnH + LCCR3_PixFlEdg + LCCR3_VrtSnchH +
X LCCR3_HorSnchH + LCCR3_ACBsCntOff +
X LCCR3_ACBsDiv(2) + LCCR3_PixClkDiv(44);
+ } else if (machine_is_cerf()) {
+ DPRINTK("Configuring Cerf LCD\n");
+ lcd_shadow.lccr0 =
+ LCCR0_LEN + LCCR0_Color + LCCR0_Sngl +
+ LCCR0_LDM + LCCR0_BAM + LCCR0_ERM + LCCR0_Pas +
+ LCCR0_LtlEnd + LCCR0_DMADel(0);
+ lcd_shadow.lccr1 =
+ LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(6) +
+ LCCR1_BegLnDel(61) + LCCR1_EndLnDel(9);
+ lcd_shadow.lccr2 =
+ LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(1) +
+ LCCR2_BegFrmDel(3) + LCCR2_EndFrmDel(0);
+ lcd_shadow.lccr3 =
+ LCCR3_OutEnH + LCCR3_PixFlEdg + LCCR3_VrtSnchH +
+ LCCR3_HorSnchH + LCCR3_ACBsCntOff +
+ LCCR3_ACBsDiv(2) + LCCR3_PixClkDiv(38);
X } else if (machine_is_lart()) {
X DPRINTK("Configuring LART LCD\n");
X lcd_shadow.lccr0 =
@@ -1034,13 +1072,14 @@
X }
X
X /* Restore interrupt status */


- restore_flags(flags);
+ local_irq_restore(flags);
X

X if (( LCCR0 != lcd_shadow.lccr0 ) ||
X ( LCCR1 != lcd_shadow.lccr1 ) ||
X ( LCCR2 != lcd_shadow.lccr2 ) ||
X ( LCCR3 != lcd_shadow.lccr3 ) ||
- ( DBAR1 != lcd_shadow.dbar1 ))
+ ( DBAR1 != lcd_shadow.dbar1 ) ||
+ ( DBAR2 != lcd_shadow.dbar2 ))
X {
X sa1100fb_enable_lcd_controller();
X }
@@ -1064,6 +1103,27 @@
X if (controller_state == LCD_MODE_DISABLE_BEFORE_ENABLE) {
X DPRINTK("sa1100fb_inter_handler: re-enabling LCD controller\n");
X sa1100fb_enable_lcd_controller();
+ } else {
+ /*
+ * Second half of sa1100fb_disable_lcd_controller()
+ */
+ if (machine_is_assabet()) {
+#ifdef CONFIG_SA1100_ASSABET
+ BCR_clear(BCR_LCD_ON);
+#endif
+ } else if (machine_is_bitsy()) {
+#ifdef CONFIG_SA1100_BITSY
+ if (current_par.controller_state != LCD_MODE_DISABLE_BEFORE_ENABLE)
+ clr_bitsy_egpio(EGPIO_BITSY_LCD_ON | EGPIO_BITSY_LCD_PCI | EGPIO_BITSY_LCD_5V_ON | EGPIO_BITSY_LVDD_ON);
+#endif
+ } else if (machine_is_penny()) {
+#ifdef CONFIG_SA1100_PENNY
+ FpgaLcdCS1 = 0x000; /* LCD Backlight to 0% */
+ FpgaPortI &= ~LCD_ON; /* Turn off LCD Backlight */
+#endif
+ } else if (machine_is_tifon()) {
+ GPCR = GPIO_GPIO(24); /* turn off display */
+ }
X }
X }
X LCSR = 0; /* Clear LCD Status Register */
@@ -1087,29 +1147,10 @@
X return;
X }
X
- if (machine_is_assabet()) {
-#ifdef CONFIG_SA1100_ASSABET
- BCR_clear(BCR_LCD_ON);
-#endif
- } else if (machine_is_bitsy()) {
-#ifdef CONFIG_SA1100_BITSY
- if (current_par.controller_state != LCD_MODE_DISABLE_BEFORE_ENABLE)
- clr_bitsy_egpio(EGPIO_BITSY_LCD_ON | EGPIO_BITSY_LCD_PCI | EGPIO_BITSY_LCD_5V_ON | EGPIO_BITSY_LVDD_ON);
-#endif
- } else if (machine_is_penny()) {
-#ifdef CONFIG_SA1100_PENNY
- FpgaLcdCS1 = 0x000; /* LCD Backlight to 0% */
- FpgaPortI &= ~LCD_ON; /* Turn off LCD Backlight */
-#endif
- } else if (machine_is_tifon()) {
- GPCR = GPIO_GPIO(24); /* turn off display */
- }
-
X LCSR = 0; /* Clear LCD Status Register */
X LCCR0 &= ~(LCCR0_LDM); /* Enable LCD Disable Done Interrupt */
X enable_irq(IRQ_LCD); /* Enable LCD IRQ */
X LCCR0 &= ~(LCCR0_LEN); /* Disable LCD Controller */
-
X }
X
X /*
@@ -1122,7 +1163,7 @@
X {
X u_long flags;


X
- save_flags_cli(flags);
+ local_irq_save(flags);
X

X /* Disable controller before changing parameters */
X if (current_par.controller_state == LCD_MODE_ENABLED) {
@@ -1135,14 +1176,20 @@
X current_par.v_palette_base[0] &= 0x0FFF;
X current_par.v_palette_base[0] |= SA1100_PALETTE_MODE_VAL(current_par.bits_per_pixel);
X
- /* disable the interrupts and save flags */
- save_flags_cli(flags);
+ /* Enable GPIO<9:2> for LCD usage if dual-scan */
+ if (lcd_shadow.lccr0 & LCCR0_SDS) {
+ GPDR |= 0x3fc;
+ GAFR |= 0x3fc;
+ }
X
- DBAR1 = lcd_shadow.dbar1;
+ /* Sequence from 11.7.10 */
X LCCR3 = lcd_shadow.lccr3;
X LCCR2 = lcd_shadow.lccr2;
X LCCR1 = lcd_shadow.lccr1;
- LCCR0 = lcd_shadow.lccr0;
+ LCCR0 = lcd_shadow.lccr0 & ~LCCR0_LEN;
+ DBAR1 = lcd_shadow.dbar1;
+ DBAR2 = lcd_shadow.dbar2;
+ LCCR0 |= LCCR0_LEN;
X
X if (machine_is_assabet()) {
X #ifdef CONFIG_SA1100_ASSABET
@@ -1172,7 +1219,7 @@
X
X }
X /* Restore interrupt status */


- restore_flags(flags);
+ local_irq_restore(flags);
X }
X

X /*
@@ -1263,6 +1310,9 @@
X } else if (machine_is_bitsy()) {
X GPDR = (GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 | GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9 | GPIO_LDD8);
X GAFR |= (GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 | GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9 | GPIO_LDD8);
+ } else if (machine_is_cerf()) {
+ GPDR |= 0x3fc;
+ GAFR |= 0x3fc;
X } else if (machine_is_penny()) {
X #ifdef CONFIG_SA1100_PENNY
X GPDR |= GPIO_GPDR_GFX; /* GPIO Data Direction register for LCD data bits 8-11 */
@@ -1286,3 +1336,35 @@


X
X return 0;
X }

+
+int __init sa1100fb_setup(char *options)
+{
+ char *this_opt;
+
+ if (!options || !*options)
+ return 0;
+
+ for (this_opt = strtok(options, ","); this_opt;
+ this_opt = strtok(NULL, ",")) {
+
+ if (!strncmp(this_opt, "bpp:", 4))
+ current_par.max_bpp = simple_strtoul(this_opt+4, NULL, 0);
+
+ if (!strncmp(this_opt, "lccr0:", 6))
+ lcd_shadow.lccr0 = simple_strtoul(this_opt+6, NULL, 0);
+ if (!strncmp(this_opt, "lccr1:", 6)) {
+ lcd_shadow.lccr1 = simple_strtoul(this_opt+6, NULL, 0);
+ current_par.max_xres = (lcd_shadow.lccr1 & 0x3ff) + 16;
+ }
+ if (!strncmp(this_opt, "lccr2:", 6)) {
+ lcd_shadow.lccr2 = simple_strtoul(this_opt+6, NULL, 0);
+ current_par.max_yres = (lcd_shadow.lccr0 & LCCR0_SDS) ?
+ ((lcd_shadow.lccr2 & 0x3ff) + 1) * 2 :
+ ((lcd_shadow.lccr2 & 0x3ff) + 1);
+ }
+ if (!strncmp(this_opt, "lccr3:", 6))
+ lcd_shadow.lccr3 = simple_strtoul(this_opt+6, NULL, 0);


+ }
+ return 0;
+}
+

diff -u --recursive --new-file v2.4.0-test8/linux/drivers/video/sisfb.c linux/drivers/video/sisfb.c
--- v2.4.0-test8/linux/drivers/video/sisfb.c Mon Aug 28 21:25:25 2000
+++ linux/drivers/video/sisfb.c Mon Sep 18 14:57:01 2000
@@ -356,8 +356,6 @@
X 0x0B, 0x0C, 0x0D, 0x0F, 0x10
X };
X
-#ifdef CONFIG_FB_SIS_LINUXBIOS
-
X #define Monitor1Sense 0x20
X
X unsigned char SRegsInit[] = {
@@ -371,6 +369,8 @@
X 0x8e, 0x40, 0x00, 0x00, 0x08, 0x00, 0xff, 0xff
X };
X
+#ifdef CONFIG_FB_SIS_LINUXBIOS
+
X unsigned char SRegs[] = {
X 0x03, 0x01, 0x0F, 0x00, 0x0E, 0xA1, 0x02, 0x13,
X 0x3F, 0x86, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
@@ -1440,7 +1440,6 @@
X
X static u16 get_modeID_length(unsigned long ROMAddr, u16 ModeNo)
X {
- unsigned char ModeID;
X u16 modeidlength;
X u16 usModeIDOffset;
X unsigned short PreviousWord,CurrentWord;
@@ -2804,7 +2803,6 @@
X u16 cr30flag, cr31flag;
X unsigned long ROMAddr = rom_vbase;
X u16 BaseAddr = (u16) ivideo.vga_base;
- u_short i;
X
X P3c4 = BaseAddr + 0x14;
X P3d4 = BaseAddr + 0x24;
@@ -3420,7 +3418,6 @@
X struct board *b;
X int pdev_valid = 0;
X unsigned char jTemp;
- u32 cmd;
X
X outb(0x77, 0x80);
X
@@ -3448,10 +3445,8 @@
X return -1;
X
X #ifdef CONFIG_FB_SIS_LINUXBIOS
- pci_read_config_dword(pdev, PCI_COMMAND, &cmd);
- cmd |= PCI_COMMAND_IO;
- cmd |= PCI_COMMAND_MEMORY;
- pci_write_config_dword(pdev, PCI_COMMAND, cmd);
+ if (pci_enable_device(pdev))
+ return -EIO;
X #endif
X
X ivideo.video_base = pci_resource_start(pdev, 0);
diff -u --recursive --new-file v2.4.0-test8/linux/drivers/video/valkyriefb.c linux/drivers/video/valkyriefb.c
--- v2.4.0-test8/linux/drivers/video/valkyriefb.c Fri Aug 4 18:06:34 2000
+++ linux/drivers/video/valkyriefb.c Sun Sep 17 09:48:05 2000
@@ -425,12 +425,14 @@
X struct adb_request req;
X int i;
X
+#ifdef CONFIG_ADB_CUDA
X for (i = 0; i < 3; ++i) {


X cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,

X 0x50, i + 1, params[i]);
X while (!req.complete)
X cuda_poll();
X }
+#endif
X }
X
X static void __init init_valkyrie(struct fb_info_valkyrie *p)
diff -u --recursive --new-file v2.4.0-test8/linux/fs/Config.in linux/fs/Config.in
--- v2.4.0-test8/linux/fs/Config.in Mon Aug 14 13:31:10 2000
+++ linux/fs/Config.in Mon Sep 25 13:14:53 2000
@@ -76,7 +76,7 @@
X
X dep_tristate 'Coda file system support (advanced network fs)' CONFIG_CODA_FS $CONFIG_INET
X dep_tristate 'NFS file system support' CONFIG_NFS_FS $CONFIG_INET
- dep_mbool ' Provide NFSv3 client support (EXPERIMENTAL)' CONFIG_NFS_V3 $CONFIG_NFS_FS
+ dep_mbool ' Provide NFSv3 client support' CONFIG_NFS_V3 $CONFIG_NFS_FS
X dep_bool ' Root file system on NFS' CONFIG_ROOT_NFS $CONFIG_NFS_FS $CONFIG_IP_PNP
X
X dep_tristate 'NFS server support' CONFIG_NFSD $CONFIG_INET
@@ -100,8 +100,11 @@
X
X dep_tristate 'SMB file system support (to mount Windows shares etc.)' CONFIG_SMB_FS $CONFIG_INET
X if [ "$CONFIG_SMB_FS" != "n" ]; then
- string 'Default Remote NLS Option' CONFIG_SMB_NLS_REMOTE ""
- fi
+ bool ' Use a default NLS' CONFIG_SMB_NLS_DEFAULT
+ if [ "$CONFIG_SMB_NLS_DEFAULT" = "y" ]; then
+ string ' Default Remote NLS Option' CONFIG_SMB_NLS_REMOTE "cp437"
+ fi
+ fi
X if [ "$CONFIG_IPX" != "n" -o "$CONFIG_INET" != "n" ]; then
X tristate 'NCP file system support (to mount NetWare volumes)' CONFIG_NCP_FS
X source fs/ncpfs/Config.in
diff -u --recursive --new-file v2.4.0-test8/linux/fs/Makefile linux/fs/Makefile
--- v2.4.0-test8/linux/fs/Makefile Mon Aug 28 21:27:39 2000
+++ linux/fs/Makefile Mon Oct 2 11:54:11 2000
@@ -1,348 +1,91 @@
X #
X # Makefile for the Linux filesystems.
X #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (not a .c file).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile.
+# 14 Sep 2000, Christoph Hellwig <h...@caldera.de>
+# Rewritten to use lists instead of if-statements.
+#
X
-FILESYSTEMS = $(join $(SUB_DIRS),$(SUB_DIRS:%=/%.o))
X O_TARGET := fs.o
-O_OBJS = open.o read_write.o devices.o file_table.o buffer.o \
+
+export-objs := filesystems.o
+mod-subdirs := nls
+
+obj-y := open.o read_write.o devices.o file_table.o buffer.o \
X super.o block_dev.o stat.o exec.o pipe.o namei.o fcntl.o \
X ioctl.o readdir.o select.o fifo.o locks.o \
- dcache.o inode.o attr.o bad_inode.o file.o iobuf.o \
- $(BINFMTS) $(FILESYSTEMS)
-OX_OBJS := filesystems.o
-
-ALL_SUB_DIRS := coda minix ext2 fat msdos vfat proc isofs nfs umsdos ntfs \
- hpfs sysv smbfs ncpfs ufs efs affs romfs autofs hfs lockd \
- nfsd nls devpts devfs adfs partitions qnx4 udf bfs cramfs \
- openpromfs autofs4 ramfs jffs
-
-SUB_DIRS :=
+ dcache.o inode.o attr.o bad_inode.o file.o iobuf.o dnotify.o \
+ filesystems.o
X
X ifeq ($(CONFIG_QUOTA),y)
-O_OBJS += dquot.o
+obj-y += dquot.o
X else
-O_OBJS += noquot.o
-endif
-
-ifdef CONFIG_PROC_FS
-SUB_DIRS += proc
+obj-y += noquot.o
X endif
X
-SUB_DIRS += partitions
+subdir-$(CONFIG_PROC_FS) += proc
+subdir-y += partitions
X
X # Do not add any filesystems before this line
+subdir-$(CONFIG_EXT2_FS) += ext2
+subdir-$(CONFIG_CRAMFS) += cramfs
+subdir-$(CONFIG_RAMFS) += ramfs
+subdir-$(CONFIG_CODA_FS) += coda
+subdir-$(CONFIG_MINIX_FS) += minix
+subdir-$(CONFIG_FAT_FS) += fat
+subdir-$(CONFIG_MSDOS_FS) += msdos
+subdir-$(CONFIG_VFAT_FS) += vfat
+subdir-$(CONFIG_BFS_FS) += bfs
+subdir-$(CONFIG_ISO9660_FS) += isofs
+subdir-$(CONFIG_DEVFS_FS) += devfs
+subdir-$(CONFIG_HFS_FS) += hfs
+subdir-$(CONFIG_NFS_FS) += nfs
+subdir-$(CONFIG_NFSD) += nfsd
+subdir-$(CONFIG_LOCKD) += lockd
+subdir-$(CONFIG_NLS) += nls
+subdir-$(CONFIG_UMSDOS_FS) += umsdos
+subdir-$(CONFIG_SYSV_FS) += sysv
+subdir-$(CONFIG_SMB_FS) += smbfs
+subdir-$(CONFIG_NCP_FS) += ncpfs
+subdir-$(CONFIG_HPFS_FS) += hpfs
+subdir-$(CONFIG_NTFS_FS) += ntfs
+subdir-$(CONFIG_UFS_FS) += ufs
+subdir-$(CONFIG_EFS_FS) += efs
+subdir-$(CONFIG_JFFS_FS) += jffs
+subdir-$(CONFIG_AFFS_FS) += affs
+subdir-$(CONFIG_ROMFS_FS) += romfs
+subdir-$(CONFIG_QNX4FS_FS) += qnx4
+subdir-$(CONFIG_UDF_FS) += udf
+subdir-$(CONFIG_AUTOFS_FS) += autofs
+subdir-$(CONFIG_AUTOFS4_FS) += autofs4
+subdir-$(CONFIG_ADFS_FS) += adfs
+subdir-$(CONFIG_DEVPTS_FS) += devpts
+subdir-$(CONFIG_SUN_OPENPROMFS) += openpromfs
+
+
+obj-$(CONFIG_BINFMT_AOUT) += binfmt_aout.o
+obj-$(CONFIG_BINFMT_EM86) += binfmt_em86.o
+obj-$(CONFIG_BINFMT_MISC) += binfmt_misc.o
X
-ifeq ($(CONFIG_EXT2_FS),y)
-SUB_DIRS += ext2
-else
- ifeq ($(CONFIG_EXT2_FS),m)
- MOD_SUB_DIRS += ext2
- endif
-endif
-
-ifeq ($(CONFIG_CRAMFS),y)
-SUB_DIRS += cramfs
-else
- ifeq ($(CONFIG_CRAMFS),m)
- MOD_SUB_DIRS += cramfs
- endif
-endif
-
-ifeq ($(CONFIG_RAMFS),y)
-SUB_DIRS += ramfs
-else
- ifeq ($(CONFIG_RAMFS),m)
- MOD_SUB_DIRS += ramfs
- endif
-endif
-
-ifeq ($(CONFIG_CODA_FS),y)
-SUB_DIRS += coda
-else
- ifeq ($(CONFIG_CODA_FS),m)
- MOD_SUB_DIRS += coda
- endif
-endif
-
-ifeq ($(CONFIG_MINIX_FS),y)
-SUB_DIRS += minix
-else
- ifeq ($(CONFIG_MINIX_FS),m)
- MOD_SUB_DIRS += minix
- endif
-endif
-
-ifeq ($(CONFIG_FAT_FS),y)
-SUB_DIRS += fat
-else
- ifeq ($(CONFIG_FAT_FS),m)
- MOD_SUB_DIRS += fat
- endif
-endif
-
-ifeq ($(CONFIG_MSDOS_FS),y)
-SUB_DIRS += msdos
-else
- ifeq ($(CONFIG_MSDOS_FS),m)
- MOD_SUB_DIRS += msdos
- endif
-endif
-
-ifeq ($(CONFIG_VFAT_FS),y)
-SUB_DIRS += vfat
-else
- ifeq ($(CONFIG_VFAT_FS),m)
- MOD_SUB_DIRS += vfat
- endif
-endif
-
-ifeq ($(CONFIG_BFS_FS),y)
-SUB_DIRS += bfs
-else
- ifeq ($(CONFIG_BFS_FS),m)
- MOD_SUB_DIRS += bfs
- endif
-endif
-
-ifeq ($(CONFIG_ISO9660_FS),y)
-SUB_DIRS += isofs
-else
- ifeq ($(CONFIG_ISO9660_FS),m)
- MOD_SUB_DIRS += isofs
- endif
-endif
-
-ifdef CONFIG_DEVFS_FS
-SUB_DIRS += devfs
-endif
-
-ifeq ($(CONFIG_HFS_FS),y)
-SUB_DIRS += hfs
-else
- ifeq ($(CONFIG_HFS_FS),m)
- MOD_SUB_DIRS += hfs
- endif
-endif
-
-ifeq ($(CONFIG_NFS_FS),y)
-SUB_DIRS += nfs
-else
- ifeq ($(CONFIG_NFS_FS),m)
- MOD_SUB_DIRS += nfs
- endif
-endif
-
-ifeq ($(CONFIG_NFSD),y)
-CONFIG_LOCKD := y
-SUB_DIRS += nfsd
-else
- ifeq ($(CONFIG_NFSD),m)
- MOD_SUB_DIRS += nfsd
- endif
-endif
-
-ifeq ($(CONFIG_LOCKD),y)
-SUB_DIRS += lockd
-else
- ifeq ($(CONFIG_LOCKD),m)
- MOD_SUB_DIRS := lockd $(MOD_SUB_DIRS)
- endif
-endif
-
-# Since CONFIG_NLS might be set to y while there are modules
-# to be build in the nls/ directory, we need to enter the nls
-# directory every time, but with different rules.
-ifeq ($(CONFIG_NLS),y)
-SUB_DIRS += nls
-MOD_IN_SUB_DIRS += nls
-else
- ifeq ($(CONFIG_NLS),m)
- MOD_SUB_DIRS += nls
- endif
-endif
-
-ifeq ($(CONFIG_UMSDOS_FS),y)
-SUB_DIRS += umsdos
-else
- ifeq ($(CONFIG_UMSDOS_FS),m)
- MOD_SUB_DIRS += umsdos
- endif
-endif
-
-ifeq ($(CONFIG_SYSV_FS),y)
-SUB_DIRS += sysv
-else
- ifeq ($(CONFIG_SYSV_FS),m)
- MOD_SUB_DIRS += sysv
- endif
-endif
-
-ifeq ($(CONFIG_SMB_FS),y)
-SUB_DIRS += smbfs
-else
- ifeq ($(CONFIG_SMB_FS),m)
- MOD_SUB_DIRS += smbfs
- endif
-endif
-
-ifeq ($(CONFIG_NCP_FS),y)
-SUB_DIRS += ncpfs
-else
- ifeq ($(CONFIG_NCP_FS),m)
- MOD_SUB_DIRS += ncpfs
- endif
-endif
-
-ifeq ($(CONFIG_HPFS_FS),y)
-SUB_DIRS += hpfs
-else
- ifeq ($(CONFIG_HPFS_FS),m)
- MOD_SUB_DIRS += hpfs
- endif
-endif
-
-ifeq ($(CONFIG_NTFS_FS),y)
-SUB_DIRS += ntfs
-else
- ifeq ($(CONFIG_NTFS_FS),m)
- MOD_SUB_DIRS += ntfs
- endif
-endif
-
-ifeq ($(CONFIG_UFS_FS),y)
-SUB_DIRS += ufs
-else
- ifeq ($(CONFIG_UFS_FS),m)
- MOD_SUB_DIRS += ufs
- endif
-endif
-
-ifeq ($(CONFIG_EFS_FS),y)
-SUB_DIRS += efs
-else
- ifeq ($(CONFIG_EFS_FS),m)
- MOD_SUB_DIRS += efs
- endif
-endif
-
-ifeq ($(CONFIG_JFFS_FS),y)
-SUB_DIRS += jffs
-else
- ifeq ($(CONFIG_JFFS_FS),m)
- MOD_SUB_DIRS += jffs
- endif
-endif
-
-ifeq ($(CONFIG_AFFS_FS),y)
-SUB_DIRS += affs
-else
- ifeq ($(CONFIG_AFFS_FS),m)
- MOD_SUB_DIRS += affs
- endif
-endif
-
-ifeq ($(CONFIG_ROMFS_FS),y)
-SUB_DIRS += romfs
-else
- ifeq ($(CONFIG_ROMFS_FS),m)
- MOD_SUB_DIRS += romfs
- endif
-endif
-
-ifeq ($(CONFIG_QNX4FS_FS),y)
-SUB_DIRS += qnx4
-else
- ifeq ($(CONFIG_QNX4FS_FS),m)
- MOD_SUB_DIRS += qnx4
- endif
-endif
-
-ifeq ($(CONFIG_UDF_FS),y)
-SUB_DIRS += udf
-else
- ifeq ($(CONFIG_UDF_FS),m)
- MOD_SUB_DIRS += udf
- endif
-endif
-
-ifeq ($(CONFIG_AUTOFS_FS),y)
-SUB_DIRS += autofs
-else
- ifeq ($(CONFIG_AUTOFS_FS),m)
- MOD_SUB_DIRS += autofs
- endif
-endif
-
-ifeq ($(CONFIG_AUTOFS4_FS),y)
-SUB_DIRS += autofs4
-else
- ifeq ($(CONFIG_AUTOFS4_FS),m)
- MOD_SUB_DIRS += autofs4
- endif
-endif
-
-ifeq ($(CONFIG_ADFS_FS),y)
-SUB_DIRS += adfs
-else
- ifeq ($(CONFIG_ADFS_FS),m)
- MOD_SUB_DIRS += adfs
- endif
-endif
-
-ifeq ($(CONFIG_DEVPTS_FS),y)
-SUB_DIRS += devpts
-else
- ifeq ($(CONFIG_DEVPTS_FS),m)
- MOD_SUB_DIRS += devpts
- endif
-endif
+# binfmt_script is always there
+obj-y += binfmt_script.o
X
-ifeq ($(CONFIG_SUN_OPENPROMFS),y)
-SUB_DIRS += openpromfs
-else
- ifeq ($(CONFIG_SUN_OPENPROMFS),m)
- MOD_SUB_DIRS += openpromfs
- endif
-endif
+obj-$(CONFIG_BINFMT_ELF) += binfmt_elf.o
X
-ifeq ($(CONFIG_BINFMT_AOUT),y)
-BINFMTS += binfmt_aout.o
-else
- ifeq ($(CONFIG_BINFMT_AOUT),m)
- M_OBJS += binfmt_aout.o
- endif
-endif
+# persistent filesystems
+obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
X
-ifeq ($(CONFIG_BINFMT_EM86),y)
-BINFMTS += binfmt_em86.o
-else
- ifeq ($(CONFIG_BINFMT_EM86),m)
- M_OBJS += binfmt_em86.o
- endif
-endif
X
-ifeq ($(CONFIG_BINFMT_MISC),y)
-BINFMTS += binfmt_misc.o
-else
- ifeq ($(CONFIG_BINFMT_MISC),m)
- M_OBJS += binfmt_misc.o
- endif
-endif
+# Subdirectories that should be entered when MAKING_MODULES=1, even if set to 'y'.
+both-m := $(filter $(mod-subdirs), $(subdir-y))
X
-# binfmt_script is always there
-BINFMTS += binfmt_script.o
+# Translate to Rules.make lists.


+O_OBJS := $(filter-out $(export-objs), $(obj-y))
+OX_OBJS := $(filter $(export-objs), $(obj-y))
+M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m)))
+MX_OBJS := $(sort $(filter $(export-objs), $(obj-m)))
X

-ifeq ($(CONFIG_BINFMT_ELF),y)
-BINFMTS += binfmt_elf.o
-else
- ifeq ($(CONFIG_BINFMT_ELF),m)
- M_OBJS += binfmt_elf.o
- endif
-endif
+SUB_DIRS := $(subdir-y)
+MOD_SUB_DIRS := $(sort $(subdir-m) $(both-m))
+ALL_SUB_DIRS := $(sort $(subdir-y) $(subdir-m) $(subdir-n) $(subdir-))
X
X include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.0-test8/linux/fs/adfs/adfs.h linux/fs/adfs/adfs.h
--- v2.4.0-test8/linux/fs/adfs/adfs.h Wed Jul 5 21:38:44 2000
+++ linux/fs/adfs/adfs.h Mon Sep 18 15:14:06 2000
@@ -97,6 +97,7 @@
X /* dir_*.c */
X extern struct inode_operations adfs_dir_inode_operations;
X extern struct file_operations adfs_dir_operations;
+extern struct dentry_operations adfs_dentry_operations;
X extern struct adfs_dir_ops adfs_f_dir_ops;
X extern struct adfs_dir_ops adfs_fplus_dir_ops;
X
diff -u --recursive --new-file v2.4.0-test8/linux/fs/adfs/dir.c linux/fs/adfs/dir.c
--- v2.4.0-test8/linux/fs/adfs/dir.c Fri Aug 11 14:29:02 2000
+++ linux/fs/adfs/dir.c Mon Sep 18 15:14:06 2000
@@ -1,9 +1,13 @@
X /*
- * linux/fs/adfs/dir.c
+ * linux/fs/adfs/dir.c
X *
- * Copyright (C) 1999-2000 Russell King
+ * Copyright (C) 1999-2000 Russell King
X *
- * Common directory handling for ADFS


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Common directory handling for ADFS
X */
X #include <linux/config.h>
X #include <linux/version.h>
diff -u --recursive --new-file v2.4.0-test8/linux/fs/adfs/dir_f.c linux/fs/adfs/dir_f.c
--- v2.4.0-test8/linux/fs/adfs/dir_f.c Tue Sep 5 14:07:29 2000
+++ linux/fs/adfs/dir_f.c Mon Sep 18 15:14:06 2000
@@ -3,7 +3,11 @@
X *
X * Copyright (C) 1997-1999 Russell King
X *
- * E and F format directory handling


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * E and F format directory handling
X */
X #include <linux/version.h>
X #include <linux/errno.h>
diff -u --recursive --new-file v2.4.0-test8/linux/fs/adfs/dir_f.h linux/fs/adfs/dir_f.h
--- v2.4.0-test8/linux/fs/adfs/dir_f.h Sun Feb 6 17:45:25 2000
+++ linux/fs/adfs/dir_f.h Mon Sep 18 15:14:06 2000
@@ -1,9 +1,13 @@
X /*
- * linux/fs/adfs/dir_f.h
+ * linux/fs/adfs/dir_f.h
X *
- * Copyright (C) 1999 Russell King
+ * Copyright (C) 1999 Russell King
X *
- * Structures of directories on the F format disk


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Structures of directories on the F format disk
X */
X #ifndef ADFS_DIR_F_H
X #define ADFS_DIR_F_H
diff -u --recursive --new-file v2.4.0-test8/linux/fs/adfs/dir_fplus.c linux/fs/adfs/dir_fplus.c
--- v2.4.0-test8/linux/fs/adfs/dir_fplus.c Wed Jun 21 10:10:02 2000
+++ linux/fs/adfs/dir_fplus.c Mon Sep 18 15:14:06 2000


@@ -1,7 +1,11 @@
X /*

X * linux/fs/adfs/dir_fplus.c
X *
- * Copyright (C) 1997-1999 Russell King
+ * Copyright (C) 1997-1999 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

X */
X #include <linux/version.h>
X #include <linux/errno.h>
diff -u --recursive --new-file v2.4.0-test8/linux/fs/adfs/dir_fplus.h linux/fs/adfs/dir_fplus.h
--- v2.4.0-test8/linux/fs/adfs/dir_fplus.h Sun Feb 6 17:45:25 2000
+++ linux/fs/adfs/dir_fplus.h Mon Sep 18 15:14:06 2000
@@ -1,9 +1,13 @@
X /*
- * linux/fs/adfs/dir_fplus.h
+ * linux/fs/adfs/dir_fplus.h
X *
- * Copyright (C) 1999 Russell King
+ * Copyright (C) 1999 Russell King
X *
- * Structures of directories on the F+ format disk


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Structures of directories on the F+ format disk
X */
X
X #define ADFS_FPLUS_NAME_LEN 255
diff -u --recursive --new-file v2.4.0-test8/linux/fs/adfs/file.c linux/fs/adfs/file.c
--- v2.4.0-test8/linux/fs/adfs/file.c Wed Jun 21 10:10:02 2000
+++ linux/fs/adfs/file.c Wed Sep 27 13:41:33 2000
@@ -22,7 +22,6 @@
X #include <linux/version.h>
X #include <linux/errno.h>
X #include <linux/fs.h>
-#include <linux/ext2_fs.h>
X #include <linux/fcntl.h>
X #include <linux/sched.h>
X #include <linux/stat.h>
diff -u --recursive --new-file v2.4.0-test8/linux/fs/adfs/inode.c linux/fs/adfs/inode.c
--- v2.4.0-test8/linux/fs/adfs/inode.c Sat Jul 8 19:26:12 2000
+++ linux/fs/adfs/inode.c Mon Sep 18 15:14:06 2000


@@ -1,7 +1,11 @@
X /*

X * linux/fs/adfs/inode.c
X *
- * Copyright (C) 1997-1999 Russell King
+ * Copyright (C) 1997-1999 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

X */
X #include <linux/version.h>
X #include <linux/errno.h>
diff -u --recursive --new-file v2.4.0-test8/linux/fs/adfs/map.c linux/fs/adfs/map.c
--- v2.4.0-test8/linux/fs/adfs/map.c Wed Jun 21 10:10:02 2000
+++ linux/fs/adfs/map.c Mon Sep 18 15:14:06 2000


@@ -1,7 +1,11 @@
X /*

X * linux/fs/adfs/map.c
X *
- * Copyright (C) 1997-1999 Russell King
+ * Copyright (C) 1997-1999 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

X */
X #include <linux/version.h>
X #include <linux/errno.h>
diff -u --recursive --new-file v2.4.0-test8/linux/fs/adfs/super.c linux/fs/adfs/super.c
--- v2.4.0-test8/linux/fs/adfs/super.c Wed Jun 21 10:10:02 2000
+++ linux/fs/adfs/super.c Mon Sep 18 15:14:06 2000


@@ -1,7 +1,11 @@
X /*

X * linux/fs/adfs/super.c
X *
- * Copyright (C) 1997-1999 Russell King
+ * Copyright (C) 1997-1999 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

X */
X #include <linux/version.h>
X #include <linux/module.h>
@@ -425,7 +429,8 @@
X kfree(sb->u.adfs_sb.s_map);
X adfs_error(sb, "get root inode failed\n");
X goto error;
- }
+ } else
+ sb->s_root->d_op = &adfs_dentry_operations;
X return sb;
X
X error_free_bh:
diff -u --recursive --new-file v2.4.0-test8/linux/fs/attr.c linux/fs/attr.c
--- v2.4.0-test8/linux/fs/attr.c Mon May 8 14:31:13 2000
+++ linux/fs/attr.c Fri Sep 22 14:21:18 2000
@@ -9,6 +9,8 @@
X #include <linux/mm.h>
X #include <linux/string.h>
X #include <linux/smp_lock.h>
+#include <linux/dnotify.h>
+#include <linux/fcntl.h>
X
X /* Taken over from the old code... */
X
@@ -79,6 +81,28 @@
X mark_inode_dirty(inode);
X }
X
+static int setattr_mask(unsigned int ia_valid)
+{
+ unsigned long dn_mask = 0;
+
+ if (ia_valid & ATTR_UID)
+ dn_mask |= DN_ATTRIB;
+ if (ia_valid & ATTR_GID)
+ dn_mask |= DN_ATTRIB;
+ if (ia_valid & ATTR_SIZE)
+ dn_mask |= DN_MODIFY;
+ /* both times implies a utime(s) call */
+ if ((ia_valid & (ATTR_ATIME|ATTR_MTIME)) == (ATTR_ATIME|ATTR_MTIME))
+ dn_mask |= DN_ATTRIB;
+ else if (ia_valid & ATTR_ATIME)
+ dn_mask |= DN_ACCESS;
+ else if (ia_valid & ATTR_MTIME)
+ dn_mask |= DN_MODIFY;
+ if (ia_valid & ATTR_MODE)
+ dn_mask |= DN_ATTRIB;
+ return dn_mask;
+}
+
X int notify_change(struct dentry * dentry, struct iattr * attr)
X {
X struct inode *inode = dentry->d_inode;
@@ -101,5 +125,10 @@
X inode_setattr(inode, attr);
X }
X unlock_kernel();
+ if (!error) {
+ unsigned long dn_mask = setattr_mask(ia_valid);
+ if (dn_mask)
+ inode_dir_notify(dentry->d_parent->d_inode, dn_mask);
+ }
X return error;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/fs/bfs/inode.c linux/fs/bfs/inode.c
--- v2.4.0-test8/linux/fs/bfs/inode.c Tue Sep 5 14:07:29 2000
+++ linux/fs/bfs/inode.c Sun Sep 17 09:51:57 2000
@@ -197,7 +197,7 @@
X buf->f_bfree = buf->f_bavail = s->su_freeb;
X buf->f_files = s->su_lasti + 1 - BFS_ROOT_INO;
X buf->f_ffree = s->su_freei;
- buf->f_fsid.val[0] = s->s_dev;
+ buf->f_fsid.val[0] = kdev_t_to_nr(s->s_dev);
X buf->f_namelen = BFS_NAMELEN;
X return 0;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/fs/block_dev.c linux/fs/block_dev.c
--- v2.4.0-test8/linux/fs/block_dev.c Tue Sep 5 14:07:31 2000
+++ linux/fs/block_dev.c Sun Oct 1 20:35:16 2000
@@ -30,17 +30,17 @@
X ssize_t block, blocks;
X loff_t offset;
X ssize_t chars;
- ssize_t written = 0;
+ ssize_t written;
X struct buffer_head * bhlist[NBUF];
X size_t size;
- kdev_t dev;
+ kdev_t dev = inode->i_rdev;
X struct buffer_head * bh, *bufferlist[NBUF];
X register char * p;
X
- write_error = buffercount = 0;
- dev = inode->i_rdev;
- if ( is_read_only( inode->i_rdev ))
+ if (is_read_only(dev))
X return -EPERM;
+
+ written = write_error = buffercount = 0;
X blocksize = BLOCK_SIZE;
X if (blksize_size[MAJOR(dev)] && blksize_size[MAJOR(dev)][MINOR(dev)])
X blocksize = blksize_size[MAJOR(dev)][MINOR(dev)];
@@ -311,6 +311,39 @@
X }
X
X /*
+ * private llseek:
+ * for a block special file file->f_dentry->d_inode->i_size is zero
+ * so we compute the size by hand (just as in block_read/write above)
+ */
+static loff_t block_llseek(struct file *file, loff_t offset, int origin)
+{
+ long long retval;
+ kdev_t dev;
+
+ switch (origin) {
+ case 2:
+ dev = file->f_dentry->d_inode->i_rdev;
+ if (blk_size[MAJOR(dev)])
+ offset += (loff_t) blk_size[MAJOR(dev)][MINOR(dev)] << BLOCK_SIZE_BITS;
+ /* else? return -EINVAL? */


+ break;
+ case 1:

+ offset += file->f_pos;
+ }
+ retval = -EINVAL;
+ if (offset >= 0) {
+ if (offset != file->f_pos) {
+ file->f_pos = offset;
+ file->f_reada = 0;
+ file->f_version = ++event;
+ }
+ retval = offset;


+ }
+ return retval;
+}
+
+
+/*

X * Filp may be NULL when we are called by an msync of a vma
X * since the vma has no handle.
X */
@@ -435,9 +468,7 @@
X static struct {
X const char *name;
X struct block_device_operations *bdops;
-} blkdevs[MAX_BLKDEV] = {
- { NULL, NULL },
-};
+} blkdevs[MAX_BLKDEV];
X
X int get_blkdev_list(char * p)
X {
@@ -612,7 +643,7 @@
X
X int blkdev_open(struct inode * inode, struct file * filp)
X {
- int ret = -ENODEV;
+ int ret = -ENXIO;
X struct block_device *bdev = inode->i_bdev;
X down(&bdev->bd_sem);
X lock_kernel();
@@ -678,6 +709,7 @@
X struct file_operations def_blk_fops = {
X open: blkdev_open,
X release: blkdev_close,
+ llseek: block_llseek,
X read: block_read,
X write: block_write,
X fsync: block_fsync,
diff -u --recursive --new-file v2.4.0-test8/linux/fs/buffer.c linux/fs/buffer.c
--- v2.4.0-test8/linux/fs/buffer.c Wed Sep 6 08:29:45 2000
+++ linux/fs/buffer.c Mon Oct 2 12:03:34 2000
@@ -35,6 +35,7 @@
X #include <linux/locks.h>
X #include <linux/errno.h>
X #include <linux/swap.h>
+#include <linux/swapctl.h>
X #include <linux/smp_lock.h>
X #include <linux/vmalloc.h>
X #include <linux/blkdev.h>
@@ -409,8 +410,9 @@
X */
X #define _hashfn(dev,block) \
X ((((dev)<<(bh_hash_shift - 6)) ^ ((dev)<<(bh_hash_shift - 9))) ^ \
- (((block)<<(bh_hash_shift - 6)) ^ ((block) >> 13) ^ ((block) << (bh_hash_shift - 12))))
-#define hash(dev,block) hash_table[(_hashfn(dev,block) & bh_hash_mask)]
+ (((block)<<(bh_hash_shift - 6)) ^ ((block) >> 13) ^ \
+ ((block) << (bh_hash_shift - 12))))
+#define hash(dev,block) hash_table[(_hashfn(HASHDEV(dev),block) & bh_hash_mask)]
X
X static __inline__ void __hash_link(struct buffer_head *bh, struct buffer_head **head)
X {
@@ -856,23 +858,35 @@
X /* -1 -> no need to flush
X 0 -> async flush
X 1 -> sync flush (wait for I/O completation) */
-static int balance_dirty_state(kdev_t dev)
+int balance_dirty_state(kdev_t dev)
X {
X unsigned long dirty, tot, hard_dirty_limit, soft_dirty_limit;
+ int shortage;
X
X dirty = size_buffers_type[BUF_DIRTY] >> PAGE_SHIFT;
X tot = nr_free_buffer_pages();
- tot -= size_buffers_type[BUF_PROTECTED] >> PAGE_SHIFT;
X
X dirty *= 200;
X soft_dirty_limit = tot * bdf_prm.b_un.nfract;
X hard_dirty_limit = soft_dirty_limit * 2;
X
+ /* First, check for the "real" dirty limit. */
X if (dirty > soft_dirty_limit) {
X if (dirty > hard_dirty_limit)


X return 1;
X return 0;
X }

+
+ /*
+ * If we are about to get low on free pages and
+ * cleaning the inactive_dirty pages would help
+ * fix this, wake up bdflush.
+ */
+ shortage = free_shortage();
+ if (shortage && nr_inactive_dirty_pages > shortage &&
+ nr_inactive_dirty_pages > freepages.high)
+ return 0;
+


X return -1;
X }
X

@@ -1380,6 +1394,19 @@
X }
X
X /*
+ * NOTE! All mapped/uptodate combinations are valid:
+ *
+ * Mapped Uptodate Meaning
+ *
+ * No No "unknown" - must do get_block()
+ * No Yes "hole" - zero-filled
+ * Yes No "allocated" - allocated on disk, not read in
+ * Yes Yes "valid" - allocated and up-to-date in memory.
+ *
+ * "Dirty" is valid only with the last case (mapped+uptodate).
+ */
+
+/*
X * block_write_full_page() is SMP-safe - currently it's still
X * being called with the kernel lock held, but the code is ready.
X */
@@ -1471,6 +1498,10 @@
X goto out;
X if (buffer_new(bh)) {
X unmap_underlying_metadata(bh);


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 097'
echo 'File patch-2.4.0-test9 is continued in part 098'
echo "098" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part102

#!/bin/sh -x
# this is part 102 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 102; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

X *
- * Copyright (c) 1998 Russell King.
- * Copyright (c) 1998 Phil Blundell
+ * Copyright (C) 1998 Russell King.
+ * Copyright (C) 1998 Phil Blundell
X *
X * CATS has a real-time clock, though the evaluation board doesn't.
X *
@@ -19,7 +19,7 @@
X
X #include <linux/mc146818rtc.h>
X
-#include <asm/dec21285.h>
+#include <asm/hardware/dec21285.h>
X #include <asm/leds.h>
X #include <asm/mach-types.h>
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-ebsa285/timex.h linux/include/asm-arm/arch-ebsa285/timex.h
--- v2.4.0-test8/linux/include/asm-arm/arch-ebsa285/timex.h Tue Apr 25 16:54:38 2000
+++ linux/include/asm-arm/arch-ebsa285/timex.h Mon Sep 18 15:15:23 2000


@@ -1,9 +1,13 @@
X /*

- * linux/include/asm-arm/arch-ebsa285/timex.h
+ * linux/include/asm-arm/arch-ebsa285/timex.h
X *
- * EBSA285 architecture timex specifications
+ * Copyright (C) 1998 Russell King
X *
- * Copyright (C) 1998 Russell King


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * EBSA285 architecture timex specifications


X */
X
X /*

diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-ebsa285/uncompress.h linux/include/asm-arm/arch-ebsa285/uncompress.h
--- v2.4.0-test8/linux/include/asm-arm/arch-ebsa285/uncompress.h Sun Sep 3 11:19:11 2000
+++ linux/include/asm-arm/arch-ebsa285/uncompress.h Mon Sep 18 15:15:23 2000


@@ -1,7 +1,11 @@
X /*

- * linux/include/asm-arm/arch-ebsa285/uncompress.h
+ * linux/include/asm-arm/arch-ebsa285/uncompress.h
X *
- * Copyright (C) 1996-1999 Russell King
+ * Copyright (C) 1996-1999 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X */

X #include <asm/mach-types.h>
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-ebsa285/vmalloc.h linux/include/asm-arm/arch-ebsa285/vmalloc.h
--- v2.4.0-test8/linux/include/asm-arm/arch-ebsa285/vmalloc.h Mon Mar 27 10:46:29 2000
+++ linux/include/asm-arm/arch-ebsa285/vmalloc.h Mon Sep 18 15:15:23 2000
@@ -1,5 +1,9 @@
X /*
- * linux/include/asm-arm/arch-ebsa285/vmalloc.h
+ * linux/include/asm-arm/arch-ebsa285/vmalloc.h


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X */
X

X /*
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-nexuspci/dma.h linux/include/asm-arm/arch-nexuspci/dma.h
--- v2.4.0-test8/linux/include/asm-arm/arch-nexuspci/dma.h Tue Jul 18 22:43:25 2000
+++ linux/include/asm-arm/arch-nexuspci/dma.h Mon Sep 18 15:15:23 2000
@@ -7,6 +7,13 @@
X */
X
X /*


+ * This program is free software; you can redistribute it and/or

+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+/*
X * This is the maximum DMA address that can be DMAd to.
X */
X #define MAX_DMA_ADDRESS 0xffffffff
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-nexuspci/hardware.h linux/include/asm-arm/arch-nexuspci/hardware.h
--- v2.4.0-test8/linux/include/asm-arm/arch-nexuspci/hardware.h Sun Sep 3 11:19:11 2000
+++ linux/include/asm-arm/arch-nexuspci/hardware.h Mon Sep 18 15:15:23 2000
@@ -5,6 +5,14 @@
X *
X * This file contains the hardware definitions of the FTV PCI card.
X */
+
+/*


+ * This program is free software; you can redistribute it and/or

+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
X #ifndef __ASM_ARCH_HARDWARE_H
X #define __ASM_ARCH_HARDWARE_H
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-nexuspci/irq.h linux/include/asm-arm/arch-nexuspci/irq.h
--- v2.4.0-test8/linux/include/asm-arm/arch-nexuspci/irq.h Mon Feb 28 14:16:37 2000
+++ linux/include/asm-arm/arch-nexuspci/irq.h Mon Sep 18 15:15:23 2000
@@ -4,6 +4,13 @@
X * Copyright (C) 1998, 1999, 2000 Philip Blundell
X */
X
+/*


+ * This program is free software; you can redistribute it and/or

+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
X #include <asm/io.h>
X
X #define fixup_irq(x) (x)
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-nexuspci/irqs.h linux/include/asm-arm/arch-nexuspci/irqs.h
--- v2.4.0-test8/linux/include/asm-arm/arch-nexuspci/irqs.h Mon Feb 28 14:16:37 2000
+++ linux/include/asm-arm/arch-nexuspci/irqs.h Mon Sep 18 15:15:23 2000
@@ -4,9 +4,18 @@
X * Copyright (C) 1997, 1998, 2000 Philip Blundell
X */
X
-/* The hardware is capable of routing any interrupt source (except the
- DUART) to either IRQ or FIQ. We ignore FIQ and use IRQ exclusively
- for simplicity. */
+/*


+ * This program is free software; you can redistribute it and/or

+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+/*
+ * The hardware is capable of routing any interrupt source (except the
+ * DUART) to either IRQ or FIQ. We ignore FIQ and use IRQ exclusively
+ * for simplicity.
+ */
X
X #define IRQ_DUART 0
X #define IRQ_PLX 1
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-nexuspci/system.h linux/include/asm-arm/arch-nexuspci/system.h
--- v2.4.0-test8/linux/include/asm-arm/arch-nexuspci/system.h Tue Jul 18 22:43:25 2000
+++ linux/include/asm-arm/arch-nexuspci/system.h Mon Sep 18 15:15:23 2000
@@ -3,6 +3,14 @@
X *
X * Copyright (c) 1996, 97, 98, 99, 2000 FutureTV Labs Ltd.
X */
+
+/*


+ * This program is free software; you can redistribute it and/or

+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
X #ifndef __ASM_ARCH_SYSTEM_H
X #define __ASM_ARCH_SYSTEM_H
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-nexuspci/time.h linux/include/asm-arm/arch-nexuspci/time.h
--- v2.4.0-test8/linux/include/asm-arm/arch-nexuspci/time.h Sun Sep 3 11:19:11 2000
+++ linux/include/asm-arm/arch-nexuspci/time.h Mon Sep 18 15:15:23 2000
@@ -7,6 +7,13 @@
X * SCC chip.
X */
X
+/*


+ * This program is free software; you can redistribute it and/or

+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
X static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
X {
X static int count = 25;
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-nexuspci/uncompress.h linux/include/asm-arm/arch-nexuspci/uncompress.h
--- v2.4.0-test8/linux/include/asm-arm/arch-nexuspci/uncompress.h Sun Sep 3 11:19:11 2000
+++ linux/include/asm-arm/arch-nexuspci/uncompress.h Mon Sep 18 15:15:23 2000
@@ -4,6 +4,13 @@
X * Copyright (C) 1998, 1999, 2000 Philip Blundell
X */
X
+/*


+ * This program is free software; you can redistribute it and/or

+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
X #include <asm/hardware.h>
X #include <asm/io.h>
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-rpc/acornfb.h linux/include/asm-arm/arch-rpc/acornfb.h
--- v2.4.0-test8/linux/include/asm-arm/arch-rpc/acornfb.h Wed Oct 20 16:29:08 1999
+++ linux/include/asm-arm/arch-rpc/acornfb.h Mon Sep 18 15:15:23 2000


@@ -1,9 +1,13 @@
X /*

- * linux/include/asm-arm/arch-rpc/acornfb.h
+ * linux/include/asm-arm/arch-rpc/acornfb.h
X *
- * (C) 1999 Russell King


+ * Copyright (C) 1999 Russell King
X *

- * AcornFB architecture specific code


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * AcornFB architecture specific code
X */
X
X #define acornfb_valid_pixrate(rate) (1)
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-rpc/dma.h linux/include/asm-arm/arch-rpc/dma.h
--- v2.4.0-test8/linux/include/asm-arm/arch-rpc/dma.h Tue Jul 18 22:43:25 2000
+++ linux/include/asm-arm/arch-rpc/dma.h Mon Sep 18 15:15:23 2000


@@ -1,5 +1,11 @@
X /*

- * linux/include/asm-arm/arch-rpc/dma.h
+ * linux/include/asm-arm/arch-rpc/dma.h
+ *
+ * Copyright (C) 1997 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X */

X #ifndef __ASM_ARCH_DMA_H
X #define __ASM_ARCH_DMA_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-rpc/hardware.h linux/include/asm-arm/arch-rpc/hardware.h
--- v2.4.0-test8/linux/include/asm-arm/arch-rpc/hardware.h Sun Aug 13 09:54:15 2000
+++ linux/include/asm-arm/arch-rpc/hardware.h Mon Sep 18 15:15:23 2000


@@ -1,9 +1,13 @@
X /*

- * linux/include/asm-arm/arch-rpc/hardware.h
+ * linux/include/asm-arm/arch-rpc/hardware.h
X *
- * Copyright (C) 1996-1999 Russell King.
+ * Copyright (C) 1996-1999 Russell King.
X *
- * This file contains the hardware definitions of the RiscPC series machines.


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * This file contains the hardware definitions of the RiscPC series machines.
X */
X #ifndef __ASM_ARCH_HARDWARE_H
X #define __ASM_ARCH_HARDWARE_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-rpc/ide.h linux/include/asm-arm/arch-rpc/ide.h
--- v2.4.0-test8/linux/include/asm-arm/arch-rpc/ide.h Mon Jun 26 12:04:42 2000
+++ linux/include/asm-arm/arch-rpc/ide.h Mon Sep 18 15:15:23 2000
@@ -1,10 +1,14 @@
X /*
- * linux/include/asm-arm/arch-rpc/ide.h
+ * linux/include/asm-arm/arch-rpc/ide.h
X *
- * Copyright (c) 1997 Russell King
+ * Copyright (C) 1997 Russell King
X *
- * Modifications:
- * 29-07-1998 RMK Major re-work of IDE architecture specific code


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Modifications:
+ * 29-07-1998 RMK Major re-work of IDE architecture specific code
X */
X #include <asm/irq.h>
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-rpc/io.h linux/include/asm-arm/arch-rpc/io.h
--- v2.4.0-test8/linux/include/asm-arm/arch-rpc/io.h Thu Feb 24 22:44:47 2000
+++ linux/include/asm-arm/arch-rpc/io.h Mon Sep 18 15:15:23 2000


@@ -1,7 +1,11 @@
X /*

- * linux/include/asm-arm/arch-rpc/io.h
+ * linux/include/asm-arm/arch-rpc/io.h
X *
- * Copyright (C) 1997 Russell King
+ * Copyright (C) 1997 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X *

X * Modifications:
X * 06-Dec-1997 RMK Created.
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-rpc/irq.h linux/include/asm-arm/arch-rpc/irq.h
--- v2.4.0-test8/linux/include/asm-arm/arch-rpc/irq.h Sun Sep 3 11:19:11 2000
+++ linux/include/asm-arm/arch-rpc/irq.h Mon Sep 18 15:15:23 2000
@@ -1,13 +1,17 @@
X /*
- * include/asm-arm/arch-rpc/irq.h
+ * linux/include/asm-arm/arch-rpc/irq.h
X *
- * Copyright (C) 1996 Russell King
+ * Copyright (C) 1996 Russell King
X *
- * Changelog:


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Changelog:
X * 10-10-1996 RMK Brought up to date with arch-sa110eval
X * 22-08-1998 RMK Restructured IRQ routines
X */


-#include <asm/iomd.h>
+#include <asm/hardware/iomd.h>
X

X #define fixup_irq(x) (x)
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-rpc/irqs.h linux/include/asm-arm/arch-rpc/irqs.h
--- v2.4.0-test8/linux/include/asm-arm/arch-rpc/irqs.h Sun Sep 6 10:45:30 1998
+++ linux/include/asm-arm/arch-rpc/irqs.h Mon Sep 18 15:15:23 2000


@@ -1,7 +1,11 @@
X /*

- * linux/include/asm-arm/arch-rpc/irqs.h
+ * linux/include/asm-arm/arch-rpc/irqs.h
X *
- * Copyright (C) 1996 Russell King
+ * Copyright (C) 1996 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X */
X

X #define IRQ_PRINTER 0
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-rpc/keyboard.h linux/include/asm-arm/arch-rpc/keyboard.h
--- v2.4.0-test8/linux/include/asm-arm/arch-rpc/keyboard.h Sat May 8 11:06:57 1999
+++ linux/include/asm-arm/arch-rpc/keyboard.h Mon Sep 18 15:15:23 2000
@@ -1,11 +1,14 @@
X /*
- * linux/include/asm-arm/arch-rpc/keyboard.h
+ * linux/include/asm-arm/arch-rpc/keyboard.h
X *
- * Keyboard driver definitions for RiscPC architecture
+ * Copyright (C) 1998 Russell King
X *
- * (C) 1998 Russell King


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Keyboard driver definitions for RiscPC architecture
X */
-
X #include <asm/irq.h>
X
X #define NR_SCANCODES 128
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-rpc/memory.h linux/include/asm-arm/arch-rpc/memory.h
--- v2.4.0-test8/linux/include/asm-arm/arch-rpc/memory.h Thu Oct 28 10:16:02 1999
+++ linux/include/asm-arm/arch-rpc/memory.h Mon Sep 18 15:15:23 2000
@@ -1,15 +1,19 @@
X /*
- * linux/include/asm-arm/arch-rpc/memory.h
+ * linux/include/asm-arm/arch-rpc/memory.h
X *
- * Copyright (c) 1996,1997,1998 Russell King.
+ * Copyright (C) 1996,1997,1998 Russell King.
X *
- * Changelog:
- * 20-Oct-1996 RMK Created
- * 31-Dec-1997 RMK Fixed definitions to reduce warnings
- * 11-Jan-1998 RMK Uninlined to reduce hits on cache
- * 08-Feb-1998 RMK Added __virt_to_bus and __bus_to_virt
- * 21-Mar-1999 RMK Renamed to memory.h
- * RMK Added TASK_SIZE and PAGE_OFFSET


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Changelog:
+ * 20-Oct-1996 RMK Created
+ * 31-Dec-1997 RMK Fixed definitions to reduce warnings
+ * 11-Jan-1998 RMK Uninlined to reduce hits on cache
+ * 08-Feb-1998 RMK Added __virt_to_bus and __bus_to_virt
+ * 21-Mar-1999 RMK Renamed to memory.h
+ * RMK Added TASK_SIZE and PAGE_OFFSET
X */
X #ifndef __ASM_ARCH_MMU_H
X #define __ASM_ARCH_MMU_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-rpc/processor.h linux/include/asm-arm/arch-rpc/processor.h
--- v2.4.0-test8/linux/include/asm-arm/arch-rpc/processor.h Wed Oct 20 16:29:08 1999
+++ linux/include/asm-arm/arch-rpc/processor.h Mon Sep 18 15:15:23 2000
@@ -1,11 +1,15 @@
X /*
- * linux/include/asm-arm/arch-rpc/processor.h
+ * linux/include/asm-arm/arch-rpc/processor.h
X *
- * Copyright (c) 1996-1999 Russell King.
+ * Copyright (C) 1996-1999 Russell King.
X *
- * Changelog:
- * 10-Sep-1996 RMK Created
- * 21-Mar-1999 RMK Added asm/arch/memory.h


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Changelog:
+ * 10-Sep-1996 RMK Created
+ * 21-Mar-1999 RMK Added asm/arch/memory.h
X */
X
X #ifndef __ASM_ARCH_PROCESSOR_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-rpc/serial.h linux/include/asm-arm/arch-rpc/serial.h
--- v2.4.0-test8/linux/include/asm-arm/arch-rpc/serial.h Tue Nov 23 22:23:11 1999
+++ linux/include/asm-arm/arch-rpc/serial.h Mon Sep 18 15:15:23 2000
@@ -1,10 +1,14 @@
X /*
- * linux/include/asm-arm/arch-rpc/serial.h
+ * linux/include/asm-arm/arch-rpc/serial.h
X *
- * Copyright (c) 1996 Russell King.
+ * Copyright (C) 1996 Russell King.
X *
- * Changelog:
- * 15-10-1996 RMK Created


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Changelog:
+ * 15-10-1996 RMK Created
X */
X #ifndef __ASM_ARCH_SERIAL_H
X #define __ASM_ARCH_SERIAL_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-rpc/system.h linux/include/asm-arm/arch-rpc/system.h
--- v2.4.0-test8/linux/include/asm-arm/arch-rpc/system.h Tue Jul 18 22:43:25 2000
+++ linux/include/asm-arm/arch-rpc/system.h Mon Sep 18 15:15:23 2000
@@ -1,10 +1,14 @@
X /*
- * linux/include/asm-arm/arch-rpc/system.h
+ * linux/include/asm-arm/arch-rpc/system.h
X *
- * Copyright (c) 1996-1999 Russell King.
+ * Copyright (C) 1996-1999 Russell King.


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X */

X #include <asm/arch/hardware.h>
-#include <asm/iomd.h>
+#include <asm/hardware/iomd.h>
X #include <asm/io.h>
X
X static void arch_idle(void)
@@ -17,7 +21,7 @@
X if (current->need_resched || hlt_counter)
X goto slow_out;
X cpu_do_idle(IDLE_WAIT_FAST);
- } while (time_before(start_idle, jiffies + HZ/3));
+ } while (time_before(jiffies, start_idle + HZ/50));
X
X cpu_do_idle(IDLE_CLOCK_SLOW);
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-rpc/time.h linux/include/asm-arm/arch-rpc/time.h
--- v2.4.0-test8/linux/include/asm-arm/arch-rpc/time.h Sun Feb 6 17:45:25 2000
+++ linux/include/asm-arm/arch-rpc/time.h Mon Sep 18 15:15:23 2000
@@ -1,12 +1,16 @@
X /*
- * linux/include/asm-arm/arch-rpc/time.h
+ * linux/include/asm-arm/arch-rpc/time.h
X *
- * Copyright (c) 1996-2000 Russell King.
+ * Copyright (C) 1996-2000 Russell King.
X *
- * Changelog:
- * 24-Sep-1996 RMK Created
- * 10-Oct-1996 RMK Brought up to date with arch-sa110eval
- * 04-Dec-1997 RMK Updated for new arch/arm/time.c


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Changelog:
+ * 24-Sep-1996 RMK Created
+ * 10-Oct-1996 RMK Brought up to date with arch-sa110eval
+ * 04-Dec-1997 RMK Updated for new arch/arm/time.c
X */
X extern void ioctime_init(void);
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-rpc/timex.h linux/include/asm-arm/arch-rpc/timex.h
--- v2.4.0-test8/linux/include/asm-arm/arch-rpc/timex.h Tue Jan 20 16:39:42 1998
+++ linux/include/asm-arm/arch-rpc/timex.h Mon Sep 18 15:15:23 2000


@@ -1,9 +1,13 @@
X /*

- * linux/include/asm-arm/arch-rpc/timex.h
+ * linux/include/asm-arm/arch-rpc/timex.h
X *
- * RiscPC architecture timex specifications
+ * Copyright (C) 1997, 1998 Russell King
X *
- * Copyright (C) 1997, 1998 Russell King


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * RiscPC architecture timex specifications


X */
X
X /*

diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-rpc/uncompress.h linux/include/asm-arm/arch-rpc/uncompress.h
--- v2.4.0-test8/linux/include/asm-arm/arch-rpc/uncompress.h Sat May 8 11:06:57 1999
+++ linux/include/asm-arm/arch-rpc/uncompress.h Mon Sep 18 15:15:23 2000


@@ -1,7 +1,11 @@
X /*

- * linux/include/asm-arm/arch-a5k/uncompress.h
+ * linux/include/asm-arm/arch-rpc/uncompress.h
X *
- * Copyright (C) 1996 Russell King
+ * Copyright (C) 1996 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X */

X #define VIDMEM ((char *)SCREEN_START)
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-rpc/vmalloc.h linux/include/asm-arm/arch-rpc/vmalloc.h
--- v2.4.0-test8/linux/include/asm-arm/arch-rpc/vmalloc.h Tue Apr 25 16:54:38 2000
+++ linux/include/asm-arm/arch-rpc/vmalloc.h Mon Sep 18 15:15:23 2000


@@ -1,5 +1,11 @@
X /*

- * linux/include/asm-arm/arch-rpc/vmalloc.h
+ * linux/include/asm-arm/arch-rpc/vmalloc.h
+ *
+ * Copyright (C) 1997 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X */
X

X /*
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-sa1100/SA-1100.h linux/include/asm-arm/arch-sa1100/SA-1100.h
--- v2.4.0-test8/linux/include/asm-arm/arch-sa1100/SA-1100.h Tue Jul 18 22:43:25 2000
+++ linux/include/asm-arm/arch-sa1100/SA-1100.h Mon Sep 18 15:15:23 2000
@@ -2417,8 +2417,8 @@
X (0xF << FShft (DDAR_DS))
X #define DDAR_DA Fld (24, 8) /* Device Address */
X #define DDAR_DevAdd(Add) /* Device Address */ \
- ((Add) & 0xF0000000 | \
- ((Add) & 0X003FFFFC) << (FShft (DDAR_DA) - 2))
+ (((Add) & 0xF0000000) | \
+ (((Add) & 0X003FFFFC) << (FShft (DDAR_DA) - 2)))
X #define DDAR_Ser0UDCWr /* Ser. port 0 UDC Write */ \
X (DDAR_DevWr + DDAR_Brst8 + DDAR_8BitDev + \
X DDAR_Ser0UDCTr + DDAR_DevAdd (_Ser0UDCDR))
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-sa1100/assabet.h linux/include/asm-arm/arch-sa1100/assabet.h
--- v2.4.0-test8/linux/include/asm-arm/arch-sa1100/assabet.h Mon Jun 19 17:59:35 2000
+++ linux/include/asm-arm/arch-sa1100/assabet.h Mon Sep 18 15:15:23 2000
@@ -28,7 +28,7 @@
X
X /* Board Control Register */
X
-#define BCR_BASE 0xdc000000
+#define BCR_BASE 0xf1000000
X #define BCR (*(volatile unsigned int *)(BCR_BASE))
X
X #define BCR_DB1110 (0x00A07410)
@@ -105,8 +105,8 @@
X #define NEPONSET_USAR_IRQ MISC_IRQ1
X
X #define NEPONSET_CPLD_BASE (0x10000000)
-#define Nep_p2v( x ) ((x) - NEPONSET_CPLD_BASE + 0xd4000000)
-#define Nep_v2p( x ) ((x) - 0xd4000000 + NEPONSET_CPLD_BASE)
+#define Nep_p2v( x ) ((x) - NEPONSET_CPLD_BASE + 0xf0000000)
+#define Nep_v2p( x ) ((x) - 0xf0000000 + NEPONSET_CPLD_BASE)
X
X #define _IRR 0x10000024 /* Interrupt Reason Register */
X #define _AUD_CTL 0x100000c0 /* Audio controls (RW) */
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-sa1100/bitsy.h linux/include/asm-arm/arch-sa1100/bitsy.h
--- v2.4.0-test8/linux/include/asm-arm/arch-sa1100/bitsy.h Tue Jul 18 22:43:25 2000
+++ linux/include/asm-arm/arch-sa1100/bitsy.h Mon Sep 18 15:15:23 2000
@@ -38,6 +38,7 @@
X #define EGPIO_BITSY_LVDD_ON (1 << 15) /* enable 9V and -6.5V to LCD. */
X
X #ifndef __ASSEMBLY__
+#define BITSY_EGPIO (*(volatile int *)0xf0000000)
X extern void clr_bitsy_egpio(unsigned long x);
X extern void set_bitsy_egpio(unsigned long x);
X #endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-sa1100/cerf.h linux/include/asm-arm/arch-sa1100/cerf.h
--- v2.4.0-test8/linux/include/asm-arm/arch-sa1100/cerf.h Sun Aug 13 09:54:15 2000
+++ linux/include/asm-arm/arch-sa1100/cerf.h Mon Sep 18 15:15:23 2000
@@ -12,5 +12,8 @@
X #define IRQ_GPIO_CF_BVD2 IRQ_GPIO19
X #define IRQ_GPIO_CF_BVD1 IRQ_GPIO20
X
+#define GPIO_UCB1200_IRQ GPIO_GPIO (18)
+#define IRQ_GPIO_UCB1200_IRQ IRQ_GPIO18
+
X #endif
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-sa1100/hardware.h linux/include/asm-arm/arch-sa1100/hardware.h
--- v2.4.0-test8/linux/include/asm-arm/arch-sa1100/hardware.h Sun Aug 13 09:54:15 2000
+++ linux/include/asm-arm/arch-sa1100/hardware.h Mon Sep 18 15:15:23 2000
@@ -13,17 +13,28 @@
X #define __ASM_ARCH_HARDWARE_H
X
X #include <linux/config.h>
+#include <asm/mach-types.h>
+
X
X /* Flushing areas */
X #define FLUSH_BASE_PHYS 0xe0000000 /* SA1100 zero bank */
-#define FLUSH_BASE 0xdf000000
-#define FLUSH_BASE_MINICACHE 0xdf800000
+#define FLUSH_BASE 0xf5000000
+#define FLUSH_BASE_MINICACHE 0xf5800000
X #define UNCACHEABLE_ADDR 0xfa050000
X
X
X /*
- * We requires absolute addresses i.e. (0xe00000 + 0x3f8) for in*()/out*()
- * macros to be useful for all cases.
+ * Those are statically mapped PCMCIA IO space for designs using it as a
+ * generic IO bus, typically with ISA parts, hardwired IDE interfaces, etc.
+ * The actual PCMCIA code is mapping required IO region at run time.
+ */
+#define PCMCIA_IO_0_BASE 0xf6000000
+#define PCMCIA_IO_1_BASE 0xf7000000
+
+
+/*
+ * We requires absolute addresses i.e. (PCMCIA_IO_0_BASE + 0x3f8) for
+ * in*()/out*() macros to be usable for all cases.
X */
X #define PCIO_BASE 0
X
@@ -37,8 +48,6 @@
X * 90000000 fa000000
X * a0000000 fc000000
X * b0000000 fe000000
- *
- * Nb: PCMCIA is mapped from 0xe0000000 to f7ffffff in mm-sa1100.c
X */
X
X #define VIO_BASE 0xf8000000 /* virtual start of IO space */
@@ -89,20 +98,24 @@
X #include "bitsy.h"
X #endif
X
-#if defined(CONFIG_SA1100_GRAPHICSCLIENT) || defined(CONFIG_SA1100_THINCLIENT)
+#if defined(CONFIG_SA1100_THINCLIENT)
X #include "thinclient.h"
X #endif
X
+#if defined(CONFIG_SA1100_GRAPHICSCLIENT)
+#include "graphicsclient.h"
+#endif
+
X
X #ifdef CONFIG_SA1101
X
X /*
X * We have mapped the sa1101 depending on the value of SA1101_BASE.
- * It then appears from 0xdc000000.
+ * It then appears from 0xf4000000.
X */
X
-#define SA1101_p2v( x ) ((x) - SA1101_BASE + 0xdc000000)
-#define SA1101_v2p( x ) ((x) - 0xdc000000 + SA1101_BASE)
+#define SA1101_p2v( x ) ((x) - SA1101_BASE + 0xf4000000)
+#define SA1101_v2p( x ) ((x) - 0xf4000000 + SA1101_BASE)
X
X #include "SA-1101.h"
X
@@ -111,8 +124,8 @@
X
X #ifdef CONFIG_SA1111
X
-#define SA1111_p2v( x ) ((x) - SA1111_BASE + 0xd8000000)
-#define SA1111_v2p( x ) ((x) - 0xd8000000 + SA1111_BASE)
+#define SA1111_p2v( x ) ((x) - SA1111_BASE + 0xf4000000)
+#define SA1111_v2p( x ) ((x) - 0xf4000000 + SA1111_BASE)
X
X #include "SA-1111.h"
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-sa1100/ide.h linux/include/asm-arm/arch-sa1100/ide.h
--- v2.4.0-test8/linux/include/asm-arm/arch-sa1100/ide.h Sun Aug 13 09:54:15 2000
+++ linux/include/asm-arm/arch-sa1100/ide.h Mon Sep 18 15:15:23 2000
@@ -3,14 +3,22 @@
X *
X * Copyright (c) 1998 Hugo Fiennes & Nicolas Pitre
X *
+ * 18-aug-2000: Cleanup by Erik Mouw (J.A.K...@its.tudelft.nl)
+ * Get rid of the special ide_init_hwif_ports() functions
+ * and make a generalised function that can be used by all
+ * architectures.


X */
X
X #include <linux/config.h>

-
X #include <asm/irq.h>


X #include <asm/hardware.h>
X #include <asm/mach-types.h>
X

+
+#define PCMCIA_IO_0_BASE 0xe0000000
+#define PCMCIA_IO_1_BASE 0xe4000000
+
+
X /*
X * Set up a hw structure for a specified data port, control port and IRQ.
X * This should follow whatever the default interface uses.
@@ -20,47 +28,33 @@
X {
X ide_ioreg_t reg;
X int i;
- int ioshift = 0;
-
+ int regincr = 1;
+
X /* The Empeg board has the first two address lines unused */
X if (machine_is_empeg())
- ioshift = 2;
-
+ regincr = 1 << 2;
+
+ /* The LART doesn't use A0 for IDE */
+ if (machine_is_lart())
+ regincr = 1 << 1;
+
X memset(hw, 0, sizeof(*hw));
X
- reg = (ide_ioreg_t) (data_port << ioshift);
+ reg = (ide_ioreg_t)data_port;
+
X for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
X hw->io_ports[i] = reg;
- reg += (1 << ioshift);
+ reg += regincr;
X }
X
- hw->io_ports[IDE_CONTROL_OFFSET] =
- (ide_ioreg_t) (ctrl_port << ioshift);
+ hw->io_ports[IDE_CONTROL_OFFSET] = (ide_ioreg_t) ctrl_port;
X
X if (irq)
X *irq = 0;
X }
X
-/*
- * Special case for the empeg board which has the first two
- * address lines unused
- */
-static __inline__ void
-empeg_ide_init_hwif_ports(hw_regs_t *hw, int data_port, int ctrl_port)
-{
- ide_ioreg_t reg;
- int i;
X
- memset(hw, 0, sizeof(*hw));
X
- reg = (ide_ioreg_t) (0xe0000000 + (data_port << 2));
- for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
- hw->io_ports[i] = reg;
- reg += (1 << 2);
- }
- hw->io_ports[IDE_CONTROL_OFFSET] =
- (ide_ioreg_t) (0xe0000000 + (ctrl_port << 2));
-}
X
X /*
X * This registers the standard ports for this architecture with the IDE
@@ -92,10 +86,10 @@
X /* MAC 23/4/1999, swap these round so that the left hand
X hard disk is hda when viewed from the front. This
X doesn't match the silkscreen however. */
- empeg_ide_init_hwif_ports(&hw,0x10,0x1e);
+ ide_init_hwif_ports(&hw, PCMCIA_IO_0_BASE + 0x40, PCMCIA_IO_0_BASE + 0x78, NULL);
X hw.irq = EMPEG_IRQ_IDE2;
X ide_register_hw(&hw, NULL);
- empeg_ide_init_hwif_ports(&hw,0x00,0x0e);
+ ide_init_hwif_ports(&hw, PCMCIA_IO_0_BASE + 0x00, PCMCIA_IO_0_BASE + 0x38, NULL);
X hw.irq = ,EMPEG_IRQ_IDE1;
X ide_register_hw(&hw, NULL);
X #endif
@@ -112,7 +106,7 @@
X /* set the pcmcia interface timing */
X MECR = 0x00060006;
X
- ide_init_hwif_ports(&hw, 0xe00001f0, 0xe00003f6, NULL);
+ ide_init_hwif_ports(&hw, PCMCIA_IO_0_BASE + 0x1f0, PCMCIA_IO_0_BASE + 0x3f6, NULL);
X hw.irq = IRQ_GPIO7;
X ide_register_hw(&hw, NULL);
X #endif
@@ -129,8 +123,7 @@
X MECR = 0x00060006;
X
X /* init the interface */
-/* ide_init_hwif_ports(&hw, 0xe00000000, 0xe00001000, NULL); */
- ide_init_hwif_ports(&hw, 0xe00001000, 0xe00000000, NULL);
+ ide_init_hwif_ports(&hw, PCMCIA_IO_0_BASE + 0x0000, PCMCIA_IO_0_BASE + 0x1000, NULL);
X hw.irq = IRQ_GPIO1;
X ide_register_hw(&hw, NULL);
X #endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-sa1100/memory.h linux/include/asm-arm/arch-sa1100/memory.h
--- v2.4.0-test8/linux/include/asm-arm/arch-sa1100/memory.h Thu Jan 13 13:30:31 2000
+++ linux/include/asm-arm/arch-sa1100/memory.h Mon Sep 18 15:15:23 2000
@@ -24,22 +24,22 @@
X */
X #define PHYS_OFFSET (0xc0000000UL)
X
-
-#define __virt_to_phys__is_a_macro
-#define __phys_to_virt__is_a_macro
-
X /*
- * The following gives a maximum memory size of 128MB (32MB in each bank).
+ * We take advantage of the fact that physical and virtual address can be the
+ * same. The NUMA code is handling the large holes that might exist between
+ * all memory banks.
X */
-#define __virt_to_phys(x) (((x) & 0xf9ffffff) | ((x) & 0x06000000) << 2)
-#define __phys_to_virt(x) (((x) & 0xe7ffffff) | ((x) & 0x18000000) >> 2)
+#define __virt_to_phys__is_a_macro
+#define __phys_to_virt__is_a_macro
+#define __virt_to_phys(x) (x)
+#define __phys_to_virt(x) (x)
X
X /*
X * Virtual view <-> DMA view memory address translations
X * virt_to_bus: Used to translate the virtual address to an
- * address suitable to be passed to set_dma_addr
+ * address suitable to be passed to set_dma_addr
X * bus_to_virt: Used to convert an address for DMA operations
- * to an address that the kernel can use.
+ * to an address that the kernel can use.
X *
X * On the SA1100, bus addresses are equivalent to physical addresses.
X */
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-sa1100/mmzone.h linux/include/asm-arm/arch-sa1100/mmzone.h
--- v2.4.0-test8/linux/include/asm-arm/arch-sa1100/mmzone.h Wed Aug 9 13:46:01 2000
+++ linux/include/asm-arm/arch-sa1100/mmzone.h Mon Sep 18 15:15:23 2000
@@ -11,6 +11,14 @@
X *
X * Of course, all this isn't mandatory for SA1100 implementations with only
X * one used memory bank. For those, simply undefine CONFIG_DISCONTIGMEM.
+ *
+ * The nodes are matched with the physical memory bank addresses which are
+ * incidentally the same as virtual addresses.
+ *
+ * node 0: 0xc0000000 - 0xc7ffffff
+ * node 1: 0xc8000000 - 0xcfffffff
+ * node 2: 0xd0000000 - 0xd7ffffff
+ * node 3: 0xd8000000 - 0xdfffffff
X */
X
X
@@ -20,18 +28,6 @@
X extern pg_data_t sa1100_node_data[];
X
X /*
- * 32MB max in each bank, must fit with __virt_to_phys() & __phys_to_virt()
- */
-#define NODE_MAX_MEM_SHIFT 25
-#define NODE_MAX_MEM_SIZE (1<<NODE_MAX_MEM_SHIFT)
-
-/*
- * Given a kernel address, find the home node of the underlying memory.
- */
-#define KVADDR_TO_NID(addr) \
- (((unsigned long)(addr) - PAGE_OFFSET) >> NODE_MAX_MEM_SHIFT)
-
-/*
X * Return a pointer to the node data for node n.
X */
X #define NODE_DATA(nid) (&sa1100_node_data[nid])
@@ -42,11 +38,10 @@
X #define NODE_MEM_MAP(nid) (NODE_DATA(nid)->node_mem_map)
X
X /*
- * Given a mem_map_t, LOCAL_MAP_BASE finds the owning node for the
- * physical page and returns the kaddr for the mem_map of that node.
+ * Given a kernel address, find the home node of the underlying memory.
X */
-#define LOCAL_MAP_BASE(page) \
- NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(page)))
+#define KVADDR_TO_NID(addr) \
+ (((unsigned long)(addr) & 0x18000000) >> 27)
X
X /*
X * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
@@ -56,28 +51,22 @@
X NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(kaddr)))
X
X /*
- * Given a kaddr, LOCAL_BASE_ADDR finds the owning node of the memory
- * and returns the kaddr corresponding to first physical page in the
- * node's mem_map.
- */
-#define LOCAL_BASE_ADDR(kaddr) ((unsigned long)(kaddr) & ~(NODE_MAX_MEM_SIZE-1))
-
-/*
X * Given a kaddr, LOCAL_MEM_MAP finds the owning node of the memory
X * and returns the index corresponding to the appropriate page in the
X * node's mem_map.
X */
X #define LOCAL_MAP_NR(kvaddr) \
- (((unsigned long)(kvaddr)-LOCAL_BASE_ADDR((kvaddr))) >> PAGE_SHIFT)
+ (((unsigned long)(kvaddr) & 0x07ffffff) >> PAGE_SHIFT)
X
-/*
- * With discontigmem, the conceptual mem_map array starts from PAGE_OFFSET.
- * Given a kaddr, MAP_NR returns the appropriate global mem_map index so
- * it matches the corresponding node's local mem_map.
- */
-#define MAP_NR(kaddr) (LOCAL_MAP_NR((kaddr)) + \
- (((unsigned long)ADDR_TO_MAPBASE((kaddr)) - PAGE_OFFSET) / \
- sizeof(mem_map_t)))
+/*
+ * Given a kaddr, virt_to_page returns a pointer to the corresponding
+ * mem_map entry.
+ */
+#define virt_to_page(kaddr) \
+ (ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr))
+
+/*
+ * Didn't find the best way to validate a page pointer yet...
+ */
X
-#define virt_to_page(kaddr) (mem_map + MAP_NR(kaddr))
-#define VALID_PAGE(page) ((page - mem_map) < max_mapnr)
+#define VALID_PAGE(page) (1)
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-sa1100/system.h linux/include/asm-arm/arch-sa1100/system.h
--- v2.4.0-test8/linux/include/asm-arm/arch-sa1100/system.h Tue Jul 18 22:43:25 2000
+++ linux/include/asm-arm/arch-sa1100/system.h Mon Sep 18 15:15:23 2000
@@ -5,13 +5,10 @@


X */
X #include <linux/config.h>
X

-static void arch_idle(void)
+static inline void arch_idle(void)
X {
- while (!current->need_resched && !hlt_counter) {
- cpu_do_idle(IDLE_CLOCK_SLOW);
- cpu_do_idle(IDLE_WAIT_FAST);
- cpu_do_idle(IDLE_CLOCK_FAST);
- }
+ while (!current->need_resched && !hlt_counter)
+ cpu_do_idle(0);
X }
X
X #ifdef CONFIG_SA1100_VICTOR
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-sa1100/thinclient.h linux/include/asm-arm/arch-sa1100/thinclient.h
--- v2.4.0-test8/linux/include/asm-arm/arch-sa1100/thinclient.h Tue Jul 18 22:43:25 2000
+++ linux/include/asm-arm/arch-sa1100/thinclient.h Mon Sep 18 15:15:23 2000
@@ -13,8 +13,8 @@
X
X
X #define ADS_CPLD_BASE (0x10000000)
-#define ADS_p2v( x ) ((x) - ADS_CPLD_BASE + 0xdc000000)
-#define ADS_v2p( x ) ((x) - 0xdc000000 + ADS_CPLD_BASE)
+#define ADS_p2v( x ) ((x) - ADS_CPLD_BASE + 0xf0000000)
+#define ADS_v2p( x ) ((x) - 0xf0000000 + ADS_CPLD_BASE)
X
X
X /* Parallel Port */
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-sa1100/vmalloc.h linux/include/asm-arm/arch-sa1100/vmalloc.h
--- v2.4.0-test8/linux/include/asm-arm/arch-sa1100/vmalloc.h Mon Mar 27 10:46:29 2000
+++ linux/include/asm-arm/arch-sa1100/vmalloc.h Mon Sep 18 15:15:23 2000
@@ -13,4 +13,4 @@
X #define VMALLOC_OFFSET (8*1024*1024)
X #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
X #define VMALLOC_VMADDR(x) ((unsigned long)(x))
-#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+#define VMALLOC_END (0xe8000000)
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-shark/hardware.h linux/include/asm-arm/arch-shark/hardware.h
--- v2.4.0-test8/linux/include/asm-arm/arch-shark/hardware.h Mon Jun 26 12:04:42 2000
+++ linux/include/asm-arm/arch-shark/hardware.h Mon Sep 18 15:15:23 2000
@@ -20,7 +20,7 @@
X /*
X * RAM definitions
X */
-#define FLUSH_BASE_PHYS 0x60000000
+#define FLUSH_BASE_PHYS 0x80000000
X
X #else
X
@@ -28,22 +28,26 @@
X
X #endif
X
-#define IO_SIZE 0x10000000
+#define IO_SIZE 0x08000000
X #define IO_START 0x40000000
+#define ROMCARD_SIZE 0x08000000
+#define ROMCARD_START 0x10000000
X
X #define FLUSH_BASE 0xdf000000
X #define PCIO_BASE 0xe0000000
X
X
X /* defines for the Framebuffer */
-#define FB_BASE 0xd0000000
X #define FB_START 0x06000000
-#define FB_SIZE 0x00200000
X
X /* Registers for Framebuffer */
-#define FBREG_BASE (FB_BASE + FB_SIZE)
-#define FBREG_START 0x06800000
-#define FBREG_SIZE 0x000c0000
+/*#define FBREG_START 0x06800000*/
+
+#define UNCACHEABLE_ADDR 0xdf010000
+
+#define SEQUOIA_LED_GREEN (1<<6)
+#define SEQUOIA_LED_AMBER (1<<5)
+#define SEQUOIA_LED_BACK (1<<7)
X
X #endif
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-shark/io.h linux/include/asm-arm/arch-shark/io.h
--- v2.4.0-test8/linux/include/asm-arm/arch-shark/io.h Mon Mar 27 10:46:29 2000
+++ linux/include/asm-arm/arch-shark/io.h Mon Sep 18 15:15:23 2000
@@ -11,6 +11,8 @@
X #ifndef __ASM_ARM_ARCH_IO_H
X #define __ASM_ARM_ARCH_IO_H
X
+#define __arch_ioremap(off,size,nocache) __ioremap(off,size,0)
+
X #define IO_SPACE_LIMIT 0xffffffff
X
X /*
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-shark/keyboard.h linux/include/asm-arm/arch-shark/keyboard.h
--- v2.4.0-test8/linux/include/asm-arm/arch-shark/keyboard.h Sun Aug 13 09:54:15 2000
+++ linux/include/asm-arm/arch-shark/keyboard.h Mon Sep 18 15:15:23 2000
@@ -1,8 +1,8 @@
X /*
- * linux/include/asm-arm/arch-ebsa285/keyboard.h
- *
- * Keyboard driver definitions for EBSA285 architecture
- *
+ * linux/include/asm-arm/arch-shark/keyboard.h
+ * by Alexande...@stud.uni-karlsruhe.de
+ *
+ * Derived from linux/include/asm-arm/arch-ebsa285/keyboard.h
X * (C) 1998 Russell King
X * (C) 1998 Phil Blundell
X */
@@ -24,45 +24,12 @@
X
X #define NR_SCANCODES 128
X
-#define kbd_setkeycode(sc,kc) \
- ({ \
- int __ret; \
- if (have_isa_bridge) \
- __ret = pckbd_setkeycode(sc,kc);\
- else \
- __ret = -EINVAL; \
- __ret; \
- })
-
-#define kbd_getkeycode(sc) \
- ({ \
- int __ret; \
- if (have_isa_bridge) \
- __ret = pckbd_getkeycode(sc); \
- else \
- __ret = -EINVAL; \
- __ret; \
- })
-
-#define kbd_translate(sc, kcp, rm) \
- ({ \
- pckbd_translate(sc, kcp, rm); \
- })
-
+#define kbd_setkeycode(sc,kc) pckbd_setkeycode(sc,kc)
+#define kbd_getkeycode(sc) pckbd_getkeycode(sc)
+#define kbd_translate(sc, kcp, rm) pckbd_translate(sc, kcp, rm)
X #define kbd_unexpected_up pckbd_unexpected_up
-
-#define kbd_leds(leds) \
- do { \
- if (have_isa_bridge) \
- pckbd_leds(leds); \
- } while (0)
-
-#define kbd_init_hw() \
- do { \
- if (have_isa_bridge) \
- pckbd_init_hw(); \
- } while (0)
-
+#define kbd_leds(leds) pckbd_leds(leds)
+#define kbd_init_hw() pckbd_init_hw()
X #define kbd_sysrq_xlate pckbd_sysrq_xlate
X
X #define kbd_disable_irq()
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-shark/system.h linux/include/asm-arm/arch-shark/system.h
--- v2.4.0-test8/linux/include/asm-arm/arch-shark/system.h Tue Jul 18 22:43:25 2000
+++ linux/include/asm-arm/arch-shark/system.h Mon Sep 18 15:15:23 2000
@@ -6,12 +6,19 @@
X #ifndef __ASM_ARCH_SYSTEM_H
X #define __ASM_ARCH_SYSTEM_H
X
+#include <asm/io.h>
+
X static void arch_reset(char mode)
X {
- /*
- * loop endlessly
- */
+ short temp;
X cli();
+ /* Reset the Machine via pc[3] of the sequoia chipset */
+ outw(0x09,0x24);
+ temp=inw(0x26);
+ temp = temp | (1<<3) | (1<<10);
+ outw(0x09,0x24);
+ outw(temp,0x26);
+
X }
X
X static void arch_idle(void)
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-shark/time.h linux/include/asm-arm/arch-shark/time.h
--- v2.4.0-test8/linux/include/asm-arm/arch-shark/time.h Mon Jun 19 17:59:35 2000
+++ linux/include/asm-arm/arch-shark/time.h Mon Sep 18 15:15:23 2000
@@ -43,15 +43,6 @@
X }
X }
X
-static struct irqaction timerirq = {
- timer_interrupt,
- SA_INTERRUPT,
- 0,
- "timer",
- NULL,
- NULL
-};
-
X /*
X * Set up timer interrupt, and return the current time in seconds.
X */
@@ -88,5 +79,7 @@
X xtime.tv_sec = mktime(r_time.tm_year+epoch, r_time.tm_mon+1, r_time.tm_mday,
X r_time.tm_hour, r_time.tm_min, r_time.tm_sec);
X
- setup_arm_irq(IRQ_TIMER, &timerirq);
+ timer_irq.handler = timer_interrupt;
+ timer_irq.flags = SA_INTERRUPT; /* FIXME: really? */
+ setup_arm_irq(IRQ_TIMER, &timer_irq);
X }
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-shark/vmalloc.h linux/include/asm-arm/arch-shark/vmalloc.h
--- v2.4.0-test8/linux/include/asm-arm/arch-shark/vmalloc.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/arch-shark/vmalloc.h Mon Sep 18 15:15:23 2000
@@ -0,0 +1,17 @@
+/*
+ * linux/include/asm-arm/arch-rpc/vmalloc.h
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts. That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET (8*1024*1024)
+#define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-tbox/dma.h linux/include/asm-arm/arch-tbox/dma.h
--- v2.4.0-test8/linux/include/asm-arm/arch-tbox/dma.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/arch-tbox/dma.h Mon Sep 18 15:15:23 2000
@@ -0,0 +1,37 @@
+/*
+ * linux/include/asm-arm/arch-tbox/dma.h
+ *
+ * Architecture DMA routines. We have to contend with the bizarre DMA
+ * machine built into the Tbox hardware.
+ *
+ * Copyright (C) 1998 Philip Blundell
+ */
+
+/*


+ * This program is free software; you can redistribute it and/or

+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+/*
+ * DMA channel definitions. Some of these are physically strange but
+ * we sort it out inside dma.c so the user never has to care. The
+ * exception is the double-buffering which we can't really abstract
+ * away sensibly.
+ */
+#define DMA_VIDEO 0
+#define DMA_MPEG_B 1
+#define DMA_AUDIO_B 2
+#define DMA_ASHRX_B 3
+#define DMA_ASHTX 4
+#define DMA_MPEG 5
+#define DMA_AUDIO 6
+#define DMA_ASHRX 7
+
+#define MAX_DMA_CHANNELS 0 /* XXX */
+
+/*
+ * This is the maximum DMA address that can be DMAd to.
+ */
+#define MAX_DMA_ADDRESS 0xffffffff
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-tbox/hardware.h linux/include/asm-arm/arch-tbox/hardware.h
--- v2.4.0-test8/linux/include/asm-arm/arch-tbox/hardware.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/arch-tbox/hardware.h Mon Sep 18 15:15:23 2000


@@ -0,0 +1,60 @@
+/*

+ * linux/include/asm-arm/arch-tbox/hardware.h
+ *
+ * Copyright (C) 1998, 1999, 2000 Philip Blundell
+ * Copyright (C) 2000 FutureTV Labs Ltd
+ *
+ * This file contains the hardware definitions of the Tbox
+ */
+
+/*


+ * This program is free software; you can redistribute it and/or

+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+/* Logical Physical
+ * 0xfff00000 0x00100000 I/O
+ * 0xfff00000 0x00100000 Expansion CS0
+ * 0xfff10000 0x00110000 DMA
+ * 0xfff20000 0x00120000 C-Cube
+ * 0xfff30000 0x00130000 FPGA 1
+ * 0xfff40000 0x00140000 UART 2
+ * 0xfff50000 0x00150000 UART 1
+ * 0xfff60000 0x00160000 CS8900
+ * 0xfff70000 0x00170000 INTCONT
+ * 0xfff80000 0x00180000 RAMDAC
+ * 0xfff90000 0x00190000 Control 0
+ * 0xfffa0000 0x001a0000 Control 1
+ * 0xfffb0000 0x001b0000 Control 2
+ * 0xfffc0000 0x001c0000 FPGA 2
+ * 0xfffd0000 0x001d0000 INTRESET
+ * 0xfffe0000 0x001e0000 C-Cube DMA throttle
+ * 0xffff0000 0x001f0000 Expansion CS1
+ * 0xffe00000 0x82000000 cache flush
+ */
+
+/*
+ * Mapping areas
+ */
+#define IO_BASE 0xfff00000
+#define IO_START 0x00100000
+#define FLUSH_BASE 0xffe00000
+
+#define INTCONT 0xfff70000
+
+#define FPGA1CONT 0xffff3000
+
+/*
+ * RAM definitions
+ */
+#define RAM_BASE 0x80000000
+#define FLUSH_BASE_PHYS 0x82000000
+
+#define UNCACHEABLE_ADDR INTCONT
+
+#endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-tbox/ide.h linux/include/asm-arm/arch-tbox/ide.h
--- v2.4.0-test8/linux/include/asm-arm/arch-tbox/ide.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/arch-tbox/ide.h Mon Sep 18 15:15:23 2000
@@ -0,0 +1,3 @@
+/*
+ * linux/include/asm-arm/arch-tbox/ide.h
+ */
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-tbox/io.h linux/include/asm-arm/arch-tbox/io.h
--- v2.4.0-test8/linux/include/asm-arm/arch-tbox/io.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/arch-tbox/io.h Mon Sep 18 15:15:23 2000
@@ -0,0 +1,55 @@
+/*
+ * linux/include/asm-arm/arch-tbox/io.h
+ *
+ * Copyright (C) 1996-1999 Russell King
+ * Copyright (C) 1998, 1999 Philip Blundell
+ *
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io_pc(_x) ((_x) << 2)
+
+/*
+ * Generic virtual read/write
+ */
+#define __arch_getb(a) (*(volatile unsigned char *)(a))
+#define __arch_getl(a) (*(volatile unsigned long *)(a))
+
+extern __inline__ unsigned int __arch_getw(unsigned long a)
+{
+ unsigned int value;
+ __asm__ __volatile__("ldr%?h %0, [%1, #0] @ getw"
+ : "=&r" (value)
+ : "r" (a));
+ return value;
+}
+
+
+#define __arch_putb(v,a) (*(volatile unsigned char *)(a) = (v))
+#define __arch_putl(v,a) (*(volatile unsigned long *)(a) = (v))
+
+extern __inline__ void __arch_putw(unsigned int value, unsigned long a)
+{
+ __asm__ __volatile__("str%?h %0, [%1, #0] @ putw"
+ : : "r" (value), "r" (a));
+}
+
+#define inb(p) __arch_getb(__io_pc(p))
+#define inw(p) __arch_getw(__io_pc(p))
+#define inl(p) __arch_getl(__io_pc(p))
+
+#define outb(v,p) __arch_putb(v,__io_pc(p))
+#define outw(v,p) __arch_putw(v,__io_pc(p))
+#define outl(v,p) __arch_putl(v,__io_pc(p))
+
+/* Idem, for devices on the upper byte lanes */
+#define inb_u(p) __arch_getb(__io_pc(p) + 2)
+#define inw_u(p) __arch_getw(__io_pc(p) + 2)
+
+#define outb_u(v,p) __arch_putb(v,__io_pc(p) + 2)
+#define outw_u(v,p) __arch_putw(v,__io_pc(p) + 2)
+
+#endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-tbox/irq.h linux/include/asm-arm/arch-tbox/irq.h
--- v2.4.0-test8/linux/include/asm-arm/arch-tbox/irq.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/arch-tbox/irq.h Mon Sep 18 15:15:23 2000
@@ -0,0 +1,50 @@
+/*
+ * include/asm-arm/arch-tbox/irq.h
+ *
+ * Copyright (C) 1998, 1999, 2000 Philip Blundell
+ */
+
+/*


+ * This program is free software; you can redistribute it and/or

+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/io.h>
+
+#define fixup_irq(x) (x)
+
+extern unsigned long soft_irq_mask;
+
+static void tbox_mask_irq(unsigned int irq)
+{
+ __raw_writel(0, INTCONT + (irq << 2));
+ soft_irq_mask &= ~(1<<irq);
+}
+
+static void tbox_unmask_irq(unsigned int irq)
+{
+ soft_irq_mask |= (1<<irq);
+ __raw_writel(1, INTCONT + (irq << 2));
+}
+
+static __inline__ void irq_init_irq(void)
+{
+ unsigned int i;
+
+ /* Disable all interrupts initially. */
+ for (i = 0; i < NR_IRQS; i++) {
+ if (i <= 10 || (i >= 12 && i <= 13)) {
+ irq_desc[i].valid = 1;
+ irq_desc[i].probe_ok = 0;
+ irq_desc[i].mask_ack = tbox_mask_irq;
+ irq_desc[i].mask = tbox_mask_irq;
+ irq_desc[i].unmask = tbox_unmask_irq;
+ tbox_mask_irq(i);
+ } else {
+ irq_desc[i].valid = 0;
+ irq_desc[i].probe_ok = 0;
+ }
+ }
+}
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-tbox/irqs.h linux/include/asm-arm/arch-tbox/irqs.h
--- v2.4.0-test8/linux/include/asm-arm/arch-tbox/irqs.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/arch-tbox/irqs.h Mon Sep 18 15:15:23 2000
@@ -0,0 +1,29 @@
+/*
+ * linux/include/asm-arm/arch-tbox/irqs.h
+ *
+ * Copyright (C) 1998, 2000 Philip Blundell
+ */
+
+/*


+ * This program is free software; you can redistribute it and/or

+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#define IRQ_MPEGDMA 0
+#define IRQ_ASHTX 1
+#define IRQ_ASHRX 2
+#define IRQ_VSYNC 3
+#define IRQ_HSYNC 4
+#define IRQ_MPEG 5
+#define IRQ_UART2 6
+#define IRQ_UART1 7
+#define IRQ_ETHERNET 8
+#define IRQ_TIMER 9
+#define IRQ_AUDIODMA 10
+/* bit 11 used for video field ident */
+#define IRQ_EXPMODCS0 12
+#define IRQ_EXPMODCS1 13
+
+#define irq_cannonicalize(i) (i)
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-tbox/keyboard.h linux/include/asm-arm/arch-tbox/keyboard.h
--- v2.4.0-test8/linux/include/asm-arm/arch-tbox/keyboard.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/arch-tbox/keyboard.h Mon Sep 18 15:15:23 2000
@@ -0,0 +1,29 @@
+/*
+ * linux/include/asm-arm/arch-tbox/keyboard.h
+ *
+ * Driver definitions for Tbox dummy keyboard.
+ *
+ * Copyright (C) 1998 Russell King
+ * Copyright (C) 1998 Philip Blundell
+ */
+
+#define NR_SCANCODES 128
+
+#define kbd_setkeycode(sc,kc) (-EINVAL)
+#define kbd_getkeycode(sc) (-EINVAL)
+
+/* Prototype: int kbd_pretranslate(scancode, raw_mode)
+ * Returns : 0 to ignore scancode
+ */
+#define kbd_pretranslate(sc,rm) (1)
+
+/* Prototype: int kbd_translate(scancode, *keycode, *up_flag, raw_mode)
+ * Returns : 0 to ignore scancode, *keycode set to keycode, *up_flag
+ * set to 0200 if scancode indicates release
+ */
+#define kbd_translate(sc, kcp, rm) 0
+#define kbd_unexpected_up(kc) (0200)
+#define kbd_leds(leds) do { } while (0)
+#define kbd_init_hw() do { } while (0)
+#define kbd_disable_irq() do { } while (0)
+#define kbd_enable_irq() do { } while (0)
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-tbox/memory.h linux/include/asm-arm/arch-tbox/memory.h
--- v2.4.0-test8/linux/include/asm-arm/arch-tbox/memory.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/arch-tbox/memory.h Mon Sep 18 15:15:23 2000
@@ -0,0 +1,38 @@
+/*
+ * linux/include/asm-arm/arch-tbox/memory.h
+ *
+ * Copyright (c) 1996-1999 Russell King.
+ * Copyright (c) 1998-1999 Phil Blundell
+ */
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Task size: 3GB
+ */
+#define TASK_SIZE (0xc0000000UL)
+#define TASK_SIZE_26 (0x04000000UL)
+
+/*
+ * Page offset: 3GB
+ */
+#define PAGE_OFFSET (0xc0000000UL)
+#define PHYS_OFFSET (0x80000000UL)
+
+/*
+ * DRAM is contiguous
+ */
+#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET + PHYS_OFFSET)
+#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET - PHYS_OFFSET)
+#define __virt_to_phys__is_a_macro
+#define __phys_to_virt__is_a_macro
+
+/*
+ * Bus view is the same as physical view
+ */
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(x) __virt_to_phys(x)
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(x) __phys_to_virt(x)
+
+#endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-tbox/param.h linux/include/asm-arm/arch-tbox/param.h
--- v2.4.0-test8/linux/include/asm-arm/arch-tbox/param.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/arch-tbox/param.h Mon Sep 18 15:15:23 2000
@@ -0,0 +1 @@
+#define HZ 1000
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-tbox/processor.h linux/include/asm-arm/arch-tbox/processor.h
--- v2.4.0-test8/linux/include/asm-arm/arch-tbox/processor.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/arch-tbox/processor.h Mon Sep 18 15:15:23 2000
@@ -0,0 +1,24 @@
+/*
+ * linux/include/asm-arm/arch-tbox/processor.h
+ * from linux/include/asm-arm/arch-ebsa110/processor.h
+ *
+ * Copyright (C) 1996,1997,1998 Russell King
+ */
+
+#ifndef __ASM_ARCH_PROCESSOR_H
+#define __ASM_ARCH_PROCESSOR_H
+
+/*
+ * Bus types
+ */
+#define EISA_bus 0
+#define EISA_bus__is_a_macro /* for versions in ksyms.c */
+#define MCA_bus 0
+#define MCA_bus__is_a_macro /* for versions in ksyms.c */
+
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
+
+#endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-tbox/serial.h linux/include/asm-arm/arch-tbox/serial.h
--- v2.4.0-test8/linux/include/asm-arm/arch-tbox/serial.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/arch-tbox/serial.h Mon Sep 18 15:15:23 2000
@@ -0,0 +1,34 @@
+/*
+ * linux/include/asm-arm/arch-tbox/serial.h
+ *
+ * Copyright (c) 1996 Russell King.
+ * Copyright (c) 1998 Phil Blundell
+ *
+ * Changelog:
+ * 15-10-1996 RMK Created
+ * 09-06-1998 PJB tbox version
+ */
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+/*
+ * This assumes you have a 1.8432 MHz clock for your UART.
+ *
+ * It'd be nice if someone built a serial card with a 24.576 MHz
+ * clock, since the 16550A is capable of handling a top speed of 1.5
+ * megabits/second; but this requires the faster clock.
+ */
+#define BASE_BAUD (1843200 / 16)
+
+#define RS_TABLE_SIZE 2
+
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+
+ /* UART CLK PORT IRQ FLAGS */
+#define STD_SERIAL_PORT_DEFNS \
+ { 0, BASE_BAUD, 0xffff4000 >> 2, 6, STD_COM_FLAGS }, /* ttyS0 */ \
+ { 0, BASE_BAUD, 0xffff5000 >> 2, 7, STD_COM_FLAGS }, /* ttyS1 */
+
+#define EXTRA_SERIAL_PORT_DEFNS
+
+#endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-tbox/system.h linux/include/asm-arm/arch-tbox/system.h
--- v2.4.0-test8/linux/include/asm-arm/arch-tbox/system.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/arch-tbox/system.h Mon Sep 18 15:15:23 2000
@@ -0,0 +1,33 @@
+/*
+ * linux/include/asm-arm/arch-tbox/system.h
+ *
+ * Copyright (c) 1996-1999 Russell King.
+ */
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+static void arch_idle(void)
+{
+ unsigned long start_idle;
+
+ start_idle = jiffies;
+
+ do {
+ if (current->need_resched || hlt_counter)
+ goto slow_out;
+ cpu_do_idle(IDLE_WAIT_FAST);
+ } while (time_before(jiffies, start_idle + HZ/50));
+
+ cpu_do_idle(IDLE_CLOCK_SLOW);
+
+ while (!current->need_resched && !hlt_counter) {
+ cpu_do_idle(IDLE_WAIT_SLOW);
+ }
+
+ cpu_do_idle(IDLE_CLOCK_FAST);
+slow_out:
+}
+
+#define arch_reset(mode) do { } while (0)
+
+#endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-tbox/time.h linux/include/asm-arm/arch-tbox/time.h
--- v2.4.0-test8/linux/include/asm-arm/arch-tbox/time.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/arch-tbox/time.h Mon Sep 18 15:15:23 2000
@@ -0,0 +1,36 @@
+/*
+ * linux/include/asm-arm/arch-tbox/time.h
+ *
+ * Copyright (c) 1997, 1999 Phil Blundell.
+ * Copyright (c) 2000 FutureTV Labs Ltd
+ *
+ * Tbox has no real-time clock -- we get millisecond ticks to update
+ * our soft copy.
+ */
+
+#include <asm/io.h>
+#include <asm/hardware.h>
+
+#define update_rtc()
+
+static void timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
+{
+ /* Clear irq */
+ __raw_writel(1, FPGA1CONT + 0xc);
+ __raw_writel(0, FPGA1CONT + 0xc);
+
+ do_timer(regs);
+}
+
+extern __inline__ void setup_timer (void)
+{
+ /*
+ * Default the date to 1 Jan 1970 0:0:0
+ * You will have to run a time daemon to set the
+ * clock correctly at bootup
+ */
+ xtime.tv_sec = mktime(1970, 1, 1, 0, 0, 0);
+
+ timer_irq.handler = timer_interrupt;
+ setup_arm_irq(IRQ_TIMER, &timer_irq);
+}
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-tbox/timex.h linux/include/asm-arm/arch-tbox/timex.h


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 102'
echo 'File patch-2.4.0-test9 is continued in part 103'
echo "103" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part098

#!/bin/sh -x
# this is part 098 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 098; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ if (Page_Uptodate(page)) {
+ set_bit(BH_Uptodate, &bh->b_state);
+ continue;
+ }
X if (block_end > to)
X memset(kaddr+to, 0, block_end-to);
X if (block_start < from)
@@ -1480,6 +1511,10 @@
X continue;
X }
X }
+ if (Page_Uptodate(page)) {
+ set_bit(BH_Uptodate, &bh->b_state);
+ continue;
+ }
X if (!buffer_uptodate(bh) &&
X (block_start < from || block_end > to)) {
X ll_rw_block(READ, 1, &bh);
@@ -1574,8 +1609,10 @@
X continue;
X
X if (!buffer_mapped(bh)) {
- if (iblock < lblock)
- get_block(inode, iblock, bh, 0);
+ if (iblock < lblock) {
+ if (get_block(inode, iblock, bh, 0))
+ continue;
+ }
X if (!buffer_mapped(bh)) {
X if (!kaddr)
X kaddr = kmap(page);
@@ -1758,17 +1795,27 @@
X pos += blocksize;
X }
X
+ err = 0;
+ if (!buffer_mapped(bh)) {
+ /* Hole? Nothing to do */
+ if (buffer_uptodate(bh))
+ goto unlock;
+ get_block(inode, iblock, bh, 0);
+ /* Still unmapped? Nothing to do */
+ if (!buffer_mapped(bh))
+ goto unlock;
+ }
+
+ /* Ok, it's mapped. Make sure it's up-to-date */
+ if (Page_Uptodate(page))
+ set_bit(BH_Uptodate, &bh->b_state);
+
+ bh->b_end_io = end_buffer_io_sync;
X if (!buffer_uptodate(bh)) {
- err = 0;
- if (!buffer_mapped(bh)) {
- get_block(inode, iblock, bh, 0);
- if (!buffer_mapped(bh))
- goto unlock;
- }
X err = -EIO;
- bh->b_end_io = end_buffer_io_sync;
X ll_rw_block(READ, 1, &bh);
X wait_on_buffer(bh);
+ /* Uhhuh. Read error. Complain and punt. */
X if (!buffer_uptodate(bh))
X goto unlock;
X }
@@ -2152,6 +2199,7 @@
X page = alloc_page(GFP_BUFFER);
X if (!page)
X goto out;
+ LockPage(page);
X bh = create_buffers(page, size, 0);
X if (!bh)
X goto no_buffer_head;
@@ -2184,10 +2232,12 @@
X page->buffers = bh;
X page->flags &= ~(1 << PG_referenced);
X lru_cache_add(page);
+ UnlockPage(page);
X atomic_inc(&buffermem_pages);
X return 1;
X
X no_buffer_head:
+ UnlockPage(page);
X page_cache_release(page);
X out:
X return 0;
@@ -2244,7 +2294,9 @@
X {
X struct buffer_head * tmp, * bh = page->buffers;
X int index = BUFSIZE_INDEX(bh->b_size);
+ int loop = 0;
X
+cleaned_buffers_try_again:
X spin_lock(&lru_list_lock);
X write_lock(&hash_table_lock);
X spin_lock(&free_list[index].lock);
@@ -2290,8 +2342,14 @@
X spin_unlock(&free_list[index].lock);
X write_unlock(&hash_table_lock);
X spin_unlock(&lru_list_lock);
- if (wait)
+ if (wait) {
X sync_page_buffers(bh, wait);
+ /* We waited synchronously, so we can free the buffers. */
+ if (wait > 1 && !loop) {
+ loop = 1;
+ goto cleaned_buffers_try_again;
+ }
+ }


X return 0;
X }
X

@@ -2609,6 +2667,8 @@
X CHECK_EMERGENCY_SYNC
X
X flushed = flush_dirty_buffers(0);
+ if (free_shortage())
+ flushed += page_launder(GFP_BUFFER, 0);
X
X /* If wakeup_bdflush will wakeup us
X after our bdflush_done wakeup, then
@@ -2619,14 +2679,16 @@
X (as we would be sleeping) and so it would
X deadlock in SMP. */
X __set_current_state(TASK_INTERRUPTIBLE);
- wake_up(&bdflush_done);
+ wake_up_all(&bdflush_done);
X /*
X * If there are still a lot of dirty buffers around,
X * skip the sleep and flush some more. Otherwise, we
X * go to sleep waiting a wakeup.
X */
- if (!flushed || balance_dirty_state(NODEV) < 0)
+ if (!flushed || balance_dirty_state(NODEV) < 0) {
+ run_task_queue(&tq_disk);
X schedule();
+ }
X /* Remember to mark us as running otherwise
X the next schedule will block. */
X __set_current_state(TASK_RUNNING);
diff -u --recursive --new-file v2.4.0-test8/linux/fs/coda/cache.c linux/fs/coda/cache.c
--- v2.4.0-test8/linux/fs/coda/cache.c Wed Jul 5 11:30:59 2000
+++ linux/fs/coda/cache.c Thu Sep 21 09:59:46 2000
@@ -24,168 +24,60 @@
X #include <linux/coda_fs_i.h>
X #include <linux/coda_cache.h>
X
-/* create a new acl cache entry and enlist it */
-static struct coda_cache *coda_cache_create(struct inode *inode)
+/* replace or extend an acl cache hit */
+void coda_cache_enter(struct inode *inode, int mask)
X {
X struct coda_inode_info *cii = ITOC(inode);
- struct coda_sb_info *sbi = coda_sbp(inode->i_sb);
- struct coda_cache *cc = NULL;
- ENTRY;
-
- if ( !sbi || !cii ) {
- printk("coda_cache_create: NULL sbi or cii!\n");
- return NULL;
- }
-
- CODA_ALLOC(cc, struct coda_cache *, sizeof(*cc));
-
- if ( !cc ) {
- printk("Out of memory in coda_cache_create!\n");
- return NULL;
- }
-
- coda_load_creds(&cc->cc_cred);
- cc->cc_mask = 0;
-
- INIT_LIST_HEAD(&cc->cc_cclist);
- INIT_LIST_HEAD(&cc->cc_cnlist);
- list_add(&cc->cc_cclist, &sbi->sbi_cchead);
- list_add(&cc->cc_cnlist, &cii->c_cnhead);
-
- return cc;
-}
+ ENTRY;
X
-/* destroy an acl cache entry */
-static void coda_cache_destroy(struct coda_cache *el)
-{
- ENTRY;
- if (list_empty(&el->cc_cclist) || list_empty(&el->cc_cnlist)) {
- printk("coda_cache_destroy: loose entry!");
- return;
- }
- list_del(&el->cc_cclist);
- list_del(&el->cc_cnlist);
- CODA_FREE(el, sizeof(struct coda_cache));
+ if ( !coda_cred_ok(&cii->c_cached_cred) ) {
+ coda_load_creds(&cii->c_cached_cred);
+ cii->c_cached_perm = mask;
+ } else
+ cii->c_cached_perm |= mask;
X }
X
-/* see if there is a match for the current
- credentials already */
-static struct coda_cache * coda_cache_find(struct inode *inode)
+/* remove cached acl from an inode */
+void coda_cache_clear_inode(struct inode *inode)
X {
X struct coda_inode_info *cii = ITOC(inode);
- struct list_head *le;
- struct coda_cache *cc = NULL;
-
- list_for_each(le, &cii->c_cnhead)
- {
- /* compare name and creds */
- cc = list_entry(le, struct coda_cache, cc_cnlist);
- if ( !coda_cred_ok(&cc->cc_cred) )
- continue;
- CDEBUG(D_CACHE, "HIT for ino %ld\n", inode->i_ino );
- return cc; /* cache hit */
- }
- return NULL;
-}
-
-/* create or extend an acl cache hit */
-void coda_cache_enter(struct inode *inode, int mask)
-{
- struct coda_cache *cc;
-
- cc = coda_cache_find(inode);
-
- if (!cc)
- cc = coda_cache_create(inode);
- if (cc)
- cc->cc_mask |= mask;
+ ENTRY;
+ cii->c_cached_perm = 0;
X }
X
-/* remove all cached acl matches from an inode */
-void coda_cache_clear_inode(struct inode *inode)
+/* remove all acl caches for a principal (or all principals when cred == NULL)*/
+void coda_cache_clear_all(struct super_block *sb, struct coda_cred *cred)
X {
- struct list_head *le;
- struct coda_inode_info *cii;
- struct coda_cache *cc;
- ENTRY;
+ struct coda_sb_info *sbi;
+ struct coda_inode_info *cii;
+ struct list_head *tmp;
X
- if ( !inode ) {
- CDEBUG(D_CACHE, "coda_cache_clear_inode: NULL inode\n");
- return;
- }
- cii = ITOC(inode);
-
- le = cii->c_cnhead.next;
- while ( le != &cii->c_cnhead ) {
- cc = list_entry(le, struct coda_cache, cc_cnlist);
- le = le->next;
- coda_cache_destroy(cc);
- }
-}
+ ENTRY;
+ sbi = coda_sbp(sb);
+ if (!sbi) BUG();
X
-/* remove all acl caches */
-void coda_cache_clear_all(struct super_block *sb)
-{
- struct list_head *le;
- struct coda_cache *cc;
- struct coda_sb_info *sbi = coda_sbp(sb);
-
- if ( !sbi ) {
- printk("coda_cache_clear_all: NULL sbi\n");
- return;
- }
-
- le = sbi->sbi_cchead.next;
- while ( le != &sbi->sbi_cchead ) {
- cc = list_entry(le, struct coda_cache, cc_cclist);
- le = le->next;
- coda_cache_destroy(cc);
- }
-}
+ list_for_each(tmp, &sbi->sbi_cihead)
+ {
+ cii = list_entry(tmp, struct coda_inode_info, c_cilist);
+ if ( cii->c_magic != CODA_CNODE_MAGIC ) BUG();
X
-/* remove all acl caches for a principal */
-void coda_cache_clear_cred(struct super_block *sb, struct coda_cred *cred)
-{
- struct list_head *le;
- struct coda_cache *cc;
- struct coda_sb_info *sbi = coda_sbp(sb);
-
- if ( !sbi ) {
- printk("coda_cache_clear_all: NULL sbi\n");
- return;
- }
-
- le = sbi->sbi_cchead.next;
- while ( le != &sbi->sbi_cchead ) {
- cc = list_entry(le, struct coda_cache, cc_cclist);
- le = le->next;
- if ( coda_cred_eq(&cc->cc_cred, cred))
- coda_cache_destroy(cc);
+ if (!cred || coda_cred_eq(cred, &cii->c_cached_cred))
+ cii->c_cached_perm = 0;
X }
X }
X
X
-/* check if the mask has been matched against the acl
- already */
+/* check if the mask has been matched against the acl already */
X int coda_cache_check(struct inode *inode, int mask)
X {
X struct coda_inode_info *cii = ITOC(inode);
- struct list_head *le;
- struct coda_cache *cc = NULL;
+ int hit;
X
- list_for_each(le, &cii->c_cnhead)
- {
- /* compare name and creds */
- cc = list_entry(le, struct coda_cache, cc_cnlist);
- if ( (cc->cc_mask & mask) != mask )
- continue;
- if ( !coda_cred_ok(&cc->cc_cred) )
- continue;
- CDEBUG(D_CACHE, "HIT for ino %ld\n", inode->i_ino );
- return 1; /* cache hit */
- }
- CDEBUG(D_CACHE, "MISS for ino %ld\n", inode->i_ino );
- return 0;
+ hit = ((mask & cii->c_cached_perm) == mask) &&
+ coda_cred_ok(&cii->c_cached_cred);
+
+ CDEBUG(D_CACHE, "%s for ino %ld\n", hit ? "HIT" : "MISS", inode->i_ino);
+ return hit;
X }
X
X
diff -u --recursive --new-file v2.4.0-test8/linux/fs/coda/cnode.c linux/fs/coda/cnode.c
--- v2.4.0-test8/linux/fs/coda/cnode.c Wed Jun 21 10:10:02 2000
+++ linux/fs/coda/cnode.c Thu Sep 21 09:59:46 2000
@@ -59,7 +59,6 @@
X struct coda_vattr * attr)
X {
X struct inode *inode;
- struct coda_sb_info *sbi= coda_sbp(sb);
X struct coda_inode_info *cii;
X ino_t ino = attr->va_fileid;
X
@@ -71,50 +70,26 @@
X
X /* check if the inode is already initialized */
X cii = ITOC(inode);
- if (cii->c_magic == CODA_CNODE_MAGIC) {
+ if (cii->c_fid.Volume != 0 || cii->c_fid.Vnode != 0 || cii->c_fid.Unique != 0) {
X /* see if it is the right one (might have an inode collision) */
- if ( !coda_fideq(fid, &cii->c_fid) ) {
+ if ( !coda_fideq(fid, &cii->c_fid) ) {
X printk("coda_iget: initialized inode old %s new %s!\n",
X coda_f2s(&cii->c_fid), coda_f2s2(fid));
X iput(inode);
X return ERR_PTR(-ENOENT);
X }
- /* replace the attributes, type might have changed */
- coda_fill_inode(inode, attr);
+ /* we will still replace the attributes, type might have changed */
X goto out;
X }
X
X /* new, empty inode found... initializing */
X
X /* Initialize the Coda inode info structure */
- memset(cii, 0, (int) sizeof(struct coda_inode_info));
- cii->c_magic = CODA_CNODE_MAGIC;
X cii->c_fid = *fid;
- cii->c_flags = 0;
X cii->c_vnode = inode;
- INIT_LIST_HEAD(&(cii->c_cnhead));
- INIT_LIST_HEAD(&(cii->c_volrootlist));
X
- coda_fill_inode(inode, attr);
-
- /* check if it is a weird fid (hashed fid != ino), f.i mountpoints
- repair object, expanded local-global conflict trees, etc.
- */
- if ( coda_f2i(fid) == ino )
- goto out;
-
- /* check if we expected this weird fid */
- if ( !coda_fid_is_weird(fid) ) {
- printk("Coda: unknown weird fid: ino %ld, fid %s."
- "Tell Peter.\n", (long)ino, coda_f2s(&cii->c_fid));


- goto out;
- }
-

- /* add the inode to a global list so we can find it back later */
- list_add(&cii->c_volrootlist, &sbi->sbi_volroothead);
- CDEBUG(D_CNODE, "Added %ld, %s to volroothead\n",
- (long)ino, coda_f2s(&cii->c_fid));
X out:
+ coda_fill_inode(inode, attr);
X return inode;
X }
X
@@ -161,22 +136,14 @@
X void coda_replace_fid(struct inode *inode, struct ViceFid *oldfid,
X struct ViceFid *newfid)
X {
- struct coda_inode_info *cnp;
- struct coda_sb_info *sbi= coda_sbp(inode->i_sb);
+ struct coda_inode_info *cii;
X
- cnp = ITOC(inode);
-
- if ( ! coda_fideq(&cnp->c_fid, oldfid) )
- printk("What? oldfid != cnp->c_fid. Call 911.\n");
-
- cnp->c_fid = *newfid;
+ cii = ITOC(inode);
X
- list_del(&cnp->c_volrootlist);
- INIT_LIST_HEAD(&cnp->c_volrootlist);
- if ( coda_fid_is_weird(newfid) )
- list_add(&cnp->c_volrootlist, &sbi->sbi_volroothead);
+ if ( ! coda_fideq(&cii->c_fid, oldfid) )
+ printk("What? oldfid != cii->c_fid. Call 911.\n");
X
- return;
+ cii->c_fid = *newfid;
X }
X
X
@@ -197,24 +164,18 @@


X return NULL;
X }
X

- if ( !fid ) {
- printk("coda_fid_to_inode: no fid!\n");
- return NULL;
- }
X CDEBUG(D_INODE, "%s\n", coda_f2s(fid));
X
X
+ /* weird fids cannot be hashed, have to look for them the hard way */
X if ( coda_fid_is_weird(fid) ) {
- struct list_head *lh, *le;
X struct coda_sb_info *sbi = coda_sbp(sb);
- le = lh = &sbi->sbi_volroothead;
+ struct list_head *le;
X
- while ( (le = le->next) != lh ) {
- cii = list_entry(le, struct coda_inode_info,
- c_volrootlist);
- /* paranoia check, should never trigger */
- if ( cii->c_magic != CODA_CNODE_MAGIC )
- printk("coda_fid_to_inode: Bad magic in inode %x.\n", cii->c_magic);
+ list_for_each(le, &sbi->sbi_cihead)
+ {
+ cii = list_entry(le, struct coda_inode_info, c_cilist);
+ if ( cii->c_magic != CODA_CNODE_MAGIC ) BUG();
X
X CDEBUG(D_DOWNCALL, "iterating, now doing %s, ino %ld\n",
X coda_f2s(&cii->c_fid), cii->c_vnode->i_ino);
@@ -240,26 +201,19 @@
X
X /* check if this inode is linked to a cnode */
X cii = ITOC(inode);
- if ( cii->c_magic != CODA_CNODE_MAGIC ) {
- CDEBUG(D_INODE, "uninitialized inode. Return.\n");
- goto bad_inode;
- }
X
- /* make sure fid is the one we want */
- if ( !coda_fideq(fid, &(cii->c_fid)) ) {
+ /* make sure this is the one we want */
+ if ( coda_fideq(fid, &cii->c_fid) ) {
+ CDEBUG(D_INODE, "found %ld\n", inode->i_ino);
+ return inode;
+ }
+
X #if 0
- printk("coda_fid2inode: bad cnode (ino %ld, fid %s)", nr,
- coda_f2s(fid));
+ printk("coda_fid2inode: bad cnode (ino %ld, fid %s)", nr, coda_f2s(fid));
X #endif
- goto bad_inode;
- }
-
- CDEBUG(D_INODE, "found %ld\n", inode->i_ino);
- return inode;
+ iput(inode);
+ return NULL;
X
-bad_inode:
- iput(inode);
- return NULL;
X }
X
X /* the CONTROL inode is made without asking attributes from Venus */
@@ -271,7 +225,7 @@
X if ( *inode ) {
X (*inode)->i_op = &coda_ioctl_inode_operations;
X (*inode)->i_fop = &coda_ioctl_operations;
- (*inode)->i_mode = 00444;
+ (*inode)->i_mode = 0444;
X error = 0;
X } else {
X error = -ENOMEM;
diff -u --recursive --new-file v2.4.0-test8/linux/fs/coda/coda_linux.c linux/fs/coda/coda_linux.c
--- v2.4.0-test8/linux/fs/coda/coda_linux.c Thu Feb 10 12:16:58 2000
+++ linux/fs/coda/coda_linux.c Tue Sep 19 15:08:59 2000
@@ -23,7 +23,6 @@
X #include <linux/coda_linux.h>
X #include <linux/coda_psdev.h>
X #include <linux/coda_fs_i.h>
-#include <linux/coda_cache.h>
X
X /* initialize the debugging variables */
X int coda_debug = 0;
@@ -71,12 +70,6 @@
X }
X }
X
-/* is this a volume root FID */
-int coda_fid_is_volroot(struct ViceFid *fid)
-{
- return ( (fid->Vnode == 1) && (fid->Unique == 1 ) );
-}
-
X int coda_fid_is_weird(struct ViceFid *fid)
X {
X /* volume roots */
diff -u --recursive --new-file v2.4.0-test8/linux/fs/coda/dir.c linux/fs/coda/dir.c
--- v2.4.0-test8/linux/fs/coda/dir.c Fri Aug 11 14:29:02 2000
+++ linux/fs/coda/dir.c Tue Sep 19 15:08:59 2000
@@ -170,12 +170,13 @@
X
X ENTRY;
X coda_vfs_stat.permission++;
- coda_permission_stat.count++;
X
X if ( mask == 0 )
X return 0;
X
- if ( coda_access_cache == 1 ) {
+ if ( coda_access_cache ) {
+ coda_permission_stat.count++;
+
X if ( coda_cache_check(inode, mask) ) {
X coda_permission_stat.hit_count++;
X return 0;
@@ -472,6 +473,7 @@
X const char *new_name = new_dentry->d_name.name;
X int old_length = old_dentry->d_name.len;
X int new_length = new_dentry->d_name.len;
+ int link_adjust = 0;
X int error;
X
X ENTRY;
@@ -488,16 +490,16 @@
X
X if ( !error ) {
X if ( new_dentry->d_inode ) {
- if ( S_ISDIR(new_dentry->d_inode->i_mode) ) {
- old_dir->i_nlink--;
- new_dir->i_nlink++;
- }
- coda_flag_inode(new_dentry->d_inode, C_VATTR);
- }
+ if ( S_ISDIR(new_dentry->d_inode->i_mode) )
+ link_adjust = 1;
X
- /* coda_flag_inode(old_dir, C_VATTR); */
- /* coda_flag_inode(new_dir, C_VATTR); */
- old_dir->i_mtime = new_dir->i_mtime = CURRENT_TIME;
+ coda_dir_changed(old_dir, -link_adjust);
+ coda_dir_changed(new_dir, link_adjust);
+ coda_flag_inode(new_dentry->d_inode, C_VATTR);
+ } else {
+ coda_flag_inode(old_dir, C_VATTR);
+ coda_flag_inode(new_dir, C_VATTR);
+ }
X }
X
X CDEBUG(D_INODE, "result %d\n", error);
@@ -578,6 +580,7 @@
X unsigned short flags = f->f_flags & (~O_EXCL);
X unsigned short coda_flags = coda_flags_to_cflags(flags);
X struct coda_cred *cred;
+ struct coda_inode_info *cii;
X
X lock_kernel();
X ENTRY;
@@ -617,8 +620,11 @@
X }
X i->i_mapping = cont_inode->i_mapping;
X
- CDEBUG(D_FILE, "result %d, coda i->i_count is %d for ino %ld\n",
- error, atomic_read(&i->i_count), i->i_ino);
+ cii = ITOC(i);
+ cii->c_contcount++;
+
+ CDEBUG(D_FILE, "result %d, coda i->i_count is %d, cii->contcount is %d for ino %ld\n",
+ error, atomic_read(&i->i_count), cii->c_contcount, i->i_ino);
X CDEBUG(D_FILE, "cache ino: %ld, count %d, ops %p\n",
X cont_inode->i_ino, atomic_read(&cont_inode->i_count),
X cont_inode->i_op);
@@ -634,6 +640,7 @@
X unsigned short flags = (f->f_flags) & (~O_EXCL);
X unsigned short cflags = coda_flags_to_cflags(flags);
X struct coda_cred *cred;
+ struct coda_inode_info *cii;
X
X lock_kernel();
X ENTRY;
@@ -644,10 +651,16 @@
X if (i->i_mapping != &i->i_data)
X container = (struct inode *)i->i_mapping->host;
X
- CDEBUG(D_FILE, "RELEASE coda (ino %ld, ct %d) cache (ino %ld, ct %d)\n",
- i->i_ino, atomic_read(&i->i_count),
+ cii = ITOC(i);
+ CDEBUG(D_FILE, "RELEASE coda (ino %ld, ct %d, cc %d) cache (ino %ld, ct %d)\n",
+ i->i_ino, atomic_read(&i->i_count), cii->c_contcount,
X (container ? container->i_ino : 0),
X (container ? atomic_read(&container->i_count) : -99));
+
+ if (--cii->c_contcount == 0 && container) {
+ i->i_mapping = &i->i_data;
+ iput(container);
+ }
X
X error = venus_release(i->i_sb, coda_i2f(i), cflags, cred);
X
diff -u --recursive --new-file v2.4.0-test8/linux/fs/coda/file.c linux/fs/coda/file.c
--- v2.4.0-test8/linux/fs/coda/file.c Thu Jun 29 16:20:07 2000
+++ linux/fs/coda/file.c Tue Sep 19 15:08:59 2000
@@ -23,18 +23,21 @@
X #include <linux/coda_linux.h>
X #include <linux/coda_fs_i.h>
X #include <linux/coda_psdev.h>
-#include <linux/coda_cache.h>
X #include <linux/coda_proc.h>
X
X static ssize_t
X coda_file_write(struct file *file,const char *buf,size_t count,loff_t *ppos)
X {
X struct inode *inode = file->f_dentry->d_inode;
+ struct inode *container = (struct inode*)inode->i_mapping->host;
X ssize_t n;
X
+ down(&container->i_sem);
+
X n = generic_file_write(file, buf, count, ppos);
+ inode->i_size = container->i_size;
X
- inode->i_size = ((struct inode*)inode->i_mapping->host)->i_size;
+ up(&container->i_sem);
X
X return n;
X }
@@ -63,7 +66,7 @@
X result = file_fsync(NULL, &cont_dentry, datasync);
X up(&cont_dentry.d_inode->i_sem);
X
- if ( result == 0 ) {
+ if ( result == 0 && datasync == 0 ) {
X lock_kernel();
X result = venus_fsync(inode->i_sb, coda_i2f(inode));
X unlock_kernel();
diff -u --recursive --new-file v2.4.0-test8/linux/fs/coda/inode.c linux/fs/coda/inode.c
--- v2.4.0-test8/linux/fs/coda/inode.c Wed Jun 21 10:10:02 2000
+++ linux/fs/coda/inode.c Thu Sep 21 09:59:46 2000
@@ -18,6 +18,7 @@
X #include <linux/locks.h>
X #include <linux/unistd.h>
X #include <linux/smp_lock.h>
+#include <linux/file.h>
X
X #include <asm/system.h>
X #include <asm/uaccess.h>
@@ -48,6 +49,47 @@
X statfs: coda_statfs,
X };
X
+static int get_device_index(struct coda_mount_data *data)
+{
+ struct file *file;
+ struct inode *inode;
+ int idx;
+
+ if(data == NULL) {
+ printk("coda_read_super: Bad mount data\n");


+ return -1;
+ }
+

+ if(data->version != CODA_MOUNT_VERSION) {
+ printk("coda_read_super: Bad mount version\n");


+ return -1;
+ }
+

+ file = fget(data->fd);
+ inode = NULL;
+ if(file)
+ inode = file->f_dentry->d_inode;
+
+ if(!inode || !S_ISCHR(inode->i_mode) ||
+ MAJOR(inode->i_rdev) != CODA_PSDEV_MAJOR) {
+ if(file)
+ fput(file);
+
+ printk("coda_read_super: Bad file\n");


+ return -1;
+ }
+

+ idx = MINOR(inode->i_rdev);
+ fput(file);
+
+ if(idx < 0 || idx >= MAX_CODADEVS) {
+ printk("coda_read_super: Bad minor number\n");


+ return -1;
+ }
+

+ return idx;
+}
+
X static struct super_block * coda_read_super(struct super_block *sb,
X void *data, int silent)
X {
@@ -57,23 +99,41 @@
X ViceFid fid;
X kdev_t dev = sb->s_dev;
X int error;
-
+ int idx;
X ENTRY;
X
- vc = &coda_upc_comm;
- sbi = &coda_super_info;
+ idx = get_device_index((struct coda_mount_data *) data);
+
+ /* Ignore errors in data, for backward compatibility */
+ if(idx == -1)
+ idx = 0;
+
+ printk(KERN_INFO "coda_read_super: device index: %i\n", idx);
+
+ vc = &coda_comms[idx];
+ if (!vc->vc_inuse) {
+ printk("coda_read_super: No pseudo device\n");
+ EXIT;

+ return NULL;
+ }
+

+ if ( vc->vc_sb ) {
+ printk("coda_read_super: Device already mounted\n");
+ EXIT;

+ return NULL;
+ }
X

- if ( sbi->sbi_sb ) {
- printk("Already mounted\n");
+ sbi = kmalloc(sizeof(struct coda_sb_info), GFP_KERNEL);
+ if(!sbi) {
X EXIT;

X return NULL;
X }
X

+ vc->vc_sb = sb;
+
X sbi->sbi_sb = sb;
- sbi->sbi_psdev = psdev;
X sbi->sbi_vcomm = vc;
- INIT_LIST_HEAD(&(sbi->sbi_cchead));
- INIT_LIST_HEAD(&(sbi->sbi_volroothead));
+ INIT_LIST_HEAD(&sbi->sbi_cihead);
X
X sb->u.generic_sbp = sbi;
X sb->s_blocksize = 1024; /* XXXXX what do we put here?? */
@@ -100,7 +160,6 @@
X
X printk("coda_read_super: rootinode is %ld dev %d\n",
X root->i_ino, root->i_dev);
- sbi->sbi_root = root;
X sb->s_root = d_alloc_root(root);
X EXIT;
X return sb;
@@ -108,9 +167,9 @@
X error:
X EXIT;
X if (sbi) {
- sbi->sbi_vcomm = NULL;
- sbi->sbi_root = NULL;
- sbi->sbi_sb = NULL;
+ kfree(sbi);
+ if(vc)
+ vc->vc_sb = NULL;
X }
X if (root) {
X iput(root);
@@ -120,15 +179,16 @@
X
X static void coda_put_super(struct super_block *sb)
X {
- struct coda_sb_info *sb_info;
+ struct coda_sb_info *sbi;
X
X ENTRY;
X
- coda_cache_clear_all(sb);
- sb_info = coda_sbp(sb);
- coda_super_info.sbi_sb = NULL;
+ sbi = coda_sbp(sb);
+ sbi->sbi_vcomm->vc_sb = NULL;
+ list_del_init(&sbi->sbi_cihead);
+
X printk("Coda: Bye bye.\n");
- memset(sb_info, 0, sizeof(* sb_info));
+ kfree(sbi);
X
X EXIT;
X }
@@ -136,11 +196,21 @@
X /* all filling in of inodes postponed until lookup */
X static void coda_read_inode(struct inode *inode)
X {
+ struct coda_sb_info *sbi = coda_sbp(inode->i_sb);
X struct coda_inode_info *cii;
X ENTRY;
+
+ if (!sbi) BUG();
+
X cii = ITOC(inode);
- cii->c_magic = 0;
- return;
+ if (cii->c_magic == CODA_CNODE_MAGIC) {
+ printk("coda_read_inode: initialized inode");
+ return;
+ }
+
+ memset(cii, 0, sizeof(struct coda_inode_info));
+ list_add(&cii->c_cilist, &sbi->sbi_cihead);
+ cii->c_magic = CODA_CNODE_MAGIC;
X }
X
X static void coda_clear_inode(struct inode *inode)
@@ -152,15 +222,13 @@
X CDEBUG(D_SUPER, " inode->ino: %ld, count: %d\n",
X inode->i_ino, atomic_read(&inode->i_count));
X
- if ( inode->i_ino == CTL_INO || cii->c_magic != CODA_CNODE_MAGIC )
- goto out;
+ if ( cii->c_magic != CODA_CNODE_MAGIC )
+ return;
X
- lock_kernel();
+ list_del_init(&cii->c_cilist);
X
- if ( !list_empty(&cii->c_volrootlist) ) {
- list_del(&cii->c_volrootlist);
- INIT_LIST_HEAD(&cii->c_volrootlist);
- }
+ if ( inode->i_ino == CTL_INO )
+ goto out;
X
X if ( inode->i_mapping != &inode->i_data ) {
X open_inode = (struct inode *)inode->i_mapping->host;
@@ -170,12 +238,11 @@
X iput(open_inode);
X }
X
- coda_cache_clear_inode(inode);
- unlock_kernel();
-
X CDEBUG(D_DOWNCALL, "clearing inode: %ld, %x\n", inode->i_ino, cii->c_flags);
+ coda_cache_clear_inode(inode);
X out:
X inode->u.coda_i.c_magic = 0;
+ memset(&inode->u.coda_i.c_fid, 0, sizeof(struct ViceFid));
X EXIT;
X }
X
@@ -237,9 +304,4 @@
X /* init_coda: used by filesystems.c to register coda */
X
X DECLARE_FSTYPE( coda_fs_type, "coda", coda_read_super, 0);
-
-int init_coda_fs(void)
-{
- return register_filesystem(&coda_fs_type);
-}
X
diff -u --recursive --new-file v2.4.0-test8/linux/fs/coda/pioctl.c linux/fs/coda/pioctl.c
--- v2.4.0-test8/linux/fs/coda/pioctl.c Wed Jul 26 09:09:39 2000
+++ linux/fs/coda/pioctl.c Tue Sep 19 15:08:59 2000
@@ -23,13 +23,12 @@
X #include <linux/coda.h>
X #include <linux/coda_linux.h>
X #include <linux/coda_fs_i.h>
-#include <linux/coda_cache.h>
X #include <linux/coda_psdev.h>
X
X /* pioctl ops */
X static int coda_ioctl_permission(struct inode *inode, int mask);
X static int coda_pioctl(struct inode * inode, struct file * filp,
- unsigned int cmd, unsigned long arg);
+ unsigned int cmd, unsigned long user_data);
X
X /* exported from this file */
X struct inode_operations coda_ioctl_inode_operations =
@@ -52,7 +51,7 @@
X }
X
X static int coda_pioctl(struct inode * inode, struct file * filp,
- unsigned int cmd, unsigned long user_data)
+ unsigned int cmd, unsigned long user_data)
X {
X struct nameidata nd;
X int error;
diff -u --recursive --new-file v2.4.0-test8/linux/fs/coda/psdev.c linux/fs/coda/psdev.c
--- v2.4.0-test8/linux/fs/coda/psdev.c Wed Jul 12 21:58:43 2000
+++ linux/fs/coda/psdev.c Tue Sep 19 15:08:59 2000
@@ -46,21 +46,19 @@
X #include <linux/coda_linux.h>
X #include <linux/coda_fs_i.h>
X #include <linux/coda_psdev.h>
-#include <linux/coda_cache.h>
X #include <linux/coda_proc.h>
X
X /*
X * Coda stuff
X */
X extern struct file_system_type coda_fs_type;
-extern int init_coda_fs(void);
X
X /* statistics */
X int coda_hard = 0; /* allows signals during upcalls */
X unsigned long coda_timeout = 30; /* .. secs, then signals will dequeue */
X
-struct coda_sb_info coda_super_info;
-struct venus_comm coda_upc_comm;
+
+struct venus_comm coda_comms[MAX_CODADEVS];
X
X /*
X * Device operations
@@ -68,7 +66,7 @@
X
X static unsigned int coda_psdev_poll(struct file *file, poll_table * wait)
X {
- struct venus_comm *vcp = &coda_upc_comm;
+ struct venus_comm *vcp = (struct venus_comm *) file->private_data;
X unsigned int mask = POLLOUT | POLLWRNORM;
X
X poll_wait(file, &vcp->vc_waitq, wait);
@@ -101,7 +99,7 @@
X static ssize_t coda_psdev_write(struct file *file, const char *buf,
X size_t nbytes, loff_t *off)
X {
- struct venus_comm *vcp = &coda_upc_comm;
+ struct venus_comm *vcp = (struct venus_comm *) file->private_data;
X struct upc_req *req = NULL;
X struct upc_req *tmp;
X struct list_head *lh;
@@ -109,8 +107,6 @@
X ssize_t retval = 0, count = 0;
X int error;
X
- if ( !coda_upc_comm.vc_inuse )
- return -EIO;
X /* Peek at the opcode, uniquefier */
X if (copy_from_user(&hdr, buf, 2 * sizeof(u_long)))
X return -EFAULT;
@@ -123,7 +119,7 @@
X union outputArgs *dcbuf;
X int size = sizeof(*dcbuf);
X
- sb = coda_super_info.sbi_sb;
+ sb = vcp->vc_sb;
X if ( !sb ) {
X CDEBUG(D_PSDEV, "coda_psdev_write: downcall, no SB!\n");
X count = nbytes;
@@ -221,7 +217,7 @@
X size_t nbytes, loff_t *off)
X {
X DECLARE_WAITQUEUE(wait, current);
- struct venus_comm *vcp = &coda_upc_comm;
+ struct venus_comm *vcp = (struct venus_comm *) file->private_data;
X struct upc_req *req;
X ssize_t retval = 0, count = 0;
X
@@ -245,7 +241,7 @@
X schedule();


X }
X
- current->state = TASK_RUNNING;

+ set_current_state(TASK_RUNNING);
X remove_wait_queue(&vcp->vc_waitq, &wait);
X
X if (retval)
@@ -285,21 +281,32 @@
X return (count ? count : retval);
X }
X
-
X static int coda_psdev_open(struct inode * inode, struct file * file)
X {
- struct venus_comm *vcp = &coda_upc_comm;
+ struct venus_comm *vcp;
+ int idx;
X ENTRY;
-
- /* first opener, initialize */
+
X lock_kernel();
+ idx = MINOR(inode->i_rdev);
+ if(idx >= MAX_CODADEVS)
+ return -ENODEV;
+
+ vcp = &coda_comms[idx];
+ if(vcp->vc_inuse)
+ return -EBUSY;
+
X if (!vcp->vc_inuse++) {
- INIT_LIST_HEAD(&vcp->vc_pending);
- INIT_LIST_HEAD(&vcp->vc_processing);
- vcp->vc_seq = 0;
+ INIT_LIST_HEAD(&vcp->vc_pending);
+ INIT_LIST_HEAD(&vcp->vc_processing);
+ init_waitqueue_head(&vcp->vc_waitq);
+ vcp->vc_sb = 0;
+ vcp->vc_seq = 0;
X }
+
+ file->private_data = vcp;
X
- CDEBUG(D_PSDEV, "inuse: %d\n", vcp->vc_inuse);
+ CDEBUG(D_PSDEV, "device %i - inuse: %d\n", idx, vcp->vc_inuse);
X
X EXIT;
X unlock_kernel();
@@ -309,7 +316,7 @@
X
X static int coda_psdev_release(struct inode * inode, struct file * file)
X {
- struct venus_comm *vcp = &coda_upc_comm;
+ struct venus_comm *vcp = (struct venus_comm *) file->private_data;
X struct upc_req *req;
X struct list_head *lh, *next;
X ENTRY;
@@ -369,29 +376,9 @@
X release: coda_psdev_release,
X };
X
-
-
-int __init init_coda(void)
-{
- int status;
- printk(KERN_INFO "Coda Kernel/Venus communications, v4.6.0, br...@cs.cmu.edu\n");
-
- status = init_coda_psdev();
- if ( status ) {
- printk("Problem (%d) in init_coda_psdev\n", status);
- return status;
- }
-
- status = init_coda_fs();
- if (status) {
- printk("coda: failed in init_coda_fs!\n");
- }
- return status;
-}
-
X static devfs_handle_t devfs_handle = NULL;
X
-int init_coda_psdev(void)
+static int init_coda_psdev(void)
X {
X if(devfs_register_chrdev(CODA_PSDEV_MAJOR,"coda_psdev",
X &coda_psdev_fops)) {
@@ -404,9 +391,6 @@
X CODA_PSDEV_MAJOR, 0,
X S_IFCHR | S_IRUSR | S_IWUSR,
X &coda_psdev_fops, NULL);
- memset(&coda_upc_comm, 0, sizeof(coda_upc_comm));
- memset(&coda_super_info, 0, sizeof(coda_super_info));
- init_waitqueue_head(&coda_upc_comm.vc_waitq);
X
X coda_sysctl_init();
X
@@ -414,36 +398,35 @@
X }
X
X
-#ifdef MODULE
-
X MODULE_AUTHOR("Peter J. Braam <br...@cs.cmu.edu>");
X
-int init_module(void)
+static int __init init_coda(void)
X {
X int status;
- printk(KERN_INFO "Coda Kernel/Venus communications (module), v5.0-pre1, br...@cs.cmu.edu.\n");
+ printk(KERN_INFO "Coda Kernel/Venus communications, v5.3.9, co...@cs.cmu.edu\n");
X
+
X status = init_coda_psdev();
X if ( status ) {
X printk("Problem (%d) in init_coda_psdev\n", status);
X return status;
X }
-
- status = init_coda_fs();
+
+ status = register_filesystem(&coda_fs_type);
X if (status) {
X printk("coda: failed in init_coda_fs!\n");
X }
X return status;
X }
X
-
-void cleanup_module(void)
+static void __exit exit_coda(void)
X {
X int err;
X
X ENTRY;
X
- if ( (err = unregister_filesystem(&coda_fs_type)) != 0 ) {
+ err = unregister_filesystem(&coda_fs_type);
+ if ( err != 0 ) {
X printk("coda: failed to unregister filesystem\n");
X }
X devfs_unregister (devfs_handle);
@@ -451,5 +434,5 @@
X coda_sysctl_clean();
X }
X
-#endif
-
+module_init(init_coda);
+module_exit(exit_coda);
diff -u --recursive --new-file v2.4.0-test8/linux/fs/coda/symlink.c linux/fs/coda/symlink.c
--- v2.4.0-test8/linux/fs/coda/symlink.c Wed Jul 5 11:31:01 2000
+++ linux/fs/coda/symlink.c Tue Sep 19 15:08:59 2000
@@ -20,7 +20,6 @@
X #include <linux/coda_linux.h>
X #include <linux/coda_psdev.h>
X #include <linux/coda_fs_i.h>
-#include <linux/coda_cache.h>
X #include <linux/coda_proc.h>
X
X static int coda_symlink_filler(struct file *file, struct page *page)
diff -u --recursive --new-file v2.4.0-test8/linux/fs/coda/sysctl.c linux/fs/coda/sysctl.c
--- v2.4.0-test8/linux/fs/coda/sysctl.c Wed Jun 21 10:10:02 2000
+++ linux/fs/coda/sysctl.c Tue Sep 19 15:08:59 2000
@@ -76,9 +76,9 @@
X /* keep this in sync with coda.h! */
X char *coda_upcall_names[] = {
X "totals ", /* 0 */
- "noop ", /* 1 */
+ "- ", /* 1 */
X "root ", /* 2 */
- "sync ", /* 3 */
+ "open_by_fd ", /* 3 */
X "open ", /* 4 */
X "close ", /* 5 */
X "ioctl ", /* 6 */
@@ -96,7 +96,7 @@
X "symlink ", /* 18 */
X "readlink ", /* 19 */
X "fsync ", /* 20 */
- "inactive ", /* 21 */
+ "- ", /* 21 */
X "vget ", /* 22 */
X "signal ", /* 23 */
X "replace ", /* 24 */
@@ -104,13 +104,12 @@
X "purgeuser ", /* 26 */
X "zapfile ", /* 27 */
X "zapdir ", /* 28 */
- "noop2 ", /* 29 */
+ "- ", /* 29 */
X "purgefid ", /* 30 */
X "open_by_path", /* 31 */
X "resolve ", /* 32 */
X "reintegrate ", /* 33 */
- "statfs ", /* 34 */
- "make_cinode " /* 35 */
+ "statfs " /* 34 */
X };
X
X
diff -u --recursive --new-file v2.4.0-test8/linux/fs/coda/upcall.c linux/fs/coda/upcall.c
--- v2.4.0-test8/linux/fs/coda/upcall.c Sun Sep 3 11:46:40 2000
+++ linux/fs/coda/upcall.c Tue Sep 19 15:08:59 2000
@@ -543,7 +543,8 @@
X goto exit;
X }
X
- error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);
+ error = coda_upcall(coda_sbp(sb), SIZE(ioctl) + data->vi.in_size,
+ &outsize, inp);
X
X if (error) {
X printk("coda_pioctl: Venus returns: %d for %s\n",
@@ -607,7 +608,8 @@


X *
X */
X

-static inline unsigned long coda_waitfor_upcall(struct upc_req *vmp)
+static inline unsigned long coda_waitfor_upcall(struct upc_req *vmp,
+ struct venus_comm *vcommp)
X {
X DECLARE_WAITQUEUE(wait, current);
X struct timeval begin = { 0, 0 }, end = { 0, 0 };
@@ -625,7 +627,7 @@
X set_current_state(TASK_UNINTERRUPTIBLE);
X
X /* venus died */
- if ( !coda_upc_comm.vc_inuse )
+ if ( !vcommp->vc_inuse )
X break;
X
X /* got a reply */
@@ -645,7 +647,7 @@
X schedule();
X }
X remove_wait_queue(&vmp->uc_sleep, &wait);


- current->state = TASK_RUNNING;
+ set_current_state(TASK_RUNNING);
X

X if (coda_upcall_timestamping && begin.tv_sec != 0) {
X do_gettimeofday(&end);
@@ -685,9 +687,9 @@
X struct upc_req *req;
X int error = 0;
X
-ENTRY;
+ ENTRY;
X
- vcommp = &coda_upc_comm;
+ vcommp = sbi->sbi_vcomm;
X if ( !vcommp->vc_inuse ) {
X printk("No pseudo device in upcall comms at %p\n", vcommp);
X return -ENXIO;
@@ -724,7 +726,7 @@
X * ENODEV. */
X
X /* Go to sleep. Wake up on signals only after the timeout. */
- runtime = coda_waitfor_upcall(req);
+ runtime = coda_waitfor_upcall(req, vcommp);
X coda_upcall_stats(((union inputArgs *)buffer)->ih.opcode, runtime);
X
X CDEBUG(D_TIMING, "opc: %d time: %ld uniq: %d size: %d\n",
@@ -738,11 +740,6 @@
X if (req->uc_flags & REQ_WRITE) {
X out = (union outputArgs *)req->uc_data;
X /* here we map positive Venus errors to kernel errors */
- if ( out->oh.result < 0 ) {
- printk("Tell Peter: Venus returns negative error %ld, for oc %ld!\n",
- out->oh.result, out->oh.opcode);
- out->oh.result = EINTR;
- }
X error = -out->oh.result;
X CDEBUG(D_UPCALL,
X "upcall: (u,o,r) (%ld, %ld, %ld) out at %p\n",
@@ -855,7 +852,7 @@
X case CODA_FLUSH : {
X clstats(CODA_FLUSH);
X CDEBUG(D_DOWNCALL, "CODA_FLUSH\n");
- coda_cache_clear_all(sb);
+ coda_cache_clear_all(sb, NULL);
X shrink_dcache_sb(sb);
X coda_flag_inode(sb->s_root->d_inode, C_FLUSH);
X return(0);
@@ -869,7 +866,7 @@
X return 0;
X }
X clstats(CODA_PURGEUSER);
- coda_cache_clear_cred(sb, cred);
+ coda_cache_clear_all(sb, cred);
X return(0);
X }
X
diff -u --recursive --new-file v2.4.0-test8/linux/fs/cramfs/uncompress.c linux/fs/cramfs/uncompress.c
--- v2.4.0-test8/linux/fs/cramfs/uncompress.c Wed Apr 12 09:47:29 2000
+++ linux/fs/cramfs/uncompress.c Sun Oct 1 20:35:16 2000
@@ -20,7 +20,7 @@
X #include "inflate/zlib.h"
X
X static z_stream stream;
-static int initialized = 0;
+static int initialized;
X
X /* Returns length of decompressed data. */
X int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen)
diff -u --recursive --new-file v2.4.0-test8/linux/fs/dcache.c linux/fs/dcache.c
--- v2.4.0-test8/linux/fs/dcache.c Fri Aug 11 19:14:46 2000
+++ linux/fs/dcache.c Sun Oct 1 19:55:17 2000
@@ -551,20 +551,29 @@
X * ...
X * 6 - base-level: try to shrink a bit.
X */
-int shrink_dcache_memory(int priority, unsigned int gfp_mask)
+void shrink_dcache_memory(int priority, unsigned int gfp_mask)
X {
X int count = 0;
+
+ /*
+ * Nasty deadlock avoidance.
+ *
+ * ext2_new_block->getblk->GFP->shrink_dcache_memory->prune_dcache->
+ * prune_one_dentry->dput->dentry_iput->iput->inode->i_sb->s_op->
+ * put_inode->ext2_discard_prealloc->ext2_free_blocks->lock_super->
+ * DEADLOCK.
+ *
+ * We should make sure we don't hold the superblock lock over
+ * block allocations, but for now:
+ */
+ if (!(gfp_mask & __GFP_IO))
+ return;
+
X if (priority)
X count = dentry_stat.nr_unused / priority;
+
X prune_dcache(count);
- /* FIXME: kmem_cache_shrink here should tell us
- the number of pages freed, and it should
- work in a __GFP_DMA/__GFP_HIGHMEM behaviour
- to free only the interesting pages in
- function of the needs of the current allocation. */
X kmem_cache_shrink(dentry_cache);
-
- return 0;
X }
X
X #define NAME_ALLOC_LEN(len) ((len+16) & ~15)
@@ -1248,7 +1257,7 @@
X panic("Cannot create buffer head SLAB cache");
X
X names_cachep = kmem_cache_create("names_cache",
- PAGE_SIZE, 0,
+ PATH_MAX + 1, 0,
X SLAB_HWCACHE_ALIGN, NULL, NULL);
X if (!names_cachep)
X panic("Cannot create names SLAB cache");
diff -u --recursive --new-file v2.4.0-test8/linux/fs/devices.c linux/fs/devices.c
--- v2.4.0-test8/linux/fs/devices.c Fri Jul 28 12:39:00 2000
+++ linux/fs/devices.c Sun Oct 1 20:35:16 2000
@@ -36,9 +36,7 @@
X };
X
X static rwlock_t chrdevs_lock = RW_LOCK_UNLOCKED;
-static struct device_struct chrdevs[MAX_CHRDEV] = {


- { NULL, NULL },
-};

+static struct device_struct chrdevs[MAX_CHRDEV];
X
X extern int get_blkdev_list(char *);
X
diff -u --recursive --new-file v2.4.0-test8/linux/fs/dnotify.c linux/fs/dnotify.c
--- v2.4.0-test8/linux/fs/dnotify.c Wed Dec 31 16:00:00 1969
+++ linux/fs/dnotify.c Fri Sep 22 14:21:18 2000
@@ -0,0 +1,140 @@
+/*
+ * Directory notifications for Linux.
+ *
+ * Copyright (C) 2000 Stephen Rothwell
+ *


+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the

+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *


+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.

+ */
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/dnotify.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+
+extern void send_sigio(struct fown_struct *fown, int fd, int band);
+
+int dir_notify_enable = 1;
+
+static rwlock_t dn_lock = RW_LOCK_UNLOCKED;
+static kmem_cache_t *dn_cache;
+
+static void redo_inode_mask(struct inode *inode)
+{
+ unsigned long new_mask;
+ struct dnotify_struct *dn;
+
+ new_mask = 0;
+ for (dn = inode->i_dnotify; dn != NULL; dn = dn->dn_next)
+ new_mask |= dn->dn_mask & ~DN_MULTISHOT;
+ inode->i_dnotify_mask = new_mask;
+}
+
+int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg)
+{
+ struct dnotify_struct *dn = NULL;
+ struct dnotify_struct *odn;
+ struct dnotify_struct **prev;
+ struct inode *inode;
+ int turning_off = (arg & ~DN_MULTISHOT) == 0;
+
+ if (!turning_off && !dir_notify_enable)
+ return -EINVAL;
+ inode = filp->f_dentry->d_inode;
+ if (!S_ISDIR(inode->i_mode))
+ return -ENOTDIR;
+ if (!turning_off) {
+ dn = kmem_cache_alloc(dn_cache, SLAB_KERNEL);
+ if (dn == NULL)
+ return -ENOMEM;
+ }
+ write_lock(&dn_lock);
+ prev = &inode->i_dnotify;
+ for (odn = *prev; odn != NULL; prev = &odn->dn_next, odn = *prev)
+ if (odn->dn_filp == filp)
+ break;
+ if (odn != NULL) {
+ if (turning_off) {
+ *prev = odn->dn_next;
+ redo_inode_mask(inode);
+ dn = odn;
+ goto out_free;
+ }
+ odn->dn_fd = fd;
+ odn->dn_mask |= arg;
+ inode->i_dnotify_mask |= arg & ~DN_MULTISHOT;
+ goto out_free;
+ }
+ if (turning_off)
+ goto out;
+ filp->f_owner.pid = current->pid;
+ filp->f_owner.uid = current->uid;
+ filp->f_owner.euid = current->euid;
+ dn->dn_magic = DNOTIFY_MAGIC;
+ dn->dn_mask = arg;
+ dn->dn_fd = fd;
+ dn->dn_filp = filp;
+ inode->i_dnotify_mask |= arg & ~DN_MULTISHOT;
+ dn->dn_next = inode->i_dnotify;
+ inode->i_dnotify = dn;
+out:
+ write_unlock(&dn_lock);
+ return 0;
+out_free:
+ kmem_cache_free(dn_cache, dn);
+ goto out;
+}
+
+void __inode_dir_notify(struct inode *inode, unsigned long event)
+{
+ struct dnotify_struct * dn;
+ struct dnotify_struct **prev;
+ struct fown_struct * fown;
+ int changed = 0;
+
+ write_lock(&dn_lock);
+ prev = &inode->i_dnotify;
+ while ((dn = *prev) != NULL) {
+ if ((dn->dn_mask & event) == 0) {
+ prev = &dn->dn_next;
+ continue;
+ }
+ if (dn->dn_magic != DNOTIFY_MAGIC) {
+ printk(KERN_ERR "__inode_dir_notify: bad magic "
+ "number in dnotify_struct!\n");
+ return;
+ }
+ fown = &dn->dn_filp->f_owner;
+ if (fown->pid)
+ send_sigio(fown, dn->dn_fd, POLL_MSG);
+ if (dn->dn_mask & DN_MULTISHOT)
+ prev = &dn->dn_next;
+ else {
+ *prev = dn->dn_next;
+ changed = 1;
+ kmem_cache_free(dn_cache, dn);
+ }
+ }
+ if (changed)
+ redo_inode_mask(inode);
+ write_unlock(&dn_lock);
+}
+
+static int __init dnotify_init(void)
+{
+ dn_cache = kmem_cache_create("dnotify cache",
+ sizeof(struct dnotify_struct), 0, 0, NULL, NULL);
+ if (!dn_cache)
+ panic("cannot create dnotify slab cache");


+ return 0;
+}
+

+module_init(dnotify_init)
diff -u --recursive --new-file v2.4.0-test8/linux/fs/dquot.c linux/fs/dquot.c
--- v2.4.0-test8/linux/fs/dquot.c Tue Sep 5 13:59:18 2000
+++ linux/fs/dquot.c Wed Sep 27 14:12:08 2000
@@ -1285,12 +1285,15 @@
X blocks = isize_to_blocks(inode->i_size, BLOCK_SIZE_BITS);
X else
X blocks = (inode->i_blocks >> 1);
- for (cnt = 0; cnt < MAXQUOTAS; cnt++)
+ for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+ if (!transfer_to[cnt])
+ continue;
X if (check_idq(transfer_to[cnt], 1) == NO_QUOTA ||
X check_bdq(transfer_to[cnt], blocks, 0) == NO_QUOTA) {
X cnt = MAXQUOTAS;
X goto put_all;
X }
+ }
X
X if ((error = notify_change(dentry, iattr)))
X goto put_all;
diff -u --recursive --new-file v2.4.0-test8/linux/fs/ext2/balloc.c linux/fs/ext2/balloc.c
--- v2.4.0-test8/linux/fs/ext2/balloc.c Tue Sep 5 14:07:29 2000
+++ linux/fs/ext2/balloc.c Wed Sep 27 13:41:33 2000
@@ -13,6 +13,7 @@
X
X #include <linux/config.h>
X #include <linux/fs.h>
+#include <linux/ext2_fs.h>
X #include <linux/locks.h>
X #include <linux/quotaops.h>
X
diff -u --recursive --new-file v2.4.0-test8/linux/fs/ext2/bitmap.c linux/fs/ext2/bitmap.c
--- v2.4.0-test8/linux/fs/ext2/bitmap.c Thu Dec 2 15:24:49 1999
+++ linux/fs/ext2/bitmap.c Wed Sep 27 13:41:33 2000
@@ -8,7 +8,7 @@
X */
X
X #include <linux/fs.h>
-
+#include <linux/ext2_fs.h>
X
X
X static int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
diff -u --recursive --new-file v2.4.0-test8/linux/fs/ext2/dir.c linux/fs/ext2/dir.c
--- v2.4.0-test8/linux/fs/ext2/dir.c Fri Aug 11 14:29:01 2000
+++ linux/fs/ext2/dir.c Wed Sep 27 13:41:33 2000
@@ -19,6 +19,7 @@
X */
X
X #include <linux/fs.h>
+#include <linux/ext2_fs.h>
X
X static unsigned char ext2_filetype_table[] = {
X DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
diff -u --recursive --new-file v2.4.0-test8/linux/fs/ext2/file.c linux/fs/ext2/file.c
--- v2.4.0-test8/linux/fs/ext2/file.c Thu Jul 27 19:27:34 2000
+++ linux/fs/ext2/file.c Wed Sep 27 13:41:33 2000
@@ -19,6 +19,7 @@
X */
X
X #include <linux/fs.h>
+#include <linux/ext2_fs.h>
X #include <linux/sched.h>
X
X static loff_t ext2_file_lseek(struct file *, loff_t, int);
diff -u --recursive --new-file v2.4.0-test8/linux/fs/ext2/fsync.c linux/fs/ext2/fsync.c
--- v2.4.0-test8/linux/fs/ext2/fsync.c Thu Jun 29 15:53:57 2000
+++ linux/fs/ext2/fsync.c Wed Sep 27 13:41:33 2000
@@ -23,6 +23,7 @@
X */
X
X #include <linux/fs.h>
+#include <linux/ext2_fs.h>
X #include <linux/locks.h>
X #include <linux/smp_lock.h>
X
diff -u --recursive --new-file v2.4.0-test8/linux/fs/ext2/ialloc.c linux/fs/ext2/ialloc.c
--- v2.4.0-test8/linux/fs/ext2/ialloc.c Tue Sep 5 14:07:29 2000
+++ linux/fs/ext2/ialloc.c Wed Sep 27 13:41:33 2000
@@ -14,6 +14,7 @@
X
X #include <linux/config.h>
X #include <linux/fs.h>
+#include <linux/ext2_fs.h>
X #include <linux/locks.h>
X #include <linux/quotaops.h>
X
diff -u --recursive --new-file v2.4.0-test8/linux/fs/ext2/inode.c linux/fs/ext2/inode.c
--- v2.4.0-test8/linux/fs/ext2/inode.c Tue Sep 5 19:01:29 2000
+++ linux/fs/ext2/inode.c Wed Sep 27 13:41:33 2000
@@ -23,6 +23,7 @@
X */
X
X #include <linux/fs.h>
+#include <linux/ext2_fs.h>
X #include <linux/locks.h>
X #include <linux/smp_lock.h>
X #include <linux/sched.h>
diff -u --recursive --new-file v2.4.0-test8/linux/fs/ext2/ioctl.c linux/fs/ext2/ioctl.c
--- v2.4.0-test8/linux/fs/ext2/ioctl.c Thu Aug 3 17:07:34 2000
+++ linux/fs/ext2/ioctl.c Wed Sep 27 13:41:33 2000
@@ -8,6 +8,7 @@
X */
X
X #include <linux/fs.h>
+#include <linux/ext2_fs.h>
X #include <linux/sched.h>
X #include <asm/uaccess.h>
X
diff -u --recursive --new-file v2.4.0-test8/linux/fs/ext2/namei.c linux/fs/ext2/namei.c
--- v2.4.0-test8/linux/fs/ext2/namei.c Tue Sep 5 14:07:29 2000
+++ linux/fs/ext2/namei.c Wed Sep 27 13:41:33 2000
@@ -19,6 +19,7 @@
X */
X
X #include <linux/fs.h>
+#include <linux/ext2_fs.h>
X #include <linux/locks.h>
X #include <linux/quotaops.h>
X
diff -u --recursive --new-file v2.4.0-test8/linux/fs/ext2/super.c linux/fs/ext2/super.c
--- v2.4.0-test8/linux/fs/ext2/super.c Tue Sep 5 14:07:29 2000
+++ linux/fs/ext2/super.c Wed Sep 27 13:41:33 2000
@@ -20,6 +20,7 @@
X #include <linux/module.h>
X #include <linux/string.h>
X #include <linux/fs.h>
+#include <linux/ext2_fs.h>
X #include <linux/slab.h>
X #include <linux/init.h>
X #include <linux/locks.h>
@@ -167,7 +168,7 @@
X else if (!strcmp (this_char, "errors")) {
X if (!value || !*value) {
X printk ("EXT2-fs: the errors option requires "
- "an argument");
+ "an argument\n");
X return 0;
X }
X if (!strcmp (value, "continue")) {
diff -u --recursive --new-file v2.4.0-test8/linux/fs/ext2/symlink.c linux/fs/ext2/symlink.c
--- v2.4.0-test8/linux/fs/ext2/symlink.c Fri Apr 7 13:38:00 2000
+++ linux/fs/ext2/symlink.c Wed Sep 27 13:41:33 2000
@@ -18,6 +18,7 @@
X */
X
X #include <linux/fs.h>
+#include <linux/ext2_fs.h>
X
X static int ext2_readlink(struct dentry *dentry, char *buffer, int buflen)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/fs/fcntl.c linux/fs/fcntl.c
--- v2.4.0-test8/linux/fs/fcntl.c Sat Aug 12 19:48:04 2000
+++ linux/fs/fcntl.c Fri Sep 22 14:21:18 2000
@@ -4,8 +4,10 @@
X * Copyright (C) 1991, 1992 Linus Torvalds
X */
X
+#include <linux/init.h>
X #include <linux/mm.h>
X #include <linux/file.h>
+#include <linux/dnotify.h>
X #include <linux/smp_lock.h>
X #include <linux/slab.h>
X
@@ -14,6 +16,8 @@
X #include <asm/uaccess.h>
X
X extern int sock_fcntl (struct file *, unsigned int cmd, unsigned long arg);
+extern int fcntl_setlease(unsigned int fd, struct file *filp, long arg);
+extern int fcntl_getlease(struct file *filp);
X
X /* Expand files. Return <0 on error; 0 nothing done; 1 files expanded,
X * we may have blocked.
@@ -195,6 +199,7 @@
X static int setfl(int fd, struct file * filp, unsigned long arg)
X {
X struct inode * inode = filp->f_dentry->d_inode;
+ int error;
X
X /*
X * In the case of an append-only file, O_APPEND
@@ -205,8 +210,11 @@
X
X /* Did FASYNC state change? */
X if ((arg ^ filp->f_flags) & FASYNC) {
- if (filp->f_op && filp->f_op->fasync)
- filp->f_op->fasync(fd, filp, (arg & FASYNC) != 0);
+ if (filp->f_op && filp->f_op->fasync) {
+ error = filp->f_op->fasync(fd, filp, (arg & FASYNC) != 0);
+ if (error < 0)
+ return error;
+ }
X }
X
X /* required for strict SunOS emulation */
@@ -221,11 +229,10 @@
X static long do_fcntl(unsigned int fd, unsigned int cmd,
X unsigned long arg, struct file * filp)
X {
- long err = 0;
+ long err = -EINVAL;
X
X switch (cmd) {
X case F_DUPFD:
- err = -EINVAL;
X if (arg < NR_OPEN) {
X get_file(filp);
X err = dupfd(filp, arg);
@@ -235,20 +242,21 @@
X err = get_close_on_exec(fd);
X break;
X case F_SETFD:
+ err = 0;
X set_close_on_exec(fd, arg&1);
X break;
X case F_GETFL:
X err = filp->f_flags;
X break;
X case F_SETFL:
+ lock_kernel();
X err = setfl(fd, filp, arg);
+ unlock_kernel();
X break;
X case F_GETLK:
X err = fcntl_getlk(fd, (struct flock *) arg);
X break;
X case F_SETLK:
- err = fcntl_setlk(fd, cmd, (struct flock *) arg);
- break;
X case F_SETLKW:
X err = fcntl_setlk(fd, cmd, (struct flock *) arg);
X break;
@@ -263,11 +271,14 @@
X err = filp->f_owner.pid;
X break;
X case F_SETOWN:
+ lock_kernel();
X filp->f_owner.pid = arg;
X filp->f_owner.uid = current->uid;
X filp->f_owner.euid = current->euid;
+ err = 0;
X if (S_ISSOCK (filp->f_dentry->d_inode->i_mode))
X err = sock_fcntl (filp, F_SETOWN, arg);
+ unlock_kernel();
X break;
X case F_GETSIG:
X err = filp->f_owner.signum;
@@ -275,12 +286,20 @@
X case F_SETSIG:
X /* arg == 0 restores default behaviour. */
X if (arg < 0 || arg > _NSIG) {
- err = -EINVAL;
X break;
X }
X err = 0;
X filp->f_owner.signum = arg;
X break;
+ case F_GETLEASE:
+ err = fcntl_getlease(filp);
+ break;
+ case F_SETLEASE:
+ err = fcntl_setlease(fd, filp, arg);
+ break;
+ case F_NOTIFY:
+ err = fcntl_dirnotify(fd, filp, arg);
+ break;
X default:
X /* sockets need a few special fcntls. */
X err = -EINVAL;
@@ -301,9 +320,7 @@
X if (!filp)
X goto out;
X
- lock_kernel();
X err = do_fcntl(fd, cmd, arg, filp);
- unlock_kernel();
X
X fput(filp);
X out:
@@ -356,7 +373,7 @@
X
X static void send_sigio_to_task(struct task_struct *p,
X struct fown_struct *fown,
- struct fasync_struct *fa,
+ int fd,
X int reason)
X {
X if ((fown->euid != 0) &&
@@ -384,7 +401,7 @@
X si.si_band = ~0L;
X else
X si.si_band = band_table[reason - POLL_IN];
- si.si_fd = fa->fa_fd;
+ si.si_fd = fd;
X if (!send_sig_info(fown->signum, &si, p))
X break;
X /* fall-through: fall back on the old plain SIGIO signal */
@@ -393,15 +410,14 @@
X }
X }
X
-static void send_sigio(struct fown_struct *fown, struct fasync_struct *fa,
- int band)
+void send_sigio(struct fown_struct *fown, int fd, int band)
X {
X struct task_struct * p;
X int pid = fown->pid;
X
X read_lock(&tasklist_lock);
X if ( (pid > 0) && (p = find_task_by_pid(pid)) ) {
- send_sigio_to_task(p, fown, fa, band);
+ send_sigio_to_task(p, fown, fd, band);
X goto out;
X }
X for_each_task(p) {
@@ -410,18 +426,20 @@
X match = -p->pgrp;
X if (pid != match)
X continue;
- send_sigio_to_task(p, fown, fa, band);
+ send_sigio_to_task(p, fown, fd, band);
X }
X out:
X read_unlock(&tasklist_lock);
X }
X
+static rwlock_t fasync_lock = RW_LOCK_UNLOCKED;
+static kmem_cache_t *fasync_cache;
+
X /*
X * fasync_helper() is used by some character device drivers (mainly mice)
X * to set up the fasync queue. It returns negative on error, 0 if it did
X * no changes and positive if it added/deleted the entry.
X */
-static rwlock_t fasync_lock = RW_LOCK_UNLOCKED;
X int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fapp)
X {
X struct fasync_struct *fa, **fp;
@@ -429,7 +447,7 @@
X int result = 0;
X
X if (on) {
- new = kmalloc(sizeof(struct fasync_struct), GFP_KERNEL);
+ new = kmem_cache_alloc(fasync_cache, SLAB_KERNEL);
X if (!new)
X return -ENOMEM;
X }
@@ -438,10 +456,10 @@
X if (fa->fa_file == filp) {
X if(on) {
X fa->fa_fd = fd;
- kfree(new);
+ kmem_cache_free(fasync_cache, new);
X } else {
X *fp = fa->fa_next;
- kfree(fa);
+ kmem_cache_free(fasync_cache, fa);
X result = 1;
X }
X goto out;
@@ -466,7 +484,7 @@
X while (fa) {
X struct fown_struct * fown;
X if (fa->magic != FASYNC_MAGIC) {
- printk("kill_fasync: bad magic number in "
+ printk(KERN_ERR "kill_fasync: bad magic number in "
X "fasync_struct!\n");
X return;
X }
@@ -475,7 +493,7 @@
X queued signum: SIGURG has its own default signalling
X mechanism. */
X if (fown->pid && !(sig == SIGURG && fown->signum == 0))
- send_sigio(fown, fa, band);
+ send_sigio(fown, fa->fa_fd, band);
X fa = fa->fa_next;
X }
X }
@@ -486,3 +504,14 @@
X __kill_fasync(*fp, sig, band);
X read_unlock(&fasync_lock);
X }
+
+static int __init fasync_init(void)
+{
+ fasync_cache = kmem_cache_create("fasync cache",
+ sizeof(struct fasync_struct), 0, 0, NULL, NULL);
+ if (!fasync_cache)
+ panic("cannot create fasync slab cache");


+ return 0;
+}
+

+module_init(fasync_init)
diff -u --recursive --new-file v2.4.0-test8/linux/fs/file_table.c linux/fs/file_table.c
--- v2.4.0-test8/linux/fs/file_table.c Thu Jul 27 16:47:16 2000
+++ linux/fs/file_table.c Tue Sep 19 08:31:53 2000
@@ -98,48 +98,35 @@


X return 0;
X }
X

-/*
- * Called when retiring the last use of a file pointer.
- */
-static void __fput(struct file *filp)
+void fput(struct file * file)
X {
- struct dentry * dentry = filp->f_dentry;
- struct vfsmount * mnt = filp->f_vfsmnt;
+ struct dentry * dentry = file->f_dentry;
+ struct vfsmount * mnt = file->f_vfsmnt;
X struct inode * inode = dentry->d_inode;
X
- if (filp->f_op && filp->f_op->release)
- filp->f_op->release(inode, filp);
- fops_put(filp->f_op);
- filp->f_dentry = NULL;
- filp->f_vfsmnt = NULL;
- if (filp->f_mode & FMODE_WRITE)
- put_write_access(inode);
- dput(dentry);
- if (mnt)
- mntput(mnt);
-}
-
-static void _fput(struct file *file)
-{
- locks_remove_flock(file);
- __fput(file);
-
- file_list_lock();
- list_del(&file->f_list);
- list_add(&file->f_list, &free_list);
- files_stat.nr_free_files++;
- file_list_unlock();
-}
-
-void fput(struct file * file)
-{
- if (atomic_dec_and_test(&file->f_count))
- _fput(file);
+ if (atomic_dec_and_test(&file->f_count)) {
+ locks_remove_flock(file);
+ if (file->f_op && file->f_op->release)
+ file->f_op->release(inode, file);
+ fops_put(file->f_op);
+ file->f_dentry = NULL;
+ file->f_vfsmnt = NULL;


+ if (file->f_mode & FMODE_WRITE)

+ put_write_access(inode);
+ dput(dentry);
+ if (mnt)
+ mntput(mnt);
+ file_list_lock();
+ list_del(&file->f_list);
+ list_add(&file->f_list, &free_list);
+ files_stat.nr_free_files++;
+ file_list_unlock();
+ }
X }
X
X struct file * fget(unsigned int fd)
X {
- struct file * file = NULL;
+ struct file * file;
X struct files_struct *files = current->files;
X
X read_lock(&files->file_lock);
diff -u --recursive --new-file v2.4.0-test8/linux/fs/filesystems.c linux/fs/filesystems.c
--- v2.4.0-test8/linux/fs/filesystems.c Sat Sep 2 11:33:30 2000
+++ linux/fs/filesystems.c Mon Sep 25 17:05:01 2000
@@ -21,10 +21,6 @@
X #include <linux/module.h>
X #include <linux/nfsd/interface.h>
X
-#ifdef CONFIG_CODA_FS
-extern int init_coda(void);
-#endif
-
X #ifdef CONFIG_DEVPTS_FS
X extern int init_devpts_fs(void);
X #endif
@@ -35,10 +31,6 @@
X
X #ifdef CONFIG_NFS_FS
X init_nfs_fs();
-#endif
-
-#ifdef CONFIG_CODA_FS
- init_coda();
X #endif
X
X #ifdef CONFIG_DEVPTS_FS
diff -u --recursive --new-file v2.4.0-test8/linux/fs/inode.c linux/fs/inode.c
--- v2.4.0-test8/linux/fs/inode.c Thu Aug 17 11:27:25 2000
+++ linux/fs/inode.c Sun Oct 1 20:35:16 2000
@@ -71,7 +71,7 @@
X int nr_inodes;
X int nr_unused;
X int dummy[5];
-} inodes_stat = {0, 0,};
+} inodes_stat;
X
X static kmem_cache_t * inode_cachep;
X
@@ -454,21 +454,25 @@
X dispose_list(freeable);
X }
X
-int shrink_icache_memory(int priority, int gfp_mask)
+void shrink_icache_memory(int priority, int gfp_mask)
X {
X int count = 0;
-
+
+ /*
+ * Nasty deadlock avoidance..
+ *
+ * We may hold various FS locks, and we don't
+ * want to recurse into the FS that called us
+ * in clear_inode() and friends..
+ */
+ if (!(gfp_mask & __GFP_IO))
+ return;
+
X if (priority)
X count = inodes_stat.nr_unused / priority;
+
X prune_icache(count);
- /* FIXME: kmem_cache_shrink here should tell us
- the number of pages freed, and it should
- work in a __GFP_DMA/__GFP_HIGHMEM behaviour
- to free only the interesting pages in
- function of the needs of the current allocation. */
X kmem_cache_shrink(inode_cachep);
-
- return 0;
X }
X
X /*
@@ -509,9 +513,9 @@
X */
X static void clean_inode(struct inode *inode)
X {
- static struct address_space_operations empty_aops = {};
- static struct inode_operations empty_iops = {};
- static struct file_operations empty_fops = {};
+ static struct address_space_operations empty_aops;
+ static struct inode_operations empty_iops;
+ static struct file_operations empty_fops;
X memset(&inode->u, 0, sizeof(inode->u));
X inode->i_sock = 0;
X inode->i_op = &empty_iops;
diff -u --recursive --new-file v2.4.0-test8/linux/fs/lockd/clntlock.c linux/fs/lockd/clntlock.c
--- v2.4.0-test8/linux/fs/lockd/clntlock.c Thu Jun 29 14:06:47 2000
+++ linux/fs/lockd/clntlock.c Fri Sep 22 14:21:18 2000
@@ -168,6 +168,7 @@
X * reclaim is in progress */
X lock_kernel();
X lockd_up();
+ down(&file_lock_sem);


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 098'
echo 'File patch-2.4.0-test9 is continued in part 099'
echo "099" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part099

#!/bin/sh -x
# this is part 099 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 099; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

X
X /* First, reclaim all locks that have been granted previously. */
X restart:


@@ -185,6 +186,7 @@
X }

X tmp = tmp->next;
X }
+ up(&file_lock_sem);
X
X host->h_reclaiming = 0;
X wake_up(&host->h_gracewait);
diff -u --recursive --new-file v2.4.0-test8/linux/fs/lockd/clntproc.c linux/fs/lockd/clntproc.c
--- v2.4.0-test8/linux/fs/lockd/clntproc.c Wed Jun 21 12:43:38 2000
+++ linux/fs/lockd/clntproc.c Thu Sep 21 13:38:58 2000
@@ -47,7 +47,6 @@
X struct nlm_args *argp = &req->a_args;
X struct nlm_lock *lock = &argp->lock;
X
- memset(argp, 0, sizeof(*argp));
X nlmclnt_next_cookie(&argp->cookie);
X argp->state = nsm_local_state;
X memcpy(&lock->fh, NFS_FH(fl->fl_file->f_dentry), sizeof(struct nfs_fh));
@@ -55,7 +54,7 @@
X lock->oh.data = req->a_owner;
X lock->oh.len = sprintf(req->a_owner, "%d@%s",
X current->pid, system_utsname.nodename);
- lock->fl = *fl;
+ locks_copy_lock(&lock->fl, fl);
X }
X
X /*
@@ -157,7 +156,9 @@
X call->a_flags = RPC_TASK_ASYNC;
X } else {
X spin_unlock_irqrestore(&current->sigmask_lock, flags);
- call->a_flags = 0;
+ memset(call, 0, sizeof(*call));
+ locks_init_lock(&call->a_args.lock.fl);
+ locks_init_lock(&call->a_res.lock.fl);
X }
X call->a_host = host;
X
@@ -214,8 +215,12 @@
X
X while (!signalled()) {
X call = (struct nlm_rqst *) kmalloc(sizeof(struct nlm_rqst), GFP_KERNEL);
- if (call)
+ if (call) {
+ memset(call, 0, sizeof(*call));
+ locks_init_lock(&call->a_args.lock.fl);
+ locks_init_lock(&call->a_res.lock.fl);
X return call;
+ }
X printk("nlmclnt_alloc_call: failed, waiting for memory\n");
X current->state = TASK_INTERRUPTIBLE;
X schedule_timeout(5*HZ);
@@ -389,7 +394,7 @@
X * Report the conflicting lock back to the application.
X * FIXME: Is it OK to report the pid back as well?
X */
- memcpy(fl, &req->a_res.lock.fl, sizeof(*fl));
+ locks_copy_lock(fl, &req->a_res.lock.fl);
X /* fl->fl_pid = 0; */
X } else {
X return nlm_stat_to_errno(req->a_res.status);
@@ -476,6 +481,9 @@
X int status;
X
X req = &reqst;
+ memset(req, 0, sizeof(*req));
+ locks_init_lock(&req->a_args.lock.fl);
+ locks_init_lock(&req->a_res.lock.fl);
X req->a_host = host;
X req->a_flags = 0;
X
diff -u --recursive --new-file v2.4.0-test8/linux/fs/lockd/host.c linux/fs/lockd/host.c
--- v2.4.0-test8/linux/fs/lockd/host.c Wed Jun 21 12:43:38 2000
+++ linux/fs/lockd/host.c Sun Oct 1 20:35:16 2000
@@ -29,8 +29,8 @@
X #define NLM_HOST_ADDR(sv) (&(sv)->s_nlmclnt->cl_xprt->addr)
X
X static struct nlm_host * nlm_hosts[NLM_HOST_NRHASH];
-static unsigned long next_gc = 0;
-static int nrhosts = 0;
+static unsigned long next_gc;
+static int nrhosts;
X static DECLARE_MUTEX(nlm_host_sema);
X
X
diff -u --recursive --new-file v2.4.0-test8/linux/fs/lockd/svc.c linux/fs/lockd/svc.c
--- v2.4.0-test8/linux/fs/lockd/svc.c Fri Jun 23 21:12:53 2000
+++ linux/fs/lockd/svc.c Sun Oct 1 20:35:16 2000
@@ -39,12 +39,12 @@
X #define ALLOWED_SIGS (sigmask(SIGKILL))
X
X extern struct svc_program nlmsvc_program;
-struct nlmsvc_binding * nlmsvc_ops = NULL;
+struct nlmsvc_binding * nlmsvc_ops;
X static DECLARE_MUTEX(nlmsvc_sema);
-static unsigned int nlmsvc_users = 0;
-static pid_t nlmsvc_pid = 0;
-unsigned long nlmsvc_grace_period = 0;
-unsigned long nlmsvc_timeout = 0;
+static unsigned int nlmsvc_users;
+static pid_t nlmsvc_pid;
+unsigned long nlmsvc_grace_period;
+unsigned long nlmsvc_timeout;
X
X static DECLARE_MUTEX_LOCKED(lockd_start);
X static DECLARE_WAIT_QUEUE_HEAD(lockd_exit);
@@ -53,7 +53,7 @@
X * Currently the following can be set only at insmod time.
X * Ideally, they would be accessible through the sysctl interface.
X */
-unsigned long nlm_grace_period = 0;
+unsigned long nlm_grace_period;
X unsigned long nlm_timeout = LOCKD_DFLT_TIMEO;
X
X /*
diff -u --recursive --new-file v2.4.0-test8/linux/fs/lockd/svclock.c linux/fs/lockd/svclock.c
--- v2.4.0-test8/linux/fs/lockd/svclock.c Thu Jun 29 14:06:47 2000
+++ linux/fs/lockd/svclock.c Thu Sep 21 13:38:58 2000
@@ -170,6 +170,8 @@
X if (!(block = (struct nlm_block *) kmalloc(sizeof(*block), GFP_KERNEL)))
X goto failed;
X memset(block, 0, sizeof(*block));
+ locks_init_lock(&block->b_call.a_args.lock.fl);
+ locks_init_lock(&block->b_call.a_res.lock.fl);
X
X /* Set notifier function for VFS, and init args */
X lock->fl.fl_notify = nlmsvc_notify_blocked;
@@ -347,7 +349,7 @@
X /* Append to list of blocked */
X nlmsvc_insert_block(block, NLM_NEVER);
X
- if (!list_empty(&block->b_call.a_args.lock.fl.fl_block)) {
+ if (list_empty(&block->b_call.a_args.lock.fl.fl_list)) {
X /* Now add block to block list of the conflicting lock
X if we haven't done so. */
X dprintk("lockd: blocking on this lock.\n");
diff -u --recursive --new-file v2.4.0-test8/linux/fs/lockd/svcshare.c linux/fs/lockd/svcshare.c
--- v2.4.0-test8/linux/fs/lockd/svcshare.c Tue Jun 1 23:25:47 1999
+++ linux/fs/lockd/svcshare.c Thu Sep 21 13:38:58 2000
@@ -54,7 +54,6 @@
X share->s_owner.len = oh->len;
X share->s_next = file->f_shares;
X file->f_shares = share;
- file->f_count += 1;
X
X update:
X share->s_access = argp->fsm_access;
diff -u --recursive --new-file v2.4.0-test8/linux/fs/lockd/xdr.c linux/fs/lockd/xdr.c
--- v2.4.0-test8/linux/fs/lockd/xdr.c Wed Jul 5 22:15:27 2000
+++ linux/fs/lockd/xdr.c Thu Sep 21 13:38:58 2000
@@ -129,7 +129,7 @@
X || !(p = nlm_decode_oh(p, &lock->oh)))
X return NULL;
X
- memset(fl, 0, sizeof(*fl));
+ locks_init_lock(fl);
X fl->fl_owner = current->files;
X fl->fl_pid = ntohl(*p++);
X fl->fl_flags = FL_POSIX;
@@ -314,6 +314,7 @@
X int len;
X
X memset(lock, 0, sizeof(*lock));
+ locks_init_lock(&lock->fl);
X lock->fl.fl_pid = ~(u32) 0;
X
X if (!(p = nlm_decode_cookie(p, &argp->cookie))
@@ -430,6 +431,7 @@
X s32 start, len, end;
X
X memset(&resp->lock, 0, sizeof(resp->lock));
+ locks_init_lock(fl);
X excl = ntohl(*p++);
X fl->fl_pid = ntohl(*p++);
X if (!(p = nlm_decode_oh(p, &resp->lock.oh)))
diff -u --recursive --new-file v2.4.0-test8/linux/fs/lockd/xdr4.c linux/fs/lockd/xdr4.c
--- v2.4.0-test8/linux/fs/lockd/xdr4.c Mon Apr 10 23:02:45 2000
+++ linux/fs/lockd/xdr4.c Thu Sep 21 13:38:59 2000
@@ -131,7 +131,7 @@
X || !(p = nlm4_decode_oh(p, &lock->oh)))
X return NULL;
X
- memset(fl, 0, sizeof(*fl));
+ locks_init_lock(fl);
X fl->fl_owner = current->files;
X fl->fl_pid = ntohl(*p++);
X fl->fl_flags = FL_POSIX;
@@ -322,6 +322,7 @@
X int len;
X
X memset(lock, 0, sizeof(*lock));
+ locks_init_lock(&lock->fl);
X lock->fl.fl_pid = ~(u32) 0;
X
X if (!(p = nlm4_decode_cookie(p, &argp->cookie))
@@ -438,6 +439,7 @@
X s64 start, end, len;
X
X memset(&resp->lock, 0, sizeof(resp->lock));
+ locks_init_lock(fl);
X excl = ntohl(*p++);
X fl->fl_pid = ntohl(*p++);
X if (!(p = nlm4_decode_oh(p, &resp->lock.oh)))
diff -u --recursive --new-file v2.4.0-test8/linux/fs/locks.c linux/fs/locks.c
--- v2.4.0-test8/linux/fs/locks.c Tue Aug 29 12:41:12 2000
+++ linux/fs/locks.c Sun Oct 1 19:45:29 2000
@@ -1,3 +1,4 @@
+#define MSNFS /* HACK HACK */
X /*
X * linux/fs/locks.c
X *
@@ -108,25 +109,44 @@
X * Use generic list implementation from <linux/list.h>.
X * Sped up posix_locks_deadlock by only considering blocked locks.
X * Matthew Wilcox <wi...@thepuffingroup.com>, March, 2000.
+ *
+ * Leases and LOCK_MAND
+ * Matthew Wilcox <wi...@linuxcare.com>, June, 2000.
+ * Stephen Rothwell <s...@linuxcare.com>, June, 2000.
X */
X
X #include <linux/malloc.h>
X #include <linux/file.h>
X #include <linux/smp_lock.h>
X #include <linux/init.h>
+#include <linux/capability.h>
+#include <linux/sched.h>
X
+#include <asm/semaphore.h>
X #include <asm/uaccess.h>
X
+DECLARE_MUTEX(file_lock_sem);
+
+#define acquire_fl_sem() down(&file_lock_sem)
+#define release_fl_sem() up(&file_lock_sem)
+
+int leases_enable = 1;
+int lease_break_time = 45;
+
X LIST_HEAD(file_lock_list);
X static LIST_HEAD(blocked_list);
X
X static kmem_cache_t *filelock_cache;
X
X /* Allocate an empty lock structure. */
-static struct file_lock *locks_alloc_lock(void)
+static struct file_lock *locks_alloc_lock(int account)
X {
X struct file_lock *fl;
+ if (account && current->locks >= current->rlim[RLIMIT_LOCKS].rlim_cur)
+ return NULL;
X fl = kmem_cache_alloc(filelock_cache, SLAB_KERNEL);
+ if (fl)
+ current->locks++;
X return fl;
X }
X
@@ -137,19 +157,38 @@
X BUG();
X return;
X }
-
+ current->locks--;
X if (waitqueue_active(&fl->fl_wait))
X panic("Attempting to free lock with active wait queue");
X
X if (!list_empty(&fl->fl_block))
X panic("Attempting to free lock with active block list");
X
- if (!list_empty(&fl->fl_link))
+ if (!list_empty(&fl->fl_link) || !list_empty(&fl->fl_list))
X panic("Attempting to free lock on active lock list");
X
X kmem_cache_free(filelock_cache, fl);
X }
X
+void locks_init_lock(struct file_lock *fl)
+{
+ INIT_LIST_HEAD(&fl->fl_link);
+ INIT_LIST_HEAD(&fl->fl_block);
+ INIT_LIST_HEAD(&fl->fl_list);
+ init_waitqueue_head(&fl->fl_wait);
+ fl->fl_next = NULL;
+ fl->fl_fasync = NULL;
+ fl->fl_owner = 0;
+ fl->fl_pid = 0;
+ fl->fl_file = NULL;
+ fl->fl_flags = 0;
+ fl->fl_type = 0;
+ fl->fl_start = fl->fl_end = 0;
+ fl->fl_notify = NULL;
+ fl->fl_insert = NULL;
+ fl->fl_remove = NULL;
+}
+
X /*
X * Initialises the fields of the file lock which are invariant for
X * free file_locks.
@@ -162,16 +201,13 @@
X SLAB_CTOR_CONSTRUCTOR)
X return;
X
- lock->fl_next = NULL;
- INIT_LIST_HEAD(&lock->fl_link);
- INIT_LIST_HEAD(&lock->fl_block);
- init_waitqueue_head(&lock->fl_wait);
+ locks_init_lock(lock);
X }
X
X /*
X * Initialize a new lock from an existing file_lock structure.
X */
-static void locks_copy_lock(struct file_lock *new, struct file_lock *fl)
+void locks_copy_lock(struct file_lock *new, struct file_lock *fl)
X {
X new->fl_owner = fl->fl_owner;
X new->fl_pid = fl->fl_pid;
@@ -189,7 +225,7 @@
X /* Fill in a file_lock structure with an appropriate FLOCK lock. */
X static struct file_lock *flock_make_lock(struct file *filp, unsigned int type)
X {
- struct file_lock *fl = locks_alloc_lock();
+ struct file_lock *fl = locks_alloc_lock(1);
X if (fl == NULL)
X return NULL;
X
@@ -207,6 +243,20 @@
X return fl;
X }
X
+static int assign_type(struct file_lock *fl, int type)
+{
+ switch (type) {
+ case F_RDLCK:
+ case F_WRLCK:
+ case F_UNLCK:
+ fl->fl_type = type;
+ break;
+ default:
+ return -EINVAL;
+ }


+ return 0;
+}
+

X /* Verify a "struct flock" and copy it to a "struct file_lock" as a POSIX
X * style lock.
X */
@@ -234,6 +284,8 @@
X fl->fl_end = start + l->l_len - 1;
X if (l->l_len > 0 && fl->fl_end < 0)
X return (0);
+ if (fl->fl_end > OFFT_OFFSET_MAX)
+ return 0;
X fl->fl_start = start; /* we record the absolute position */
X if (l->l_len == 0)
X fl->fl_end = OFFSET_MAX;
@@ -246,17 +298,7 @@
X fl->fl_insert = NULL;
X fl->fl_remove = NULL;
X
- switch (l->l_type) {
- case F_RDLCK:
- case F_WRLCK:
- case F_UNLCK:
- fl->fl_type = l->l_type;
- break;
- default:


- return (0);
- }
-

- return (1);
+ return (assign_type(fl, l->l_type) == 0);
X }
X
X #if BITS_PER_LONG == 32
@@ -310,6 +352,32 @@
X }
X #endif
X
+/* Allocate a file_lock initialised to this type of lease */
+static int lease_alloc(struct file *filp, int type, struct file_lock **flp)
+{
+ struct file_lock *fl = locks_alloc_lock(1);
+ if (fl == NULL)
+ return -ENOMEM;
+
+ fl->fl_owner = current->files;
+ fl->fl_pid = current->pid;
+
+ fl->fl_file = filp;
+ fl->fl_flags = FL_LEASE;
+ if (assign_type(fl, type) != 0) {
+ locks_free_lock(fl);
+ return -EINVAL;
+ }
+ fl->fl_start = 0;
+ fl->fl_end = OFFSET_MAX;
+ fl->fl_notify = NULL;
+ fl->fl_insert = NULL;
+ fl->fl_remove = NULL;
+
+ *flp = fl;


+ return 0;
+}
+

X /* Check if two locks overlap each other.
X */
X static inline int locks_overlap(struct file_lock *fl1, struct file_lock *fl2)
@@ -335,10 +403,11 @@
X */
X static void locks_delete_block(struct file_lock *waiter)
X {
- list_del(&waiter->fl_block);
- INIT_LIST_HEAD(&waiter->fl_block);
+ list_del(&waiter->fl_list);
+ INIT_LIST_HEAD(&waiter->fl_list);
X list_del(&waiter->fl_link);
X INIT_LIST_HEAD(&waiter->fl_link);
+ waiter->fl_next = NULL;
X }
X
X /* Insert waiter into blocker's block list.
@@ -349,15 +418,15 @@
X static void locks_insert_block(struct file_lock *blocker,
X struct file_lock *waiter)
X {
- if (!list_empty(&waiter->fl_block)) {
+ if (!list_empty(&waiter->fl_list)) {
X printk(KERN_ERR "locks_insert_block: removing duplicated lock "
X "(pid=%d %Ld-%Ld type=%d)\n", waiter->fl_pid,
X waiter->fl_start, waiter->fl_end, waiter->fl_type);
X locks_delete_block(waiter);
X }
- list_add_tail(&waiter->fl_block, &blocker->fl_block);
- list_add(&waiter->fl_link, &blocked_list);
+ list_add_tail(&waiter->fl_list, &blocker->fl_block);
X waiter->fl_next = blocker;
+ list_add(&waiter->fl_link, &blocked_list);
X }
X
X /* Wake up processes blocked waiting for blocker.
@@ -367,7 +436,7 @@
X static void locks_wake_up_blocks(struct file_lock *blocker, unsigned int wait)
X {
X while (!list_empty(&blocker->fl_block)) {
- struct file_lock *waiter = list_entry(blocker->fl_block.next, struct file_lock, fl_block);
+ struct file_lock *waiter = list_entry(blocker->fl_block.next, struct file_lock, fl_list);
X /* N.B. Is it possible for the notify function to block?? */
X if (waiter->fl_notify)
X waiter->fl_notify(waiter);
@@ -402,10 +471,10 @@
X fl->fl_insert(fl);
X }
X
-/* Delete a lock and free it.
- * First remove our lock from the active lock lists. Then call
- * locks_wake_up_blocks() to wake up processes that are blocked
- * waiting for this lock. Finally free the lock structure.
+/* Delete a lock and then free it.
+ * Remove our lock from the lock lists, wake up processes that are blocked
+ * waiting for this lock, notify the FS that the lock has been cleared and
+ * finally free the lock.
X */
X static void locks_delete_lock(struct file_lock **thisfl_p, unsigned int wait)
X {
@@ -418,6 +487,12 @@
X list_del(&fl->fl_link);
X INIT_LIST_HEAD(&fl->fl_link);
X
+ fasync_helper(0, fl->fl_file, 0, &fl->fl_fasync);
+ if (fl->fl_fasync != NULL){
+ printk("locks_delete_lock: fasync == %p\n", fl->fl_fasync);
+ fl->fl_fasync = NULL;
+ }
+
X if (fl->fl_remove)
X fl->fl_remove(fl);
X
@@ -431,17 +506,14 @@
X }
X
X /* Determine if lock sys_fl blocks lock caller_fl. Common functionality
- * checks for overlapping locks and shared/exclusive status.
+ * checks for shared/exclusive status of overlapping locks.
X */
X static int locks_conflict(struct file_lock *caller_fl, struct file_lock *sys_fl)
X {
- if (!locks_overlap(caller_fl, sys_fl))
- return (0);
-
X switch (caller_fl->fl_type) {
X case F_RDLCK:
X return (sys_fl->fl_type == F_WRLCK);
-
+
X case F_WRLCK:
X return (1);
X
@@ -465,6 +537,10 @@
X locks_same_owner(caller_fl, sys_fl))
X return (0);
X
+ /* Check whether they overlap */
+ if (!locks_overlap(caller_fl, sys_fl))
+ return 0;
+
X return (locks_conflict(caller_fl, sys_fl));
X }
X
@@ -479,21 +555,66 @@
X if (!(sys_fl->fl_flags & FL_FLOCK) ||
X (caller_fl->fl_file == sys_fl->fl_file))
X return (0);
+#ifdef MSNFS
+ if ((caller_fl->fl_type & LOCK_MAND) || (sys_fl->fl_type & LOCK_MAND))
+ return 0;
+#endif
X
X return (locks_conflict(caller_fl, sys_fl));
X }
X
+int interruptible_sleep_on_locked(wait_queue_head_t *fl_wait, struct semaphore *sem, int timeout)
+{
+ int result = 0;
+ wait_queue_t wait;
+ init_waitqueue_entry(&wait, current);
+
+ __add_wait_queue(fl_wait, &wait);
+ current->state = TASK_INTERRUPTIBLE;
+ up(sem);


+ if (timeout == 0)

+ schedule();
+ else
+ result = schedule_timeout(timeout);
+ if (signal_pending(current))
+ result = -ERESTARTSYS;
+ down(sem);
+ remove_wait_queue(fl_wait, &wait);
+ current->state = TASK_RUNNING;
+ return result;
+}
+
+static int locks_block_on(struct file_lock *blocker, struct file_lock *waiter)
+{
+ int result;
+ locks_insert_block(blocker, waiter);
+ result = interruptible_sleep_on_locked(&waiter->fl_wait, &file_lock_sem, 0);
+ locks_delete_block(waiter);


+ return result;
+}
+

+static int locks_block_on_timeout(struct file_lock *blocker, struct file_lock *waiter, int time)
+{
+ int result;
+ locks_insert_block(blocker, waiter);
+ result = interruptible_sleep_on_locked(&waiter->fl_wait, &file_lock_sem, time);
+ locks_delete_block(waiter);


+ return result;
+}
+

X struct file_lock *
X posix_test_lock(struct file *filp, struct file_lock *fl)
X {
X struct file_lock *cfl;
X
+ acquire_fl_sem();
X for (cfl = filp->f_dentry->d_inode->i_flock; cfl; cfl = cfl->fl_next) {
X if (!(cfl->fl_flags & FL_POSIX))
X continue;
X if (posix_locks_conflict(cfl, fl))
X break;
X }
+ release_fl_sem();
X
X return (cfl);
X }
@@ -528,9 +649,8 @@
X next_task:
X if (caller_owner == blocked_owner && caller_pid == blocked_pid)
X return 1;
- while (tmp != &blocked_list) {
+ list_for_each(tmp, &blocked_list) {
X struct file_lock *fl = list_entry(tmp, struct file_lock, fl_link);
- tmp = tmp->next;
X if ((fl->fl_owner == blocked_owner)
X && (fl->fl_pid == blocked_pid)) {
X fl = fl->fl_next;
@@ -550,14 +670,14 @@
X /*
X * Search the lock list for this inode for any POSIX locks.
X */
- lock_kernel();
+ acquire_fl_sem();
X for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
X if (!(fl->fl_flags & FL_POSIX))
X continue;
X if (fl->fl_owner != owner)
X break;
X }
- unlock_kernel();
+ release_fl_sem();
X return fl ? -EAGAIN : 0;
X }
X
@@ -566,7 +686,7 @@
X size_t count)
X {
X struct file_lock *fl;
- struct file_lock *new_fl = locks_alloc_lock();
+ struct file_lock *new_fl = locks_alloc_lock(0);
X int error;
X
X new_fl->fl_owner = current->files;
@@ -578,36 +698,29 @@
X new_fl->fl_end = offset + count - 1;
X
X error = 0;
- lock_kernel();
+ acquire_fl_sem();
X
X repeat:
X /* Search the lock list for this inode for locks that conflict with
X * the proposed read/write.
X */
- for (fl = inode->i_flock; ; fl = fl->fl_next) {
- error = 0;
- if (!fl)
- break;
+ for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
X if (!(fl->fl_flags & FL_POSIX))
X continue;
- /* Block for writes against a "read" lock,
- * and both reads and writes against a "write" lock.
- */
+ if (fl->fl_start > new_fl->fl_end)
+ break;
X if (posix_locks_conflict(new_fl, fl)) {
X error = -EAGAIN;
X if (filp && (filp->f_flags & O_NONBLOCK))
X break;
- error = -ERESTARTSYS;
- if (signal_pending(current))
- break;
X error = -EDEADLK;
X if (posix_locks_deadlock(new_fl, fl))
X break;
-
- locks_insert_block(fl, new_fl);
- interruptible_sleep_on(&new_fl->fl_wait);
- locks_delete_block(new_fl);
-
+
+ error = locks_block_on(fl, new_fl);
+ if (error != 0)
+ break;
+
X /*
X * If we've been sleeping someone might have
X * changed the permissions behind our back.
@@ -617,14 +730,14 @@
X goto repeat;
X }
X }
- unlock_kernel();
X locks_free_lock(new_fl);
+ release_fl_sem();
X return error;
X }
X
-/* Try to create a FLOCK lock on filp. We always insert new FLOCK locks at
- * the head of the list, but that's secret knowledge known only to the next
- * two functions.
+/* Try to create a FLOCK lock on filp. We always insert new FLOCK locks
+ * at the head of the list, but that's secret knowledge known only to
+ * flock_lock_file and posix_lock_file.
X */
X static int flock_lock_file(struct file *filp, unsigned int lock_type,
X unsigned int wait)
@@ -643,7 +756,7 @@
X error = -ENOLCK;
X new_fl = flock_make_lock(filp, lock_type);
X if (!new_fl)
- goto out;
+ return error;
X }
X
X error = 0;
@@ -659,7 +772,7 @@
X }
X before = &fl->fl_next;
X }
- /* change means that we are changing the type of an existing lock, or
+ /* change means that we are changing the type of an existing lock,
X * or else unlocking it.
X */
X if (change) {
@@ -675,10 +788,6 @@
X goto out;
X
X repeat:
- /* Check signals each time we start */
- error = -ERESTARTSYS;
- if (signal_pending(current))
- goto out;
X for (fl = inode->i_flock; (fl != NULL) && (fl->fl_flags & FL_FLOCK);
X fl = fl->fl_next) {
X if (!flock_locks_conflict(new_fl, fl))
@@ -686,9 +795,9 @@
X error = -EAGAIN;
X if (!wait)
X goto out;
- locks_insert_block(fl, new_fl);
- interruptible_sleep_on(&new_fl->fl_wait);
- locks_delete_block(new_fl);
+ error = locks_block_on(fl, new_fl);
+ if (error != 0)
+ goto out;
X goto repeat;
X }
X locks_insert_lock(&inode->i_flock, new_fl);
@@ -701,7 +810,13 @@
X return error;
X }
X
-/* Add a POSIX style lock to a file.
+/**
+ * posix_lock_file:
+ * @filp: The file to apply the lock to
+ * @caller: The lock to be applied
+ * @wait: 1 to retry automatically, 0 to return -EAGAIN
+ *
+ * Add a POSIX style lock to a file.
X * We merge adjacent locks whenever possible. POSIX locks are sorted by owner
X * task, then by starting address
X *
@@ -728,12 +843,13 @@
X * We may need two file_lock structures for this operation,
X * so we get them in advance to avoid races.
X */
- new_fl = locks_alloc_lock();
- new_fl2 = locks_alloc_lock();
+ new_fl = locks_alloc_lock(0);
+ new_fl2 = locks_alloc_lock(0);
X error = -ENOLCK; /* "no luck" */
X if (!(new_fl && new_fl2))
X goto out;
X
+ acquire_fl_sem();
X if (caller->fl_type != F_UNLCK) {
X repeat:
X for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
@@ -747,12 +863,10 @@
X error = -EDEADLK;
X if (posix_locks_deadlock(caller, fl))
X goto out;
- error = -ERESTARTSYS;
- if (signal_pending(current))
+
+ error = locks_block_on(fl, caller);
+ if (error != 0)
X goto out;
- locks_insert_block(fl, caller);
- interruptible_sleep_on(&caller->fl_wait);
- locks_delete_block(caller);
X goto repeat;
X }
X }
@@ -880,6 +994,7 @@
X locks_wake_up_blocks(left, 0);
X }
X out:
+ release_fl_sem();
X /*
X * Free any unused locks.
X */
@@ -891,6 +1006,10 @@
X }
X
X static inline int flock_translate_cmd(int cmd) {
+#ifdef MSNFS
+ if (cmd & LOCK_MAND)
+ return cmd & (LOCK_MAND | LOCK_RW);
+#endif
X switch (cmd &~ LOCK_NB) {
X case LOCK_SH:
X return F_RDLCK;
@@ -902,8 +1021,270 @@


X return -EINVAL;
X }
X

-/* flock() system call entry point. Apply a FL_FLOCK style lock to
- * an open file descriptor.
+/**
+ * __get_lease - revoke all outstanding leases on file
+ * @inode: the inode of the file to return
+ * @mode: the open mode (read or write)
+ *
+ * get_lease (inlined for speed) has checked there already
+ * is a lease on this file. Leases are broken on a call to open()
+ * or truncate(). This function can sleep unless you
+ * specified %O_NONBLOCK to your open().
+ */
+int __get_lease(struct inode *inode, unsigned int mode)
+{
+ int error = 0, future;
+ struct file_lock *new_fl, *flock;
+ struct file_lock *fl;
+ int alloc_err;
+
+ alloc_err = lease_alloc(NULL, 0, &new_fl);
+
+ acquire_fl_sem();
+ flock = inode->i_flock;
+ if (flock->fl_type & F_INPROGRESS) {
+ if ((mode & O_NONBLOCK)
+ || (flock->fl_owner == current->files)) {
+ error = -EWOULDBLOCK;
+ goto out;
+ }
+ if (alloc_err != 0) {
+ error = alloc_err;
+ goto out;
+ }
+ do {
+ error = locks_block_on(flock, new_fl);
+ if (error != 0)
+ goto out;
+ flock = inode->i_flock;
+ if (!(flock && (flock->fl_flags & FL_LEASE)))
+ goto out;
+ } while (flock->fl_type & F_INPROGRESS);
+ }
+
+ if (mode & FMODE_WRITE) {
+ /* If we want write access, we have to revoke any lease. */
+ future = F_UNLCK | F_INPROGRESS;
+ } else if (flock->fl_type & F_WRLCK) {
+ /* Downgrade the exclusive lease to a read-only lease. */
+ future = F_RDLCK | F_INPROGRESS;
+ } else {
+ /* the existing lease was read-only, so we can read too. */


+ goto out;
+ }
+

+ if (alloc_err && (flock->fl_owner != current->files)) {
+ error = alloc_err;


+ goto out;
+ }
+

+ fl = flock;
+ do {
+ fl->fl_type = future;
+ fl = fl->fl_next;
+ } while (fl != NULL && (fl->fl_flags & FL_LEASE));
+
+ kill_fasync(&flock->fl_fasync, SIGIO, POLL_MSG);
+
+ if ((mode & O_NONBLOCK) || (flock->fl_owner == current->files)) {
+ error = -EWOULDBLOCK;


+ goto out;
+ }
+

+ if (lease_break_time > 0)
+ error = lease_break_time * HZ;
+ else
+ error = 0;
+restart:
+ error = locks_block_on_timeout(flock, new_fl, error);
+ if (error == 0) {
+ /* We timed out. Unilaterally break the lease. */
+ locks_delete_lock(&inode->i_flock, 0);
+ printk(KERN_WARNING "lease timed out\n");
+ } else if (error > 0) {
+ flock = inode->i_flock;
+ if (flock && (flock->fl_flags & FL_LEASE))
+ goto restart;
+ error = 0;
+ }
+
+out:
+ release_fl_sem();
+ if (!alloc_err)
+ locks_free_lock(new_fl);
+ return error;
+}
+
+/**
+ * lease_get_mtime
+ * @inode: the inode
+ *
+ * This is to force NFS clients to flush their caches for files with
+ * exclusive leases. The justification is that if someone has an
+ * exclusive lease, then they could be modifiying it.
+ */
+time_t lease_get_mtime(struct inode *inode)
+{
+ struct file_lock *flock = inode->i_flock;
+ if (flock && (flock->fl_flags & FL_LEASE) && (flock->fl_type & F_WRLCK))
+ return CURRENT_TIME;
+ return inode->i_mtime;
+}
+
+/**
+ * fcntl_getlease - Enquire what lease is currently active
+ * @filp: the file
+ *
+ * The value returned by this function will be one of
+ *
+ * %F_RDLCK to indicate a read-only (type II) lease is held.
+ *
+ * %F_WRLCK to indicate an exclusive lease is held.
+ *
+ * XXX: sfr & i disagree over whether F_INPROGRESS
+ * should be returned to userspace.
+ */
+int fcntl_getlease(struct file *filp)
+{
+ struct file_lock *fl;
+
+ fl = filp->f_dentry->d_inode->i_flock;
+ if ((fl == NULL) || ((fl->fl_flags & FL_LEASE) == 0))
+ return F_UNLCK;
+ return fl->fl_type & ~F_INPROGRESS;
+}
+
+/* We already had a lease on this file; just change its type */
+static int lease_modify(struct file_lock **before, int arg, int fd, struct file *filp)
+{
+ struct file_lock *fl = *before;
+ int error = assign_type(fl, arg);
+ if (error < 0)
+ goto out;
+
+ locks_wake_up_blocks(fl, 0);
+
+ if (arg == F_UNLCK) {
+ filp->f_owner.pid = 0;
+ filp->f_owner.uid = 0;
+ filp->f_owner.euid = 0;
+ filp->f_owner.signum = 0;
+ locks_delete_lock(before, 0);
+ fasync_helper(fd, filp, 0, &fl->fl_fasync);
+ }
+
+out:
+ return error;
+}
+
+/**
+ * fcntl_setlease - sets a lease on an open file
+ * @fd: open file descriptor
+ * @filp: file pointer
+ * @arg: type of lease to obtain
+ *
+ * Call this fcntl to establish a lease on the file.
+ * Note that you also need to call %F_SETSIG to
+ * receive a signal when the lease is broken.
+ */
+int fcntl_setlease(unsigned int fd, struct file *filp, long arg)
+{
+ struct file_lock *fl, **before, **my_before = NULL;
+ struct dentry *dentry;
+ struct inode *inode;
+ int error, rdlease_count = 0, wrlease_count = 0;
+
+ dentry = filp->f_dentry;
+ inode = dentry->d_inode;
+
+ if ((current->fsuid != inode->i_uid) && !capable(CAP_LEASE))
+ return -EACCES;
+ if (!S_ISREG(inode->i_mode))
+ return -EINVAL;
+
+ /*
+ * FIXME: What about F_RDLCK and files open for writing?
+ */
+ if ((arg == F_WRLCK)
+ && ((atomic_read(&dentry->d_count) > 1)
+ || (atomic_read(&inode->i_count) > 1)))
+ return -EAGAIN;
+
+ before = &inode->i_flock;
+
+ acquire_fl_sem();
+
+ while ((fl = *before) != NULL) {
+ if (fl->fl_flags != FL_LEASE)
+ break;
+ if (fl->fl_file == filp)
+ my_before = before;
+ else if (fl->fl_type & F_WRLCK)
+ wrlease_count++;
+ else
+ rdlease_count++;
+ before = &fl->fl_next;
+ }
+
+ if ((arg == F_RDLCK && (wrlease_count > 0)) ||
+ (arg == F_WRLCK && ((rdlease_count + wrlease_count) > 0))) {
+ error = -EAGAIN;
+ goto out_unlock;
+ }
+
+ if (my_before != NULL) {
+ error = lease_modify(my_before, arg, fd, filp);
+ goto out_unlock;
+ }
+
+ if (arg == F_UNLCK) {
+ error = 0;
+ goto out_unlock;
+ }
+
+ if (!leases_enable) {
+ error = -EINVAL;
+ goto out_unlock;
+ }
+
+ error = lease_alloc(filp, arg, &fl);
+ if (error)
+ goto out_unlock;
+
+ error = fasync_helper(fd, filp, 1, &fl->fl_fasync);
+ if (error < 0) {
+ locks_free_lock(fl);
+ goto out_unlock;
+ }
+ fl->fl_next = *before;
+ *before = fl;
+ list_add(&fl->fl_link, &file_lock_list);


+ filp->f_owner.pid = current->pid;
+ filp->f_owner.uid = current->uid;
+ filp->f_owner.euid = current->euid;

+out_unlock:
+ release_fl_sem();
+ return error;
+}
+
+/**
+ * sys_flock: - flock() system call.
+ * @fd: the file descriptor to lock.
+ * @cmd: the type of lock to apply.
+ *
+ * Apply a %FL_FLOCK style lock to an open file descriptor.
+ * The @cmd can be one of
+ *
+ * %LOCK_SH -- a shared lock.
+ *
+ * %LOCK_EX -- an exclusive lock.
+ *
+ * %LOCK_UN -- remove an existing lock.
+ *
+ * %LOCK_MAND -- a `mandatory' flock. This exists to emulate Windows Share Modes.
+ *
+ * %LOCK_MAND can be combined with %LOCK_READ or %LOCK_WRITE to allow other
+ * processes read and write access respectively.
X */
X asmlinkage long sys_flock(unsigned int fd, unsigned int cmd)
X {
@@ -921,13 +1302,17 @@
X type = error;
X
X error = -EBADF;
- if ((type != F_UNLCK) && !(filp->f_mode & 3))
+ if ((type != F_UNLCK)
+#ifdef MSNFS
+ && !(type & LOCK_MAND)
+#endif
+ && !(filp->f_mode & 3))
X goto out_putf;
X
- lock_kernel();
+ acquire_fl_sem();
X error = flock_lock_file(filp, type,
X (cmd & (LOCK_UN | LOCK_NB)) ? 0 : 1);
- unlock_kernel();
+ release_fl_sem();
X
X out_putf:
X fput(filp);
@@ -941,7 +1326,7 @@
X int fcntl_getlk(unsigned int fd, struct flock *l)
X {
X struct file *filp;
- struct file_lock *fl, *file_lock = locks_alloc_lock();
+ struct file_lock *fl, file_lock;
X struct flock flock;
X int error;
X
@@ -958,20 +1343,20 @@
X goto out;
X
X error = -EINVAL;
- if (!flock_to_posix_lock(filp, file_lock, &flock))
+ if (!flock_to_posix_lock(filp, &file_lock, &flock))
X goto out_putf;
X
X if (filp->f_op->lock) {
- error = filp->f_op->lock(filp, F_GETLK, file_lock);
+ error = filp->f_op->lock(filp, F_GETLK, &file_lock);
X if (error < 0)
X goto out_putf;
X else if (error == LOCK_USE_CLNT)
X /* Bypass for NFS with no locking - 2.0.36 compat */
- fl = posix_test_lock(filp, file_lock);
+ fl = posix_test_lock(filp, &file_lock);
X else
- fl = (file_lock->fl_type == F_UNLCK ? NULL : file_lock);
+ fl = (file_lock.fl_type == F_UNLCK ? NULL : &file_lock);
X } else {
- fl = posix_test_lock(filp, file_lock);
+ fl = posix_test_lock(filp, &file_lock);
X }
X
X flock.l_type = F_UNLCK;
@@ -1002,7 +1387,6 @@
X out_putf:
X fput(filp);
X out:
- locks_free_lock(file_lock);
X return error;
X }
X
@@ -1012,7 +1396,7 @@
X int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l)
X {
X struct file *filp;
- struct file_lock *file_lock = locks_alloc_lock();
+ struct file_lock *file_lock = locks_alloc_lock(0);
X struct flock flock;
X struct inode *inode;
X int error;
@@ -1107,7 +1491,7 @@
X int fcntl_getlk64(unsigned int fd, struct flock64 *l)
X {
X struct file *filp;
- struct file_lock *fl, *file_lock = locks_alloc_lock();
+ struct file_lock *fl, file_lock;
X struct flock64 flock;
X int error;
X
@@ -1124,20 +1508,20 @@
X goto out;
X
X error = -EINVAL;
- if (!flock64_to_posix_lock(filp, file_lock, &flock))
+ if (!flock64_to_posix_lock(filp, &file_lock, &flock))
X goto out_putf;
X
X if (filp->f_op->lock) {
- error = filp->f_op->lock(filp, F_GETLK, file_lock);
+ error = filp->f_op->lock(filp, F_GETLK, &file_lock);
X if (error < 0)
X goto out_putf;
X else if (error == LOCK_USE_CLNT)
X /* Bypass for NFS with no locking - 2.0.36 compat */
- fl = posix_test_lock(filp, file_lock);
+ fl = posix_test_lock(filp, &file_lock);
X else
- fl = (file_lock->fl_type == F_UNLCK ? NULL : file_lock);
+ fl = (file_lock.fl_type == F_UNLCK ? NULL : &file_lock);
X } else {
- fl = posix_test_lock(filp, file_lock);
+ fl = posix_test_lock(filp, &file_lock);
X }
X
X flock.l_type = F_UNLCK;
@@ -1156,7 +1540,6 @@
X out_putf:
X fput(filp);
X out:
- locks_free_lock(file_lock);
X return error;
X }
X
@@ -1166,7 +1549,7 @@
X int fcntl_setlk64(unsigned int fd, unsigned int cmd, struct flock64 *l)
X {
X struct file *filp;
- struct file_lock *file_lock = locks_alloc_lock();
+ struct file_lock *file_lock = locks_alloc_lock(0);
X struct flock64 flock;
X struct inode *inode;
X int error;
@@ -1262,17 +1645,16 @@
X */
X return;
X }
- lock_kernel();
-repeat:
+ acquire_fl_sem();
X before = &inode->i_flock;
X while ((fl = *before) != NULL) {
X if ((fl->fl_flags & FL_POSIX) && fl->fl_owner == owner) {
X locks_delete_lock(before, 0);
- goto repeat;
+ continue;
X }
X before = &fl->fl_next;
X }
- unlock_kernel();
+ release_fl_sem();
X }
X
X /*
@@ -1281,76 +1663,104 @@
X void locks_remove_flock(struct file *filp)


X {
X struct inode * inode = filp->f_dentry->d_inode;

- struct file_lock file_lock, *fl;
+ struct file_lock *fl;
X struct file_lock **before;
+
X if (!inode->i_flock)
X return;
X
- lock_kernel();
-repeat:
+ acquire_fl_sem();
X before = &inode->i_flock;
+
X while ((fl = *before) != NULL) {
- if ((fl->fl_flags & FL_FLOCK) && fl->fl_file == filp) {
- int (*lock)(struct file *, int, struct file_lock *);
- lock = NULL;
- if (filp->f_op)
- lock = filp->f_op->lock;
- if (lock) {
- file_lock = *fl;
- file_lock.fl_type = F_UNLCK;
- }
+ if ((fl->fl_flags & (FL_FLOCK|FL_LEASE))
+ && (fl->fl_file == filp)) {
X locks_delete_lock(before, 0);
- if (lock) {
- lock(filp, F_SETLK, &file_lock);
- /* List may have changed: */
- goto repeat;
- }
X continue;
- }
+ }
X before = &fl->fl_next;
X }
- unlock_kernel();
+ release_fl_sem();
X }
X
-/* The following two are for the benefit of lockd.
+/**
+ * posix_block_lock - blocks waiting for a file lock
+ * @blocker: the lock which is blocking
+ * @waiter: the lock which conflicts and has to wait
+ *
+ * lockd needs to block waiting for locks.
X */
X void
X posix_block_lock(struct file_lock *blocker, struct file_lock *waiter)
X {
- lock_kernel();
+ acquire_fl_sem();
X locks_insert_block(blocker, waiter);
- unlock_kernel();
+ release_fl_sem();
X }
X
+/**
+ * posix_unblock_lock - stop waiting for a file lock
+ * @waiter: the lock which was waiting
+ *
+ * lockd needs to block waiting for locks.
+ */
X void
X posix_unblock_lock(struct file_lock *waiter)
X {
- locks_delete_block(waiter);
- return;
+ acquire_fl_sem();
+ if (!list_empty(&waiter->fl_list)) {
+ locks_delete_block(waiter);
+ wake_up(&waiter->fl_wait);
+ }
+ release_fl_sem();
X }
X
X static void lock_get_status(char* out, struct file_lock *fl, int id, char *pfx)
X {
- struct inode *inode;
+ struct inode *inode = NULL;
X
- inode = fl->fl_file->f_dentry->d_inode;
+ if (fl->fl_file != NULL)
+ inode = fl->fl_file->f_dentry->d_inode;
X
X out += sprintf(out, "%d:%s ", id, pfx);
X if (fl->fl_flags & FL_POSIX) {
X out += sprintf(out, "%6s %s ",
X (fl->fl_flags & FL_ACCESS) ? "ACCESS" : "POSIX ",
+ (inode == NULL) ? "*NOINODE*" :
X (IS_MANDLOCK(inode) &&
X (inode->i_mode & (S_IXGRP | S_ISGID)) == S_ISGID) ?
X "MANDATORY" : "ADVISORY ");
+ } else if (fl->fl_flags & FL_FLOCK) {
+#ifdef MSNFS
+ if (fl->fl_type & LOCK_MAND) {
+ out += sprintf(out, "FLOCK MSNFS ");
+ } else
+#endif
+ out += sprintf(out, "FLOCK ADVISORY ");
+ } else if (fl->fl_flags & FL_LEASE) {
+ out += sprintf(out, "LEASE MANDATORY ");
+ } else {
+ out += sprintf(out, "UNKNOWN UNKNOWN ");
X }
- else {
- out += sprintf(out, "FLOCK ADVISORY ");
- }
- out += sprintf(out, "%s ", (fl->fl_type == F_RDLCK) ? "READ " : "WRITE");
- out += sprintf(out, "%d %s:%ld %Ld %Ld ",
+#ifdef MSNFS
+ if (fl->fl_type & LOCK_MAND) {
+ out += sprintf(out, "%s ",
+ (fl->fl_type & LOCK_READ)
+ ? (fl->fl_type & LOCK_WRITE) ? "RW " : "READ "
+ : (fl->fl_type & LOCK_WRITE) ? "WRITE" : "NONE ");
+ } else
+#endif
+ out += sprintf(out, "%s ",
+ (fl->fl_type & F_WRLCK) ? "WRITE" : "READ ");
+ out += sprintf(out, "%d %s:%ld ",
X fl->fl_pid,
- kdevname(inode->i_dev), inode->i_ino,
- (long long)fl->fl_start, (long long)fl->fl_end);
+ inode ? kdevname(inode->i_dev) : "<none>",
+ inode ? inode->i_ino : 0);
+ out += sprintf(out, "%Ld ", fl->fl_start);
+ if (fl->fl_end == OFFSET_MAX)
+ out += sprintf(out, "EOF ");
+ else
+ out += sprintf(out, "%Ld ", fl->fl_end);
X sprintf(out, "%08lx %08lx %08lx %08lx %08lx\n",
X (long)fl, (long)fl->fl_link.prev, (long)fl->fl_link.next,
X (long)fl->fl_next, (long)fl->fl_block.next);
@@ -1378,6 +1788,14 @@
X *pos += len;
X }
X
+/**
+ * get_locks_status - reports lock usage in /proc/locks
+ * @buffer: address in userspace to write into
+ * @start: ?
+ * @offset: how far we are through the buffer
+ * @length: how much to read
+ */
+
X int get_locks_status(char *buffer, char **start, off_t offset, int length)
X {
X struct list_head *tmp;
@@ -1385,7 +1803,7 @@
X off_t pos = 0;
X int i = 0;
X
- lock_kernel();
+ acquire_fl_sem();
X list_for_each(tmp, &file_lock_list) {
X struct list_head *btmp;
X struct file_lock *fl = list_entry(tmp, struct file_lock, fl_link);
@@ -1397,7 +1815,7 @@
X
X list_for_each(btmp, &fl->fl_block) {
X struct file_lock *bfl = list_entry(btmp,
- struct file_lock, fl_block);
+ struct file_lock, fl_list);
X lock_get_status(q, bfl, i, " ->");
X move_lock_status(&q, &pos, offset);
X
@@ -1406,12 +1824,88 @@
X }
X }
X done:
- unlock_kernel();
+ release_fl_sem();
X *start = buffer;
X if(q-buffer < length)
X return (q-buffer);
X return length;
X }
+
+#ifdef MSNFS
+/**
+ * lock_may_read - checks that the region is free of locks
+ * @inode: the inode that is being read
+ * @start: the first byte to read
+ * @len: the number of bytes to read
+ *
+ * Emulates Windows locking requirements. Whole-file
+ * mandatory locks (share modes) can prohibit a read and
+ * byte-range POSIX locks can prohibit a read if they overlap.
+ *
+ * N.B. this function is only ever called
+ * from knfsd and ownership of locks is never checked.
+ */
+int lock_may_read(struct inode *inode, loff_t start, unsigned long len)
+{
+ struct file_lock *fl;
+ int result = 1;
+ acquire_fl_sem();
+ for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
+ if (fl->fl_flags == FL_POSIX) {
+ if (fl->fl_type == F_RDLCK)
+ continue;
+ if ((fl->fl_end < start) || (fl->fl_start > (start + len)))
+ continue;
+ } else if (fl->fl_flags == FL_FLOCK) {
+ if (!(fl->fl_type & LOCK_MAND))
+ continue;
+ if (fl->fl_type & LOCK_READ)
+ continue;
+ } else
+ continue;
+ result = 0;
+ break;
+ }
+ release_fl_sem();


+ return result;
+}
+

+/**
+ * lock_may_write - checks that the region is free of locks
+ * @inode: the inode that is being written
+ * @start: the first byte to write
+ * @len: the number of bytes to write
+ *
+ * Emulates Windows locking requirements. Whole-file
+ * mandatory locks (share modes) can prohibit a write and
+ * byte-range POSIX locks can prohibit a write if they overlap.
+ *
+ * N.B. this function is only ever called
+ * from knfsd and ownership of locks is never checked.
+ */
+int lock_may_write(struct inode *inode, loff_t start, unsigned long len)
+{
+ struct file_lock *fl;
+ int result = 1;
+ acquire_fl_sem();
+ for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
+ if (fl->fl_flags == FL_POSIX) {
+ if ((fl->fl_end < start) || (fl->fl_start > (start + len)))
+ continue;
+ } else if (fl->fl_flags == FL_FLOCK) {
+ if (!(fl->fl_type & LOCK_MAND))
+ continue;
+ if (fl->fl_type & LOCK_WRITE)
+ continue;
+ } else
+ continue;
+ result = 0;
+ break;
+ }
+ release_fl_sem();
+ return result;
+}
+#endif
X
X static int __init filelock_init(void)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/fs/minix/Makefile linux/fs/minix/Makefile
--- v2.4.0-test8/linux/fs/minix/Makefile Thu Feb 10 12:16:58 2000
+++ linux/fs/minix/Makefile Wed Sep 27 19:23:40 2000
@@ -8,7 +8,7 @@
X # Note 2! The CFLAGS definitions are now in the main makefile.
X
X O_TARGET := minix.o
-O_OBJS := bitmap.o truncate.o namei.o inode.o file.o dir.o fsync.o
+O_OBJS := bitmap.o itree_v1.o itree_v2.o namei.o inode.o file.o dir.o
X M_OBJS := $(O_TARGET)
X
X include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.0-test8/linux/fs/minix/bitmap.c linux/fs/minix/bitmap.c
--- v2.4.0-test8/linux/fs/minix/bitmap.c Tue Sep 5 14:07:30 2000
+++ linux/fs/minix/bitmap.c Wed Sep 27 19:23:40 2000
@@ -83,8 +83,6 @@
X if (!minix_test_and_clear_bit(bit,bh->b_data))
X printk("free_block (%s:%d): bit already cleared\n",
X kdevname(sb->s_dev), block);
- else
- DQUOT_FREE_BLOCK(sb, inode, 1);
X mark_buffer_dirty(bh);
X return;
X }
@@ -100,9 +98,6 @@
X return 0;
X }
X repeat:
- if(DQUOT_ALLOC_BLOCK(sb, inode, 1))
- return -EDQUOT;
-
X j = 8192;
X bh = NULL;
X for (i = 0; i < sb->u.minix_sb.s_zmap_blocks; i++) {
@@ -114,7 +109,6 @@
X return 0;
X if (minix_test_and_set_bit(j,bh->b_data)) {
X printk("new_block: bit already set");
- DQUOT_FREE_BLOCK(sb, inode, 1);
X goto repeat;
X }
X mark_buffer_dirty(bh);
@@ -215,9 +209,6 @@
X return;
X }
X
- DQUOT_FREE_INODE(inode->i_sb, inode);
- DQUOT_DROP(inode);
-
X bh = inode->i_sb->u.minix_sb.s_imap[ino >> 13];
X minix_clear_inode(inode);
X clear_inode(inode);
@@ -276,14 +267,6 @@
X mark_inode_dirty(inode);
X
X unlock_super(sb);
- if(DQUOT_ALLOC_INODE(sb, inode)) {
- sb->dq_op->drop(inode);
- inode->i_nlink = 0;
- iput(inode);
- *error = -EDQUOT;


- return NULL;
- }
-

X *error = 0;
X return inode;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/fs/minix/file.c linux/fs/minix/file.c
--- v2.4.0-test8/linux/fs/minix/file.c Sat Feb 26 20:33:06 2000
+++ linux/fs/minix/file.c Wed Sep 27 19:23:40 2000
@@ -13,6 +13,8 @@
X * We have mostly NULLs here: the current defaults are OK for
X * the minix filesystem.
X */
+static int minix_sync_file(struct file *, struct dentry *, int);
+
X struct file_operations minix_file_operations = {
X read: generic_file_read,
X write: generic_file_write,
@@ -23,3 +25,15 @@
X struct inode_operations minix_file_inode_operations = {
X truncate: minix_truncate,
X };
+
+static int minix_sync_file(struct file * file,
+ struct dentry *dentry,
+ int datasync)
+{
+ struct inode *inode = dentry->d_inode;
+
+ if (INODE_VERSION(inode) == MINIX_V1)
+ return V1_minix_sync_file(inode);
+ else
+ return V2_minix_sync_file(inode);
+}
diff -u --recursive --new-file v2.4.0-test8/linux/fs/minix/fsync.c linux/fs/minix/fsync.c
--- v2.4.0-test8/linux/fs/minix/fsync.c Thu Jun 29 16:01:11 2000
+++ linux/fs/minix/fsync.c Wed Dec 31 16:00:00 1969
@@ -1,344 +0,0 @@
-/*
- * linux/fs/minix/fsync.c
- *
- * Copyright (C) 1993 Stephen Tweedie (s...@dcs.ed.ac.uk)
- * from
- * Copyright (C) 1991, 1992 Linus Torvalds
- *
- * Copyright (C) 1996 Gertjan van Wingerde (ger...@cs.vu.nl)
- * Minix V2 fs support
- *
- * minix fsync primitive
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/stat.h>
-#include <linux/fcntl.h>
-#include <linux/locks.h>
-#include <linux/smp_lock.h>
-
-#include <linux/fs.h>
-#include <linux/minix_fs.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-
-#define blocksize BLOCK_SIZE
-
-/*
- * The functions for minix V1 fs file synchronization.
- */
-static int V1_sync_block (struct inode * inode, unsigned short * block, int wait)
-{
- struct buffer_head * bh;
- unsigned short tmp;
-
- if (!*block)
- return 0;
- tmp = *block;
- bh = get_hash_table(inode->i_dev, *block, blocksize);
- if (!bh)
- return 0;
- if (*block != tmp) {
- brelse (bh);
- return 1;
- }
- if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
- brelse(bh);
- return -1;
- }
- if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh))
- {
- brelse(bh);
- return 0;
- }
- ll_rw_block(WRITE, 1, &bh);
- atomic_dec(&bh->b_count);


- return 0;
-}
-

-static int V1_sync_iblock (struct inode * inode, unsigned short * iblock,
- struct buffer_head **bh, int wait)
-{
- int rc;
- unsigned short tmp;
-
- *bh = NULL;
- tmp = *iblock;
- if (!tmp)
- return 0;
- rc = V1_sync_block (inode, iblock, wait);
- if (rc)
- return rc;
- *bh = bread(inode->i_dev, tmp, blocksize);
- if (tmp != *iblock) {
- brelse(*bh);
- *bh = NULL;
- return 1;
- }
- if (!*bh)
- return -1;


- return 0;
-}
-

-static int V1_sync_direct(struct inode *inode, int wait)
-{
- int i;
- int rc, err = 0;
-
- for (i = 0; i < 7; i++) {
- rc = V1_sync_block (inode,
- (unsigned short *) inode->u.minix_i.u.i1_data + i, wait);
- if (rc > 0)
- break;
- if (rc)
- err = rc;
- }


- return err;
-}
-

-static int V1_sync_indirect(struct inode *inode, unsigned short *iblock, int wait)
-{
- int i;
- struct buffer_head * ind_bh;
- int rc, err = 0;
-
- rc = V1_sync_iblock (inode, iblock, &ind_bh, wait);
- if (rc || !ind_bh)
- return rc;
-
- for (i = 0; i < 512; i++) {
- rc = V1_sync_block (inode,
- ((unsigned short *) ind_bh->b_data) + i,
- wait);
- if (rc > 0)
- break;
- if (rc)
- err = rc;
- }
- brelse(ind_bh);


- return err;
-}
-

-static int V1_sync_dindirect(struct inode *inode, unsigned short *diblock,
- int wait)
-{
- int i;
- struct buffer_head * dind_bh;
- int rc, err = 0;
-
- rc = V1_sync_iblock (inode, diblock, &dind_bh, wait);
- if (rc || !dind_bh)
- return rc;
-
- for (i = 0; i < 512; i++) {
- rc = V1_sync_indirect (inode,
- ((unsigned short *) dind_bh->b_data) + i,
- wait);
- if (rc > 0)
- break;
- if (rc)
- err = rc;
- }
- brelse(dind_bh);


- return err;
-}
-

-static int V1_minix_sync_file(struct inode * inode, struct file * file)
-{
- int wait, err = 0;
-
- lock_kernel();
- for (wait=0; wait<=1; wait++)
- {
- err |= V1_sync_direct(inode, wait);
- err |= V1_sync_indirect(inode, inode->u.minix_i.u.i1_data + 7, wait);
- err |= V1_sync_dindirect(inode, inode->u.minix_i.u.i1_data + 8, wait);
- }
- err |= minix_sync_inode (inode);
- unlock_kernel();
- return (err < 0) ? -EIO : 0;
-}
-
-/*
- * The functions for minix V2 fs file synchronization.
- */
-static int V2_sync_block (struct inode * inode, unsigned long * block, int wait)
-{
- struct buffer_head * bh;
- unsigned long tmp;
-
- if (!*block)
- return 0;
- tmp = *block;
- bh = get_hash_table(inode->i_dev, *block, blocksize);
- if (!bh)
- return 0;
- if (*block != tmp) {
- brelse (bh);
- return 1;
- }
- if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
- brelse(bh);
- return -1;
- }
- if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh))
- {
- brelse(bh);
- return 0;
- }
- ll_rw_block(WRITE, 1, &bh);
- atomic_dec(&bh->b_count);


- return 0;
-}
-

-static int V2_sync_iblock (struct inode * inode, unsigned long * iblock,
- struct buffer_head **bh, int wait)
-{
- int rc;
- unsigned long tmp;
-
- *bh = NULL;
- tmp = *iblock;
- if (!tmp)
- return 0;
- rc = V2_sync_block (inode, iblock, wait);
- if (rc)
- return rc;
- *bh = bread(inode->i_dev, tmp, blocksize);
- if (tmp != *iblock) {
- brelse(*bh);
- *bh = NULL;
- return 1;
- }
- if (!*bh)
- return -1;


- return 0;
-}
-

-static int V2_sync_direct(struct inode *inode, int wait)
-{
- int i;
- int rc, err = 0;
-
- for (i = 0; i < 7; i++) {
- rc = V2_sync_block (inode,
- (unsigned long *)inode->u.minix_i.u.i2_data + i, wait);
- if (rc > 0)
- break;
- if (rc)
- err = rc;
- }


- return err;
-}
-

-static int V2_sync_indirect(struct inode *inode, unsigned long *iblock, int wait)
-{
- int i;
- struct buffer_head * ind_bh;
- int rc, err = 0;
-
- rc = V2_sync_iblock (inode, iblock, &ind_bh, wait);
- if (rc || !ind_bh)
- return rc;
-
- for (i = 0; i < 256; i++) {
- rc = V2_sync_block (inode,
- ((unsigned long *) ind_bh->b_data) + i,
- wait);
- if (rc > 0)
- break;
- if (rc)
- err = rc;
- }
- brelse(ind_bh);


- return err;
-}
-

-static int V2_sync_dindirect(struct inode *inode, unsigned long *diblock,
- int wait)
-{
- int i;
- struct buffer_head * dind_bh;
- int rc, err = 0;
-
- rc = V2_sync_iblock (inode, diblock, &dind_bh, wait);
- if (rc || !dind_bh)
- return rc;
-
- for (i = 0; i < 256; i++) {
- rc = V2_sync_indirect (inode,
- ((unsigned long *) dind_bh->b_data) + i,
- wait);
- if (rc > 0)
- break;
- if (rc)
- err = rc;
- }
- brelse(dind_bh);


- return err;
-}
-

-static int V2_sync_tindirect(struct inode *inode, unsigned long *tiblock,
- int wait)
-{
- int i;
- struct buffer_head * tind_bh;
- int rc, err = 0;
-
- rc = V2_sync_iblock (inode, tiblock, &tind_bh, wait);
- if (rc || !tind_bh)
- return rc;
-
- for (i = 0; i < 256; i++) {
- rc = V2_sync_dindirect (inode,
- ((unsigned long *) tind_bh->b_data) + i,
- wait);
- if (rc > 0)
- break;
- if (rc)
- err = rc;
- }
- brelse(tind_bh);


- return err;
-}
-

-static int V2_minix_sync_file(struct inode * inode, struct file * file)
-{
- int wait, err = 0;
-
- lock_kernel();
- for (wait=0; wait<=1; wait++)
- {
- err |= V2_sync_direct(inode, wait);
- err |= V2_sync_indirect(inode,
- (unsigned long *) inode->u.minix_i.u.i2_data + 7, wait);
- err |= V2_sync_dindirect(inode,
- (unsigned long *) inode->u.minix_i.u.i2_data + 8, wait);
- err |= V2_sync_tindirect(inode,
- (unsigned long *) inode->u.minix_i.u.i2_data + 9, wait);
- }
- err |= minix_sync_inode (inode);
- unlock_kernel();
- return (err < 0) ? -EIO : 0;
-}
-
-/*
- * The function which is called for file synchronization. File may be
- * NULL
- */
-
-int minix_sync_file(struct file * file, struct dentry *dentry, int datasync)
-{
- struct inode *inode = dentry->d_inode;
-
- if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
- S_ISLNK(inode->i_mode)))
- return -EINVAL;
-
- if (INODE_VERSION(inode) == MINIX_V1)
- return V1_minix_sync_file(inode, file);
- else
- return V2_minix_sync_file(inode, file);
-}
diff -u --recursive --new-file v2.4.0-test8/linux/fs/minix/inode.c linux/fs/minix/inode.c
--- v2.4.0-test8/linux/fs/minix/inode.c Tue Sep 5 14:07:30 2000
+++ linux/fs/minix/inode.c Wed Sep 27 19:23:40 2000
@@ -348,573 +348,13 @@


X return 0;
X }
X
-/*

- * The minix V1 fs bmap functions.
- */
-#define V1_inode_bmap(inode,nr) (((unsigned short *)(inode)->u.minix_i.u.i1_data)[(nr)])
-
-static int V1_block_bmap(struct buffer_head * bh, int nr)
-{
- int tmp;
-
- if (!bh)
- return 0;
- tmp = ((unsigned short *) bh->b_data)[nr];
- brelse(bh);
- return tmp;
-}
-
-static int V1_minix_block_map(struct inode * inode, long block)
-{
- int i, ret;
-
- ret = 0;
- lock_kernel();
- if (block < 0) {
- printk("minix_bmap: block<0");
- goto out;
- }
- if (block >= (inode->i_sb->u.minix_sb.s_max_size/BLOCK_SIZE)) {
- printk("minix_bmap: block>big");
- goto out;
- }
- if (block < 7) {
- ret = V1_inode_bmap(inode,block);
- goto out;
- }
- block -= 7;
- if (block < 512) {
- i = V1_inode_bmap(inode,7);
- if (!i)
- goto out;
- ret = V1_block_bmap(bread(inode->i_dev, i,
- BLOCK_SIZE), block);
- goto out;
- }
- block -= 512;
- i = V1_inode_bmap(inode,8);
- if (!i)
- goto out;
- i = V1_block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block>>9);
- if (!i)
- goto out;
- ret = V1_block_bmap(bread(inode->i_dev, i, BLOCK_SIZE),
- block & 511);
-out:
- unlock_kernel();


- return ret;
-}
-

-/*
- * The minix V2 fs bmap functions.
- */
-#define V2_inode_bmap(inode,nr) (((unsigned int *)(inode)->u.minix_i.u.i2_data)[(nr)])
-static int V2_block_bmap(struct buffer_head * bh, int nr)
-{
- int tmp;
-
- if (!bh)
- return 0;
- tmp = ((unsigned int *) bh->b_data)[nr];
- brelse(bh);
- return tmp;
-}
-
-static int V2_minix_block_map(struct inode * inode, int block)
-{
- int i, ret;
-
- ret = 0;
- lock_kernel();
- if (block < 0) {
- printk("minix_bmap: block<0");
- goto out;
- }
- if (block >= (inode->i_sb->u.minix_sb.s_max_size/BLOCK_SIZE)) {
- printk("minix_bmap: block>big");
- goto out;
- }
- if (block < 7) {
- ret = V2_inode_bmap(inode,block);
- goto out;
- }
- block -= 7;
- if (block < 256) {
- i = V2_inode_bmap(inode, 7);
- if (!i)
- goto out;
- ret = V2_block_bmap(bread(inode->i_dev, i,
- BLOCK_SIZE), block);
- goto out;
- }
- block -= 256;
- if (block < (256 * 256)) {
- i = V2_inode_bmap(inode, 8);
- if (!i)
- goto out;
- i = V2_block_bmap(bread(inode->i_dev, i, BLOCK_SIZE),
- block >> 8);
- if (!i)
- goto out;
- ret = V2_block_bmap(bread(inode->i_dev, i, BLOCK_SIZE),
- block & 255);
- goto out;
- }
- block -= (256 * 256);
- i = V2_inode_bmap(inode, 9);
- if (!i)
- goto out;
- i = V2_block_bmap(bread(inode->i_dev, i, BLOCK_SIZE),
- block >> 16);
- if (!i)
- goto out;
- i = V2_block_bmap(bread(inode->i_dev, i, BLOCK_SIZE),
- (block >> 8) & 255);
- if (!i)
- goto out;
- ret = V2_block_bmap(bread(inode->i_dev, i, BLOCK_SIZE),
- block & 255);
-out:
- unlock_kernel();


- return ret;
-}
-

-/*
- * The minix V1 fs getblk functions.
- */
-static struct buffer_head * V1_inode_getblk(struct inode * inode, int nr,
- int new_block, int *err,
- int metadata, int *phys, int *new)
-{
- int tmp;
- unsigned short *p;
- struct buffer_head * result;
-
- p = inode->u.minix_i.u.i1_data + nr;
-repeat:
- tmp = *p;
- if (tmp) {
- if (metadata) {
- result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
- if (tmp == *p)
- return result;
- brelse(result);
- goto repeat;
- } else {
- *phys = tmp;


- return NULL;
- }
- }
-

- tmp = minix_new_block(inode);
- if (!tmp) {
- *err = -ENOSPC;
- return NULL;
- }
- if (metadata) {
- result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
- if (*p) {
- minix_free_block(inode, tmp);
- brelse(result);
- goto repeat;
- }
- memset(result->b_data, 0, BLOCK_SIZE);
- mark_buffer_uptodate(result, 1);
- mark_buffer_dirty(result);
- } else {
- if (*p) {
- /*
- * Nobody is allowed to change block allocation
- * state from under us:
- */
- BUG();
- minix_free_block(inode, tmp);
- goto repeat;
- }
- *phys = tmp;
- result = NULL;
- *err = 0;
- *new = 1;
- }
- *p = tmp;
-
- inode->i_ctime = CURRENT_TIME;
- mark_inode_dirty(inode);


- return result;
-}
-

-static struct buffer_head * V1_block_getblk(struct inode * inode,
- struct buffer_head * bh, int nr, int new_block, int *err,
- int metadata, int *phys, int *new)
-{
- int tmp;
- unsigned short *p;
- struct buffer_head * result;
-
- result = NULL;
- if (!bh)
- goto out;
- if (!buffer_uptodate(bh)) {
- ll_rw_block(READ, 1, &bh);
- wait_on_buffer(bh);
- if (!buffer_uptodate(bh))
- goto out;
- }
- p = nr + (unsigned short *) bh->b_data;
-repeat:
- tmp = *p;
- if (tmp) {
- if (metadata) {
- result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
- if (tmp == *p)
- goto out;
- brelse(result);
- goto repeat;
- } else {
- *phys = tmp;


- goto out;
- }
- }
-

- tmp = minix_new_block(inode);
- if (!tmp)
- goto out;
- if (metadata) {
- result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
- if (*p) {
- minix_free_block(inode, tmp);
- brelse(result);
- goto repeat;
- }
- memset(result->b_data, 0, BLOCK_SIZE);
- mark_buffer_uptodate(result, 1);
- mark_buffer_dirty(result);
- } else {
- *phys = tmp;
- *new = 1;
- }
- if (*p) {
- minix_free_block(inode, tmp);
- brelse(result);
- goto repeat;
- }
-
- *p = tmp;
- mark_buffer_dirty(bh);
- *err = 0;
-out:
- brelse(bh);


- return result;
-}
-

-static int V1_get_block(struct inode * inode, long block,
- struct buffer_head *bh_result, int create)
-{
- int ret, err, new, phys, ptr;
- struct buffer_head *bh;
-
- if (!create) {
- phys = V1_minix_block_map(inode, block);
- if (phys) {
- bh_result->b_dev = inode->i_dev;
- bh_result->b_blocknr = phys;
- bh_result->b_state |= (1UL << BH_Mapped);
- }


- return 0;
- }
-

- err = -EIO;
- new = 0;
- ret = 0;
- bh = NULL;
-
- lock_kernel();
- if (block < 0)
- goto abort_negative;
- if (block >= inode->i_sb->u.minix_sb.s_max_size/BLOCK_SIZE)
- goto abort_too_big;
-
- err = 0;
- ptr = block;
- /*
- * ok, these macros clean the logic up a bit and make
- * it much more readable:
- */
-#define GET_INODE_DATABLOCK(x) \
- V1_inode_getblk(inode, x, block, &err, 0, &phys, &new)
-#define GET_INODE_PTR(x) \
- V1_inode_getblk(inode, x, block, &err, 1, NULL, NULL)
-#define GET_INDIRECT_DATABLOCK(x) \
- V1_block_getblk(inode, bh, x, block, &err, 0, &phys, &new)
-#define GET_INDIRECT_PTR(x) \
- V1_block_getblk(inode, bh, x, block, &err, 1, NULL, NULL)
-
- if (ptr < 7) {
- bh = GET_INODE_DATABLOCK(ptr);
- goto out;
- }
- ptr -= 7;
- if (ptr < 512) {
- bh = GET_INODE_PTR(7);
- goto get_indirect;
- }
- ptr -= 512;
- bh = GET_INODE_PTR(8);
- bh = GET_INDIRECT_PTR((ptr >> 9) & 511);
-get_indirect:
- bh = GET_INDIRECT_DATABLOCK(ptr & 511);
-
-#undef GET_INODE_DATABLOCK
-#undef GET_INODE_PTR
-#undef GET_INDIRECT_DATABLOCK
-#undef GET_INDIRECT_PTR
-
-out:
- if (err)
- goto abort;
- bh_result->b_dev = inode->i_dev;
- bh_result->b_blocknr = phys;
- bh_result->b_state |= (1UL << BH_Mapped);
- if (new)
- bh_result->b_state |= (1UL << BH_New);
-abort:
- unlock_kernel();
- return err;
-
-abort_negative:
- printk("minix_getblk: block<0");
- goto abort;
-
-abort_too_big:
- printk("minix_getblk: block>big");
- goto abort;
-}
-
-/*
- * The minix V2 fs getblk functions.
- */
-static struct buffer_head * V2_inode_getblk(struct inode * inode, int nr,
- int new_block, int *err,
- int metadata, int *phys, int *new)
-{
- int tmp;
- unsigned int *p;
- struct buffer_head * result;
-
- p = (unsigned int *) inode->u.minix_i.u.i2_data + nr;
-repeat:
- tmp = *p;
- if (tmp) {
- if (metadata) {
- result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
- if (tmp == *p)
- return result;
- brelse(result);
- goto repeat;
- } else {
- *phys = tmp;


- return NULL;
- }
- }
-

- tmp = minix_new_block(inode);
- if (!tmp) {
- *err = -ENOSPC;
- return NULL;
- }
- if (metadata) {
- result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
- if (*p) {
- minix_free_block(inode, tmp);
- brelse(result);
- goto repeat;
- }
- memset(result->b_data, 0, BLOCK_SIZE);
- mark_buffer_uptodate(result, 1);
- mark_buffer_dirty(result);
- } else {


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 099'
echo 'File patch-2.4.0-test9 is continued in part 100'
echo "100" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part100

#!/bin/sh -x
# this is part 100 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 100; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

- if (*p) {
- /*
- * Nobody is allowed to change block allocation
- * state from under us:
- */
- BUG();
- minix_free_block(inode, tmp);
- goto repeat;
- }
- *phys = tmp;
- result = NULL;
- *err = 0;
- *new = 1;
- }
- *p = tmp;
-
- inode->i_ctime = CURRENT_TIME;
- mark_inode_dirty(inode);
- return result;
-}
-

-static struct buffer_head * V2_block_getblk(struct inode * inode,


- struct buffer_head * bh, int nr, int new_block, int *err,
- int metadata, int *phys, int *new)
-{
- int tmp;

- unsigned int *p;
- struct buffer_head * result;
-

- result = NULL;
- if (!bh)
- goto out;
- if (!buffer_uptodate(bh)) {
- ll_rw_block(READ, 1, &bh);
- wait_on_buffer(bh);
- if (!buffer_uptodate(bh))
- goto out;
- }

- p = nr + (unsigned int *) bh->b_data;

-static int V2_get_block(struct inode * inode, long block,


- struct buffer_head *bh_result, int create)
-{
- int ret, err, new, phys, ptr;
- struct buffer_head * bh;
-
- if (!create) {

- phys = V2_minix_block_map(inode, block);

- V2_inode_getblk(inode, x, block, &err, 0, &phys, &new)
-#define GET_INODE_PTR(x) \
- V2_inode_getblk(inode, x, block, &err, 1, NULL, NULL)
-#define GET_INDIRECT_DATABLOCK(x) \
- V2_block_getblk(inode, bh, x, block, &err, 0, &phys, &new)
-#define GET_INDIRECT_PTR(x) \
- V2_block_getblk(inode, bh, x, block, &err, 1, NULL, NULL)


-
- if (ptr < 7) {
- bh = GET_INODE_DATABLOCK(ptr);
- goto out;
- }
- ptr -= 7;

- if (ptr < 256) {


- bh = GET_INODE_PTR(7);
- goto get_indirect;
- }

- ptr -= 256;
- if (ptr < 256*256) {
- bh = GET_INODE_PTR(8);
- goto get_double;
- }
- ptr -= 256*256;
- bh = GET_INODE_PTR(9);
- bh = GET_INDIRECT_PTR((ptr >> 16) & 255);
-get_double:
- bh = GET_INDIRECT_PTR((ptr >> 8) & 255);
-get_indirect:
- bh = GET_INDIRECT_DATABLOCK(ptr & 255);

X static int minix_get_block(struct inode *inode, long block,
X struct buffer_head *bh_result, int create)
X {
X if (INODE_VERSION(inode) == MINIX_V1)
- return V1_get_block(inode, block, bh_result, create);
+ return V1_minix_get_block(inode, block, bh_result, create);
X else
- return V2_get_block(inode, block, bh_result, create);
+ return V2_minix_get_block(inode, block, bh_result, create);
X }
X
X /*
@@ -1214,6 +654,17 @@
X err = -1;
X brelse (bh);
X return err;
+}
+
+/*
+ * The function that is called for file truncation.
+ */
+void minix_truncate(struct inode * inode)


+{
+ if (INODE_VERSION(inode) == MINIX_V1)

+ V1_minix_truncate(inode);
+ else
+ V2_minix_truncate(inode);
X }
X
X static DECLARE_FSTYPE_DEV(minix_fs_type,"minix",minix_read_super);
diff -u --recursive --new-file v2.4.0-test8/linux/fs/minix/itree_common.c linux/fs/minix/itree_common.c
--- v2.4.0-test8/linux/fs/minix/itree_common.c Wed Dec 31 16:00:00 1969
+++ linux/fs/minix/itree_common.c Wed Sep 27 19:23:40 2000
@@ -0,0 +1,417 @@
+/* Generic part */
+
+typedef struct {
+ block_t *p;
+ block_t key;
+ struct buffer_head *bh;
+} Indirect;
+
+static inline void add_chain(Indirect *p, struct buffer_head *bh, block_t *v)
+{
+ p->key = *(p->p = v);
+ p->bh = bh;
+}
+
+static inline int verify_chain(Indirect *from, Indirect *to)
+{
+ while (from <= to && from->key == *from->p)
+ from++;
+ return (from > to);
+}
+
+static inline block_t *block_end(struct buffer_head *bh)
+{
+ return (block_t *)((char*)bh->b_data + BLOCK_SIZE);
+}
+
+static inline Indirect *get_branch(struct inode *inode,
+ int depth,
+ int *offsets,
+ Indirect chain[DEPTH],
+ int *err)
+{
+ kdev_t dev = inode->i_dev;
+ Indirect *p = chain;
+ struct buffer_head *bh;
+
+ *err = 0;
+ /* i_data is not going away, no lock needed */
+ add_chain (chain, NULL, i_data(inode) + *offsets);
+ if (!p->key)
+ goto no_block;
+ while (--depth) {
+ bh = bread(dev, block_to_cpu(p->key), BLOCK_SIZE);
+ if (!bh)
+ goto failure;
+ /* Reader: pointers */
+ if (!verify_chain(chain, p))
+ goto changed;
+ add_chain(++p, bh, (block_t *)bh->b_data + *++offsets);
+ /* Reader: end */
+ if (!p->key)
+ goto no_block;


+ }
+ return NULL;
+

+changed:
+ *err = -EAGAIN;
+ goto no_block;
+failure:
+ *err = -EIO;
+no_block:
+ return p;
+}
+
+static int alloc_branch(struct inode *inode,
+ int num,
+ int *offsets,
+ Indirect *branch)
+{
+ int n = 0;
+ int i;
+ int parent = minix_new_block(inode);
+
+ branch[0].key = cpu_to_block(parent);
+ if (parent) for (n = 1; n < num; n++) {
+ struct buffer_head *bh;
+ /* Allocate the next block */
+ int nr = minix_new_block(inode);
+ if (!nr)
+ break;
+ branch[n].key = cpu_to_block(nr);
+ bh = getblk(inode->i_dev, parent, BLOCK_SIZE);
+ if (!buffer_uptodate(bh))
+ wait_on_buffer(bh);
+ memset(bh->b_data, 0, BLOCK_SIZE);
+ branch[n].bh = bh;
+ branch[n].p = (block_t*) bh->b_data + offsets[n];
+ *branch[n].p = branch[n].key;
+ mark_buffer_uptodate(bh, 1);
+ mark_buffer_dirty(bh);
+ parent = nr;
+ }
+ if (n == num)
+ return 0;
+
+ /* Allocation failed, free what we already allocated */
+ for (i = 1; i < n; i++)
+ bforget(branch[i].bh);
+ for (i = 0; i < n; i++)
+ minix_free_block(inode, block_to_cpu(branch[i].key));
+ return -ENOSPC;
+}
+
+static inline int splice_branch(struct inode *inode,
+ Indirect chain[DEPTH],
+ Indirect *where,
+ int num)
+{
+ int i;
+
+ /* Verify that place we are splicing to is still there and vacant */
+
+ /* Writer: pointers */
+ if (!verify_chain(chain, where-1) || *where->p)
+ /* Writer: end */
+ goto changed;
+
+ /* That's it */
+
+ *where->p = where->key;
+
+ /* Writer: end */
+
+ /* We are done with atomic stuff, now do the rest of housekeeping */
+
+ inode->i_ctime = CURRENT_TIME;
+
+ /* had we spliced it onto indirect block? */
+ if (where->bh)
+ mark_buffer_dirty(where->bh);
+
+ mark_inode_dirty(inode);
+ return 0;
+
+changed:
+ for (i = 1; i < num; i++)
+ bforget(where[i].bh);
+ for (i = 0; i < num; i++)
+ minix_free_block(inode, block_to_cpu(where[i].key));


+ return -EAGAIN;
+}
+

+static inline int get_block(struct inode * inode, long block,
+ struct buffer_head *bh_result, int create)
+{
+ int err = -EIO;
+ int offsets[DEPTH];
+ Indirect chain[DEPTH];
+ Indirect *partial;
+ int left;
+ int depth = block_to_path(inode, block, offsets);
+
+ if (depth == 0)
+ goto out;
+
+ lock_kernel();
+reread:
+ partial = get_branch(inode, depth, offsets, chain, &err);
+
+ /* Simplest case - block found, no allocation needed */
+ if (!partial) {
+got_it:
+ bh_result->b_dev = inode->i_dev;
+ bh_result->b_blocknr = block_to_cpu(chain[depth-1].key);
+ bh_result->b_state |= (1UL << BH_Mapped);
+ /* Clean up and exit */
+ partial = chain+depth-1; /* the whole chain */
+ goto cleanup;
+ }
+
+ /* Next simple case - plain lookup or failed read of indirect block */
+ if (!create || err == -EIO) {
+cleanup:
+ while (partial > chain) {
+ brelse(partial->bh);
+ partial--;
+ }
+ unlock_kernel();
+out:
+ return err;
+ }
+
+ /*
+ * Indirect block might be removed by truncate while we were
+ * reading it. Handling of that case (forget what we've got and
+ * reread) is taken out of the main path.
+ */
+ if (err == -EAGAIN)
+ goto changed;
+
+ left = (chain + depth) - partial;
+ err = alloc_branch(inode, left, offsets+(partial-chain), partial);
+ if (err)
+ goto cleanup;
+
+ if (splice_branch(inode, chain, partial, left) < 0)
+ goto changed;
+
+ bh_result->b_state |= (1UL << BH_New);
+ goto got_it;
+
+changed:
+ while (partial > chain) {
+ bforget(partial->bh);
+ partial--;
+ }
+ goto reread;
+}
+
+static inline int all_zeroes(block_t *p, block_t *q)
+{
+ while (p < q)
+ if (*p++)
+ return 0;


+ return 1;
+}
+

+static Indirect *find_shared(struct inode *inode,
+ int depth,
+ int offsets[DEPTH],
+ Indirect chain[DEPTH],
+ block_t *top)
+{
+ Indirect *partial, *p;
+ int k, err;
+
+ *top = 0;
+ for (k = depth; k > 1 && !offsets[k-1]; k--)
+ ;
+ partial = get_branch(inode, k, offsets, chain, &err);
+ /* Writer: pointers */
+ if (!partial)
+ partial = chain + k-1;
+ if (!partial->key && *partial->p)
+ /* Writer: end */
+ goto no_top;
+ for (p=partial;p>chain && all_zeroes((block_t*)p->bh->b_data,p->p);p--)
+ ;
+ if (p == chain + k - 1 && p > chain) {
+ p->p--;
+ } else {
+ *top = *p->p;
+ *p->p = 0;
+ }
+ /* Writer: end */
+
+ while(partial > p)
+ {
+ brelse(partial->bh);
+ partial--;
+ }
+no_top:
+ return partial;
+}
+
+static inline void free_data(struct inode *inode, block_t *p, block_t *q)
+{
+ unsigned long nr;
+
+ for ( ; p < q ; p++) {
+ nr = block_to_cpu(*p);
+ if (nr) {
+ *p = 0;
+ minix_free_block(inode, nr);
+ }
+ }
+}
+
+static void free_branches(struct inode *inode, block_t *p, block_t *q, int depth)
+{
+ struct buffer_head * bh;
+ unsigned long nr;
+
+ if (depth--) {
+ for ( ; p < q ; p++) {
+ nr = block_to_cpu(*p);
+ if (!nr)
+ continue;
+ *p = 0;
+ bh = bread (inode->i_dev, nr, BLOCK_SIZE);
+ if (!bh)
+ continue;
+ free_branches(inode, (block_t*)bh->b_data,
+ block_end(bh), depth);
+ bforget(bh);
+ minix_free_block(inode, nr);
+ mark_inode_dirty(inode);
+ }
+ } else
+ free_data(inode, p, q);
+}
+
+static inline void truncate (struct inode * inode)
+{
+ block_t *idata = i_data(inode);
+ int offsets[DEPTH];
+ Indirect chain[DEPTH];
+ Indirect *partial;
+ block_t nr = 0;
+ int n;
+ int first_whole;
+ long iblock;
+
+ iblock = (inode->i_size + BLOCK_SIZE-1) >> 10;
+ block_truncate_page(inode->i_mapping, inode->i_size, get_block);
+
+ n = block_to_path(inode, iblock, offsets);
+ if (!n)
+ return;
+
+ if (n == 1) {
+ free_data(inode, idata+offsets[0], idata + DIRECT);
+ first_whole = 0;
+ goto do_indirects;
+ }
+
+ first_whole = offsets[0] + 1 - DIRECT;
+ partial = find_shared(inode, n, offsets, chain, &nr);
+ if (nr) {
+ if (partial == chain)
+ mark_inode_dirty(inode);
+ else
+ mark_buffer_dirty(partial->bh);
+ free_branches(inode, &nr, &nr+1, (chain+n-1) - partial);
+ }
+ /* Clear the ends of indirect blocks on the shared branch */
+ while (partial > chain) {
+ free_branches(inode, partial->p + 1, block_end(partial->bh),
+ (chain+n-1) - partial);
+ mark_buffer_dirty(partial->bh);
+ brelse (partial->bh);
+ partial--;
+ }
+do_indirects:
+ /* Kill the remaining (whole) subtrees */
+ while (first_whole < DEPTH-1) {
+ nr = idata[DIRECT+first_whole];
+ if (nr) {
+ idata[DIRECT+first_whole] = 0;
+ mark_inode_dirty(inode);
+ free_branches(inode, &nr, &nr+1, first_whole+1);
+ }
+ first_whole++;
+ }
+ inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+ mark_inode_dirty(inode);
+}
+
+static int sync_block (struct inode * inode, block_t block, int wait)
+{
+ struct buffer_head * bh;
+
+ if (!block)
+ return 0;
+ bh = get_hash_table(inode->i_dev, block_to_cpu(block), BLOCK_SIZE);
+ if (!bh)
+ return 0;
+ if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
+ brelse(bh);
+ return -1;
+ }
+ if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh))
+ {
+ brelse(bh);
+ return 0;
+ }
+ ll_rw_block(WRITE, 1, &bh);
+ atomic_dec(&bh->b_count);


+ return 0;
+}
+

+static int sync_indirect(struct inode *inode, block_t iblock, int depth,
+ int wait)
+{
+ struct buffer_head * ind_bh = NULL;
+ int rc, err = 0;
+
+ if (!iblock)
+ return 0;
+
+ rc = sync_block (inode, iblock, wait);
+ if (rc)
+ return rc;
+
+ ind_bh = bread(inode->i_dev, block_to_cpu(iblock), BLOCK_SIZE);
+ if (!ind_bh)
+ return -1;
+
+ if (--depth) {
+ block_t *p = (block_t*)ind_bh->b_data;
+ block_t *end = block_end(ind_bh);
+ while (p < end) {
+ rc = sync_indirect (inode, *p++, depth, wait);
+ if (rc > 0)
+ break;
+ if (rc)
+ err = rc;
+ }
+ }
+ brelse(ind_bh);
+ return err;
+}
+
+static inline int sync_file(struct inode * inode)
+{
+ int wait, err = 0, i;
+ block_t *idata = i_data(inode);
+
+ lock_kernel();
+ err = generic_buffer_fdatasync(inode, 0, ~0UL);
+ for (wait=0; wait<=1; wait++)
+ for (i=1; i<DEPTH; i++)
+ err |= sync_indirect(inode, idata[DIRECT+i-1], i, wait);
+ err |= minix_sync_inode (inode);
+ unlock_kernel();
+ return (err < 0) ? -EIO : 0;
+}
diff -u --recursive --new-file v2.4.0-test8/linux/fs/minix/itree_v1.c linux/fs/minix/itree_v1.c
--- v2.4.0-test8/linux/fs/minix/itree_v1.c Wed Dec 31 16:00:00 1969
+++ linux/fs/minix/itree_v1.c Wed Sep 27 19:23:40 2000
@@ -0,0 +1,63 @@
+#include <linux/sched.h>
+#include <linux/locks.h>
+#include <linux/minix_fs.h>
+#include <linux/smp_lock.h>
+
+enum {DEPTH = 3, DIRECT = 7}; /* Only double indirect */
+
+typedef u16 block_t; /* 16 bit, host order */
+
+static inline unsigned long block_to_cpu(block_t n)
+{
+ return n;
+}
+
+static inline block_t cpu_to_block(unsigned long n)
+{
+ return n;
+}
+
+static inline block_t *i_data(struct inode *inode)
+{
+ return (block_t *)inode->u.minix_i.u.i1_data;
+}
+
+static int block_to_path(struct inode * inode, long block, int offsets[DEPTH])
+{
+ int n = 0;
+
+ if (block < 0) {
+ printk("minix_bmap: block<0");
+ } else if (block >= (inode->i_sb->u.minix_sb.s_max_size/BLOCK_SIZE)) {
+ printk("minix_bmap: block>big");
+ } else if (block < 7) {
+ offsets[n++] = block;
+ } else if ((block -= 7) < 512) {
+ offsets[n++] = 7;
+ offsets[n++] = block;
+ } else {
+ block -= 512;
+ offsets[n++] = 8;
+ offsets[n++] = block>>9;
+ offsets[n++] = block & 511;
+ }
+ return n;
+}
+
+#include "itree_common.c"
+
+int V1_minix_get_block(struct inode * inode, long block,
+ struct buffer_head *bh_result, int create)
+{
+ return get_block(inode, block, bh_result, create);
+}
+
+void V1_minix_truncate(struct inode * inode)
+{
+ truncate(inode);
+}
+
+int V1_minix_sync_file(struct inode * inode)
+{
+ return sync_file(inode);
+}
diff -u --recursive --new-file v2.4.0-test8/linux/fs/minix/itree_v2.c linux/fs/minix/itree_v2.c
--- v2.4.0-test8/linux/fs/minix/itree_v2.c Wed Dec 31 16:00:00 1969
+++ linux/fs/minix/itree_v2.c Wed Sep 27 19:23:40 2000
@@ -0,0 +1,68 @@
+#include <linux/sched.h>
+#include <linux/locks.h>
+#include <linux/minix_fs.h>
+#include <linux/smp_lock.h>
+
+enum {DIRECT = 7, DEPTH = 4}; /* Have triple indirect */
+
+typedef u32 block_t; /* 32 bit, host order */
+
+static inline unsigned long block_to_cpu(block_t n)
+{
+ return n;
+}
+
+static inline block_t cpu_to_block(unsigned long n)
+{
+ return n;
+}
+
+static inline block_t *i_data(struct inode *inode)
+{
+ return (block_t *)inode->u.minix_i.u.i2_data;
+}
+
+static int block_to_path(struct inode * inode, long block, int offsets[DEPTH])
+{
+ int n = 0;
+
+ if (block < 0) {
+ printk("minix_bmap: block<0");
+ } else if (block >= (inode->i_sb->u.minix_sb.s_max_size/BLOCK_SIZE)) {
+ printk("minix_bmap: block>big");
+ } else if (block < 7) {
+ offsets[n++] = block;
+ } else if ((block -= 7) < 256) {
+ offsets[n++] = 7;
+ offsets[n++] = block;
+ } else if ((block -= 256) < 256*256) {
+ offsets[n++] = 8;
+ offsets[n++] = block>>8;
+ offsets[n++] = block & 255;
+ } else {
+ block -= 256*256;
+ offsets[n++] = 9;
+ offsets[n++] = block>>16;
+ offsets[n++] = (block>>8) & 255;
+ offsets[n++] = block & 255;
+ }
+ return n;
+}
+
+#include "itree_common.c"
+
+int V2_minix_get_block(struct inode * inode, long block,
+ struct buffer_head *bh_result, int create)
+{
+ return get_block(inode, block, bh_result, create);
+}
+
+void V2_minix_truncate(struct inode * inode)
+{
+ truncate(inode);
+}
+
+int V2_minix_sync_file(struct inode * inode)
+{
+ return sync_file(inode);
+}
diff -u --recursive --new-file v2.4.0-test8/linux/fs/minix/namei.c linux/fs/minix/namei.c
--- v2.4.0-test8/linux/fs/minix/namei.c Tue Sep 5 14:07:30 2000
+++ linux/fs/minix/namei.c Wed Sep 27 19:23:40 2000
@@ -389,7 +389,6 @@
X if (!bh)
X goto end_rmdir;
X inode = dentry->d_inode;
- DQUOT_INIT(inode);
X
X if (!empty_dir(inode)) {
X retval = -ENOTEMPTY;


@@ -424,7 +423,6 @@
X

X retval = -ENOENT;
X inode = dentry->d_inode;
- DQUOT_INIT(inode);
X bh = minix_find_entry(dir, dentry->d_name.name,
X dentry->d_name.len, &de);
X if (!bh || de->inode != inode->i_ino)
@@ -557,8 +555,6 @@
X if (!new_inode) {
X brelse(new_bh);
X new_bh = NULL;
- } else {
- DQUOT_INIT(new_inode);
X }
X }
X if (S_ISDIR(old_inode->i_mode)) {
diff -u --recursive --new-file v2.4.0-test8/linux/fs/minix/truncate.c linux/fs/minix/truncate.c
--- v2.4.0-test8/linux/fs/minix/truncate.c Tue Sep 5 14:07:30 2000
+++ linux/fs/minix/truncate.c Wed Dec 31 16:00:00 1969
@@ -1,420 +0,0 @@
-/*
- * linux/fs/truncate.c
- *


- * Copyright (C) 1991, 1992 Linus Torvalds
- *
- * Copyright (C) 1996 Gertjan van Wingerde (ger...@cs.vu.nl)

- * Minix V2 fs support.


- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>

-#include <linux/minix_fs.h>
-#include <linux/stat.h>
-#include <linux/fcntl.h>
-
-#define DIRECT_BLOCK ((inode->i_size + 1023) >> 10)
-#define INDIRECT_BLOCK(offset) (DIRECT_BLOCK-offset)
-#define V1_DINDIRECT_BLOCK(offset) ((DIRECT_BLOCK-offset)>>9)
-#define V2_DINDIRECT_BLOCK(offset) ((DIRECT_BLOCK-offset)>>8)
-#define TINDIRECT_BLOCK(offset) ((DIRECT_BLOCK-(offset))>>8)
-
-/*
- * Truncate has the most races in the whole filesystem: coding it is
- * a pain in the a**, especially as I don't do any locking.
- *
- * The code may look a bit weird, but that's just because I've tried to
- * handle things like file-size changes in a somewhat graceful manner.
- * Anyway, truncating a file at the same time somebody else writes to it
- * is likely to result in pretty weird behaviour...
- *
- * The new code handles normal truncates (size = 0) as well as the more
- * general case (size = XXX). I hope.
- */
-
-#define DATA_BUFFER_USED(bh) \
- (atomic_read(&bh->b_count) > 1 || buffer_locked(bh))
-
-/*
- * The functions for minix V1 fs truncation.
- */
-static int V1_trunc_direct(struct inode * inode)
-{
- unsigned short * p;


- struct buffer_head * bh;

- int i, tmp;
- int retry = 0;
-
-repeat:
- for (i = DIRECT_BLOCK ; i < 7 ; i++) {
- p = i + inode->u.minix_i.u.i1_data;
- if (!(tmp = *p))
- continue;
- bh = get_hash_table(inode->i_dev,tmp,BLOCK_SIZE);
- if (i < DIRECT_BLOCK) {
- brelse(bh);
- goto repeat;
- }
- if ((bh && DATA_BUFFER_USED(bh)) || tmp != *p) {
- retry = 1;
- brelse(bh);
- continue;
- }
- *p = 0;
- mark_inode_dirty(inode);
- bforget(bh);
- minix_free_block(inode,tmp);
- }
- return retry;
-}
-
-static int V1_trunc_indirect(struct inode * inode, int offset, unsigned short * p)


-{
- struct buffer_head * bh;

- int i, tmp;


- struct buffer_head * ind_bh;

- unsigned short * ind;
- int retry = 0;
-
- tmp = *p;


- if (!tmp)
- return 0;

- ind_bh = bread(inode->i_dev, tmp, BLOCK_SIZE);
- if (tmp != *p) {
- brelse(ind_bh);
- return 1;
- }
- if (!ind_bh) {
- *p = 0;
- return 0;
- }
-repeat:
- for (i = INDIRECT_BLOCK(offset) ; i < 512 ; i++) {
- if (i < 0)
- i = 0;
- if (i < INDIRECT_BLOCK(offset))
- goto repeat;
- ind = i+(unsigned short *) ind_bh->b_data;
- tmp = *ind;
- if (!tmp)
- continue;
- bh = get_hash_table(inode->i_dev,tmp,BLOCK_SIZE);
- if (i < INDIRECT_BLOCK(offset)) {
- brelse(bh);
- goto repeat;
- }
- if ((bh && DATA_BUFFER_USED(bh)) || tmp != *ind) {
- retry = 1;
- brelse(bh);
- continue;
- }
- *ind = 0;
- mark_buffer_dirty(ind_bh);
- bforget(bh);
- minix_free_block(inode,tmp);
- }
- ind = (unsigned short *) ind_bh->b_data;


- for (i = 0; i < 512; i++)

- if (*(ind++))
- break;
- if (i >= 512) {
- if (atomic_read(&ind_bh->b_count) != 1)
- retry = 1;
- else {
- tmp = *p;
- *p = 0;
- minix_free_block(inode,tmp);
- }
- }
- brelse(ind_bh);
- return retry;
-}
-
-static int V1_trunc_dindirect(struct inode * inode, int offset, unsigned short *p)
-{
- int i, tmp;


- struct buffer_head * dind_bh;

- unsigned short * dind;
- int retry = 0;
-
- if (!(tmp = *p))
- return 0;
- dind_bh = bread(inode->i_dev, tmp, BLOCK_SIZE);
- if (tmp != *p) {
- brelse(dind_bh);
- return 1;
- }
- if (!dind_bh) {
- *p = 0;
- return 0;
- }
-repeat:
- for (i = V1_DINDIRECT_BLOCK(offset) ; i < 512 ; i ++) {
- if (i < 0)
- i = 0;
- if (i < V1_DINDIRECT_BLOCK(offset))
- goto repeat;
- dind = i+(unsigned short *) dind_bh->b_data;
- retry |= V1_trunc_indirect(inode,offset+(i<<9),dind);
- mark_buffer_dirty(dind_bh);
- }
- dind = (unsigned short *) dind_bh->b_data;


- for (i = 0; i < 512; i++)

- if (*(dind++))
- break;
- if (i >= 512) {
- if (atomic_read(&dind_bh->b_count) != 1)
- retry = 1;
- else {
- tmp = *p;
- *p = 0;
- mark_inode_dirty(inode);
- minix_free_block(inode,tmp);
- }
- }
- brelse(dind_bh);
- return retry;
-}
-
-static void V1_minix_truncate(struct inode * inode)
-{
- int retry;


-
- if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
- S_ISLNK(inode->i_mode)))

- return;
- while (1) {
- retry = V1_trunc_direct(inode);
- retry |= V1_trunc_indirect(inode, 7, inode->u.minix_i.u.i1_data + 7);
- retry |= V1_trunc_dindirect(inode, 7+512, inode->u.minix_i.u.i1_data + 8);
- if (!retry)
- break;
- current->counter = 0;
- schedule();
- }
- inode->i_mtime = inode->i_ctime = CURRENT_TIME;
- mark_inode_dirty(inode);
-}
-
-/*
- * The functions for minix V2 fs truncation.
- */
-static int V2_trunc_direct(struct inode * inode)
-{
- unsigned long * p;


- struct buffer_head * bh;

- int i, tmp;
- int retry = 0;
-
-repeat:
- for (i = DIRECT_BLOCK ; i < 7 ; i++) {
- p = (unsigned long *) inode->u.minix_i.u.i2_data + i;
- if (!(tmp = *p))
- continue;
- bh = get_hash_table(inode->i_dev,tmp,BLOCK_SIZE);
- if (i < DIRECT_BLOCK) {
- brelse(bh);
- goto repeat;
- }
- if ((bh && DATA_BUFFER_USED(bh)) || tmp != *p) {
- retry = 1;
- brelse(bh);
- continue;
- }
- *p = 0;
- mark_inode_dirty(inode);
- bforget(bh);
- minix_free_block(inode,tmp);
- }
- return retry;
-}
-
-static int V2_trunc_indirect(struct inode * inode, int offset, unsigned long * p)


-{
- struct buffer_head * bh;

- int i, tmp;


- struct buffer_head * ind_bh;

- unsigned long * ind;
- int retry = 0;
-
- tmp = *p;


- if (!tmp)
- return 0;

- ind_bh = bread(inode->i_dev, tmp, BLOCK_SIZE);
- if (tmp != *p) {
- brelse(ind_bh);
- return 1;
- }
- if (!ind_bh) {
- *p = 0;
- return 0;
- }
-repeat:
- for (i = INDIRECT_BLOCK(offset) ; i < 256 ; i++) {
- if (i < 0)
- i = 0;
- if (i < INDIRECT_BLOCK(offset))
- goto repeat;
- ind = i+(unsigned long *) ind_bh->b_data;
- tmp = *ind;
- if (!tmp)
- continue;
- bh = get_hash_table(inode->i_dev,tmp,BLOCK_SIZE);
- if (i < INDIRECT_BLOCK(offset)) {
- brelse(bh);
- goto repeat;
- }
- if ((bh && DATA_BUFFER_USED(bh)) || tmp != *ind) {
- retry = 1;
- brelse(bh);
- continue;
- }
- *ind = 0;
- mark_buffer_dirty(ind_bh);
- bforget(bh);
- minix_free_block(inode,tmp);
- }
- ind = (unsigned long *) ind_bh->b_data;


- for (i = 0; i < 256; i++)

- if (*(ind++))
- break;
- if (i >= 256) {
- if (atomic_read(&ind_bh->b_count) != 1)
- retry = 1;
- else {
- tmp = *p;
- *p = 0;
- minix_free_block(inode,tmp);
- }
- }
- brelse(ind_bh);
- return retry;
-}
-
-static int V2_trunc_dindirect(struct inode * inode, int offset, unsigned long *p)
-{
- int i, tmp;


- struct buffer_head * dind_bh;

- unsigned long * dind;
- int retry = 0;
-
- if (!(tmp = *p))
- return 0;
- dind_bh = bread(inode->i_dev, tmp, BLOCK_SIZE);
- if (tmp != *p) {
- brelse(dind_bh);
- return 1;
- }
- if (!dind_bh) {
- *p = 0;
- return 0;
- }
-repeat:
- for (i = V2_DINDIRECT_BLOCK(offset) ; i < 256 ; i ++) {
- if (i < 0)
- i = 0;
- if (i < V2_DINDIRECT_BLOCK(offset))
- goto repeat;
- dind = i+(unsigned long *) dind_bh->b_data;
- retry |= V2_trunc_indirect(inode,offset+(i<<8),dind);
- mark_buffer_dirty(dind_bh);
- }
- dind = (unsigned long *) dind_bh->b_data;


- for (i = 0; i < 256; i++)

- if (*(dind++))
- break;
- if (i >= 256) {
- if (atomic_read(&dind_bh->b_count) != 1)
- retry = 1;
- else {
- tmp = *p;
- *p = 0;
- mark_inode_dirty(inode);
- minix_free_block(inode,tmp);
- }
- }
- brelse(dind_bh);
- return retry;
-}
-
-static int V2_trunc_tindirect(struct inode * inode, int offset, unsigned long * p)
-{
- int i, tmp;


- struct buffer_head * tind_bh;

- unsigned long * tind;
- int retry = 0;
-
- if (!(tmp = *p))
- return 0;
- tind_bh = bread(inode->i_dev, tmp, BLOCK_SIZE);
- if (tmp != *p) {
- brelse(tind_bh);
- return 1;
- }
- if (!tind_bh) {
- *p = 0;
- return 0;
- }
-repeat:
- for (i = TINDIRECT_BLOCK(offset) ; i < 256 ; i ++) {
- if (i < 0)
- i = 0;
- if (i < TINDIRECT_BLOCK(offset))
- goto repeat;
- tind = i+(unsigned long *) tind_bh->b_data;
- retry |= V2_trunc_dindirect(inode,offset+(i<<8),tind);
- mark_buffer_dirty(tind_bh);
- }
- tind = (unsigned long *) tind_bh->b_data;


- for (i = 0; i < 256; i++)

- if (*(tind++))
- break;
- if (i >= 256) {
- if (atomic_read(&tind_bh->b_count) != 1)
- retry = 1;
- else {
- tmp = *p;
- *p = 0;
- mark_inode_dirty(inode);
- minix_free_block(inode,tmp);
- }
- }
- brelse(tind_bh);
- return retry;
-}
-
-static void V2_minix_truncate(struct inode * inode)
-{
- int retry;


-
- if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
- S_ISLNK(inode->i_mode)))

- return;
- while (1) {
- retry = V2_trunc_direct(inode);
- retry |= V2_trunc_indirect(inode,7,
- (unsigned long *) inode->u.minix_i.u.i2_data + 7);
- retry |= V2_trunc_dindirect(inode, 7+256,
- (unsigned long *) inode->u.minix_i.u.i2_data + 8);
- retry |= V2_trunc_tindirect(inode, 7+256+256*256,
- (unsigned long *) inode->u.minix_i.u.i2_data + 9);
- if (!retry)
- break;
- run_task_queue(&tq_disk);
- current->policy |= SCHED_YIELD;
- schedule();
- }
- inode->i_mtime = inode->i_ctime = CURRENT_TIME;
- mark_inode_dirty(inode);
-}
-
-/*
- * The function that is called for file truncation.
- */
-void minix_truncate(struct inode * inode)


-{
- if (INODE_VERSION(inode) == MINIX_V1)

- V1_minix_truncate(inode);
- else
- V2_minix_truncate(inode);
-}
diff -u --recursive --new-file v2.4.0-test8/linux/fs/namei.c linux/fs/namei.c
--- v2.4.0-test8/linux/fs/namei.c Sun Sep 3 22:49:25 2000
+++ linux/fs/namei.c Fri Sep 22 14:21:18 2000
@@ -21,6 +21,7 @@
X #include <linux/quotaops.h>
X #include <linux/pagemap.h>
X #include <linux/dcache.h>
+#include <linux/dnotify.h>
X
X #include <asm/uaccess.h>
X #include <asm/unaligned.h>
@@ -107,7 +108,7 @@
X static inline int do_getname(const char *filename, char *page)
X {
X int retval;
- unsigned long len = PAGE_SIZE;
+ unsigned long len = PATH_MAX + 1;
X
X if ((unsigned long) filename >= TASK_SIZE) {
X if (!segment_eq(get_fs(), KERNEL_DS))
@@ -180,7 +181,7 @@
X
X /* read and search access */
X if ((mask == S_IROTH) ||
- (S_ISDIR(mode) && !(mask & ~(S_IROTH | S_IXOTH))))
+ (S_ISDIR(inode->i_mode) && !(mask & ~(S_IROTH | S_IXOTH))))
X if (capable(CAP_DAC_READ_SEARCH))
X return 0;
X
@@ -683,7 +684,7 @@
X }
X
X /* SMP-safe */
-int path_init(const char *name,unsigned int flags,struct nameidata *nd)
+int path_init(const char *name, unsigned int flags, struct nameidata *nd)
X {
X nd->last_type = LAST_ROOT; /* if there are only slashes... */
X nd->flags = flags;
@@ -912,6 +913,8 @@
X unlock_kernel();
X exit_lock:
X up(&dir->i_zombie);
+ if (!error)
+ inode_dir_notify(dir, DN_CREATE);


X return error;
X }
X

@@ -1066,6 +1069,13 @@


X goto exit;
X }
X

+ /*
+ * Ensure there are no outstanding leases on the file.
+ */
+ error = get_lease(inode, flag);
+ if (error)
+ goto exit;
+
X if (flag & O_TRUNC) {
X error = get_write_access(inode);
X if (error)
@@ -1183,6 +1193,8 @@
X unlock_kernel();
X exit_lock:
X up(&dir->i_zombie);
+ if (!error)
+ inode_dir_notify(dir, DN_CREATE);


X return error;
X }
X

@@ -1250,6 +1262,8 @@
X
X exit_lock:
X up(&dir->i_zombie);
+ if (!error)
+ inode_dir_notify(dir, DN_CREATE);


X return error;
X }
X

@@ -1338,8 +1352,10 @@
X dentry->d_inode->i_flags |= S_DEAD;
X }
X double_up(&dir->i_zombie, &dentry->d_inode->i_zombie);
- if (!error)
+ if (!error) {
+ inode_dir_notify(dir, DN_DELETE);
X d_delete(dentry);
+ }
X dput(dentry);
X
X return error;


@@ -1406,6 +1422,8 @@
X }

X }
X up(&dir->i_zombie);
+ if (!error)
+ inode_dir_notify(dir, DN_DELETE);


X return error;
X }
X

@@ -1472,6 +1490,8 @@
X
X exit_lock:
X up(&dir->i_zombie);
+ if (!error)
+ inode_dir_notify(dir, DN_CREATE);


X return error;
X }
X

@@ -1544,6 +1564,8 @@
X
X exit_lock:
X up(&dir->i_zombie);
+ if (!error)
+ inode_dir_notify(dir, DN_CREATE);


X return error;
X }
X

@@ -1749,10 +1771,20 @@
X int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
X struct inode *new_dir, struct dentry *new_dentry)
X {
+ int error;
X if (S_ISDIR(old_dentry->d_inode->i_mode))
- return vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
+ error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
X else
- return vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
+ error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
+ if (!error) {
+ if (old_dir == new_dir)
+ inode_dir_notify(old_dir, DN_RENAME);
+ else {
+ inode_dir_notify(old_dir, DN_DELETE);
+ inode_dir_notify(new_dir, DN_CREATE);
+ }
+ }


+ return error;
X }
X

X static inline int do_rename(const char * oldname, const char * newname)
diff -u --recursive --new-file v2.4.0-test8/linux/fs/ncpfs/file.c linux/fs/ncpfs/file.c
--- v2.4.0-test8/linux/fs/ncpfs/file.c Wed Jul 5 11:56:28 2000
+++ linux/fs/ncpfs/file.c Fri Sep 15 14:26:23 2000
@@ -256,7 +256,7 @@
X }
X if (ncp_write_kernel(NCP_SERVER(inode),
X NCP_FINFO(inode)->file_handle,
- pos, to_write, buf, &written_this_time) != 0) {
+ pos, to_write, bouncebuffer, &written_this_time) != 0) {
X errno = -EIO;
X break;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/fs/nfs/dir.c linux/fs/nfs/dir.c
--- v2.4.0-test8/linux/fs/nfs/dir.c Tue Sep 5 14:02:41 2000
+++ linux/fs/nfs/dir.c Mon Sep 11 08:38:25 2000
@@ -809,14 +809,9 @@
X dentry->d_parent->d_name.name, dentry->d_name.name,
X atomic_read(&dentry->d_count));
X
- /*
- * Note that a silly-renamed file can be deleted once it's
- * no longer in use -- it's just an ordinary file now.
- */
- if (atomic_read(&dentry->d_count) == 1) {
- dentry->d_flags &= ~DCACHE_NFSFS_RENAMED;
+ if (atomic_read(&dentry->d_count) == 1)
X goto out; /* No need to silly rename. */
- }
+
X
X #ifdef NFS_PARANOIA
X if (!dentry->d_inode)
@@ -900,12 +895,21 @@
X #endif


X goto out;
X }
+

+ /* If the dentry was sillyrenamed, we simply call d_delete() */
+ if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {
+ error = 0;
+ goto out_delete;
+ }
+
X nfs_zap_caches(dir_i);
X if (inode)
X NFS_CACHEINV(inode);
X error = NFS_PROTO(dir_i)->remove(dir, &dentry->d_name);
X if (error < 0)
X goto out;
+
+ out_delete:
X /*
X * Free the inode
X */
diff -u --recursive --new-file v2.4.0-test8/linux/fs/nfs/file.c linux/fs/nfs/file.c
--- v2.4.0-test8/linux/fs/nfs/file.c Thu Jun 29 16:02:40 2000
+++ linux/fs/nfs/file.c Mon Sep 18 15:18:56 2000
@@ -291,10 +291,13 @@
X status = 0;
X
X /*
- * Make sure we re-validate anything we've got cached.
+ * Make sure we clear the cache whenever we try to get the lock.
X * This makes locking act as a cache coherency point.
X */
X out_ok:
- NFS_CACHEINV(inode);
+ if ((cmd == F_SETLK || cmd == F_SETLKW) && fl->fl_type != F_UNLCK) {
+ nfs_wb_all(inode); /* we may have slept */
+ nfs_zap_caches(inode);
+ }
X return status;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/fs/nfs/inode.c linux/fs/nfs/inode.c
--- v2.4.0-test8/linux/fs/nfs/inode.c Mon Aug 21 13:00:25 2000
+++ linux/fs/nfs/inode.c Mon Sep 25 13:13:53 2000
@@ -353,6 +353,7 @@
X
X clnt->cl_intr = (data->flags & NFS_MOUNT_INTR)? 1 : 0;
X clnt->cl_softrtry = (data->flags & NFS_MOUNT_SOFT)? 1 : 0;
+ clnt->cl_droppriv = (data->flags & NFS_MOUNT_BROKEN_SUID) ? 1 : 0;
X clnt->cl_chatty = 1;
X server->client = clnt;
X
diff -u --recursive --new-file v2.4.0-test8/linux/fs/nfs/nfs3proc.c linux/fs/nfs/nfs3proc.c
--- v2.4.0-test8/linux/fs/nfs/nfs3proc.c Tue Sep 5 14:02:41 2000
+++ linux/fs/nfs/nfs3proc.c Mon Sep 11 08:38:25 2000
@@ -279,6 +279,7 @@
X arg->fh = NFS_FH(dir);
X arg->name = name->name;
X arg->len = name->len;
+ res->valid = 0;
X msg->rpc_proc = NFS3PROC_REMOVE;
X msg->rpc_argp = arg;
X msg->rpc_resp = res;
@@ -288,10 +289,13 @@
X static void
X nfs3_proc_unlink_done(struct dentry *dir, struct rpc_message *msg)
X {
- struct nfs_fattr *dir_attr = (struct nfs_fattr*)msg->rpc_resp;
+ struct nfs_fattr *dir_attr;
X
- nfs_refresh_inode(dir->d_inode, dir_attr);
- kfree(msg->rpc_argp);
+ if (msg->rpc_argp) {
+ dir_attr = (struct nfs_fattr*)msg->rpc_resp;
+ nfs_refresh_inode(dir->d_inode, dir_attr);
+ kfree(msg->rpc_argp);
+ }


X }
X
X static int

diff -u --recursive --new-file v2.4.0-test8/linux/fs/nfs/nfsroot.c linux/fs/nfs/nfsroot.c
--- v2.4.0-test8/linux/fs/nfs/nfsroot.c Fri Apr 21 13:36:40 2000
+++ linux/fs/nfs/nfsroot.c Mon Sep 25 13:13:53 2000
@@ -157,6 +157,7 @@
X #endif
X { "udp", ~NFS_MOUNT_TCP, 0 },
X { "tcp", ~NFS_MOUNT_TCP, NFS_MOUNT_TCP },
+ { "broken_suid",~NFS_MOUNT_BROKEN_SUID, NFS_MOUNT_BROKEN_SUID },
X { NULL, 0, 0 }
X };
X
diff -u --recursive --new-file v2.4.0-test8/linux/fs/nfs/proc.c linux/fs/nfs/proc.c
--- v2.4.0-test8/linux/fs/nfs/proc.c Tue Sep 5 14:02:41 2000
+++ linux/fs/nfs/proc.c Mon Sep 11 08:38:25 2000
@@ -251,8 +251,10 @@
X static void
X nfs_proc_unlink_done(struct dentry *dir, struct rpc_message *msg)
X {
- NFS_CACHEINV(dir->d_inode);
- kfree(msg->rpc_argp);
+ if (msg->rpc_argp) {
+ NFS_CACHEINV(dir->d_inode);
+ kfree(msg->rpc_argp);
+ }


X }
X
X static int

diff -u --recursive --new-file v2.4.0-test8/linux/fs/nfs/unlink.c linux/fs/nfs/unlink.c
--- v2.4.0-test8/linux/fs/nfs/unlink.c Tue Sep 5 14:02:41 2000
+++ linux/fs/nfs/unlink.c Sun Oct 1 20:35:16 2000
@@ -23,7 +23,7 @@
X unsigned int count;
X };
X
-static struct nfs_unlinkdata *nfs_deletes = NULL;
+static struct nfs_unlinkdata *nfs_deletes;
X static struct rpc_wait_queue nfs_delete_queue = RPC_INIT_WAITQ("nfs_delete_queue");
X
X /**
@@ -121,8 +121,11 @@
X {
X struct nfs_unlinkdata *data = (struct nfs_unlinkdata *)task->tk_calldata;
X struct dentry *dir = data->dir;
- struct inode *dir_i = dir->d_inode;
+ struct inode *dir_i;
X
+ if (!dir)
+ return;
+ dir_i = dir->d_inode;
X nfs_zap_caches(dir_i);
X NFS_PROTO(dir_i)->unlink_done(dir, &task->tk_msg);
X rpcauth_releasecred(task->tk_auth, data->cred);
@@ -206,6 +209,7 @@
X return;
X data->count++;
X nfs_copy_dname(dentry, data);
+ dentry->d_flags &= ~DCACHE_NFSFS_RENAMED;
X if (data->task.tk_rpcwait == &nfs_delete_queue)
X rpc_wake_up_task(&data->task);
X nfs_put_unlinkdata(data);
diff -u --recursive --new-file v2.4.0-test8/linux/fs/nfsd/export.c linux/fs/nfsd/export.c
--- v2.4.0-test8/linux/fs/nfsd/export.c Mon Jun 26 11:44:15 2000
+++ linux/fs/nfsd/export.c Sun Oct 1 20:35:16 2000


@@ -1,3 +1,4 @@
+#define MSNFS /* HACK HACK */
X /*

X * linux/fs/nfsd/export.c
X *
@@ -56,12 +57,12 @@
X struct svc_client * h_client;
X };
X static struct svc_clnthash * clnt_hash[CLIENT_HASHMAX];
-static svc_client * clients = NULL;


-static int initialized = 0;

+static svc_client * clients;
+static int initialized;
X
-static int hash_lock = 0;
-static int want_lock = 0;
-static int hash_count = 0;
+static int hash_lock;
+static int want_lock;
+static int hash_count;
X static DECLARE_WAIT_QUEUE_HEAD( hash_wait );
X
X
@@ -556,6 +557,9 @@
X { NFSEXP_CROSSMNT, {"nohide", ""}},
X { NFSEXP_NOSUBTREECHECK, {"no_subtree_check", ""}},
X { NFSEXP_NOAUTHNLM, {"insecure_locks", ""}},
+#ifdef NSMFS
+ { NFSEXP_MSNFS, {"msnfs", ""}},
+#endif
X { 0, {"", ""}}
X };
X
diff -u --recursive --new-file v2.4.0-test8/linux/fs/nfsd/nfs3proc.c linux/fs/nfsd/nfs3proc.c
--- v2.4.0-test8/linux/fs/nfsd/nfs3proc.c Fri Jun 23 21:22:12 2000
+++ linux/fs/nfsd/nfs3proc.c Wed Sep 27 13:41:33 2000
@@ -11,6 +11,7 @@
X #include <linux/errno.h>
X #include <linux/locks.h>


X #include <linux/fs.h>
+#include <linux/ext2_fs.h>

X #include <linux/stat.h>
X #include <linux/fcntl.h>
X #include <linux/net.h>
diff -u --recursive --new-file v2.4.0-test8/linux/fs/nfsd/nfs3xdr.c linux/fs/nfsd/nfs3xdr.c
--- v2.4.0-test8/linux/fs/nfsd/nfs3xdr.c Fri Aug 11 14:29:02 2000
+++ linux/fs/nfsd/nfs3xdr.c Fri Sep 22 14:21:18 2000
@@ -193,7 +193,7 @@
X p = xdr_encode_hyper(p, (u64) inode->i_dev);
X p = xdr_encode_hyper(p, (u64) inode->i_ino);
X p = encode_time3(p, inode->i_atime);
- p = encode_time3(p, inode->i_mtime);
+ p = encode_time3(p, lease_get_mtime(inode));
X p = encode_time3(p, inode->i_ctime);
X
X return p;
diff -u --recursive --new-file v2.4.0-test8/linux/fs/nfsd/nfsctl.c linux/fs/nfsd/nfsctl.c
--- v2.4.0-test8/linux/fs/nfsd/nfsctl.c Mon Aug 28 21:27:39 2000
+++ linux/fs/nfsd/nfsctl.c Sun Oct 1 20:35:16 2000
@@ -46,7 +46,7 @@
X static int nfsctl_ugidupdate(struct nfsctl_ugidmap *data);
X #endif
X

-static int initialized = 0;
+static int initialized;
X

X int exp_procfs_exports(char *buffer, char **start, off_t offset,
X int length, int *eof, void *data);
diff -u --recursive --new-file v2.4.0-test8/linux/fs/nfsd/nfsfh.c linux/fs/nfsd/nfsfh.c
--- v2.4.0-test8/linux/fs/nfsd/nfsfh.c Fri Aug 11 14:29:02 2000
+++ linux/fs/nfsd/nfsfh.c Wed Sep 27 13:54:30 2000
@@ -405,7 +405,7 @@
X || !S_ISDIR(dentry->d_inode->i_mode)) {
X goto err_dentry;
X }
- if ((!dentry->d_flags & DCACHE_NFSD_DISCONNECTED))
+ if (!(dentry->d_flags & DCACHE_NFSD_DISCONNECTED))
X found = 1;
X tmp = splice(result, dentry);
X err = PTR_ERR(tmp);
diff -u --recursive --new-file v2.4.0-test8/linux/fs/nfsd/nfssvc.c linux/fs/nfsd/nfssvc.c
--- v2.4.0-test8/linux/fs/nfsd/nfssvc.c Fri Sep 1 14:33:04 2000
+++ linux/fs/nfsd/nfssvc.c Sun Oct 1 20:35:16 2000
@@ -41,9 +41,9 @@
X
X extern struct svc_program nfsd_program;
X static void nfsd(struct svc_rqst *rqstp);
-struct timeval nfssvc_boot = { 0, 0 };
-static struct svc_serv *nfsd_serv = NULL;
-static int nfsd_busy = 0;
+struct timeval nfssvc_boot;
+static struct svc_serv *nfsd_serv;
+static int nfsd_busy;
X static unsigned long nfsd_last_call;
X
X struct nfsd_list {
@@ -154,6 +154,8 @@
X current->pgrp = 1;
X sprintf(current->comm, "nfsd");
X current->fs->umask = 0;
+
+ current->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
X
X nfsdstats.th_cnt++;
X /* Let svc_process check client's authentication. */
diff -u --recursive --new-file v2.4.0-test8/linux/fs/nfsd/nfsxdr.c linux/fs/nfsd/nfsxdr.c
--- v2.4.0-test8/linux/fs/nfsd/nfsxdr.c Fri Aug 11 14:29:02 2000
+++ linux/fs/nfsd/nfsxdr.c Fri Sep 22 14:21:19 2000
@@ -155,7 +155,7 @@
X *p++ = htonl((u32) inode->i_ino);
X *p++ = htonl((u32) inode->i_atime);
X *p++ = 0;
- *p++ = htonl((u32) inode->i_mtime);
+ *p++ = htonl((u32) lease_get_mtime(inode));
X *p++ = 0;
X *p++ = htonl((u32) inode->i_ctime);
X *p++ = 0;
diff -u --recursive --new-file v2.4.0-test8/linux/fs/nfsd/vfs.c linux/fs/nfsd/vfs.c
--- v2.4.0-test8/linux/fs/nfsd/vfs.c Mon Aug 28 21:27:39 2000
+++ linux/fs/nfsd/vfs.c Sun Sep 24 17:10:45 2000


@@ -1,3 +1,4 @@
+#define MSNFS /* HACK HACK */
X /*

X * linux/fs/nfsd/vfs.c
X *
@@ -249,6 +250,15 @@
X if (err)


X goto out;
X }
+

+ /*
+ * If we are changing the size of the file, then
+ * we need to break all leases.
+ */
+ err = get_lease(inode, FMODE_WRITE);
+ if (err)
+ goto out_nfserr;
+
X err = get_write_access(inode);
X if (err)
X goto out_nfserr;
@@ -443,6 +453,14 @@
X if (!inode->i_fop)
X goto out;
X
+ /*
+ * Check to see if there are any leases on this file.
+ * This may block while leases are broken.
+ */
+ err = get_lease(inode, (access & MAY_WRITE) ? FMODE_WRITE : 0);
+ if (err)
+ goto out_nfserr;
+
X if ((access & MAY_WRITE) && (err = get_write_access(inode)) != 0)
X goto out_nfserr;
X
@@ -451,11 +469,11 @@
X atomic_set(&filp->f_count, 1);
X filp->f_dentry = dentry;
X if (access & MAY_WRITE) {
- filp->f_flags = O_WRONLY;
+ filp->f_flags = O_WRONLY|O_LARGEFILE;
X filp->f_mode = FMODE_WRITE;
X DQUOT_INIT(inode);
X } else {
- filp->f_flags = O_RDONLY;
+ filp->f_flags = O_RDONLY|O_LARGEFILE;
X filp->f_mode = FMODE_READ;
X }
X
@@ -577,6 +595,11 @@
X err = nfserr_perm;
X if (!file.f_op->read)
X goto out_close;
+#ifdef MSNFS
+ if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
+ (!lock_may_read(file.f_dentry->d_inode, offset, *count)))
+ goto out_close;
+#endif
X
X /* Get readahead parameters */
X ra = nfsd_get_raparms(fhp->fh_export->ex_dev, fhp->fh_dentry->d_inode->i_ino);
@@ -643,6 +666,11 @@
X err = nfserr_perm;
X if (!file.f_op->write)
X goto out_close;
+#ifdef MSNFS
+ if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
+ (!lock_may_write(file.f_dentry->d_inode, offset, cnt)))
+ goto out_close;
+#endif
X
X dentry = file.f_dentry;
X inode = dentry->d_inode;
@@ -1250,6 +1278,13 @@
X goto out_dput_old;
X
X
+#ifdef MSNFS
+ if ((ffhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
+ ((atomic_read(&odentry->d_count) > 1)
+ || (atomic_read(&ndentry->d_count) > 1))) {
+ err = nfserr_perm;
+ } else
+#endif
X err = vfs_rename(fdir, odentry, tdir, ndentry);
X if (!err && EX_ISSYNC(tfhp->fh_export)) {
X nfsd_sync_dir(tdentry);
@@ -1311,6 +1346,12 @@
X }
X
X if (type != S_IFDIR) { /* It's UNLINK */
+#ifdef MSNFS
+ if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
+ (atomic_read(&rdentry->d_count) > 1)) {
+ err = nfserr_perm;
+ } else
+#endif
X err = vfs_unlink(dirp, rdentry);
X } else { /* It's RMDIR */
X err = vfs_rmdir(dirp, rdentry);
diff -u --recursive --new-file v2.4.0-test8/linux/fs/open.c linux/fs/open.c
--- v2.4.0-test8/linux/fs/open.c Fri Aug 11 15:16:21 2000
+++ linux/fs/open.c Sun Oct 1 20:32:01 2000
@@ -10,11 +10,14 @@


X #include <linux/file.h>
X #include <linux/smp_lock.h>

X #include <linux/quotaops.h>
+#include <linux/dnotify.h>
X #include <linux/module.h>
X #include <linux/slab.h>


X
X #include <asm/uaccess.h>
X

+#define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
+
X int vfs_statfs(struct super_block *sb, struct statfs *buf)
X {
X int retval = -ENODEV;
@@ -115,6 +118,13 @@
X if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
X goto dput_and_out;
X
+ /*
+ * Make sure that there are no leases.
+ */
+ error = get_lease(inode, FMODE_WRITE);
+ if (error)
+ goto dput_and_out;
+
X error = get_write_access(inode);
X if (error)
X goto dput_and_out;
@@ -314,7 +324,8 @@
X if (!res) {
X res = permission(nd.dentry->d_inode, mode);
X /* SuS v2 requires we report a read only fs too */
- if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode))
+ if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
+ && !special_file(nd.dentry->d_inode->i_mode))
X res = -EROFS;
X path_release(&nd);
X }
@@ -790,6 +801,7 @@
X retval = filp->f_op->flush(filp);
X unlock_kernel();
X }
+ fcntl_dirnotify(0, filp, 0);
X locks_remove_posix(filp, id);
X fput(filp);
X return retval;
diff -u --recursive --new-file v2.4.0-test8/linux/fs/partitions/acorn.c linux/fs/partitions/acorn.c
--- v2.4.0-test8/linux/fs/partitions/acorn.c Wed Aug 9 14:11:11 2000
+++ linux/fs/partitions/acorn.c Mon Sep 18 15:15:26 2000
@@ -1,12 +1,17 @@
X /*
- * linux/arch/arm/drivers/block/adfspart.c
+ * linux/fs/partitions/acorn.c


X *
- * Copyright (c) 1996-2000 Russell King.

+ * Copyright (c) 1996-2000 Russell King.
X *
- * Scan ADFS partitions on hard disk drives.


+ * This program is free software; you can redistribute it and/or modify

+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Scan ADFS partitions on hard disk drives.
X */
X #include <linux/config.h>
X #include <linux/kernel.h>
+#include <linux/types.h>
X #include <linux/kdev_t.h>
X #include <linux/major.h>
X #include <linux/string.h>
diff -u --recursive --new-file v2.4.0-test8/linux/fs/partitions/check.c linux/fs/partitions/check.c
--- v2.4.0-test8/linux/fs/partitions/check.c Mon Aug 28 21:29:17 2000
+++ linux/fs/partitions/check.c Wed Sep 27 13:39:23 2000
@@ -146,6 +146,16 @@
X sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, disk, part);
X return buf;
X }
+ if (hd->major >= COMPAQ_CISS_MAJOR && hd->major <= COMPAQ_CISS_MAJOR+7) {
+ int ctlr = hd->major - COMPAQ_CISS_MAJOR;
+ int disk = minor >> hd->minor_shift;
+ int part = minor & (( 1 << hd->minor_shift) - 1);
+ if (part == 0)
+ sprintf(buf, "%s/c%dd%d", maj, ctlr, disk);
+ else
+ sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, disk, part);
+ return buf;
+ }
X if (hd->major >= DAC960_MAJOR && hd->major <= DAC960_MAJOR+7) {
X int ctlr = hd->major - DAC960_MAJOR;
X int disk = minor >> hd->minor_shift;
@@ -177,7 +187,8 @@
X #ifdef CONFIG_DEVFS_FS
X printk(" p%d", (minor & ((1 << hd->minor_shift) - 1)));
X #else
- if (hd->major >= COMPAQ_SMART2_MAJOR+0 && hd->major <= COMPAQ_SMART2_MAJOR+7)
+ if ((hd->major >= COMPAQ_SMART2_MAJOR+0 && hd->major <= COMPAQ_SMART2_MAJOR+7) ||
+ (hd->major >= COMPAQ_CISS_MAJOR+0 && hd->major <= COMPAQ_CISS_MAJOR+7))
X printk(" p%d", (minor & ((1 << hd->minor_shift) - 1)));
X else
X printk(" %s", disk_name(hd, minor, buf));
@@ -438,9 +449,6 @@
X else
X #endif
X rd_load();
-#endif
-#ifdef CONFIG_BLK_DEV_MD
- md_run_setup();
X #endif
X return 0;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/fs/partitions/mac.c linux/fs/partitions/mac.c
--- v2.4.0-test8/linux/fs/partitions/mac.c Wed Feb 9 19:43:53 2000
+++ linux/fs/partitions/mac.c Sun Sep 17 09:51:57 2000
@@ -21,7 +21,7 @@
X #include "mac.h"
X
X #ifdef CONFIG_PPC
-extern void note_bootable_part(kdev_t dev, int part);
+extern void note_bootable_part(kdev_t dev, int part, int goodness);


X #endif
X
X /*

@@ -67,7 +67,7 @@
X brelse(bh);
X dev_pos = secsize;
X if ((bh = bread(dev, secsize/dev_bsize, dev_bsize)) == 0) {
- printk("%s: error reading partition table\n",
+ printk("%s: error reading Mac partition table\n",
X kdevname(dev));
X return -1;
X }
@@ -77,6 +77,7 @@
X brelse(bh);
X return 0; /* not a MacOS disk */
X }
+ printk(" [mac]");
X blocks_in_map = be32_to_cpu(part->map_count);
X for (blk = 1; blk <= blocks_in_map; ++blk) {
X pos = blk * secsize;
@@ -114,7 +115,8 @@
X goodness++;
X
X if (strcasecmp(part->type, "Apple_UNIX_SVR2") == 0
- || strcasecmp(part->type, "Linux_PPC") == 0) {
+ || (strnicmp(part->type, "Linux", 5) == 0
+ && strcasecmp(part->type, "Linux_swap") != 0)) {
X int i, l;
X
X goodness++;
@@ -143,7 +145,7 @@
X }
X #ifdef CONFIG_PPC
X if (found_root_goodness)
- note_bootable_part(dev, found_root);
+ note_bootable_part(dev, found_root, found_root_goodness);
X #endif
X brelse(bh);
X printk("\n");
diff -u --recursive --new-file v2.4.0-test8/linux/fs/proc/generic.c linux/fs/proc/generic.c
--- v2.4.0-test8/linux/fs/proc/generic.c Fri Aug 11 14:29:01 2000
+++ linux/fs/proc/generic.c Sun Oct 1 20:35:16 2000
@@ -190,7 +190,7 @@


X return 0;
X }
X

-static unsigned char proc_alloc_map[PROC_NDYNAMIC / 8] = {0};
+static unsigned char proc_alloc_map[PROC_NDYNAMIC / 8];
X
X static int make_inode_number(void)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/fs/proc/proc_misc.c linux/fs/proc/proc_misc.c
--- v2.4.0-test8/linux/fs/proc/proc_misc.c Mon Aug 28 21:29:17 2000
+++ linux/fs/proc/proc_misc.c Sun Sep 17 10:13:25 2000
@@ -156,22 +156,30 @@
X * have been updated.
X */
X len += sprintf(page+len,
- "MemTotal: %8lu kB\n"
- "MemFree: %8lu kB\n"
- "MemShared: %8lu kB\n"
- "Buffers: %8lu kB\n"
- "Cached: %8u kB\n"
- "HighTotal: %8lu kB\n"
- "HighFree: %8lu kB\n"
- "LowTotal: %8lu kB\n"
- "LowFree: %8lu kB\n"
- "SwapTotal: %8lu kB\n"
- "SwapFree: %8lu kB\n",
+ "MemTotal: %8lu kB\n"
+ "MemFree: %8lu kB\n"
+ "MemShared: %8lu kB\n"
+ "Buffers: %8lu kB\n"
+ "Cached: %8u kB\n"
+ "Active: %8u kB\n"
+ "Inact_dirty: %8u kB\n"
+ "Inact_clean: %8u kB\n"
+ "Inact_target: %8lu kB\n"
+ "HighTotal: %8lu kB\n"
+ "HighFree: %8lu kB\n"
+ "LowTotal: %8lu kB\n"
+ "LowFree: %8lu kB\n"
+ "SwapTotal: %8lu kB\n"
+ "SwapFree: %8lu kB\n",
X K(i.totalram),
X K(i.freeram),
X K(i.sharedram),
X K(i.bufferram),
X K(atomic_read(&page_cache_size)),
+ K(nr_active_pages),
+ K(nr_inactive_dirty_pages),
+ K(nr_inactive_clean_pages()),
+ K(inactive_target),
X K(i.totalhigh),
X K(i.freehigh),
X K(i.totalram-i.totalhigh),
@@ -328,14 +336,14 @@
X
X for (major = 0; major < DK_MAX_MAJOR; major++) {
X for (disk = 0; disk < DK_MAX_DISK; disk++) {
- int active = kstat.dk_drive_rio[major][disk] +
+ int active = kstat.dk_drive[major][disk] +
X kstat.dk_drive_rblk[major][disk] +
- kstat.dk_drive_wio[major][disk] +
X kstat.dk_drive_wblk[major][disk];
X if (active)
X len += sprintf(page + len,
- "(%u,%u):(%u,%u,%u,%u) ",
+ "(%u,%u):(%u,%u,%u,%u,%u) ",
X major, disk,
+ kstat.dk_drive[major][disk],
X kstat.dk_drive_rio[major][disk],
X kstat.dk_drive_rblk[major][disk],
X kstat.dk_drive_wio[major][disk],
diff -u --recursive --new-file v2.4.0-test8/linux/fs/proc/procfs_syms.c linux/fs/proc/procfs_syms.c
--- v2.4.0-test8/linux/fs/proc/procfs_syms.c Mon May 8 11:17:47 2000
+++ linux/fs/proc/procfs_syms.c Mon Sep 11 08:41:07 2000
@@ -28,7 +28,9 @@
X if (!err) {
X proc_mnt = kern_mount(&proc_fs_type);
X err = PTR_ERR(proc_mnt);
- if (!IS_ERR(proc_mnt))
+ if (IS_ERR(proc_mnt))
+ unregister_filesystem(&proc_fs_type);
+ else


X err = 0;
X }

X return err;
diff -u --recursive --new-file v2.4.0-test8/linux/fs/ramfs/inode.c linux/fs/ramfs/inode.c
--- v2.4.0-test8/linux/fs/ramfs/inode.c Sun Aug 6 11:43:18 2000
+++ linux/fs/ramfs/inode.c Sun Sep 17 09:51:57 2000
@@ -121,7 +121,7 @@
X inode->i_size = 0;
X inode->i_blksize = PAGE_CACHE_SIZE;
X inode->i_blocks = 0;
- inode->i_rdev = dev;
+ inode->i_rdev = to_kdev_t(dev);
X inode->i_nlink = 1;
X inode->i_op = NULL;
X inode->i_fop = NULL;
diff -u --recursive --new-file v2.4.0-test8/linux/fs/read_write.c linux/fs/read_write.c
--- v2.4.0-test8/linux/fs/read_write.c Tue Jun 20 07:52:36 2000
+++ linux/fs/read_write.c Fri Sep 22 14:21:19 2000
@@ -10,6 +10,7 @@
X #include <linux/file.h>
X #include <linux/uio.h>


X #include <linux/smp_lock.h>
+#include <linux/dnotify.h>

X
X #include <asm/uaccess.h>
X

@@ -132,6 +133,9 @@
X ret = read(file, buf, count, &file->f_pos);
X }
X }
+ if (ret > 0)
+ inode_dir_notify(file->f_dentry->d_parent->d_inode,
+ DN_ACCESS);
X fput(file);
X }
X return ret;
@@ -156,6 +160,9 @@
X ret = write(file, buf, count, &file->f_pos);
X }
X }
+ if (ret > 0)
+ inode_dir_notify(file->f_dentry->d_parent->d_inode,
+ DN_MODIFY);
X fput(file);
X }
X return ret;
@@ -257,6 +264,10 @@
X if (iov != iovstack)
X kfree(iov);
X out_nofree:
+ /* VERIFY_WRITE actually means a read, as we write to user space */
+ if ((ret + (type == VERIFY_WRITE)) > 0)
+ inode_dir_notify(file->f_dentry->d_parent->d_inode,
+ (type == VERIFY_WRITE) ? DN_MODIFY : DN_ACCESS);


X return ret;
X }
X

@@ -327,6 +338,8 @@
X if (pos < 0)
X goto out;
X ret = read(file, buf, count, &pos);
+ if (ret > 0)
+ inode_dir_notify(file->f_dentry->d_parent->d_inode, DN_ACCESS);
X out:
X fput(file);
X bad_file:
@@ -357,6 +370,8 @@
X goto out;
X
X ret = write(file, buf, count, &pos);
+ if (ret > 0)
+ inode_dir_notify(file->f_dentry->d_parent->d_inode, DN_MODIFY);
X out:
X fput(file);
X bad_file:
diff -u --recursive --new-file v2.4.0-test8/linux/fs/smbfs/inode.c linux/fs/smbfs/inode.c
--- v2.4.0-test8/linux/fs/smbfs/inode.c Mon Aug 28 12:50:58 2000
+++ linux/fs/smbfs/inode.c Tue Sep 19 11:33:06 2000
@@ -33,6 +33,13 @@
X #include "smb_debug.h"
X #include "getopt.h"
X
+/* Always pick a default string */
+#ifdef CONFIG_SMB_NLS_REMOTE
+#define SMB_NLS_REMOTE CONFIG_SMB_NLS_REMOTE
+#else
+#define SMB_NLS_REMOTE ""
+#endif
+
X static void smb_delete_inode(struct inode *);
X static void smb_put_super(struct super_block *);
X static int smb_statfs(struct super_block *, struct statfs *);
@@ -445,7 +452,7 @@
X memset(mnt, 0, sizeof(struct smb_mount_data_kernel));
X strncpy(mnt->codepage.local_name, CONFIG_NLS_DEFAULT,
X SMB_NLS_MAXNAMELEN);
- strncpy(mnt->codepage.remote_name, CONFIG_SMB_NLS_REMOTE,
+ strncpy(mnt->codepage.remote_name, SMB_NLS_REMOTE,
X SMB_NLS_MAXNAMELEN);
X
X if (ver == SMB_MOUNT_OLDVERSION) {
diff -u --recursive --new-file v2.4.0-test8/linux/fs/super.c linux/fs/super.c
--- v2.4.0-test8/linux/fs/super.c Fri Aug 11 14:31:45 2000
+++ linux/fs/super.c Mon Sep 25 13:13:53 2000
@@ -483,6 +483,7 @@
X { NFS_MOUNT_NOCTO, ",nocto", "" },
X { NFS_MOUNT_NOAC, ",noac", "" },
X { NFS_MOUNT_NONLM, ",nolock", ",lock" },
+ { NFS_MOUNT_BROKEN_SUID, ",broken_suid", "" },
X { 0, NULL, NULL }
X };
X
@@ -1303,20 +1304,21 @@
X * information (or be NULL).
X *
X * NOTE! As pre-0.97 versions of mount() didn't use this setup, the
- * flags have to have a special 16-bit magic number in the high word:
- * 0xC0ED. If this magic word isn't present, the flags and data info
- * aren't used, as the syscall assumes we are talking to an older
- * version that didn't understand them.
+ * flags used to have a special 16-bit magic number in the high word:
+ * 0xC0ED. If this magic number is present, the high word is discarded.
X */
X long do_mount(char * dev_name, char * dir_name, char *type_page,
- unsigned long new_flags, void *data_page)
+ unsigned long flags, void *data_page)
X {
X struct file_system_type * fstype;
X struct nameidata nd;
X struct vfsmount *mnt = NULL;
X struct super_block *sb;


X int retval = 0;

- unsigned long flags = 0;
+
+ /* Discard magic */
+ if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
+ flags &= ~MS_MGC_MSK;
X
X /* Basic sanity checks */
X
@@ -1328,21 +1330,25 @@
X /* OK, looks good, now let's see what do they want */
X
X /* just change the flags? - capabilities are checked in do_remount() */
- if ((new_flags & (MS_MGC_MSK|MS_REMOUNT)) == (MS_MGC_VAL|MS_REMOUNT))
- return do_remount(dir_name, new_flags&~(MS_MGC_MSK|MS_REMOUNT),
- (char *) data_page);
-
- if ((new_flags & MS_MGC_MSK) == MS_MGC_VAL)
- flags = new_flags & ~MS_MGC_MSK;
+ if (flags & MS_REMOUNT)
+ return do_remount(dir_name, flags & ~MS_REMOUNT,
+ (char *) data_page);
+
+ /* "mount --bind"? Equivalent to older "mount -t bind" */
+ /* No capabilities? What if users do thousands of these? */
+ if (flags & MS_BIND)
+ return do_loopback(dev_name, dir_name);
X
X /* For the rest we need the type */
X
X if (!type_page || !memchr(type_page, 0, PAGE_SIZE))
X return -EINVAL;
X
+#if 0 /* Can be deleted again. Introduced in patch-2.3.99-pre6 */
X /* loopback mount? This is special - requires fewer capabilities */
X if (strcmp(type_page, "bind")==0)
X return do_loopback(dev_name, dir_name);
+#endif
X
X /* for the rest we _really_ need capabilities... */
X if (!capable(CAP_SYS_ADMIN))
@@ -1354,7 +1360,8 @@
X return -ENODEV;
X
X /* ... and mountpoint. Do the lookup first to force automounting. */
- if (path_init(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE|LOOKUP_DIRECTORY, &nd))
+ if (path_init(dir_name,
+ LOOKUP_FOLLOW|LOOKUP_POSITIVE|LOOKUP_DIRECTORY, &nd))
X retval = path_walk(dir_name, &nd);
X if (retval)
X goto fs_out;
@@ -1363,7 +1370,7 @@
X if (fstype->fs_flags & FS_NOMOUNT)
X sb = ERR_PTR(-EINVAL);
X else if (fstype->fs_flags & FS_REQUIRES_DEV)
- sb = get_sb_bdev(fstype, dev_name,flags, data_page);


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 100'
echo 'File patch-2.4.0-test9 is continued in part 101'
echo "101" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part101

#!/bin/sh -x
# this is part 101 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 101; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ sb = get_sb_bdev(fstype, dev_name, flags, data_page);
X else if (fstype->fs_flags & FS_SINGLE)
X sb = get_sb_single(fstype, flags, data_page);
X else
@@ -1376,6 +1383,13 @@
X /* Something was mounted here while we slept */
X while(d_mountpoint(nd.dentry) && follow_down(&nd.mnt, &nd.dentry))
X ;
+
+ /* Refuse the same filesystem on the same mount point */
+ retval = -EBUSY;
+ if (nd.mnt && nd.mnt->mnt_sb == sb
+ && nd.mnt->mnt_root == nd.dentry)
+ goto fail;
+
X retval = -ENOENT;
X if (!nd.dentry->d_inode)
X goto fail;
@@ -1403,7 +1417,7 @@
X }
X
X asmlinkage long sys_mount(char * dev_name, char * dir_name, char * type,
- unsigned long new_flags, void * data)
+ unsigned long flags, void * data)
X {
X int retval;
X unsigned long data_page;
@@ -1423,14 +1437,18 @@
X retval = copy_mount_options (dev_name, &dev_page);
X if (retval < 0)
X goto out2;
+
X retval = copy_mount_options (data, &data_page);
- if (retval >= 0) {
- lock_kernel();
- retval = do_mount((char*)dev_page,dir_page,(char*)type_page,
- new_flags, (void*)data_page);
- unlock_kernel();
- free_page(data_page);
- }
+ if (retval < 0)
+ goto out3;
+
+ lock_kernel();
+ retval = do_mount((char*)dev_page, dir_page, (char*)type_page,
+ flags, (void*)data_page);
+ unlock_kernel();
+ free_page(data_page);
+
+out3:
X free_page(dev_page);
X out2:
X putname(dir_page);
diff -u --recursive --new-file v2.4.0-test8/linux/fs/udf/ialloc.c linux/fs/udf/ialloc.c
--- v2.4.0-test8/linux/fs/udf/ialloc.c Tue Sep 5 14:07:30 2000
+++ linux/fs/udf/ialloc.c Wed Sep 27 13:43:56 2000
@@ -119,10 +119,7 @@


X inode->i_nlink = 1;

X inode->i_dev = sb->s_dev;
X inode->i_uid = current->fsuid;
- if (test_opt (sb, GRPID))
- inode->i_gid = dir->i_gid;
- else if (dir->i_mode & S_ISGID)
- {
+ if (dir->i_mode & S_ISGID) {
X inode->i_gid = dir->i_gid;
X if (S_ISDIR(mode))
X mode |= S_ISGID;
diff -u --recursive --new-file v2.4.0-test8/linux/fs/ufs/ialloc.c linux/fs/ufs/ialloc.c
--- v2.4.0-test8/linux/fs/ufs/ialloc.c Tue Sep 5 14:07:30 2000
+++ linux/fs/ufs/ialloc.c Tue Sep 19 08:01:35 2000
@@ -265,9 +265,7 @@


X inode->i_nlink = 1;

X inode->i_dev = sb->s_dev;
X inode->i_uid = current->fsuid;
- if (test_opt (sb, GRPID))
- inode->i_gid = dir->i_gid;
- else if (dir->i_mode & S_ISGID) {
+ if (dir->i_mode & S_ISGID) {
X inode->i_gid = dir->i_gid;
X if (S_ISDIR(mode))
X mode |= S_ISGID;
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-alpha/atomic.h linux/include/asm-alpha/atomic.h
--- v2.4.0-test8/linux/include/asm-alpha/atomic.h Mon May 8 22:00:01 2000
+++ linux/include/asm-alpha/atomic.h Sun Sep 24 12:12:33 2000
@@ -1,8 +1,6 @@
X #ifndef _ALPHA_ATOMIC_H
X #define _ALPHA_ATOMIC_H
X
-#include <linux/config.h>
-
X /*
X * Atomic operations that C can't guarantee us. Useful for
X * resource counting etc...
@@ -11,11 +9,13 @@
X * than regular operations.
X */
X
-#ifdef CONFIG_SMP
+
+/*
+ * Counter is volatile to make sure gcc doesn't try to be clever
+ * and move things around on us. We need to use _exactly_ the address
+ * the user gave us, not some alias that contains the same information.
+ */
X typedef struct { volatile int counter; } atomic_t;
-#else
-typedef struct { int counter; } atomic_t;
-#endif
X
X #define ATOMIC_INIT(i) ( (atomic_t) { (i) } )
X
@@ -23,19 +23,12 @@
X #define atomic_set(v,i) ((v)->counter = (i))
X
X /*
- * Make sure gcc doesn't try to be clever and move things around
- * on us. We need to use _exactly_ the address the user gave us,
- * not some alias that contains the same information.
- */
-#define __atomic_fool_gcc(x) (*(struct { int a[100]; } *)x)
-
-/*
X * To get proper branch prediction for the main line, we must branch
X * forward to code at the end of this object's .text section, then
X * branch back to restart the operation.
X */
X
-extern __inline__ void atomic_add(int i, atomic_t * v)
+static __inline__ void atomic_add(int i, atomic_t * v)
X {
X unsigned long temp;
X __asm__ __volatile__(
@@ -46,11 +39,11 @@
X ".subsection 2\n"
X "2: br 1b\n"
X ".previous"
- :"=&r" (temp), "=m" (__atomic_fool_gcc(v))
- :"Ir" (i), "m" (__atomic_fool_gcc(v)));
+ :"=&r" (temp), "=m" (v->counter)
+ :"Ir" (i), "m" (v->counter));
X }
X
-extern __inline__ void atomic_sub(int i, atomic_t * v)
+static __inline__ void atomic_sub(int i, atomic_t * v)
X {
X unsigned long temp;
X __asm__ __volatile__(
@@ -61,14 +54,14 @@
X ".subsection 2\n"
X "2: br 1b\n"
X ".previous"
- :"=&r" (temp), "=m" (__atomic_fool_gcc(v))
- :"Ir" (i), "m" (__atomic_fool_gcc(v)));
+ :"=&r" (temp), "=m" (v->counter)
+ :"Ir" (i), "m" (v->counter));
X }
X
X /*
X * Same as above, but return the result value
X */
-extern __inline__ long atomic_add_return(int i, atomic_t * v)
+static __inline__ long atomic_add_return(int i, atomic_t * v)
X {
X long temp, result;
X __asm__ __volatile__(
@@ -81,12 +74,12 @@
X ".subsection 2\n"
X "2: br 1b\n"
X ".previous"
- :"=&r" (temp), "=m" (__atomic_fool_gcc(v)), "=&r" (result)
- :"Ir" (i), "m" (__atomic_fool_gcc(v)));
+ :"=&r" (temp), "=m" (v->counter), "=&r" (result)
+ :"Ir" (i), "m" (v->counter) : "memory");


X return result;
X }
X

-extern __inline__ long atomic_sub_return(int i, atomic_t * v)
+static __inline__ long atomic_sub_return(int i, atomic_t * v)
X {
X long temp, result;
X __asm__ __volatile__(
@@ -99,8 +92,8 @@
X ".subsection 2\n"
X "2: br 1b\n"
X ".previous"
- :"=&r" (temp), "=m" (__atomic_fool_gcc(v)), "=&r" (result)
- :"Ir" (i), "m" (__atomic_fool_gcc(v)));
+ :"=&r" (temp), "=m" (v->counter), "=&r" (result)
+ :"Ir" (i), "m" (v->counter) : "memory");
X return result;
X }
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-alpha/bitops.h linux/include/asm-alpha/bitops.h
--- v2.4.0-test8/linux/include/asm-alpha/bitops.h Mon Aug 28 21:21:57 2000
+++ linux/include/asm-alpha/bitops.h Tue Oct 3 09:24:41 2000
@@ -1,6 +1,9 @@
X #ifndef _ALPHA_BITOPS_H
X #define _ALPHA_BITOPS_H
X
+#include <linux/config.h>
+#include <linux/kernel.h>
+
X /*
X * Copyright 1994, Linus Torvalds.
X */
@@ -17,14 +20,19 @@
X * bit 0 is the LSB of addr; bit 64 is the LSB of (addr+1).
X */
X
+#define BITOPS_NO_BRANCH
+
X extern __inline__ void set_bit(unsigned long nr, volatile void * addr)
X {
+#ifndef BITOPS_NO_BRANCH
X unsigned long oldbit;
+#endif
X unsigned long temp;
X unsigned int * m = ((unsigned int *) addr) + (nr >> 5);
X
+#ifndef BITOPS_NO_BRANCH
X __asm__ __volatile__(
- "1: ldl_l %0,%1\n"
+ "1: ldl_l %0,%4\n"
X " and %0,%3,%2\n"
X " bne %2,2f\n"
X " xor %0,%3,%0\n"
@@ -36,16 +44,57 @@
X ".previous"
X :"=&r" (temp), "=m" (*m), "=&r" (oldbit)
X :"Ir" (1UL << (nr & 31)), "m" (*m));
+#else
+ __asm__ __volatile__(
+ "1: ldl_l %0,%3\n"
+ " bis %0,%2,%0\n"
+ " stl_c %0,%1\n"
+ " beq %0,2f\n"
+ ".subsection 2\n"
+ "2: br 1b\n"
+ ".previous"
+ :"=&r" (temp), "=m" (*m)
+ :"Ir" (1UL << (nr & 31)), "m" (*m));
+#endif
X }
X
+/*
+ * WARNING: non atomic version.
+ */
+extern __inline__ void __set_bit(unsigned long nr, volatile void * addr)
+{
+ unsigned int * m = ((unsigned int *) addr) + (nr >> 5);
+ /*
+ * Asm and C produces the same thing so let
+ * the compiler to do its good work.
+ */
+#if 0
+ int tmp;
+
+ __asm__ __volatile__(
+ "ldl %0,%3\n\t"
+ "bis %0,%2,%0\n\t"
+ "stl %0,%1"
+ : "=&r" (tmp), "=m" (*m)
+ : "Ir" (1UL << (nr & 31)), "m" (*m));
+#else
+ *m |= 1UL << (nr & 31);
+#endif
+}
+
+#define smp_mb__before_clear_bit() smp_mb()
+#define smp_mb__after_clear_bit() smp_mb()
X extern __inline__ void clear_bit(unsigned long nr, volatile void * addr)
X {
+#ifndef BITOPS_NO_BRANCH
X unsigned long oldbit;
+#endif
X unsigned long temp;
X unsigned int * m = ((unsigned int *) addr) + (nr >> 5);
X
+#ifndef BITOPS_NO_BRANCH
X __asm__ __volatile__(
- "1: ldl_l %0,%1\n"
+ "1: ldl_l %0,%4\n"
X " and %0,%3,%2\n"
X " beq %2,2f\n"
X " xor %0,%3,%0\n"
@@ -57,6 +106,18 @@
X ".previous"
X :"=&r" (temp), "=m" (*m), "=&r" (oldbit)
X :"Ir" (1UL << (nr & 31)), "m" (*m));
+#else
+ __asm__ __volatile__(
+ "1: ldl_l %0,%3\n"
+ " and %0,%2,%0\n"
+ " stl_c %0,%1\n"
+ " beq %0,2f\n"
+ ".subsection 2\n"
+ "2: br 1b\n"
+ ".previous"
+ :"=&r" (temp), "=m" (*m)
+ :"Ir" (~(1UL << (nr & 31))), "m" (*m));
+#endif
X }
X
X extern __inline__ void change_bit(unsigned long nr, volatile void * addr)
@@ -65,12 +126,12 @@
X unsigned int * m = ((unsigned int *) addr) + (nr >> 5);
X
X __asm__ __volatile__(
- "1: ldl_l %0,%1\n"
+ "1: ldl_l %0,%3\n"
X " xor %0,%2,%0\n"
X " stl_c %0,%1\n"
- " beq %0,3f\n"
+ " beq %0,2f\n"
X ".subsection 2\n"
- "3: br 1b\n"
+ "2: br 1b\n"
X ".previous"
X :"=&r" (temp), "=m" (*m)
X :"Ir" (1UL << (nr & 31)), "m" (*m));
@@ -84,18 +145,43 @@
X unsigned int * m = ((unsigned int *) addr) + (nr >> 5);
X
X __asm__ __volatile__(
- "1: ldl_l %0,%1\n"
+ "1: ldl_l %0,%4\n"
X " and %0,%3,%2\n"
X " bne %2,2f\n"
X " xor %0,%3,%0\n"
X " stl_c %0,%1\n"
X " beq %0,3f\n"
+#ifdef CONFIG_SMP
X " mb\n"
+#endif
X "2:\n"
X ".subsection 2\n"
X "3: br 1b\n"
X ".previous"
X :"=&r" (temp), "=m" (*m), "=&r" (oldbit)
+ :"Ir" (1UL << (nr & 31)), "m" (*m) : "memory");
+
+ return oldbit != 0;
+}
+
+/*
+ * WARNING: non atomic version.
+ */
+extern __inline__ int __test_and_set_bit(unsigned long nr,
+ volatile void * addr)
+{
+ unsigned long oldbit;
+ unsigned long temp;
+ unsigned int * m = ((unsigned int *) addr) + (nr >> 5);
+
+ __asm__ __volatile__(
+ " ldl %0,%4\n"
+ " and %0,%3,%2\n"
+ " bne %2,1f\n"
+ " xor %0,%3,%0\n"
+ " stl %0,%1\n"
+ "1:\n"
+ :"=&r" (temp), "=m" (*m), "=&r" (oldbit)
X :"Ir" (1UL << (nr & 31)), "m" (*m));
X
X return oldbit != 0;
@@ -109,18 +195,43 @@
X unsigned int * m = ((unsigned int *) addr) + (nr >> 5);
X
X __asm__ __volatile__(
- "1: ldl_l %0,%1\n"
+ "1: ldl_l %0,%4\n"
X " and %0,%3,%2\n"
X " beq %2,2f\n"
X " xor %0,%3,%0\n"
X " stl_c %0,%1\n"
X " beq %0,3f\n"
+#ifdef CONFIG_SMP
X " mb\n"
+#endif
X "2:\n"
X ".subsection 2\n"
X "3: br 1b\n"
X ".previous"
X :"=&r" (temp), "=m" (*m), "=&r" (oldbit)
+ :"Ir" (1UL << (nr & 31)), "m" (*m) : "memory");
+
+ return oldbit != 0;
+}
+
+/*
+ * WARNING: non atomic version.
+ */
+extern __inline__ int __test_and_clear_bit(unsigned long nr,
+ volatile void * addr)
+{
+ unsigned long oldbit;
+ unsigned long temp;
+ unsigned int * m = ((unsigned int *) addr) + (nr >> 5);
+
+ __asm__ __volatile__(
+ " ldl %0,%4\n"
+ " and %0,%3,%2\n"
+ " beq %2,1f\n"
+ " xor %0,%3,%0\n"
+ " stl %0,%1\n"
+ "1:\n"
+ :"=&r" (temp), "=m" (*m), "=&r" (oldbit)
X :"Ir" (1UL << (nr & 31)), "m" (*m));
X
X return oldbit != 0;
@@ -134,17 +245,19 @@
X unsigned int * m = ((unsigned int *) addr) + (nr >> 5);
X
X __asm__ __volatile__(
- "1: ldl_l %0,%1\n"
+ "1: ldl_l %0,%4\n"
X " and %0,%3,%2\n"
X " xor %0,%3,%0\n"
X " stl_c %0,%1\n"
X " beq %0,3f\n"
+#ifdef CONFIG_SMP
X " mb\n"
+#endif
X ".subsection 2\n"
X "3: br 1b\n"
X ".previous"
X :"=&r" (temp), "=m" (*m), "=&r" (oldbit)
- :"Ir" (1UL << (nr & 31)), "m" (*m));
+ :"Ir" (1UL << (nr & 31)), "m" (*m) : "memory");
X
X return oldbit != 0;
X }
@@ -279,16 +392,16 @@
X
X #ifdef __KERNEL__
X
-#define ext2_set_bit test_and_set_bit
-#define ext2_clear_bit test_and_clear_bit
+#define ext2_set_bit __test_and_set_bit
+#define ext2_clear_bit __test_and_clear_bit
X #define ext2_test_bit test_bit
X #define ext2_find_first_zero_bit find_first_zero_bit
X #define ext2_find_next_zero_bit find_next_zero_bit
X
X /* Bitmap functions for the minix filesystem. */
-#define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
-#define minix_set_bit(nr,addr) set_bit(nr,addr)
-#define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
+#define minix_test_and_set_bit(nr,addr) __test_and_set_bit(nr,addr)
+#define minix_set_bit(nr,addr) __set_bit(nr,addr)
+#define minix_test_and_clear_bit(nr,addr) __test_and_clear_bit(nr,addr)
X #define minix_test_bit(nr,addr) test_bit(nr,addr)
X #define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-alpha/elf.h linux/include/asm-alpha/elf.h
--- v2.4.0-test8/linux/include/asm-alpha/elf.h Tue Jul 11 15:43:45 2000
+++ linux/include/asm-alpha/elf.h Fri Sep 22 14:07:43 2000


@@ -127,7 +127,7 @@
X

X #ifdef __KERNEL__
X #define SET_PERSONALITY(EX, IBCS2) \
- set_personality((EX).e_flags & EF_ALPHA_32BIT \
+ set_personality(((EX).e_flags & EF_ALPHA_32BIT) \
X ? PER_LINUX_32BIT : (IBCS2) ? PER_SVR4 : PER_LINUX)
X #endif
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-alpha/fcntl.h linux/include/asm-alpha/fcntl.h
--- v2.4.0-test8/linux/include/asm-alpha/fcntl.h Fri Aug 11 14:37:49 2000
+++ linux/include/asm-alpha/fcntl.h Wed Sep 27 13:39:23 2000
@@ -48,13 +48,19 @@
X #define F_EXLCK 16 /* or 3 */
X #define F_SHLCK 32 /* or 4 */
X
+#define F_INPROGRESS 16
+
X /* operations for bsd flock(), also used by the kernel implementation */
X #define LOCK_SH 1 /* shared lock */
X #define LOCK_EX 2 /* exclusive lock */
X #define LOCK_NB 4 /* or'd with one of the above to prevent
X blocking */
X #define LOCK_UN 8 /* remove lock */
-
+#define LOCK_MAND 32 /* This is a mandatory flock */
+#define LOCK_READ 64 /* ... Which allows concurrent read operations */
+#define LOCK_WRITE 128 /* ... Which allows concurrent write operations */
+#define LOCK_RW 192 /* ... Which allows concurrent read & write ops */
+
X struct flock {
X short l_type;
X short l_whence;
@@ -66,5 +72,6 @@
X #ifdef __KERNEL__
X #define flock64 flock
X #endif
+#define F_LINUX_SPECIFIC_BASE 1024
X
X #endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-alpha/resource.h linux/include/asm-alpha/resource.h
--- v2.4.0-test8/linux/include/asm-alpha/resource.h Thu Feb 17 09:35:07 2000
+++ linux/include/asm-alpha/resource.h Wed Sep 27 13:39:23 2000
@@ -15,8 +15,9 @@
X #define RLIMIT_AS 7 /* address space limit(?) */
X #define RLIMIT_NPROC 8 /* max number of processes */
X #define RLIMIT_MEMLOCK 9 /* max locked-in-memory address space */
+#define RLIMIT_LOCKS 10 /* maximum file locks held */
X
-#define RLIM_NLIMITS 10
+#define RLIM_NLIMITS 11
X
X /*
X * SuS says limits have to be unsigned. Fine, it's unsigned, but
@@ -39,6 +40,7 @@
X {LONG_MAX, LONG_MAX}, /* RLIMIT_AS */ \
X {LONG_MAX, LONG_MAX}, /* RLIMIT_NPROC */ \
X {LONG_MAX, LONG_MAX}, /* RLIMIT_MEMLOCK */ \
+ {LONG_MAX, LONG_MAX}, /* RLIMIT_LOCKS */ \
X }
X
X #endif /* __KERNEL__ */
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-alpha/semaphore-helper.h linux/include/asm-alpha/semaphore-helper.h
--- v2.4.0-test8/linux/include/asm-alpha/semaphore-helper.h Thu Feb 24 22:36:05 2000
+++ linux/include/asm-alpha/semaphore-helper.h Fri Sep 22 14:07:43 2000
@@ -37,7 +37,7 @@
X ".subsection 2\n"
X "3: br 1b\n"
X ".previous"
- : "=r"(ret), "=r"(tmp), "=m"(__atomic_fool_gcc(&sem->waking))
+ : "=r"(ret), "=r"(tmp), "=m"(sem->waking.counter)
X : "0"(0));
X
X return ret > 0;
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-alpha/spinlock.h linux/include/asm-alpha/spinlock.h
--- v2.4.0-test8/linux/include/asm-alpha/spinlock.h Thu Feb 24 22:36:05 2000
+++ linux/include/asm-alpha/spinlock.h Fri Sep 22 14:07:43 2000
@@ -5,8 +5,8 @@
X #include <linux/kernel.h>
X #include <asm/current.h>
X
-#define DEBUG_SPINLOCK 1
-#define DEBUG_RWLOCK 1
+#define DEBUG_SPINLOCK 0
+#define DEBUG_RWLOCK 0
X
X /*
X * Simple spin lock operations. There are two variants, one clears IRQ's
@@ -38,9 +38,6 @@
X #define spin_is_locked(x) ((x)->lock != 0)
X #define spin_unlock_wait(x) ({ do { barrier(); } while ((x)->lock); })
X
-typedef struct { unsigned long a[100]; } __dummy_lock_t;
-#define __dummy_lock(lock) (*(__dummy_lock_t *)(lock))
-
X #if DEBUG_SPINLOCK
X extern void spin_unlock(spinlock_t * lock);
X extern void debug_spin_lock(spinlock_t * lock, const char *, int);
@@ -83,8 +80,8 @@
X " blbs %0,2b\n"
X " br 1b\n"
X ".previous"
- : "=r" (tmp), "=m" (__dummy_lock(lock))
- : "m"(__dummy_lock(lock)));
+ : "=r" (tmp), "=m" (lock->lock)
+ : "m"(lock->lock) : "memory");
X }
X
X #define spin_trylock(lock) (!test_and_set_bit(0,(lock)))
@@ -119,9 +116,8 @@
X " bne %1,6b\n"
X " br 1b\n"
X ".previous"
- : "=m" (__dummy_lock(lock)), "=&r" (regx)
- : "0" (__dummy_lock(lock))
- );
+ : "=m" (*(volatile int *)lock), "=&r" (regx)
+ : "0" (*(volatile int *)lock) : "memory");
X }
X
X static inline void read_lock(rwlock_t * lock)
@@ -140,9 +136,8 @@
X " blbs %1,6b\n"
X " br 1b\n"
X ".previous"
- : "=m" (__dummy_lock(lock)), "=&r" (regx)
- : "m" (__dummy_lock(lock))
- );
+ : "=m" (*(volatile int *)lock), "=&r" (regx)
+ : "m" (*(volatile int *)lock) : "memory");
X }
X #endif /* DEBUG_RWLOCK */
X

@@ -156,6 +151,7 @@
X {

X long regx;
X __asm__ __volatile__(
+ " mb\n"
X "1: ldl_l %1,%0\n"
X " addl %1,2,%1\n"
X " stl_c %1,%0\n"
@@ -163,8 +159,8 @@
X ".subsection 2\n"
X "6: br 1b\n"
X ".previous"
- : "=m" (__dummy_lock(lock)), "=&r" (regx)
- : "m" (__dummy_lock(lock)));
+ : "=m" (*(volatile int *)lock), "=&r" (regx)
+ : "m" (*(volatile int *)lock) : "memory");
X }
X
X #endif /* _ALPHA_SPINLOCK_H */
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-alpha/system.h linux/include/asm-alpha/system.h
--- v2.4.0-test8/linux/include/asm-alpha/system.h Mon Jun 26 11:26:56 2000
+++ linux/include/asm-alpha/system.h Sun Sep 24 12:12:33 2000
@@ -137,12 +137,19 @@
X #define wmb() \
X __asm__ __volatile__("wmb": : :"memory")
X
+#ifdef CONFIG_SMP
+#define smp_mb() mb()
+#define smp_rmb() rmb()
+#define smp_wmb() wmb()
+#else
+#define smp_mb() barrier()
+#define smp_rmb() barrier()
+#define smp_wmb() barrier()
+#endif
+
X #define set_mb(var, value) \
X do { var = value; mb(); } while (0)
X
-#define set_rmb(var, value) \
-do { var = value; rmb(); } while (0)
-
X #define set_wmb(var, value) \
X do { var = value; wmb(); } while (0)
X
@@ -284,11 +291,11 @@
X #define getipl() (rdps() & 7)
X #define setipl(ipl) ((void) swpipl(ipl))
X
-#define __cli() setipl(IPL_MAX)
-#define __sti() setipl(IPL_MIN)
+#define __cli() do { setipl(IPL_MAX); barrier(); } while(0)
+#define __sti() do { barrier(); setipl(IPL_MIN); } while(0)
X #define __save_flags(flags) ((flags) = rdps())
-#define __save_and_cli(flags) ((flags) = swpipl(IPL_MAX))
-#define __restore_flags(flags) setipl(flags)
+#define __save_and_cli(flags) do { (flags) = swpipl(IPL_MAX); barrier(); } while(0)
+#define __restore_flags(flags) do { barrier(); setipl(flags); barrier(); } while(0)
X
X #define local_irq_save(flags) __save_and_cli(flags)
X #define local_irq_restore(flags) __restore_flags(flags)
@@ -344,6 +351,8 @@
X
X /*
X * Atomic exchange.
+ * Since it can be used to implement critical sections
+ * it must clobber "memory" (also for interrupts in UP).
X */
X
X extern __inline__ unsigned long
@@ -352,16 +361,18 @@
X unsigned long dummy;
X
X __asm__ __volatile__(
- "1: ldl_l %0,%2\n"
+ "1: ldl_l %0,%4\n"
X " bis $31,%3,%1\n"
X " stl_c %1,%2\n"
X " beq %1,2f\n"
+#ifdef CONFIG_SMP
X " mb\n"
+#endif
X ".subsection 2\n"
X "2: br 1b\n"
X ".previous"
X : "=&r" (val), "=&r" (dummy), "=m" (*m)
- : "rI" (val), "m" (*m));
+ : "rI" (val), "m" (*m) : "memory");
X
X return val;
X }
@@ -372,16 +383,18 @@
X unsigned long dummy;
X
X __asm__ __volatile__(
- "1: ldq_l %0,%2\n"
+ "1: ldq_l %0,%4\n"
X " bis $31,%3,%1\n"
X " stq_c %1,%2\n"
X " beq %1,2f\n"
+#ifdef CONFIG_SMP
X " mb\n"
+#endif
X ".subsection 2\n"
X "2: br 1b\n"
X ".previous"
X : "=&r" (val), "=&r" (dummy), "=m" (*m)
- : "rI" (val), "m" (*m));
+ : "rI" (val), "m" (*m) : "memory");
X
X return val;
X }
@@ -416,6 +429,11 @@
X * Atomic compare and exchange. Compare OLD with MEM, if identical,
X * store NEW in MEM. Return the initial value in MEM. Success is
X * indicated by comparing RETURN with OLD.
+ *
+ * The memory barrier should be placed in SMP only when we actually
+ * make the change. If we don't change anything (so if the returned
+ * prev is equal to old) then we aren't acquiring anything new and
+ * we don't need any memory barrier as far I can tell.
X */
X
X #define __HAVE_ARCH_CMPXCHG 1
@@ -426,18 +444,21 @@
X unsigned long prev, cmp;
X
X __asm__ __volatile__(
- "1: ldl_l %0,%2\n"
+ "1: ldl_l %0,%5\n"
X " cmpeq %0,%3,%1\n"
X " beq %1,2f\n"
X " mov %4,%1\n"
X " stl_c %1,%2\n"
X " beq %1,3f\n"
- "2: mb\n"
+#ifdef CONFIG_SMP
+ " mb\n"
+#endif
+ "2:\n"
X ".subsection 2\n"
X "3: br 1b\n"
X ".previous"
X : "=&r"(prev), "=&r"(cmp), "=m"(*m)
- : "r"((long) old), "r"(new), "m"(*m));
+ : "r"((long) old), "r"(new), "m"(*m) : "memory");
X
X return prev;
X }
@@ -448,18 +469,21 @@
X unsigned long prev, cmp;
X
X __asm__ __volatile__(
- "1: ldq_l %0,%2\n"
+ "1: ldq_l %0,%5\n"
X " cmpeq %0,%3,%1\n"
X " beq %1,2f\n"
X " mov %4,%1\n"
X " stq_c %1,%2\n"
X " beq %1,3f\n"
- "2: mb\n"
+#ifdef CONFIG_SMP
+ " mb\n"
+#endif
+ "2:\n"
X ".subsection 2\n"
X "3: br 1b\n"
X ".previous"
X : "=&r"(prev), "=&r"(cmp), "=m"(*m)
- : "r"((long) old), "r"(new), "m"(*m));
+ : "r"((long) old), "r"(new), "m"(*m) : "memory");
X
X return prev;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-alpha/termios.h linux/include/asm-alpha/termios.h
--- v2.4.0-test8/linux/include/asm-alpha/termios.h Wed Oct 27 17:04:51 1999
+++ linux/include/asm-alpha/termios.h Fri Sep 22 14:21:17 2000
@@ -71,6 +71,7 @@
X #define N_SLIP 1
X #define N_MOUSE 2
X #define N_PPP 3
+#define N_STRIP 4
X #define N_AX25 5
X #define N_X25 6 /* X.25 async */
X #define N_6PACK 7
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-arc/dma.h linux/include/asm-arm/arch-arc/dma.h
--- v2.4.0-test8/linux/include/asm-arm/arch-arc/dma.h Tue Jul 18 22:43:24 2000
+++ linux/include/asm-arm/arch-arc/dma.h Mon Sep 18 15:15:22 2000
@@ -1,13 +1,17 @@
X /*
- * linux/include/asm-arm/arch-arc/dma.h
+ * linux/include/asm-arm/arch-arc/dma.h
X *
- * Copyright (C) 1996-1998 Russell King
+ * Copyright (C) 1996-1998 Russell King
X *
- * Acorn Archimedes/A5000 architecture virtual DMA
- * implementation


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

X *
- * Modifications:

- * 04-04-1998 RMK Merged arc and a5k versions
+ * Acorn Archimedes/A5000 architecture virtual DMA
+ * implementation


+ *
+ * Modifications:

+ * 04-04-1998 RMK Merged arc and a5k versions


X */
X #ifndef __ASM_ARCH_DMA_H
X #define __ASM_ARCH_DMA_H

diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-arc/hardware.h linux/include/asm-arm/arch-arc/hardware.h
--- v2.4.0-test8/linux/include/asm-arm/arch-arc/hardware.h Sun Aug 13 09:54:15 2000
+++ linux/include/asm-arm/arch-arc/hardware.h Mon Sep 18 15:15:22 2000
@@ -1,13 +1,17 @@
X /*
- * linux/include/asm-arm/arch-arc/hardware.h
+ * linux/include/asm-arm/arch-arc/hardware.h
X *
- * Copyright (C) 1996-1999 Russell King.
+ * Copyright (C) 1996-1999 Russell King.
X *
- * This file contains the hardware definitions of the
- * Acorn Archimedes/A5000 machines.


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

X *
- * Modifications:

- * 04-04-1998 PJB/RMK Merged arc and a5k versions


+ * This file contains the hardware definitions of the

+ * Acorn Archimedes/A5000 machines.


+ *
+ * Modifications:

+ * 04-04-1998 PJB/RMK Merged arc and a5k versions


X */
X #ifndef __ASM_ARCH_HARDWARE_H
X #define __ASM_ARCH_HARDWARE_H

@@ -22,7 +26,7 @@
X */
X #define HAS_IOC
X #define HAS_MEMC
-#include <asm/memc.h>
+#include <asm/hardware/memc.h>
X #define HAS_VIDC
X
X /* Hardware addresses of major areas.
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-arc/ide.h linux/include/asm-arm/arch-arc/ide.h
--- v2.4.0-test8/linux/include/asm-arm/arch-arc/ide.h Sun Aug 13 09:54:15 2000
+++ linux/include/asm-arm/arch-arc/ide.h Mon Sep 18 15:15:22 2000
@@ -1,15 +1,19 @@
X /*
- * linux/include/asm-arm/arch-arc/ide.h
+ * linux/include/asm-arm/arch-arc/ide.h
X *
- * Copyright (c) 1997,1998 Russell King
+ * Copyright (C) 1997,1998 Russell King
X *
- * IDE definitions for the Acorn Archimedes/A5000
- * architecture


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

X *
- * Modifications:

- * 04-04-1998 PJB Merged `arc' and `a5k' versions
- * 01-07-1998 RMK Added new ide_ioregspec_t


- * 29-07-1998 RMK Major re-work of IDE architecture specific code

+ * IDE definitions for the Acorn Archimedes/A5000
+ * architecture


+ *
+ * Modifications:

+ * 04-04-1998 PJB Merged `arc' and `a5k' versions
+ * 01-07-1998 RMK Added new ide_ioregspec_t


+ * 29-07-1998 RMK Major re-work of IDE architecture specific code
X */
X #include <asm/irq.h>

X #include <asm/mach-types.h>
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-arc/io.h linux/include/asm-arm/arch-arc/io.h
--- v2.4.0-test8/linux/include/asm-arm/arch-arc/io.h Thu Feb 24 22:44:47 2000
+++ linux/include/asm-arm/arch-arc/io.h Mon Sep 18 15:15:22 2000
@@ -1,10 +1,14 @@
X /*
- * linux/include/asm-arm/arch-arc/io.h
+ * linux/include/asm-arm/arch-arc/io.h
X *


- * Copyright (C) 1997 Russell King
+ * Copyright (C) 1997 Russell King

X *
- * Modifications:

- * 06-Dec-1997 RMK Created.


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Modifications:
+ * 06-Dec-1997 RMK Created.
X */


X #ifndef __ASM_ARM_ARCH_IO_H
X #define __ASM_ARM_ARCH_IO_H

diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-arc/irq.h linux/include/asm-arm/arch-arc/irq.h
--- v2.4.0-test8/linux/include/asm-arm/arch-arc/irq.h Sun Sep 3 11:19:11 2000
+++ linux/include/asm-arm/arch-arc/irq.h Mon Sep 18 15:15:22 2000
@@ -1,9 +1,13 @@
X /*
- * include/asm-arm/arch-arc/irq.h
+ * linux/include/asm-arm/arch-arc/irq.h
X *


- * Copyright (C) 1996 Russell King
+ * Copyright (C) 1996 Russell King
X *
- * Changelog:

+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Changelog:
X * 24-09-1996 RMK Created


X * 10-10-1996 RMK Brought up to date with arch-sa110eval

X * 22-10-1996 RMK Changed interrupt numbers & uses new inb/outb macros
@@ -11,7 +15,7 @@


X * 22-08-1998 RMK Restructured IRQ routines

X */
X #include <linux/config.h>

-#include <asm/ioc.h>
+#include <asm/hardware/ioc.h>
X
X #ifdef CONFIG_ARCH_ARC
X #define a_clf() clf()
@@ -168,7 +172,7 @@
X }
X }
X
- irq_mask[IRQ_KEYBOARDTX].noautoenable = 1;
+ irq_desc[IRQ_KEYBOARDTX].noautoenable = 1;
X
X init_FIQ();
X }
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-arc/irqs.h linux/include/asm-arm/arch-arc/irqs.h
--- v2.4.0-test8/linux/include/asm-arm/arch-arc/irqs.h Fri May 8 00:42:39 1998
+++ linux/include/asm-arm/arch-arc/irqs.h Mon Sep 18 15:15:22 2000
@@ -1,10 +1,14 @@
X /*
- * linux/include/asm-arm/arch-arc/irqs.h
+ * linux/include/asm-arm/arch-arc/irqs.h
X *
- * Copyright (C) 1996 Russell King, Dave Gilbert
+ * Copyright (C) 1996 Russell King, Dave Gilbert


X *
- * Modifications:

- * 04-04-1998 PJB Merged arc and a5k versions


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Modifications:
+ * 04-04-1998 PJB Merged arc and a5k versions
X */
X
X #include <linux/config.h>
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-arc/keyboard.h linux/include/asm-arm/arch-arc/keyboard.h
--- v2.4.0-test8/linux/include/asm-arm/arch-arc/keyboard.h Sat May 8 11:06:57 1999
+++ linux/include/asm-arm/arch-arc/keyboard.h Mon Sep 18 15:15:22 2000
@@ -1,10 +1,14 @@
X /*
- * linux/include/asm-arm/arch-arc/keyboard.h
+ * linux/include/asm-arm/arch-arc/keyboard.h
X *
- * Keyboard driver definitions for Acorn Archimedes/A5000
- * architecture


+ * Copyright (C) 1998 Russell King

X *
- * Copyright (C) 1998 Russell King


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Keyboard driver definitions for Acorn Archimedes/A5000
+ * architecture
X */
X
X #include <asm/irq.h>
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-arc/memory.h linux/include/asm-arm/arch-arc/memory.h
--- v2.4.0-test8/linux/include/asm-arm/arch-arc/memory.h Thu Oct 28 10:16:02 1999
+++ linux/include/asm-arm/arch-arc/memory.h Mon Sep 18 15:15:22 2000
@@ -1,7 +1,11 @@
X /*
- * linux/include/asm-arm/arch-arc/memory.h
+ * linux/include/asm-arm/arch-arc/memory.h
X *
- * Copyright (c) 1996-1999 Russell King.
+ * Copyright (C) 1996-1999 Russell King.
+ *


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

X *
X * Changelog:
X * 22-Nov-1996 RMK Created
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-arc/oldlatches.h linux/include/asm-arm/arch-arc/oldlatches.h
--- v2.4.0-test8/linux/include/asm-arm/arch-arc/oldlatches.h Tue Jul 18 22:43:24 2000
+++ linux/include/asm-arm/arch-arc/oldlatches.h Mon Sep 18 15:15:22 2000
@@ -1,12 +1,14 @@
X /*
- * linux/include/asm-arm/arch-arc/oldlatches.h
+ * linux/include/asm-arm/arch-arc/oldlatches.h
X *
- * Copyright (C) 1996 Russell King, Dave Gilbert
+ * Copyright (C) 1996 Russell King, Dave Gilbert
X *
- * Dummy oldlatches.h


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

X *
- * Modifications:

- * 04-04-1998 PJB/RMK Merged arc and a5k versions
+ * Modifications:
+ * 04-04-1998 PJB/RMK Merged arc and a5k versions
X */
X #ifndef _ASM_ARCH_OLDLATCH_H
X #define _ASM_ARCH_OLDLATCH_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-arc/processor.h linux/include/asm-arm/arch-arc/processor.h
--- v2.4.0-test8/linux/include/asm-arm/arch-arc/processor.h Wed Oct 20 16:29:08 1999
+++ linux/include/asm-arm/arch-arc/processor.h Mon Sep 18 15:15:22 2000
@@ -1,11 +1,15 @@
X /*
- * linux/include/asm-arm/arch-arc/processor.h
+ * linux/include/asm-arm/arch-arc/processor.h
X *
- * Copyright (c) 1996-1999 Russell King.
+ * Copyright (c) 1996-1999 Russell King.
X *


- * Changelog:
- * 10-Sep-1996 RMK Created
- * 21-Mar-1999 RMK Added asm/arch/memory.h

+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Changelog:
+ * 10-Sep-1996 RMK Created
+ * 21-Mar-1999 RMK Added asm/arch/memory.h
X */
X
X #ifndef __ASM_ARCH_PROCESSOR_H

diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-arc/serial.h linux/include/asm-arm/arch-arc/serial.h
--- v2.4.0-test8/linux/include/asm-arm/arch-arc/serial.h Thu Jan 13 13:30:31 2000
+++ linux/include/asm-arm/arch-arc/serial.h Mon Sep 18 15:15:22 2000
@@ -1,11 +1,15 @@
X /*
- * linux/include/asm-arm/arch-arc/serial.h
+ * linux/include/asm-arm/arch-arc/serial.h
X *
- * Copyright (c) 1996 Russell King.
+ * Copyright (C) 1996 Russell King.
X *


- * Changelog:
- * 15-10-1996 RMK Created

- * 04-04-1998 PJB Merged `arc' and `a5k' architectures


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Changelog:
+ * 15-10-1996 RMK Created

+ * 04-04-1998 PJB Merged `arc' and `a5k' architectures


X */
X #ifndef __ASM_ARCH_SERIAL_H
X #define __ASM_ARCH_SERIAL_H

diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-arc/system.h linux/include/asm-arm/arch-arc/system.h
--- v2.4.0-test8/linux/include/asm-arm/arch-arc/system.h Mon Aug 14 13:09:07 2000
+++ linux/include/asm-arm/arch-arc/system.h Mon Sep 18 15:15:22 2000
@@ -1,7 +1,11 @@
X /*
- * linux/include/asm-arm/arch-arc/system.h
+ * linux/include/asm-arm/arch-arc/system.h
X *
- * Copyright (c) 1996-1999 Russell King and Dave Gilbert
+ * Copyright (C) 1996-1999 Russell King and Dave Gilbert
+ *


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

X */


X
X static void arch_idle(void)

diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-arc/time.h linux/include/asm-arm/arch-arc/time.h
--- v2.4.0-test8/linux/include/asm-arm/arch-arc/time.h Sun Feb 6 17:45:25 2000
+++ linux/include/asm-arm/arch-arc/time.h Mon Sep 18 15:15:22 2000
@@ -1,12 +1,16 @@
X /*
- * linux/include/asm-arm/arch-arc/time.h
+ * linux/include/asm-arm/arch-arc/time.h


X *
- * Copyright (c) 1996-2000 Russell King.

+ * Copyright (C) 1996-2000 Russell King.
X *


- * Changelog:
- * 24-Sep-1996 RMK Created
- * 10-Oct-1996 RMK Brought up to date with arch-sa110eval
- * 04-Dec-1997 RMK Updated for new arch/arm/time.c

+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Changelog:
+ * 24-Sep-1996 RMK Created
+ * 10-Oct-1996 RMK Brought up to date with arch-sa110eval
+ * 04-Dec-1997 RMK Updated for new arch/arm/time.c
X */
X extern void ioctime_init(void);

X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-arc/timex.h linux/include/asm-arm/arch-arc/timex.h
--- v2.4.0-test8/linux/include/asm-arm/arch-arc/timex.h Sun Apr 12 11:42:15 1998
+++ linux/include/asm-arm/arch-arc/timex.h Mon Sep 18 15:15:22 2000
@@ -1,9 +1,13 @@
X /*
- * linux/include/asm-arm/arch-arc/timex.h
+ * linux/include/asm-arm/arch-arc/timex.h
X *
- * Acorn Archimedes/A5000 architecture timex specifications


+ * Copyright (C) 1997, 1998 Russell King

X *
- * Copyright (C) 1997, 1998 Russell King


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Acorn Archimedes/A5000 architecture timex specifications
X */
X
X /*
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-arc/uncompress.h linux/include/asm-arm/arch-arc/uncompress.h
--- v2.4.0-test8/linux/include/asm-arm/arch-arc/uncompress.h Sat May 8 11:06:57 1999
+++ linux/include/asm-arm/arch-arc/uncompress.h Mon Sep 18 15:15:22 2000
@@ -1,7 +1,11 @@
X /*
- * linux/include/asm-arm/arch-arc/uncompress.h
+ * linux/include/asm-arm/arch-arc/uncompress.h
X *


- * Copyright (C) 1996 Russell King
+ * Copyright (C) 1996 Russell King
+ *

+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

X */
X #define VIDMEM ((char *)0x02000000)
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-cl7500/hardware.h linux/include/asm-arm/arch-cl7500/hardware.h
--- v2.4.0-test8/linux/include/asm-arm/arch-cl7500/hardware.h Sun Aug 13 09:54:15 2000
+++ linux/include/asm-arm/arch-cl7500/hardware.h Mon Sep 18 15:15:22 2000
@@ -11,7 +11,7 @@
X #define __ASM_ARCH_HARDWARE_H
X
X #include <asm/arch/memory.h>
-#include <asm/iomd.h>
+#include <asm/hardware/iomd.h>
X
X /*
X * What hardware must be present
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-cl7500/irq.h linux/include/asm-arm/arch-cl7500/irq.h
--- v2.4.0-test8/linux/include/asm-arm/arch-cl7500/irq.h Tue Nov 23 22:23:11 1999
+++ linux/include/asm-arm/arch-cl7500/irq.h Mon Sep 18 15:15:22 2000
@@ -9,7 +9,7 @@


X * 22-08-1998 RMK Restructured IRQ routines

X * 11-08-1999 PJB Created ARM7500 version, derived from RiscPC code


X */
-#include <asm/iomd.h>
+#include <asm/hardware/iomd.h>

X
X static inline int fixup_irq(unsigned int irq)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-cl7500/system.h linux/include/asm-arm/arch-cl7500/system.h
--- v2.4.0-test8/linux/include/asm-arm/arch-cl7500/system.h Tue Jul 18 22:43:25 2000
+++ linux/include/asm-arm/arch-cl7500/system.h Mon Sep 18 15:15:22 2000
@@ -6,7 +6,7 @@


X #ifndef __ASM_ARCH_SYSTEM_H
X #define __ASM_ARCH_SYSTEM_H
X

-#include <asm/iomd.h>
+#include <asm/hardware/iomd.h>
X

X static void arch_idle(void)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-ebsa110/dma.h linux/include/asm-arm/arch-ebsa110/dma.h
--- v2.4.0-test8/linux/include/asm-arm/arch-ebsa110/dma.h Tue Jul 18 22:43:25 2000
+++ linux/include/asm-arm/arch-ebsa110/dma.h Mon Sep 18 15:15:22 2000
@@ -1,9 +1,13 @@
X /*
- * linux/include/asm-arm/arch-ebsa110/dma.h
+ * linux/include/asm-arm/arch-ebsa110/dma.h
X *
- * Architecture DMA routes
+ * Copyright (C) 1997,1998 Russell King
X *
- * Copyright (C) 1997,1998 Russell King


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * EBSA110 DMA definitions


X */
X #ifndef __ASM_ARCH_DMA_H
X #define __ASM_ARCH_DMA_H

diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-ebsa110/hardware.h linux/include/asm-arm/arch-ebsa110/hardware.h
--- v2.4.0-test8/linux/include/asm-arm/arch-ebsa110/hardware.h Sun Aug 13 09:54:15 2000
+++ linux/include/asm-arm/arch-ebsa110/hardware.h Mon Sep 18 15:15:22 2000
@@ -1,7 +1,11 @@
X /*
- * linux/include/asm-arm/arch-ebsa110/hardware.h
+ * linux/include/asm-arm/arch-ebsa110/hardware.h
X *
- * Copyright (C) 1996-2000 Russell King.
+ * Copyright (C) 1996-2000 Russell King.
+ *


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

X *
X * This file contains the hardware definitions of the EBSA-110.
X */
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-ebsa110/io.h linux/include/asm-arm/arch-ebsa110/io.h
--- v2.4.0-test8/linux/include/asm-arm/arch-ebsa110/io.h Thu Feb 24 22:44:47 2000
+++ linux/include/asm-arm/arch-ebsa110/io.h Mon Sep 18 15:15:23 2000
@@ -1,7 +1,11 @@
X /*
- * linux/include/asm-arm/arch-ebsa110/io.h
+ * linux/include/asm-arm/arch-ebsa110/io.h
X *
- * Copyright (C) 1997,1998 Russell King
+ * Copyright (C) 1997,1998 Russell King
+ *


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

X *
X * Modifications:
X * 06-Dec-1997 RMK Created.

diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-ebsa110/irq.h linux/include/asm-arm/arch-ebsa110/irq.h
--- v2.4.0-test8/linux/include/asm-arm/arch-ebsa110/irq.h Sat May 8 11:06:57 1999
+++ linux/include/asm-arm/arch-ebsa110/irq.h Mon Sep 18 15:15:23 2000
@@ -1,9 +1,13 @@
X /*
- * include/asm-arm/arch-ebsa110/irq.h
+ * linux/include/asm-arm/arch-ebsa110/irq.h
X *
- * Copyright (C) 1996-1998 Russell King
+ * Copyright (C) 1996-1998 Russell King


X *
- * Changelog:

+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Changelog:


X * 22-08-1998 RMK Restructured IRQ routines
X */

X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-ebsa110/irqs.h linux/include/asm-arm/arch-ebsa110/irqs.h
--- v2.4.0-test8/linux/include/asm-arm/arch-ebsa110/irqs.h Sun Sep 6 10:45:30 1998
+++ linux/include/asm-arm/arch-ebsa110/irqs.h Mon Sep 18 15:15:23 2000
@@ -1,7 +1,11 @@
X /*
- * linux/include/asm-arm/arch-ebsa110/irqs.h
+ * linux/include/asm-arm/arch-ebsa110/irqs.h
X *


- * Copyright (C) 1996 Russell King
+ * Copyright (C) 1996 Russell King
+ *

+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

X */
X
X #define NR_IRQS 8
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-ebsa110/memory.h linux/include/asm-arm/arch-ebsa110/memory.h
--- v2.4.0-test8/linux/include/asm-arm/arch-ebsa110/memory.h Thu Oct 28 10:16:02 1999
+++ linux/include/asm-arm/arch-ebsa110/memory.h Mon Sep 18 15:15:23 2000
@@ -1,13 +1,17 @@
X /*
- * linux/include/asm-arm/arch-ebsa110/memory.h
+ * linux/include/asm-arm/arch-ebsa110/memory.h
X *
- * Copyright (c) 1996-1999 Russell King.
+ * Copyright (C) 1996-1999 Russell King.
X *


- * Changelog:
- * 20-Oct-1996 RMK Created
- * 31-Dec-1997 RMK Fixed definitions to reduce warnings

- * 21-Mar-1999 RMK Renamed to memory.h

- * RMK Moved TASK_SIZE and PAGE_OFFSET here


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Changelog:
+ * 20-Oct-1996 RMK Created
+ * 31-Dec-1997 RMK Fixed definitions to reduce warnings

+ * 21-Mar-1999 RMK Renamed to memory.h

+ * RMK Moved TASK_SIZE and PAGE_OFFSET here
X */
X #ifndef __ASM_ARCH_MEMORY_H
X #define __ASM_ARCH_MEMORY_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-ebsa110/processor.h linux/include/asm-arm/arch-ebsa110/processor.h
--- v2.4.0-test8/linux/include/asm-arm/arch-ebsa110/processor.h Wed Oct 20 16:29:08 1999
+++ linux/include/asm-arm/arch-ebsa110/processor.h Mon Sep 18 15:15:23 2000
@@ -1,10 +1,14 @@
X /*
- * linux/include/asm-arm/arch-ebsa110/processor.h
+ * linux/include/asm-arm/arch-ebsa110/processor.h
X *


- * Copyright (C) 1996-1999 Russell King
+ * Copyright (C) 1996-1999 Russell King

X *
- * Changelog:

- * 21-Mar-1999 RMK Added asm/arch/memory.h


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Changelog:


+ * 21-Mar-1999 RMK Added asm/arch/memory.h
X */
X
X #ifndef __ASM_ARCH_PROCESSOR_H

diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-ebsa110/serial.h linux/include/asm-arm/arch-ebsa110/serial.h
--- v2.4.0-test8/linux/include/asm-arm/arch-ebsa110/serial.h Tue Nov 23 22:23:11 1999
+++ linux/include/asm-arm/arch-ebsa110/serial.h Mon Sep 18 15:15:23 2000
@@ -1,10 +1,14 @@
X /*
- * linux/include/asm-arm/arch-ebsa110/serial.h
+ * linux/include/asm-arm/arch-ebsa110/serial.h
X *
- * Copyright (c) 1996,1997,1998 Russell King.
+ * Copyright (C) 1996,1997,1998 Russell King.
X *


- * Changelog:
- * 15-10-1996 RMK Created

+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Changelog:
+ * 15-10-1996 RMK Created
X */
X #ifndef __ASM_ARCH_SERIAL_H
X #define __ASM_ARCH_SERIAL_H

diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-ebsa110/system.h linux/include/asm-arm/arch-ebsa110/system.h
--- v2.4.0-test8/linux/include/asm-arm/arch-ebsa110/system.h Tue Jul 18 22:43:25 2000
+++ linux/include/asm-arm/arch-ebsa110/system.h Mon Sep 18 15:15:23 2000
@@ -1,14 +1,25 @@
X /*
- * linux/include/asm-arm/arch-ebsa110/system.h
+ * linux/include/asm-arm/arch-ebsa110/system.h
X *
- * Copyright (c) 1996-1999 Russell King.
+ * Copyright (C) 1996-2000 Russell King.
+ *


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

X */


X #ifndef __ASM_ARCH_SYSTEM_H
X #define __ASM_ARCH_SYSTEM_H

X
X /*
- * This machine must never stop it MCLK. However, if we are
- * idle for a long time, slow the processor clock to MCLK.
+ * EBSA110 idling methodology:
+ *
+ * We can not execute the "wait for interrupt" instruction since that
+ * will stop our MCLK signal (which provides the clock for the glue
+ * logic, and therefore the timer interrupt).
+ *
+ * Instead, we spin, waiting for either hlt_counter or need_resched
+ * to be set. If we have been spinning for 2cs, then we drop the
+ * core clock down to the memory clock.
X */
X static void arch_idle(void)
X {
@@ -19,7 +30,7 @@
X do {


X if (current->need_resched || hlt_counter)
X goto slow_out;

- } while (time_before(start_idle, jiffies + HZ/3));
+ } while (time_before(jiffies, start_idle + HZ/50));
X
X cpu_do_idle(IDLE_CLOCK_SLOW);

X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-ebsa110/time.h linux/include/asm-arm/arch-ebsa110/time.h
--- v2.4.0-test8/linux/include/asm-arm/arch-ebsa110/time.h Sun Sep 3 11:19:11 2000
+++ linux/include/asm-arm/arch-ebsa110/time.h Mon Sep 18 15:15:23 2000
@@ -1,7 +1,11 @@
X /*
- * linux/include/asm-arm/arch-ebsa110/time.h
+ * linux/include/asm-arm/arch-ebsa110/time.h
X *
- * Copyright (c) 1996,1997,1998 Russell King.
+ * Copyright (C) 1996,1997,1998 Russell King.
+ *


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

X *
X * No real time clock on the evalulation board!
X *
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-ebsa110/timex.h linux/include/asm-arm/arch-ebsa110/timex.h
--- v2.4.0-test8/linux/include/asm-arm/arch-ebsa110/timex.h Sun Sep 6 10:45:30 1998
+++ linux/include/asm-arm/arch-ebsa110/timex.h Mon Sep 18 15:15:23 2000
@@ -1,9 +1,13 @@
X /*
- * linux/include/asm-arm/arch-ebsa110/timex.h
+ * linux/include/asm-arm/arch-ebsa110/timex.h
X *
- * EBSA110 architecture timex specifications


+ * Copyright (C) 1997, 1998 Russell King

X *
- * Copyright (C) 1997, 1998 Russell King


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * EBSA110 architecture timex specifications
X */
X
X /*
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-ebsa110/uncompress.h linux/include/asm-arm/arch-ebsa110/uncompress.h
--- v2.4.0-test8/linux/include/asm-arm/arch-ebsa110/uncompress.h Sun Sep 6 10:45:30 1998
+++ linux/include/asm-arm/arch-ebsa110/uncompress.h Mon Sep 18 15:15:23 2000
@@ -1,7 +1,11 @@
X /*
- * linux/include/asm-arm/arch-ebsa110/uncompress.h
+ * linux/include/asm-arm/arch-ebsa110/uncompress.h
X *
- * Copyright (C) 1996,1997,1998 Russell King


+ * Copyright (C) 1996,1997,1998 Russell King
+ *

+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

X */
X
X /*
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-ebsa110/vmalloc.h linux/include/asm-arm/arch-ebsa110/vmalloc.h
--- v2.4.0-test8/linux/include/asm-arm/arch-ebsa110/vmalloc.h Mon Mar 27 10:46:29 2000
+++ linux/include/asm-arm/arch-ebsa110/vmalloc.h Mon Sep 18 15:15:23 2000
@@ -1,5 +1,11 @@
X /*
- * linux/include/asm-arm/arch-ebsa110/vmalloc.h
+ * linux/include/asm-arm/arch-ebsa110/vmalloc.h
+ *
+ * Copyright (C) 1998 Russell King
+ *


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

X */
X
X /*
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-ebsa285/dma.h linux/include/asm-arm/arch-ebsa285/dma.h
--- v2.4.0-test8/linux/include/asm-arm/arch-ebsa285/dma.h Sat May 8 11:06:57 1999
+++ linux/include/asm-arm/arch-ebsa285/dma.h Mon Sep 18 15:15:23 2000
@@ -1,10 +1,10 @@
X /*
- * linux/include/asm-arm/arch-ebsa285/dma.h
+ * linux/include/asm-arm/arch-ebsa285/dma.h
X *
- * Architecture DMA routines
+ * Architecture DMA routines
X *
- * Copyright (C) 1998,1999 Russell King
- * Copyright (C) 1998,1999 Philip Blundell
+ * Copyright (C) 1998,1999 Russell King
+ * Copyright (C) 1998,1999 Philip Blundell
X */


X #ifndef __ASM_ARCH_DMA_H
X #define __ASM_ARCH_DMA_H

diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-ebsa285/hardware.h linux/include/asm-arm/arch-ebsa285/hardware.h
--- v2.4.0-test8/linux/include/asm-arm/arch-ebsa285/hardware.h Sun Sep 3 11:19:11 2000
+++ linux/include/asm-arm/arch-ebsa285/hardware.h Mon Sep 18 15:15:23 2000
@@ -1,9 +1,13 @@
X /*
- * linux/include/asm-arm/arch-ebsa285/hardware.h
+ * linux/include/asm-arm/arch-ebsa285/hardware.h
X *
- * Copyright (C) 1998-1999 Russell King.
+ * Copyright (C) 1998-1999 Russell King.
X *
- * This file contains the hardware definitions of the EBSA-285.


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * This file contains the hardware definitions of the EBSA-285.


X */
X #ifndef __ASM_ARCH_HARDWARE_H
X #define __ASM_ARCH_HARDWARE_H

diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-ebsa285/ide.h linux/include/asm-arm/arch-ebsa285/ide.h
--- v2.4.0-test8/linux/include/asm-arm/arch-ebsa285/ide.h Mon Jun 26 12:04:42 2000
+++ linux/include/asm-arm/arch-ebsa285/ide.h Mon Sep 18 15:15:23 2000
@@ -1,10 +1,14 @@
X /*
- * linux/include/asm-arm/arch-ebsa285/ide.h
+ * linux/include/asm-arm/arch-ebsa285/ide.h
X *
- * Copyright (c) 1998 Russell King
+ * Copyright (C) 1998 Russell King


X *
- * Modifications:
- * 29-07-1998 RMK Major re-work of IDE architecture specific code

+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Modifications:
+ * 29-07-1998 RMK Major re-work of IDE architecture specific code
X */
X #include <asm/irq.h>

X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-ebsa285/io.h linux/include/asm-arm/arch-ebsa285/io.h
--- v2.4.0-test8/linux/include/asm-arm/arch-ebsa285/io.h Thu Feb 24 22:44:47 2000
+++ linux/include/asm-arm/arch-ebsa285/io.h Mon Sep 18 15:15:23 2000
@@ -1,11 +1,15 @@
X /*
- * linux/include/asm-arm/arch-ebsa285/io.h
+ * linux/include/asm-arm/arch-ebsa285/io.h
X *
- * Copyright (C) 1997-1999 Russell King
+ * Copyright (C) 1997-1999 Russell King


X *
- * Modifications:

- * 06-12-1997 RMK Created.
- * 07-04-1999 RMK Major cleanup


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Modifications:
+ * 06-12-1997 RMK Created.
+ * 07-04-1999 RMK Major cleanup
X */


X #ifndef __ASM_ARM_ARCH_IO_H
X #define __ASM_ARM_ARCH_IO_H

@@ -74,7 +78,7 @@
X #define outw(v,p) __arch_putw(v,__io_pci(p))
X #define outl(v,p) __arch_putl(v,__io_pci(p))


X
-#include <asm/dec21285.h>
+#include <asm/hardware/dec21285.h>

X
X /*
X * ioremap support - validate a PCI memory address,
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-ebsa285/irq.h linux/include/asm-arm/arch-ebsa285/irq.h
--- v2.4.0-test8/linux/include/asm-arm/arch-ebsa285/irq.h Sun Aug 13 09:54:15 2000
+++ linux/include/asm-arm/arch-ebsa285/irq.h Mon Sep 18 15:15:23 2000
@@ -1,17 +1,21 @@
X /*
- * include/asm-arm/arch-ebsa285/irq.h
+ * linux/include/asm-arm/arch-ebsa285/irq.h
X *
- * Copyright (C) 1996-1998 Russell King
+ * Copyright (C) 1996-1998 Russell King


X *
- * Changelog:

- * 22-Aug-1998 RMK Restructured IRQ routines
- * 03-Sep-1998 PJB Merged CATS support
- * 20-Jan-1998 RMK Started merge of EBSA286, CATS and NetWinder
- * 26-Jan-1999 PJB Don't use IACK on CATS
- * 16-Mar-1999 RMK Added autodetect of ISA PICs


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Changelog:
+ * 22-Aug-1998 RMK Restructured IRQ routines
+ * 03-Sep-1998 PJB Merged CATS support
+ * 20-Jan-1998 RMK Started merge of EBSA286, CATS and NetWinder
+ * 26-Jan-1999 PJB Don't use IACK on CATS
+ * 16-Mar-1999 RMK Added autodetect of ISA PICs
X */
X #include <asm/hardware.h>
-#include <asm/dec21285.h>
+#include <asm/hardware/dec21285.h>
X #include <asm/irq.h>
X #include <asm/mach-types.h>
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-ebsa285/memory.h linux/include/asm-arm/arch-ebsa285/memory.h
--- v2.4.0-test8/linux/include/asm-arm/arch-ebsa285/memory.h Sun Aug 13 09:54:15 2000
+++ linux/include/asm-arm/arch-ebsa285/memory.h Mon Sep 18 15:15:23 2000
@@ -1,14 +1,18 @@
X /*
- * linux/include/asm-arm/arch-ebsa285/memory.h
+ * linux/include/asm-arm/arch-ebsa285/memory.h
X *
- * Copyright (c) 1996-1999 Russell King.
+ * Copyright (C) 1996-1999 Russell King.
X *


- * Changelog:
- * 20-Oct-1996 RMK Created

- * 31-Dec-1997 RMK Fixed definitions to reduce warnings.
- * 17-May-1998 DAG Added __virt_to_bus and __bus_to_virt functions.
- * 21-Nov-1998 RMK Changed __virt_to_bus and __bus_to_virt to macros.
- * 21-Mar-1999 RMK Added PAGE_OFFSET for co285 architecture.


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Changelog:
+ * 20-Oct-1996 RMK Created

+ * 31-Dec-1997 RMK Fixed definitions to reduce warnings.
+ * 17-May-1998 DAG Added __virt_to_bus and __bus_to_virt functions.
+ * 21-Nov-1998 RMK Changed __virt_to_bus and __bus_to_virt to macros.
+ * 21-Mar-1999 RMK Added PAGE_OFFSET for co285 architecture.
X * Renamed to memory.h
X * Moved PAGE_OFFSET and TASK_SIZE here
X */
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-ebsa285/processor.h linux/include/asm-arm/arch-ebsa285/processor.h
--- v2.4.0-test8/linux/include/asm-arm/arch-ebsa285/processor.h Wed Oct 20 16:29:08 1999
+++ linux/include/asm-arm/arch-ebsa285/processor.h Mon Sep 18 15:15:23 2000
@@ -1,10 +1,14 @@
X /*
- * linux/include/asm-arm/arch-ebsa110/processor.h
+ * linux/include/asm-arm/arch-ebsa110/processor.h
X *


- * Copyright (C) 1996-1999 Russell King
+ * Copyright (C) 1996-1999 Russell King

X *
- * Changelog:

- * 21-Mar-1999 RMK Added asm/arch/memory.h


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Changelog:


+ * 21-Mar-1999 RMK Added asm/arch/memory.h
X */
X
X #ifndef __ASM_ARCH_PROCESSOR_H

diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-ebsa285/serial.h linux/include/asm-arm/arch-ebsa285/serial.h
--- v2.4.0-test8/linux/include/asm-arm/arch-ebsa285/serial.h Tue Nov 23 22:23:11 1999
+++ linux/include/asm-arm/arch-ebsa285/serial.h Mon Sep 18 15:15:23 2000
@@ -1,11 +1,15 @@
X /*
- * linux/include/asm-arm/arch-ebsa285/serial.h
+ * linux/include/asm-arm/arch-ebsa285/serial.h
X *
- * Copyright (c) 1996,1997,1998 Russell King.
+ * Copyright (C) 1996,1997,1998 Russell King.
X *


- * Changelog:
- * 15-10-1996 RMK Created

- * 25-05-1998 PJB CATS support


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Changelog:
+ * 15-10-1996 RMK Created

+ * 25-05-1998 PJB CATS support


X */
X #ifndef __ASM_ARCH_SERIAL_H
X #define __ASM_ARCH_SERIAL_H

diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-ebsa285/system.h linux/include/asm-arm/arch-ebsa285/system.h
--- v2.4.0-test8/linux/include/asm-arm/arch-ebsa285/system.h Sun Aug 13 09:54:15 2000
+++ linux/include/asm-arm/arch-ebsa285/system.h Mon Sep 18 15:15:23 2000
@@ -1,9 +1,13 @@
X /*
- * linux/include/asm-arm/arch-ebsa285/system.h
+ * linux/include/asm-arm/arch-ebsa285/system.h
X *
- * Copyright (c) 1996-1999 Russell King.
+ * Copyright (C) 1996-1999 Russell King.
+ *


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

X */
-#include <asm/dec21285.h>
+#include <asm/hardware/dec21285.h>
X #include <asm/io.h>
X #include <asm/hardware.h>
X #include <asm/leds.h>
@@ -19,7 +23,7 @@


X if (current->need_resched || hlt_counter)
X goto slow_out;
X cpu_do_idle(IDLE_WAIT_FAST);
- } while (time_before(start_idle, jiffies + HZ/3));
+ } while (time_before(jiffies, start_idle + HZ/50));
X
X cpu_do_idle(IDLE_CLOCK_SLOW);

X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-ebsa285/time.h linux/include/asm-arm/arch-ebsa285/time.h
--- v2.4.0-test8/linux/include/asm-arm/arch-ebsa285/time.h Sun Aug 13 09:54:15 2000
+++ linux/include/asm-arm/arch-ebsa285/time.h Mon Sep 18 15:15:23 2000
@@ -1,8 +1,8 @@
X /*
- * linux/include/asm-arm/arch-ebsa285/time.h
+ * linux/include/asm-arm/arch-ebsa285/time.h


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 101'
echo 'File patch-2.4.0-test9 is continued in part 102'
echo "102" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part103

#!/bin/sh -x
# this is part 103 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 103; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

--- v2.4.0-test8/linux/include/asm-arm/arch-tbox/timex.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/arch-tbox/timex.h Mon Sep 18 15:15:23 2000
@@ -0,0 +1,8 @@
+/*
+ * linux/include/asm-arm/arch-tbox/timex.h
+ *
+ * Tbox timex specifications
+ *
+ * Copyright (C) 1999 Philip Blundell
+ */
+
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-tbox/uncompress.h linux/include/asm-arm/arch-tbox/uncompress.h
--- v2.4.0-test8/linux/include/asm-arm/arch-tbox/uncompress.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/arch-tbox/uncompress.h Mon Sep 18 15:15:23 2000
@@ -0,0 +1,42 @@
+/*
+ * linux/include/asm-arm/arch-nexuspci/uncompress.h
+ * from linux/include/asm-arm/arch-ebsa110/uncompress.h


+ *
+ * Copyright (C) 1996,1997,1998 Russell King

+ * Copyright (C) 1998, 1999 Phil Blundell


+ */
+
+#include <asm/io.h>
+

+#define UARTBASE 0x00400000
+
+/*
+ * This does not append a newline
+ */
+static void puts(const char *s)
+{
+ while (*s)
+ {
+ char c = *(s++);
+ while (!(__raw_readb(UARTBASE + 0x14) & 0x20));
+ __raw_writeb(c, UARTBASE);
+ if (c == 10) {
+ while (!(__raw_readb(UARTBASE + 0x14) & 0x20));
+ __raw_writeb(13, UARTBASE);
+ }
+ }
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+
+/*
+ * Stroke the watchdog so we don't get reset during decompression.
+ */
+#define arch_decomp_wdog() \
+ do { \
+ __raw_writel(1, 0xa00000); \
+ __raw_writel(0, 0xa00000); \
+ } while (0)
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/arch-tbox/vmalloc.h linux/include/asm-arm/arch-tbox/vmalloc.h
--- v2.4.0-test8/linux/include/asm-arm/arch-tbox/vmalloc.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/arch-tbox/vmalloc.h Mon Sep 18 15:15:23 2000


@@ -0,0 +1,17 @@
+/*
+ * linux/include/asm-arm/arch-rpc/vmalloc.h
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts. That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET (8*1024*1024)
+#define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+

diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/atomic.h linux/include/asm-arm/atomic.h
--- v2.4.0-test8/linux/include/asm-arm/atomic.h Mon Jun 26 12:04:42 2000
+++ linux/include/asm-arm/atomic.h Mon Sep 18 15:15:23 2000


@@ -1,13 +1,17 @@
X /*

- * linux/include/asm-arm/atomic.h
+ * linux/include/asm-arm/atomic.h


X *
- * Copyright (c) 1996 Russell King.

+ * Copyright (c) 1996 Russell King.


X *
- * Changelog:

- * 27-06-1996 RMK Created
- * 13-04-1997 RMK Made functions atomic!
- * 07-12-1997 RMK Upgraded for v2.1.
- * 26-08-1998 PJB Added #ifdef __KERNEL__


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Changelog:

+ * 27-06-1996 RMK Created
+ * 13-04-1997 RMK Made functions atomic!
+ * 07-12-1997 RMK Upgraded for v2.1.
+ * 26-08-1998 PJB Added #ifdef __KERNEL__
X */
X #ifndef __ASM_ARM_ATOMIC_H
X #define __ASM_ARM_ATOMIC_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/bugs.h linux/include/asm-arm/bugs.h
--- v2.4.0-test8/linux/include/asm-arm/bugs.h Mon Aug 30 18:15:21 1999
+++ linux/include/asm-arm/bugs.h Mon Sep 18 15:15:23 2000


@@ -1,7 +1,11 @@
X /*

- * include/asm-arm/bugs.h
+ * linux/include/asm-arm/bugs.h
X *
X * Copyright (C) 1995 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X */

X #ifndef __ASM_BUGS_H
X #define __ASM_BUGS_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/cache.h linux/include/asm-arm/cache.h
--- v2.4.0-test8/linux/include/asm-arm/cache.h Wed Oct 20 16:29:08 1999
+++ linux/include/asm-arm/cache.h Mon Sep 18 15:15:23 2000
@@ -1,5 +1,5 @@
X /*
- * linux/include/asm-arm/cache.h
+ * linux/include/asm-arm/cache.h
X */
X #ifndef __ASMARM_CACHE_H
X #define __ASMARM_CACHE_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/checksum.h linux/include/asm-arm/checksum.h
--- v2.4.0-test8/linux/include/asm-arm/checksum.h Mon Mar 27 10:46:29 2000
+++ linux/include/asm-arm/checksum.h Mon Sep 18 15:15:23 2000
@@ -1,5 +1,5 @@
X /*
- * linux/include/asm-arm/checksum.h
+ * linux/include/asm-arm/checksum.h
X *
X * IP checksum routines
X *
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/cpu-multi26.h linux/include/asm-arm/cpu-multi26.h
--- v2.4.0-test8/linux/include/asm-arm/cpu-multi26.h Mon Jun 26 12:04:42 2000
+++ linux/include/asm-arm/cpu-multi26.h Mon Sep 18 15:15:23 2000
@@ -1,3 +1,12 @@
+/*
+ * linux/include/asm-arm/cpu-multi26.h
+ *
+ * Copyright (C) 2000 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

+ */
X #ifndef __ASSEMBLY__
X
X #include <asm/page.h>
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/cpu-multi32.h linux/include/asm-arm/cpu-multi32.h
--- v2.4.0-test8/linux/include/asm-arm/cpu-multi32.h Mon Mar 27 10:46:29 2000
+++ linux/include/asm-arm/cpu-multi32.h Mon Sep 18 15:15:23 2000
@@ -1,3 +1,12 @@
+/*
+ * linux/include/asm-arm/cpu-multi32.h
+ *
+ * Copyright (C) 2000 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

+ */
X #ifndef __ASSEMBLY__
X
X #include <asm/page.h>
@@ -27,79 +36,91 @@
X */
X void (*_proc_fin)(void);
X /*
- * Processor architecture specific
- */
- /* CACHE
- *
- * flush all caches
- */
- void (*_flush_cache_all)(void);
- /*
- * flush a specific page or pages
- */
- void (*_flush_cache_area)(unsigned long address, unsigned long end, int flags);
- /*
- * flush cache entry for an address
- */
- void (*_flush_cache_entry)(unsigned long address);
- /*
- * clean a virtual address range from the
- * D-cache without flushing the cache.
- */
- void (*_clean_cache_area)(unsigned long start, unsigned long size);
- /*
- * flush a page to RAM
- */
- void (*_flush_ram_page)(unsigned long page);
- /* TLB
- *
- * flush all TLBs
- */
- void (*_flush_tlb_all)(void);
- /*
- * flush a specific TLB
- */
- void (*_flush_tlb_area)(unsigned long address, unsigned long end, int flags);
- /*
- * Set the page table
- */
- void (*_set_pgd)(unsigned long pgd_phys);
- /*
- * Set a PMD (handling IMP bit 4)
- */
- void (*_set_pmd)(pmd_t *pmdp, pmd_t pmd);
- /*
- * Set a PTE
- */
- void (*_set_pte)(pte_t *ptep, pte_t pte);
- /*
X * Special stuff for a reset
X */
X volatile void (*reset)(unsigned long addr);
X /*
- * flush an icached page
- */
- void (*_flush_icache_area)(unsigned long start, unsigned long size);
- /*
- * write back dirty cached data
- */
- void (*_cache_wback_area)(unsigned long start, unsigned long end);
- /*
- * purge cached data without (necessarily) writing it back
- */
- void (*_cache_purge_area)(unsigned long start, unsigned long end);
- /*
- * flush a specific TLB
- */
- void (*_flush_tlb_page)(unsigned long address, int flags);
- /*
X * Idle the processor
X */
X int (*_do_idle)(int mode);
X /*
- * flush I cache for a page
+ * Processor architecture specific
X */
- void (*_flush_icache_page)(unsigned long address);
+ struct { /* CACHE */
+ /*
+ * flush all caches
+ */
+ void (*clean_invalidate_all)(void);
+ /*
+ * flush a specific page or pages
+ */
+ void (*clean_invalidate_range)(unsigned long address, unsigned long end, int flags);
+ /*
+ * flush a page to RAM
+ */
+ void (*_flush_ram_page)(void *virt_page);
+ } cache;
+
+ struct { /* D-cache */
+ /*
+ * invalidate the specified data range
+ */
+ void (*invalidate_range)(unsigned long start, unsigned long end);
+ /*
+ * clean specified data range
+ */
+ void (*clean_range)(unsigned long start, unsigned long end);
+ /*
+ * obsolete flush cache entry
+ */
+ void (*clean_page)(void *virt_page);
+ /*
+ * clean a virtual address range from the
+ * D-cache without flushing the cache.
+ */
+ void (*clean_entry)(unsigned long start);
+ } dcache;
+
+ struct { /* I-cache */
+ /*
+ * invalidate the I-cache for the specified range
+ */
+ void (*invalidate_range)(unsigned long start, unsigned long end);
+ /*
+ * invalidate the I-cache for the specified virtual page
+ */
+ void (*invalidate_page)(void *virt_page);
+ } icache;
+
+ struct { /* TLB */
+ /*
+ * flush all TLBs
+ */
+ void (*invalidate_all)(void);
+ /*
+ * flush a specific TLB
+ */
+ void (*invalidate_range)(unsigned long address, unsigned long end);
+ /*
+ * flush a specific TLB
+ */
+ void (*invalidate_page)(unsigned long address, int flags);
+ } tlb;
+
+ struct { /* PageTable */
+ /*
+ * Set the page table
+ */
+ void (*set_pgd)(unsigned long pgd_phys);
+ /*
+ * Set a PMD (handling IMP bit 4)
+ */
+ void (*set_pmd)(pmd_t *pmdp, pmd_t pmd);
+ /*
+ * Set a PTE
+ */
+ void (*set_pte)(pte_t *ptep, pte_t pte);
+ } pgtable;
X } processor;
X
X extern const struct processor arm6_processor_functions;
@@ -110,24 +131,28 @@
X #define cpu_check_bugs() processor._check_bugs()
X #define cpu_proc_init() processor._proc_init()
X #define cpu_proc_fin() processor._proc_fin()
+#define cpu_reset(addr) processor.reset(addr)
X #define cpu_do_idle(mode) processor._do_idle(mode)
X
-#define cpu_flush_cache_all() processor._flush_cache_all()
-#define cpu_flush_cache_area(start,end,flags) processor._flush_cache_area(start,end,flags)
-#define cpu_flush_cache_entry(addr) processor._flush_cache_entry(addr)
-#define cpu_clean_cache_area(start,size) processor._clean_cache_area(start,size)
-#define cpu_flush_ram_page(page) processor._flush_ram_page(page)
-#define cpu_flush_tlb_all() processor._flush_tlb_all()
-#define cpu_flush_tlb_area(start,end,flags) processor._flush_tlb_area(start,end,flags)
-#define cpu_flush_tlb_page(addr,flags) processor._flush_tlb_page(addr,flags)
-#define cpu_set_pgd(pgd) processor._set_pgd(pgd)
-#define cpu_set_pmd(pmdp, pmd) processor._set_pmd(pmdp, pmd)
-#define cpu_set_pte(ptep, pte) processor._set_pte(ptep, pte)
-#define cpu_reset(addr) processor.reset(addr)
-#define cpu_flush_icache_area(start,end) processor._flush_icache_area(start,end)
-#define cpu_cache_wback_area(start,end) processor._cache_wback_area(start,end)
-#define cpu_cache_purge_area(start,end) processor._cache_purge_area(start,end)
-#define cpu_flush_icache_page(virt) processor._flush_icache_page(virt)
+#define cpu_cache_clean_invalidate_all() processor.cache.clean_invalidate_all()
+#define cpu_cache_clean_invalidate_range(s,e,f) processor.cache.clean_invalidate_range(s,e,f)
+#define cpu_flush_ram_page(vp) processor.cache._flush_ram_page(vp)
+
+#define cpu_dcache_clean_page(vp) processor.dcache.clean_page(vp)
+#define cpu_dcache_clean_entry(addr) processor.dcache.clean_entry(addr)
+#define cpu_dcache_clean_range(s,e) processor.dcache.clean_range(s,e)
+#define cpu_dcache_invalidate_range(s,e) processor.dcache.invalidate_range(s,e)
+
+#define cpu_icache_invalidate_range(s,e) processor.icache.invalidate_range(s,e)
+#define cpu_icache_invalidate_page(vp) processor.icache.invalidate_page(vp)
+
+#define cpu_tlb_invalidate_all() processor.tlb.invalidate_all()
+#define cpu_tlb_invalidate_range(s,e) processor.tlb.invalidate_range(s,e)
+#define cpu_tlb_invalidate_page(vp,f) processor.tlb.invalidate_page(vp,f)
+
+#define cpu_set_pgd(pgd) processor.pgtable.set_pgd(pgd)
+#define cpu_set_pmd(pmdp, pmd) processor.pgtable.set_pmd(pmdp, pmd)
+#define cpu_set_pte(ptep, pte) processor.pgtable.set_pte(ptep, pte)
X
X #define cpu_switch_mm(pgd,tsk) cpu_set_pgd(__virt_to_phys((unsigned long)(pgd)))
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/cpu-single.h linux/include/asm-arm/cpu-single.h
--- v2.4.0-test8/linux/include/asm-arm/cpu-single.h Mon Mar 27 10:46:29 2000
+++ linux/include/asm-arm/cpu-single.h Mon Sep 18 15:15:23 2000
@@ -1,4 +1,13 @@
X /*
+ * linux/include/asm-arm/cpu-single.h
+ *
+ * Copyright (C) 2000 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

+ */
+/*
X * Single CPU
X */
X #ifdef __STDC__
@@ -9,33 +18,36 @@
X #define cpu_fn(name,x) __cpu_fn(name,x)
X
X /*
- * If we are supporting multiple CPUs, then
- * we must use a table of function pointers
- * for this lot. Otherwise, we can optimise
- * the table away.
+ * If we are supporting multiple CPUs, then we must use a table of
+ * function pointers for this lot. Otherwise, we can optimise the
+ * table away.
X */
X #define cpu_data_abort cpu_fn(CPU_NAME,_data_abort)
X #define cpu_check_bugs cpu_fn(CPU_NAME,_check_bugs)
X #define cpu_proc_init cpu_fn(CPU_NAME,_proc_init)
X #define cpu_proc_fin cpu_fn(CPU_NAME,_proc_fin)
+#define cpu_reset cpu_fn(CPU_NAME,_reset)
X #define cpu_do_idle cpu_fn(CPU_NAME,_do_idle)
X
-#define cpu_flush_cache_all cpu_fn(CPU_NAME,_flush_cache_all)
-#define cpu_flush_cache_area cpu_fn(CPU_NAME,_flush_cache_area)
-#define cpu_flush_cache_entry cpu_fn(CPU_NAME,_flush_cache_entry)
-#define cpu_clean_cache_area cpu_fn(CPU_NAME,_clean_cache_area)
+#define cpu_cache_clean_invalidate_all cpu_fn(CPU_NAME,_cache_clean_invalidate_all)
+#define cpu_cache_clean_invalidate_range cpu_fn(CPU_NAME,_cache_clean_invalidate_range)
X #define cpu_flush_ram_page cpu_fn(CPU_NAME,_flush_ram_page)
-#define cpu_flush_tlb_all cpu_fn(CPU_NAME,_flush_tlb_all)
-#define cpu_flush_tlb_area cpu_fn(CPU_NAME,_flush_tlb_area)
-#define cpu_flush_tlb_page cpu_fn(CPU_NAME,_flush_tlb_page)
+
+#define cpu_dcache_invalidate_range cpu_fn(CPU_NAME,_dcache_invalidate_range)
+#define cpu_dcache_clean_range cpu_fn(CPU_NAME,_dcache_clean_range)
+#define cpu_dcache_clean_page cpu_fn(CPU_NAME,_dcache_clean_page)
+#define cpu_dcache_clean_entry cpu_fn(CPU_NAME,_dcache_clean_entry)
+
+#define cpu_icache_invalidate_range cpu_fn(CPU_NAME,_icache_invalidate_range)
+#define cpu_icache_invalidate_page cpu_fn(CPU_NAME,_icache_invalidate_page)
+
+#define cpu_tlb_invalidate_all cpu_fn(CPU_NAME,_tlb_invalidate_all)
+#define cpu_tlb_invalidate_range cpu_fn(CPU_NAME,_tlb_invalidate_range)
+#define cpu_tlb_invalidate_page cpu_fn(CPU_NAME,_tlb_invalidate_page)
+
X #define cpu_set_pgd cpu_fn(CPU_NAME,_set_pgd)
X #define cpu_set_pmd cpu_fn(CPU_NAME,_set_pmd)
X #define cpu_set_pte cpu_fn(CPU_NAME,_set_pte)
-#define cpu_reset cpu_fn(CPU_NAME,_reset)
-#define cpu_flush_icache_area cpu_fn(CPU_NAME,_flush_icache_area)
-#define cpu_cache_wback_area cpu_fn(CPU_NAME,_cache_wback_area)
-#define cpu_cache_purge_area cpu_fn(CPU_NAME,_cache_purge_area)
-#define cpu_flush_icache_page cpu_fn(CPU_NAME,_flush_icache_page)
X
X #ifndef __ASSEMBLY__
X
@@ -51,22 +63,26 @@
X extern void cpu_proc_fin(void);
X extern int cpu_do_idle(int mode);
X
-extern void cpu_flush_cache_all(void);
-extern void cpu_flush_cache_area(unsigned long address, unsigned long end, int flags);
-extern void cpu_flush_cache_entry(unsigned long address);
-extern void cpu_clean_cache_area(unsigned long start, unsigned long size);
-extern void cpu_flush_ram_page(unsigned long page);
-extern void cpu_flush_tlb_all(void);
-extern void cpu_flush_tlb_area(unsigned long address, unsigned long end, int flags);
-extern void cpu_flush_tlb_page(unsigned long address, int flags);
+extern void cpu_cache_clean_invalidate_all(void);
+extern void cpu_cache_clean_invalidate_range(unsigned long address, unsigned long end, int flags);
+extern void cpu_flush_ram_page(void *virt_page);
+
+extern void cpu_dcache_invalidate_range(unsigned long start, unsigned long end);
+extern void cpu_dcache_clean_range(unsigned long start, unsigned long end);
+extern void cpu_dcache_clean_page(void *virt_page);
+extern void cpu_dcache_clean_entry(unsigned long address);
+
+extern void cpu_icache_invalidate_range(unsigned long start, unsigned long end);
+extern void cpu_icache_invalidate_page(void *virt_page);
+
+extern void cpu_tlb_invalidate_all(void);
+extern void cpu_tlb_invalidate_range(unsigned long address, unsigned long end);
+extern void cpu_tlb_invalidate_page(unsigned long address, int flags);
+
X extern void cpu_set_pgd(unsigned long pgd_phys);
X extern void cpu_set_pmd(pmd_t *pmdp, pmd_t pmd);
X extern void cpu_set_pte(pte_t *ptep, pte_t pte);
X extern volatile void cpu_reset(unsigned long addr);
-extern void cpu_flush_icache_area(unsigned long start, unsigned long size);
-extern void cpu_cache_wback_area(unsigned long start, unsigned long end);
-extern void cpu_cache_purge_area(unsigned long start, unsigned long end);
-extern void cpu_flush_icache_page(unsigned long virt);
X
X #define cpu_switch_mm(pgd,tsk) cpu_set_pgd(__virt_to_phys((unsigned long)(pgd)))
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/dec21285.h linux/include/asm-arm/dec21285.h
--- v2.4.0-test8/linux/include/asm-arm/dec21285.h Tue Jul 18 22:43:25 2000
+++ linux/include/asm-arm/dec21285.h Wed Dec 31 16:00:00 1969
@@ -1,144 +0,0 @@
-/*
- * include/asm-arm/dec21285.h
- *


- * Copyright (C) 1998 Russell King

- *
- * DC21285 registers
- */
-#define DC21285_PCI_IACK 0x79000000
-#define DC21285_ARMCSR_BASE 0x42000000
-#define DC21285_PCI_TYPE_0_CONFIG 0x7b000000
-#define DC21285_PCI_TYPE_1_CONFIG 0x7a000000
-#define DC21285_OUTBOUND_WRITE_FLUSH 0x78000000
-#define DC21285_FLASH 0x41000000
-#define DC21285_PCI_IO 0x7c000000
-#define DC21285_PCI_MEM 0x80000000
-
-#include <linux/config.h>
-#ifndef __ASSEMBLY__
-#include <asm/arch/hardware.h>
-#define DC21285_IO(x) ((volatile unsigned long *)(ARMCSR_BASE+(x)))
-#else
-#define DC21285_IO(x) (x)
-#endif
-
-#define CSR_PCICMD DC21285_IO(0x0004)
-#define CSR_CLASSREV DC21285_IO(0x0008)
-#define CSR_PCICACHELINESIZE DC21285_IO(0x000c)
-#define CSR_PCICSRBASE DC21285_IO(0x0010)
-#define CSR_PCICSRIOBASE DC21285_IO(0x0014)
-#define CSR_PCISDRAMBASE DC21285_IO(0x0018)
-#define CSR_PCIROMBASE DC21285_IO(0x0030)
-#define CSR_MBOX0 DC21285_IO(0x0050)
-#define CSR_MBOX1 DC21285_IO(0x0054)
-#define CSR_MBOX2 DC21285_IO(0x0058)
-#define CSR_MBOX3 DC21285_IO(0x005c)
-#define CSR_DOORBELL DC21285_IO(0x0060)
-#define CSR_DOORBELL_SETUP DC21285_IO(0x0064)
-#define CSR_ROMWRITEREG DC21285_IO(0x0068)
-#define CSR_CSRBASEMASK DC21285_IO(0x00f8)
-#define CSR_CSRBASEOFFSET DC21285_IO(0x00fc)
-#define CSR_SDRAMBASEMASK DC21285_IO(0x0100)
-#define CSR_SDRAMBASEOFFSET DC21285_IO(0x0104)
-#define CSR_ROMBASEMASK DC21285_IO(0x0108)
-#define CSR_SDRAMTIMING DC21285_IO(0x010c)
-#define CSR_SDRAMADDRSIZE0 DC21285_IO(0x0110)
-#define CSR_SDRAMADDRSIZE1 DC21285_IO(0x0114)
-#define CSR_SDRAMADDRSIZE2 DC21285_IO(0x0118)
-#define CSR_SDRAMADDRSIZE3 DC21285_IO(0x011c)
-#define CSR_I2O_INFREEHEAD DC21285_IO(0x0120)
-#define CSR_I2O_INPOSTTAIL DC21285_IO(0x0124)
-#define CSR_I2O_OUTPOSTHEAD DC21285_IO(0x0128)
-#define CSR_I2O_OUTFREETAIL DC21285_IO(0x012c)
-#define CSR_I2O_INFREECOUNT DC21285_IO(0x0130)
-#define CSR_I2O_OUTPOSTCOUNT DC21285_IO(0x0134)
-#define CSR_I2O_INPOSTCOUNT DC21285_IO(0x0138)
-#define CSR_SA110_CNTL DC21285_IO(0x013c)
-#define SA110_CNTL_INITCMPLETE (1 << 0)
-#define SA110_CNTL_ASSERTSERR (1 << 1)
-#define SA110_CNTL_RXSERR (1 << 3)
-#define SA110_CNTL_SA110DRAMPARITY (1 << 4)
-#define SA110_CNTL_PCISDRAMPARITY (1 << 5)
-#define SA110_CNTL_DMASDRAMPARITY (1 << 6)
-#define SA110_CNTL_DISCARDTIMER (1 << 8)
-#define SA110_CNTL_PCINRESET (1 << 9)
-#define SA110_CNTL_I2O_256 (0 << 10)
-#define SA110_CNTL_I20_512 (1 << 10)
-#define SA110_CNTL_I2O_1024 (2 << 10)
-#define SA110_CNTL_I2O_2048 (3 << 10)
-#define SA110_CNTL_I2O_4096 (4 << 10)
-#define SA110_CNTL_I2O_8192 (5 << 10)
-#define SA110_CNTL_I2O_16384 (6 << 10)
-#define SA110_CNTL_I2O_32768 (7 << 10)
-#define SA110_CNTL_WATCHDOG (1 << 13)
-#define SA110_CNTL_ROMWIDTH_UNDEF (0 << 14)
-#define SA110_CNTL_ROMWIDTH_16 (1 << 14)
-#define SA110_CNTL_ROMWIDTH_32 (2 << 14)
-#define SA110_CNTL_ROMWIDTH_8 (3 << 14)
-#define SA110_CNTL_ROMACCESSTIME(x) ((x)<<16)
-#define SA110_CNTL_ROMBURSTTIME(x) ((x)<<20)
-#define SA110_CNTL_ROMTRISTATETIME(x) ((x)<<24)
-#define SA110_CNTL_XCSDIR(x) ((x)<<28)
-#define SA110_CNTL_PCICFN (1 << 31)
-
-/*
- * footbridge_cfn_mode() is used when we want
- * to check whether we are the central function
- */
-#define __footbridge_cfn_mode() (*CSR_SA110_CNTL & SA110_CNTL_PCICFN)
-#if defined(CONFIG_FOOTBRIDGE_HOST) && defined(CONFIG_FOOTBRIDGE_ADDIN)
-#define footbridge_cfn_mode() __footbridge_cfn_mode()
-#elif defined(CONFIG_FOOTBRIDGE_HOST)
-#define footbridge_cfn_mode() (1)
-#else
-#define footbridge_cfn_mode() (0)
-#endif
-
-#define CSR_PCIADDR_EXTN DC21285_IO(0x0140)
-#define CSR_PREFETCHMEMRANGE DC21285_IO(0x0144)
-#define CSR_XBUS_CYCLE DC21285_IO(0x0148)
-#define CSR_XBUS_IOSTROBE DC21285_IO(0x014c)
-#define CSR_DOORBELL_PCI DC21285_IO(0x0150)
-#define CSR_DOORBELL_SA110 DC21285_IO(0x0154)
-#define CSR_UARTDR DC21285_IO(0x0160)
-#define CSR_RXSTAT DC21285_IO(0x0164)
-#define CSR_H_UBRLCR DC21285_IO(0x0168)
-#define CSR_M_UBRLCR DC21285_IO(0x016c)
-#define CSR_L_UBRLCR DC21285_IO(0x0170)
-#define CSR_UARTCON DC21285_IO(0x0174)
-#define CSR_UARTFLG DC21285_IO(0x0178)
-#define CSR_IRQ_STATUS DC21285_IO(0x0180)
-#define CSR_IRQ_RAWSTATUS DC21285_IO(0x0184)
-#define CSR_IRQ_ENABLE DC21285_IO(0x0188)
-#define CSR_IRQ_DISABLE DC21285_IO(0x018c)
-#define CSR_IRQ_SOFT DC21285_IO(0x0190)
-#define CSR_FIQ_STATUS DC21285_IO(0x0280)
-#define CSR_FIQ_RAWSTATUS DC21285_IO(0x0284)
-#define CSR_FIQ_ENABLE DC21285_IO(0x0288)
-#define CSR_FIQ_DISABLE DC21285_IO(0x028c)
-#define CSR_FIQ_SOFT DC21285_IO(0x0290)
-#define CSR_TIMER1_LOAD DC21285_IO(0x0300)
-#define CSR_TIMER1_VALUE DC21285_IO(0x0304)
-#define CSR_TIMER1_CNTL DC21285_IO(0x0308)
-#define CSR_TIMER1_CLR DC21285_IO(0x030c)
-#define CSR_TIMER2_LOAD DC21285_IO(0x0320)
-#define CSR_TIMER2_VALUE DC21285_IO(0x0324)
-#define CSR_TIMER2_CNTL DC21285_IO(0x0328)
-#define CSR_TIMER2_CLR DC21285_IO(0x032c)
-#define CSR_TIMER3_LOAD DC21285_IO(0x0340)
-#define CSR_TIMER3_VALUE DC21285_IO(0x0344)
-#define CSR_TIMER3_CNTL DC21285_IO(0x0348)
-#define CSR_TIMER3_CLR DC21285_IO(0x034c)
-#define CSR_TIMER4_LOAD DC21285_IO(0x0360)
-#define CSR_TIMER4_VALUE DC21285_IO(0x0364)
-#define CSR_TIMER4_CNTL DC21285_IO(0x0368)
-#define CSR_TIMER4_CLR DC21285_IO(0x036c)
-
-#define TIMER_CNTL_ENABLE (1 << 7)
-#define TIMER_CNTL_AUTORELOAD (1 << 6)
-#define TIMER_CNTL_DIV1 (0)
-#define TIMER_CNTL_DIV16 (1 << 2)
-#define TIMER_CNTL_DIV256 (2 << 2)
-#define TIMER_CNTL_CNTEXT (3 << 2)
-
-
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/dma.h linux/include/asm-arm/dma.h
--- v2.4.0-test8/linux/include/asm-arm/dma.h Sun Sep 3 11:19:11 2000
+++ linux/include/asm-arm/dma.h Mon Sep 18 15:15:23 2000
@@ -22,11 +22,6 @@
X #define DMA_MODE_CASCADE 2
X #define DMA_AUTOINIT 4
X
-typedef struct {
- unsigned long address;
- unsigned long length;
-} dmasg_t;
-
X extern spinlock_t dma_spin_lock;
X
X extern __inline__ unsigned long claim_dma_lock(void)
@@ -85,7 +80,7 @@
X * especially since some DMA architectures don't update the
X * DMA address immediately, but defer it to the enable_dma().
X */
-extern void set_dma_sg(dmach_t channel, dmasg_t *sg, int nr_sg);
+extern void set_dma_sg(dmach_t channel, struct scatterlist *sg, int nr_sg);
X
X /* Set the DMA address for this channel
X *
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/fcntl.h linux/include/asm-arm/fcntl.h
--- v2.4.0-test8/linux/include/asm-arm/fcntl.h Wed Jul 5 11:13:39 2000
+++ linux/include/asm-arm/fcntl.h Fri Sep 22 14:21:19 2000
@@ -51,6 +51,9 @@
X #define F_EXLCK 4 /* or 3 */
X #define F_SHLCK 8 /* or 4 */
X
+/* for leases */


+#define F_INPROGRESS 16
+
X /* operations for bsd flock(), also used by the kernel implementation */
X #define LOCK_SH 1 /* shared lock */
X #define LOCK_EX 2 /* exclusive lock */

@@ -58,6 +61,11 @@


X blocking */
X #define LOCK_UN 8 /* remove lock */

X

+#define LOCK_MAND 32 /* This is a mandatory flock */
+#define LOCK_READ 64 /* ... Which allows concurrent read operations */
+#define LOCK_WRITE 128 /* ... Which allows concurrent write operations */
+#define LOCK_RW 192 /* ... Which allows concurrent read & write ops */
+
X struct flock {
X short l_type;
X short l_whence;

@@ -74,4 +82,5 @@
X pid_t l_pid;
X };
X
+#define F_LINUX_SPECIFIC_BASE 1024
X #endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/floppy.h linux/include/asm-arm/floppy.h
--- v2.4.0-test8/linux/include/asm-arm/floppy.h Mon Jun 26 12:04:42 2000
+++ linux/include/asm-arm/floppy.h Mon Sep 18 15:15:23 2000


@@ -1,9 +1,13 @@
X /*

- * linux/include/asm-arm/floppy.h
+ * linux/include/asm-arm/floppy.h
X *
- * (C) 1996-2000 Russell King
+ * Copyright (C) 1996-2000 Russell King
X *
- * Note that we don't touch FLOPPY_DMA nor FLOPPY_IRQ here


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Note that we don't touch FLOPPY_DMA nor FLOPPY_IRQ here
X */
X #ifndef __ASM_ARM_FLOPPY_H
X #define __ASM_ARM_FLOPPY_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/hardware/dec21285.h linux/include/asm-arm/hardware/dec21285.h
--- v2.4.0-test8/linux/include/asm-arm/hardware/dec21285.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/hardware/dec21285.h Mon Sep 18 15:15:23 2000
@@ -0,0 +1,148 @@
+/*
+ * linux/include/asm-arm/hardware/dec21285.h


+ *
+ * Copyright (C) 1998 Russell King
+ *

+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * DC21285 registers
+ */
+#define DC21285_PCI_IACK 0x79000000
+#define DC21285_ARMCSR_BASE 0x42000000
+#define DC21285_PCI_TYPE_0_CONFIG 0x7b000000
+#define DC21285_PCI_TYPE_1_CONFIG 0x7a000000
+#define DC21285_OUTBOUND_WRITE_FLUSH 0x78000000
+#define DC21285_FLASH 0x41000000
+#define DC21285_PCI_IO 0x7c000000
+#define DC21285_PCI_MEM 0x80000000
+
+#include <linux/config.h>
+#ifndef __ASSEMBLY__
+#include <asm/arch/hardware.h>
+#define DC21285_IO(x) ((volatile unsigned long *)(ARMCSR_BASE+(x)))
+#else
+#define DC21285_IO(x) (x)
+#endif
+
+#define CSR_PCICMD DC21285_IO(0x0004)
+#define CSR_CLASSREV DC21285_IO(0x0008)
+#define CSR_PCICACHELINESIZE DC21285_IO(0x000c)
+#define CSR_PCICSRBASE DC21285_IO(0x0010)
+#define CSR_PCICSRIOBASE DC21285_IO(0x0014)
+#define CSR_PCISDRAMBASE DC21285_IO(0x0018)
+#define CSR_PCIROMBASE DC21285_IO(0x0030)
+#define CSR_MBOX0 DC21285_IO(0x0050)
+#define CSR_MBOX1 DC21285_IO(0x0054)
+#define CSR_MBOX2 DC21285_IO(0x0058)
+#define CSR_MBOX3 DC21285_IO(0x005c)
+#define CSR_DOORBELL DC21285_IO(0x0060)
+#define CSR_DOORBELL_SETUP DC21285_IO(0x0064)
+#define CSR_ROMWRITEREG DC21285_IO(0x0068)
+#define CSR_CSRBASEMASK DC21285_IO(0x00f8)
+#define CSR_CSRBASEOFFSET DC21285_IO(0x00fc)
+#define CSR_SDRAMBASEMASK DC21285_IO(0x0100)
+#define CSR_SDRAMBASEOFFSET DC21285_IO(0x0104)
+#define CSR_ROMBASEMASK DC21285_IO(0x0108)
+#define CSR_SDRAMTIMING DC21285_IO(0x010c)
+#define CSR_SDRAMADDRSIZE0 DC21285_IO(0x0110)
+#define CSR_SDRAMADDRSIZE1 DC21285_IO(0x0114)
+#define CSR_SDRAMADDRSIZE2 DC21285_IO(0x0118)
+#define CSR_SDRAMADDRSIZE3 DC21285_IO(0x011c)
+#define CSR_I2O_INFREEHEAD DC21285_IO(0x0120)
+#define CSR_I2O_INPOSTTAIL DC21285_IO(0x0124)
+#define CSR_I2O_OUTPOSTHEAD DC21285_IO(0x0128)
+#define CSR_I2O_OUTFREETAIL DC21285_IO(0x012c)
+#define CSR_I2O_INFREECOUNT DC21285_IO(0x0130)
+#define CSR_I2O_OUTPOSTCOUNT DC21285_IO(0x0134)
+#define CSR_I2O_INPOSTCOUNT DC21285_IO(0x0138)
+#define CSR_SA110_CNTL DC21285_IO(0x013c)
+#define SA110_CNTL_INITCMPLETE (1 << 0)
+#define SA110_CNTL_ASSERTSERR (1 << 1)
+#define SA110_CNTL_RXSERR (1 << 3)
+#define SA110_CNTL_SA110DRAMPARITY (1 << 4)
+#define SA110_CNTL_PCISDRAMPARITY (1 << 5)
+#define SA110_CNTL_DMASDRAMPARITY (1 << 6)
+#define SA110_CNTL_DISCARDTIMER (1 << 8)
+#define SA110_CNTL_PCINRESET (1 << 9)
+#define SA110_CNTL_I2O_256 (0 << 10)
+#define SA110_CNTL_I20_512 (1 << 10)
+#define SA110_CNTL_I2O_1024 (2 << 10)
+#define SA110_CNTL_I2O_2048 (3 << 10)
+#define SA110_CNTL_I2O_4096 (4 << 10)
+#define SA110_CNTL_I2O_8192 (5 << 10)
+#define SA110_CNTL_I2O_16384 (6 << 10)
+#define SA110_CNTL_I2O_32768 (7 << 10)
+#define SA110_CNTL_WATCHDOG (1 << 13)
+#define SA110_CNTL_ROMWIDTH_UNDEF (0 << 14)
+#define SA110_CNTL_ROMWIDTH_16 (1 << 14)
+#define SA110_CNTL_ROMWIDTH_32 (2 << 14)
+#define SA110_CNTL_ROMWIDTH_8 (3 << 14)
+#define SA110_CNTL_ROMACCESSTIME(x) ((x)<<16)
+#define SA110_CNTL_ROMBURSTTIME(x) ((x)<<20)
+#define SA110_CNTL_ROMTRISTATETIME(x) ((x)<<24)
+#define SA110_CNTL_XCSDIR(x) ((x)<<28)
+#define SA110_CNTL_PCICFN (1 << 31)
+
+/*
+ * footbridge_cfn_mode() is used when we want
+ * to check whether we are the central function
+ */
+#define __footbridge_cfn_mode() (*CSR_SA110_CNTL & SA110_CNTL_PCICFN)
+#if defined(CONFIG_FOOTBRIDGE_HOST) && defined(CONFIG_FOOTBRIDGE_ADDIN)
+#define footbridge_cfn_mode() __footbridge_cfn_mode()
+#elif defined(CONFIG_FOOTBRIDGE_HOST)
+#define footbridge_cfn_mode() (1)
+#else
+#define footbridge_cfn_mode() (0)
+#endif
+
+#define CSR_PCIADDR_EXTN DC21285_IO(0x0140)
+#define CSR_PREFETCHMEMRANGE DC21285_IO(0x0144)
+#define CSR_XBUS_CYCLE DC21285_IO(0x0148)
+#define CSR_XBUS_IOSTROBE DC21285_IO(0x014c)
+#define CSR_DOORBELL_PCI DC21285_IO(0x0150)
+#define CSR_DOORBELL_SA110 DC21285_IO(0x0154)
+#define CSR_UARTDR DC21285_IO(0x0160)
+#define CSR_RXSTAT DC21285_IO(0x0164)
+#define CSR_H_UBRLCR DC21285_IO(0x0168)
+#define CSR_M_UBRLCR DC21285_IO(0x016c)
+#define CSR_L_UBRLCR DC21285_IO(0x0170)
+#define CSR_UARTCON DC21285_IO(0x0174)
+#define CSR_UARTFLG DC21285_IO(0x0178)
+#define CSR_IRQ_STATUS DC21285_IO(0x0180)
+#define CSR_IRQ_RAWSTATUS DC21285_IO(0x0184)
+#define CSR_IRQ_ENABLE DC21285_IO(0x0188)
+#define CSR_IRQ_DISABLE DC21285_IO(0x018c)
+#define CSR_IRQ_SOFT DC21285_IO(0x0190)
+#define CSR_FIQ_STATUS DC21285_IO(0x0280)
+#define CSR_FIQ_RAWSTATUS DC21285_IO(0x0284)
+#define CSR_FIQ_ENABLE DC21285_IO(0x0288)
+#define CSR_FIQ_DISABLE DC21285_IO(0x028c)
+#define CSR_FIQ_SOFT DC21285_IO(0x0290)
+#define CSR_TIMER1_LOAD DC21285_IO(0x0300)
+#define CSR_TIMER1_VALUE DC21285_IO(0x0304)
+#define CSR_TIMER1_CNTL DC21285_IO(0x0308)
+#define CSR_TIMER1_CLR DC21285_IO(0x030c)
+#define CSR_TIMER2_LOAD DC21285_IO(0x0320)
+#define CSR_TIMER2_VALUE DC21285_IO(0x0324)
+#define CSR_TIMER2_CNTL DC21285_IO(0x0328)
+#define CSR_TIMER2_CLR DC21285_IO(0x032c)
+#define CSR_TIMER3_LOAD DC21285_IO(0x0340)
+#define CSR_TIMER3_VALUE DC21285_IO(0x0344)
+#define CSR_TIMER3_CNTL DC21285_IO(0x0348)
+#define CSR_TIMER3_CLR DC21285_IO(0x034c)
+#define CSR_TIMER4_LOAD DC21285_IO(0x0360)
+#define CSR_TIMER4_VALUE DC21285_IO(0x0364)
+#define CSR_TIMER4_CNTL DC21285_IO(0x0368)
+#define CSR_TIMER4_CLR DC21285_IO(0x036c)
+
+#define TIMER_CNTL_ENABLE (1 << 7)
+#define TIMER_CNTL_AUTORELOAD (1 << 6)
+#define TIMER_CNTL_DIV1 (0)
+#define TIMER_CNTL_DIV16 (1 << 2)
+#define TIMER_CNTL_DIV256 (2 << 2)
+#define TIMER_CNTL_CNTEXT (3 << 2)
+
+
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/hardware/ioc.h linux/include/asm-arm/hardware/ioc.h
--- v2.4.0-test8/linux/include/asm-arm/hardware/ioc.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/hardware/ioc.h Mon Sep 18 15:15:23 2000
@@ -0,0 +1,67 @@
+/*
+ * linux/include/asm-arm/hardware/ioc.h
+ *
+ * Copyright (C) Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

+ *
+ * Use these macros to read/write the IOC. All it does is perform the actual
+ * read/write.
+ */
+
+#ifndef IOC_CONTROL
+
+#ifndef __ASSEMBLY__
+#define __IOC(offset) (IOC_BASE + (offset >> 2))
+#else
+#define __IOC(offset) offset
+#endif
+
+#define IOC_CONTROL __IOC(0x00)
+#define IOC_KARTTX __IOC(0x04)
+#define IOC_KARTRX __IOC(0x04)
+
+#define IOC_IRQSTATA __IOC(0x10)
+#define IOC_IRQREQA __IOC(0x14)
+#define IOC_IRQCLRA __IOC(0x14)
+#define IOC_IRQMASKA __IOC(0x18)
+
+#define IOC_IRQSTATB __IOC(0x20)
+#define IOC_IRQREQB __IOC(0x24)
+#define IOC_IRQMASKB __IOC(0x28)
+
+#define IOC_FIQSTAT __IOC(0x30)
+#define IOC_FIQREQ __IOC(0x34)
+#define IOC_FIQMASK __IOC(0x38)
+
+#define IOC_T0CNTL __IOC(0x40)
+#define IOC_T0LTCHL __IOC(0x40)
+#define IOC_T0CNTH __IOC(0x44)
+#define IOC_T0LTCHH __IOC(0x44)
+#define IOC_T0GO __IOC(0x48)
+#define IOC_T0LATCH __IOC(0x4c)
+
+#define IOC_T1CNTL __IOC(0x50)
+#define IOC_T1LTCHL __IOC(0x50)
+#define IOC_T1CNTH __IOC(0x54)
+#define IOC_T1LTCHH __IOC(0x54)
+#define IOC_T1GO __IOC(0x58)
+#define IOC_T1LATCH __IOC(0x5c)
+
+#define IOC_T2CNTL __IOC(0x60)
+#define IOC_T2LTCHL __IOC(0x60)
+#define IOC_T2CNTH __IOC(0x64)
+#define IOC_T2LTCHH __IOC(0x64)
+#define IOC_T2GO __IOC(0x68)
+#define IOC_T2LATCH __IOC(0x6c)
+
+#define IOC_T3CNTL __IOC(0x70)
+#define IOC_T3LTCHL __IOC(0x70)
+#define IOC_T3CNTH __IOC(0x74)
+#define IOC_T3LTCHH __IOC(0x74)
+#define IOC_T3GO __IOC(0x78)
+#define IOC_T3LATCH __IOC(0x7c)
+
+#endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/hardware/iomd.h linux/include/asm-arm/hardware/iomd.h
--- v2.4.0-test8/linux/include/asm-arm/hardware/iomd.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/hardware/iomd.h Mon Sep 18 15:15:23 2000
@@ -0,0 +1,249 @@
+/*
+ * linux/include/asm-arm/iomd.h
+ *
+ * Copyright (C) 1999 Russell King
+ *


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * This file contains information out the IOMD ASIC used in the
+ * Acorn RiscPC and subsequently integrated into the CLPS7500 chips.
+ */
+#include <linux/config.h>
+
+#ifndef __ASSEMBLY__
+#define __IOMD(offset) (IO_IOMD_BASE + (offset >> 2))
+#else
+#define __IOMD(offset) offset
+#endif
+
+#define IOMD_CONTROL __IOMD(0x000)
+#define IOMD_KARTTX __IOMD(0x004)
+#define IOMD_KARTRX __IOMD(0x004)
+#define IOMD_KCTRL __IOMD(0x008)
+
+#ifdef CONFIG_ARCH_CLPS7500
+#define IOMD_IOLINES __IOMD(0x00C)
+#endif
+
+#define IOMD_IRQSTATA __IOMD(0x010)
+#define IOMD_IRQREQA __IOMD(0x014)
+#define IOMD_IRQCLRA __IOMD(0x014)
+#define IOMD_IRQMASKA __IOMD(0x018)
+
+#ifdef CONFIG_ARCH_CLPS7500
+#define IOMD_SUSMODE __IOMD(0x01C)
+#endif
+
+#define IOMD_IRQSTATB __IOMD(0x020)
+#define IOMD_IRQREQB __IOMD(0x024)
+#define IOMD_IRQMASKB __IOMD(0x028)
+
+#define IOMD_FIQSTAT __IOMD(0x030)
+#define IOMD_FIQREQ __IOMD(0x034)
+#define IOMD_FIQMASK __IOMD(0x038)
+
+#ifdef CONFIG_ARCH_CLPS7500
+#define IOMD_CLKCTL __IOMD(0x03C)
+#endif
+
+#define IOMD_T0CNTL __IOMD(0x040)
+#define IOMD_T0LTCHL __IOMD(0x040)
+#define IOMD_T0CNTH __IOMD(0x044)
+#define IOMD_T0LTCHH __IOMD(0x044)
+#define IOMD_T0GO __IOMD(0x048)
+#define IOMD_T0LATCH __IOMD(0x04c)
+
+#define IOMD_T1CNTL __IOMD(0x050)
+#define IOMD_T1LTCHL __IOMD(0x050)
+#define IOMD_T1CNTH __IOMD(0x054)
+#define IOMD_T1LTCHH __IOMD(0x054)
+#define IOMD_T1GO __IOMD(0x058)
+#define IOMD_T1LATCH __IOMD(0x05c)
+
+#ifdef CONFIG_ARCH_CLPS7500
+#define IOMD_IRQSTATC __IOMD(0x060)
+#define IOMD_IRQREQC __IOMD(0x064)
+#define IOMD_IRQMASKC __IOMD(0x068)
+
+#define IOMD_VIDMUX __IOMD(0x06c)
+
+#define IOMD_IRQSTATD __IOMD(0x070)
+#define IOMD_IRQREQD __IOMD(0x074)
+#define IOMD_IRQMASKD __IOMD(0x078)
+#endif
+
+#define IOMD_ROMCR0 __IOMD(0x080)
+#define IOMD_ROMCR1 __IOMD(0x084)
+#ifdef CONFIG_ARCH_RPC
+#define IOMD_DRAMCR __IOMD(0x088)
+#endif
+#define IOMD_REFCR __IOMD(0x08C)
+
+#define IOMD_FSIZE __IOMD(0x090)
+#define IOMD_ID0 __IOMD(0x094)
+#define IOMD_ID1 __IOMD(0x098)
+#define IOMD_VERSION __IOMD(0x09C)
+
+#ifdef CONFIG_ARCH_RPC
+#define IOMD_MOUSEX __IOMD(0x0A0)
+#define IOMD_MOUSEY __IOMD(0x0A4)
+#endif
+
+#ifdef CONFIG_ARCH_CLPS7500
+#define IOMD_MSEDAT __IOMD(0x0A8)
+#define IOMD_MSECTL __IOMD(0x0Ac)
+#endif
+
+#ifdef CONFIG_ARCH_RPC
+#define IOMD_DMATCR __IOMD(0x0C0)
+#endif
+#define IOMD_IOTCR __IOMD(0x0C4)
+#define IOMD_ECTCR __IOMD(0x0C8)
+#ifdef CONFIG_ARCH_RPC
+#define IOMD_DMAEXT __IOMD(0x0CC)
+#endif
+#ifdef CONFIG_ARCH_CLPS7500
+#define IOMD_ASTCR __IOMD(0x0CC)
+#define IOMD_DRAMCR __IOMD(0x0D0)
+#define IOMD_SELFREF __IOMD(0x0D4)
+#define IOMD_ATODICR __IOMD(0x0E0)
+#define IOMD_ATODSR __IOMD(0x0E4)
+#define IOMD_ATODCC __IOMD(0x0E8)
+#define IOMD_ATODCNT1 __IOMD(0x0EC)
+#define IOMD_ATODCNT2 __IOMD(0x0F0)
+#define IOMD_ATODCNT3 __IOMD(0x0F4)
+#define IOMD_ATODCNT4 __IOMD(0x0F8)
+#endif
+
+#ifdef CONFIG_ARCH_RPC
+#define DMA_EXT_IO0 1
+#define DMA_EXT_IO1 2
+#define DMA_EXT_IO2 4
+#define DMA_EXT_IO3 8
+
+#define IOMD_IO0CURA __IOMD(0x100)
+#define IOMD_IO0ENDA __IOMD(0x104)
+#define IOMD_IO0CURB __IOMD(0x108)
+#define IOMD_IO0ENDB __IOMD(0x10C)
+#define IOMD_IO0CR __IOMD(0x110)
+#define IOMD_IO0ST __IOMD(0x114)
+
+#define IOMD_IO1CURA __IOMD(0x120)
+#define IOMD_IO1ENDA __IOMD(0x124)
+#define IOMD_IO1CURB __IOMD(0x128)
+#define IOMD_IO1ENDB __IOMD(0x12C)
+#define IOMD_IO1CR __IOMD(0x130)
+#define IOMD_IO1ST __IOMD(0x134)
+
+#define IOMD_IO2CURA __IOMD(0x140)
+#define IOMD_IO2ENDA __IOMD(0x144)
+#define IOMD_IO2CURB __IOMD(0x148)
+#define IOMD_IO2ENDB __IOMD(0x14C)
+#define IOMD_IO2CR __IOMD(0x150)
+#define IOMD_IO2ST __IOMD(0x154)
+
+#define IOMD_IO3CURA __IOMD(0x160)
+#define IOMD_IO3ENDA __IOMD(0x164)
+#define IOMD_IO3CURB __IOMD(0x168)
+#define IOMD_IO3ENDB __IOMD(0x16C)
+#define IOMD_IO3CR __IOMD(0x170)
+#define IOMD_IO3ST __IOMD(0x174)
+#endif
+
+#define IOMD_SD0CURA __IOMD(0x180)
+#define IOMD_SD0ENDA __IOMD(0x184)
+#define IOMD_SD0CURB __IOMD(0x188)
+#define IOMD_SD0ENDB __IOMD(0x18C)
+#define IOMD_SD0CR __IOMD(0x190)
+#define IOMD_SD0ST __IOMD(0x194)
+
+#ifdef CONFIG_ARCH_RPC
+#define IOMD_SD1CURA __IOMD(0x1A0)
+#define IOMD_SD1ENDA __IOMD(0x1A4)
+#define IOMD_SD1CURB __IOMD(0x1A8)
+#define IOMD_SD1ENDB __IOMD(0x1AC)
+#define IOMD_SD1CR __IOMD(0x1B0)
+#define IOMD_SD1ST __IOMD(0x1B4)
+#endif
+
+#define IOMD_CURSCUR __IOMD(0x1C0)
+#define IOMD_CURSINIT __IOMD(0x1C4)
+
+#define IOMD_VIDCUR __IOMD(0x1D0)
+#define IOMD_VIDEND __IOMD(0x1D4)
+#define IOMD_VIDSTART __IOMD(0x1D8)
+#define IOMD_VIDINIT __IOMD(0x1DC)
+#define IOMD_VIDCR __IOMD(0x1E0)
+
+#define IOMD_DMASTAT __IOMD(0x1F0)
+#define IOMD_DMAREQ __IOMD(0x1F4)
+#define IOMD_DMAMASK __IOMD(0x1F8)
+
+#define DMA_END_S (1 << 31)
+#define DMA_END_L (1 << 30)
+
+#define DMA_CR_C 0x80
+#define DMA_CR_D 0x40
+#define DMA_CR_E 0x20
+
+#define DMA_ST_OFL 4
+#define DMA_ST_INT 2
+#define DMA_ST_AB 1
+
+#ifndef IOC_CONTROL
+/*
+ * IOC compatability
+ */
+#define IOC_CONTROL IOMD_CONTROL
+#define IOC_IRQSTATA IOMD_IRQSTATA
+#define IOC_IRQREQA IOMD_IRQREQA
+#define IOC_IRQCLRA IOMD_IRQCLRA
+#define IOC_IRQMASKA IOMD_IRQMASKA
+
+#define IOC_IRQSTATB IOMD_IRQSTATB
+#define IOC_IRQREQB IOMD_IRQREQB
+#define IOC_IRQMASKB IOMD_IRQMASKB
+
+#define IOC_FIQSTAT IOMD_FIQSTAT
+#define IOC_FIQREQ IOMD_FIQREQ
+#define IOC_FIQMASK IOMD_FIQMASK
+
+#define IOC_T0CNTL IOMD_T0CNTL
+#define IOC_T0LTCHL IOMD_T0LTCHL
+#define IOC_T0CNTH IOMD_T0CNTH
+#define IOC_T0LTCHH IOMD_T0LTCHH
+#define IOC_T0GO IOMD_T0GO
+#define IOC_T0LATCH IOMD_T0LATCH
+
+#define IOC_T1CNTL IOMD_T1CNTL
+#define IOC_T1LTCHL IOMD_T1LTCHL
+#define IOC_T1CNTH IOMD_T1CNTH
+#define IOC_T1LTCHH IOMD_T1LTCHH
+#define IOC_T1GO IOMD_T1GO
+#define IOC_T1LATCH IOMD_T1LATCH
+#endif
+
+/*
+ * DMA (MEMC) compatability
+ */
+#define HALF_SAM vram_half_sam
+#define VDMA_ALIGNMENT (HALF_SAM * 2)
+#define VDMA_XFERSIZE (HALF_SAM)
+#define VDMA_INIT IOMD_VIDINIT
+#define VDMA_START IOMD_VIDSTART
+#define VDMA_END IOMD_VIDEND
+
+#ifndef __ASSEMBLY__
+extern unsigned int vram_half_sam;
+#define video_set_dma(start,end,offset) \
+do { \
+ outl (SCREEN_START + start, VDMA_START); \
+ outl (SCREEN_START + end - VDMA_XFERSIZE, VDMA_END); \
+ if (offset >= end - VDMA_XFERSIZE) \
+ offset |= 0x40000000; \
+ outl (SCREEN_START + offset, VDMA_INIT); \
+} while (0)
+#endif
+
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/hardware/memc.h linux/include/asm-arm/hardware/memc.h
--- v2.4.0-test8/linux/include/asm-arm/hardware/memc.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/hardware/memc.h Mon Sep 18 15:15:23 2000
@@ -0,0 +1,26 @@
+/*
+ * linux/include/asm-arm/hardware/memc.h
+ *
+ * Copyright (C) Russell King.


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

+ */
+#define VDMA_ALIGNMENT PAGE_SIZE
+#define VDMA_XFERSIZE 16
+#define VDMA_INIT 0
+#define VDMA_START 1
+#define VDMA_END 2
+
+#ifndef __ASSEMBLY__
+extern void memc_write(unsigned int reg, unsigned long val);
+
+#define video_set_dma(start,end,offset) \
+do { \
+ memc_write (VDMA_START, (start >> 2)); \
+ memc_write (VDMA_END, (end - VDMA_XFERSIZE) >> 2); \
+ memc_write (VDMA_INIT, (offset >> 2)); \
+} while (0)
+
+#endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/hardware/pci_v3.h linux/include/asm-arm/hardware/pci_v3.h
--- v2.4.0-test8/linux/include/asm-arm/hardware/pci_v3.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/hardware/pci_v3.h Mon Sep 18 15:15:23 2000
@@ -0,0 +1,148 @@
+/*
+ * linux/include/asm-arm/hardware/pci_v3.h
+ *
+ * Internal header file PCI V3 chip
+ *
+ * Copyright (C) ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd.


+ *
+ * This program is free software; you can redistribute it and/or modify

+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *


+ * This program is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of


+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef ASM_ARM_HARDWARE_PCI_V3_H
+#define ASM_ARM_HARDWARE_PCI_V3_H
+
+/* -------------------------------------------------------------------------------
+ * V3 Local Bus to PCI Bridge definitions
+ * -------------------------------------------------------------------------------
+ * Registers (these are taken from page 129 of the EPC User's Manual Rev 1.04
+ * All V3 register names are prefaced by V3_ to avoid clashing with any other
+ * PCI definitions. Their names match the user's manual.
+ *
+ * I'm assuming that I20 is disabled.
+ *
+ */
+#define V3_PCI_VENDOR 0x00000000
+#define V3_PCI_DEVICE 0x00000002
+#define V3_PCI_CMD 0x00000004
+#define V3_PCI_STAT 0x00000006
+#define V3_PCI_CC_REV 0x00000008
+#define V3_PCI_HDR_CFG 0x0000000C
+#define V3_PCI_IO_BASE 0x00000010
+#define V3_PCI_BASE0 0x00000014
+#define V3_PCI_BASE1 0x00000018
+#define V3_PCI_SUB_VENDOR 0x0000002C
+#define V3_PCI_SUB_ID 0x0000002E
+#define V3_PCI_ROM 0x00000030
+#define V3_PCI_BPARAM 0x0000003C
+#define V3_PCI_MAP0 0x00000040
+#define V3_PCI_MAP1 0x00000044
+#define V3_PCI_INT_STAT 0x00000048
+#define V3_PCI_INT_CFG 0x0000004C
+#define V3_LB_BASE0 0x00000054
+#define V3_LB_BASE1 0x00000058
+#define V3_LB_MAP0 0x0000005E
+#define V3_LB_MAP1 0x00000062
+#define V3_LB_BASE2 0x00000064
+#define V3_LB_MAP2 0x00000066
+#define V3_LB_SIZE 0x00000068
+#define V3_LB_IO_BASE 0x0000006E
+#define V3_FIFO_CFG 0x00000070
+#define V3_FIFO_PRIORITY 0x00000072
+#define V3_FIFO_STAT 0x00000074
+#define V3_LB_ISTAT 0x00000076
+#define V3_LB_IMASK 0x00000077
+#define V3_SYSTEM 0x00000078
+#define V3_LB_CFG 0x0000007A
+#define V3_PCI_CFG 0x0000007C
+#define V3_DMA_PCI_ADR0 0x00000080
+#define V3_DMA_PCI_ADR1 0x00000090
+#define V3_DMA_LOCAL_ADR0 0x00000084
+#define V3_DMA_LOCAL_ADR1 0x00000094
+#define V3_DMA_LENGTH0 0x00000088
+#define V3_DMA_LENGTH1 0x00000098
+#define V3_DMA_CSR0 0x0000008B
+#define V3_DMA_CSR1 0x0000009B
+#define V3_DMA_CTLB_ADR0 0x0000008C
+#define V3_DMA_CTLB_ADR1 0x0000009C
+#define V3_DMA_DELAY 0x000000E0
+#define V3_MAIL_DATA 0x000000C0
+#define V3_PCI_MAIL_IEWR 0x000000D0
+#define V3_PCI_MAIL_IERD 0x000000D2
+#define V3_LB_MAIL_IEWR 0x000000D4
+#define V3_LB_MAIL_IERD 0x000000D6
+#define V3_MAIL_WR_STAT 0x000000D8
+#define V3_MAIL_RD_STAT 0x000000DA
+#define V3_QBA_MAP 0x000000DC
+
+/* PCI COMMAND REGISTER bits
+ */
+#define V3_COMMAND_M_FBB_EN BIT9
+#define V3_COMMAND_M_SERR_EN BIT8
+#define V3_COMMAND_M_PAR_EN BIT6
+#define V3_COMMAND_M_MASTER_EN BIT2
+#define V3_COMMAND_M_MEM_EN BIT1
+#define V3_COMMAND_M_IO_EN BIT0
+
+/* SYSTEM REGISTER bits
+ */
+#define V3_SYSTEM_M_RST_OUT BIT15
+#define V3_SYSTEM_M_LOCK BIT14
+
+/* PCI_CFG bits
+ */
+#define V3_PCI_CFG_M_RETRY_EN BIT10
+#define V3_PCI_CFG_M_AD_LOW1 BIT9
+#define V3_PCI_CFG_M_AD_LOW0 BIT8
+
+/* PCI_BASE register bits (PCI -> Local Bus)
+ */
+#define V3_PCI_BASE_M_ADR_BASE 0xFFF00000
+#define V3_PCI_BASE_M_ADR_BASEL 0x000FFF00
+#define V3_PCI_BASE_M_PREFETCH BIT3
+#define V3_PCI_BASE_M_TYPE BIT2+BIT1
+#define V3_PCI_BASE_M_IO BIT0
+
+/* PCI MAP register bits (PCI -> Local bus)
+ */
+#define V3_PCI_MAP_M_MAP_ADR 0xFFF00000
+#define V3_PCI_MAP_M_RD_POST_INH BIT15
+#define V3_PCI_MAP_M_ROM_SIZE BIT11+BIT10
+#define V3_PCI_MAP_M_SWAP BIT9+BIT8
+#define V3_PCI_MAP_M_ADR_SIZE 0x000000F0
+#define V3_PCI_MAP_M_REG_EN BIT1
+#define V3_PCI_MAP_M_ENABLE BIT0
+
+/* 9 => 512M window size
+ */
+#define V3_PCI_MAP_M_ADR_SIZE_512M 0x00000090
+/* A => 1024M window size
+ */
+#define V3_PCI_MAP_M_ADR_SIZE_1024M 0x000000A0
+
+/* LB_BASE register bits (Local bus -> PCI)
+ */
+#define V3_LB_BASE_M_MAP_ADR 0xFFF00000
+#define V3_LB_BASE_M_SWAP BIT9+BIT8
+#define V3_LB_BASE_M_ADR_SIZE 0x000000F0
+#define V3_LB_BASE_M_PREFETCH BIT3
+#define V3_LB_BASE_M_ENABLE BIT0
+
+/* LB_MAP register bits (Local bus -> PCI)
+ */
+#define V3_LB_MAP_M_MAP_ADR 0xFFF0
+#define V3_LB_MAP_M_TYPE 0x000E
+#define V3_LB_MAP_M_AD_LOW_EN BIT0
+
+#endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/hardware/serial_amba.h linux/include/asm-arm/hardware/serial_amba.h
--- v2.4.0-test8/linux/include/asm-arm/hardware/serial_amba.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-arm/hardware/serial_amba.h Mon Sep 18 15:15:23 2000
@@ -0,0 +1,91 @@
+/*
+ * linux/include/asm-arm/hardware/serial_amba.h
+ *
+ * Internal header file for AMBA serial ports
+ *
+ * Copyright (C) ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd.


+ *
+ * This program is free software; you can redistribute it and/or modify

+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *


+ * This program is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of


+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef ASM_ARM_HARDWARE_SERIAL_AMBA_H
+#define ASM_ARM_HARDWARE_SERIAL_AMBA_H
+
+/* -------------------------------------------------------------------------------
+ * From AMBA UART (PL010) Block Specification (ARM-0001-CUST-DSPC-A03)
+ * -------------------------------------------------------------------------------
+ * UART Register Offsets.
+ */
+#define AMBA_UARTDR 0x00 /* Data read or written from the interface. */
+#define AMBA_UARTRSR 0x04 /* Receive status register (Read). */
+#define AMBA_UARTECR 0x04 /* Error clear register (Write). */
+#define AMBA_UARTLCR_H 0x08 /* Line control register, high byte. */
+#define AMBA_UARTLCR_M 0x0C /* Line control register, middle byte. */
+#define AMBA_UARTLCR_L 0x10 /* Line control register, low byte. */
+#define AMBA_UARTCR 0x14 /* Control register. */
+#define AMBA_UARTFR 0x18 /* Flag register (Read only). */
+#define AMBA_UARTIIR 0x1C /* Interrupt indentification register (Read). */
+#define AMBA_UARTICR 0x1C /* Interrupt clear register (Write). */
+#define AMBA_UARTILPR 0x20 /* IrDA low power counter register. */
+
+#define AMBA_UARTRSR_OE 0x08
+#define AMBA_UARTRSR_BE 0x04
+#define AMBA_UARTRSR_PE 0x02
+#define AMBA_UARTRSR_FE 0x01
+
+#define AMBA_UARTFR_TXFF 0x20
+#define AMBA_UARTFR_RXFE 0x10
+#define AMBA_UARTFR_BUSY 0x08
+#define AMBA_UARTFR_DCD 0x04
+#define AMBA_UARTFR_DSR 0x02
+#define AMBA_UARTFR_CTS 0x01
+#define AMBA_UARTFR_TMSK (AMBA_UARTFR_TXFF + AMBA_UARTFR_BUSY)
+
+#define AMBA_UARTCR_RTIE 0x40
+#define AMBA_UARTCR_TIE 0x20
+#define AMBA_UARTCR_RIE 0x10
+#define AMBA_UARTCR_MSIE 0x08
+#define AMBA_UARTCR_IIRLP 0x04
+#define AMBA_UARTCR_SIREN 0x02
+#define AMBA_UARTCR_UARTEN 0x01
+
+#define AMBA_UARTLCR_H_WLEN_8 0x60
+#define AMBA_UARTLCR_H_WLEN_7 0x40
+#define AMBA_UARTLCR_H_WLEN_6 0x20
+#define AMBA_UARTLCR_H_WLEN_5 0x00
+#define AMBA_UARTLCR_H_FEN 0x10
+#define AMBA_UARTLCR_H_STP2 0x08
+#define AMBA_UARTLCR_H_EPS 0x04
+#define AMBA_UARTLCR_H_PEN 0x02
+#define AMBA_UARTLCR_H_BRK 0x01
+
+#define AMBA_UARTIIR_RTIS 0x08
+#define AMBA_UARTIIR_TIS 0x04
+#define AMBA_UARTIIR_RIS 0x02
+#define AMBA_UARTIIR_MIS 0x01
+
+#define ARM_BAUD_460800 1
+#define ARM_BAUD_230400 3
+#define ARM_BAUD_115200 7
+#define ARM_BAUD_57600 15
+#define ARM_BAUD_38400 23
+#define ARM_BAUD_19200 47
+#define ARM_BAUD_14400 63
+#define ARM_BAUD_9600 95
+#define ARM_BAUD_4800 191
+#define ARM_BAUD_2400 383
+#define ARM_BAUD_1200 767
+
+#endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/hardware.h linux/include/asm-arm/hardware.h
--- v2.4.0-test8/linux/include/asm-arm/hardware.h Sun Aug 13 09:54:15 2000
+++ linux/include/asm-arm/hardware.h Mon Sep 18 15:15:23 2000


@@ -1,9 +1,13 @@
X /*

- * linux/include/asm-arm/hardware.h
+ * linux/include/asm-arm/hardware.h


X *
- * Copyright (C) 1996 Russell King
+ * Copyright (C) 1996 Russell King
X *

- * Common hardware definitions


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Common hardware definitions
X */
X
X #ifndef __ASM_HARDWARE_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/io.h linux/include/asm-arm/io.h
--- v2.4.0-test8/linux/include/asm-arm/io.h Mon Jun 26 12:04:42 2000
+++ linux/include/asm-arm/io.h Mon Sep 18 15:15:23 2000


@@ -1,7 +1,11 @@
X /*

- * linux/include/asm-arm/io.h
+ * linux/include/asm-arm/io.h
X *
- * Copyright (C) 1996-2000 Russell King
+ * Copyright (C) 1996-2000 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X *
X * Modifications:

X * 16-Sep-1996 RMK Inlined the inx/outx functions & optimised for both
@@ -19,7 +23,6 @@
X #include <linux/types.h>
X #include <asm/arch/hardware.h>
X #include <asm/arch/io.h>
-#include <asm/proc/io.h>
X
X #define outb_p(val,port) outb((val),(port))
X #define outw_p(val,port) outw((val),(port))
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/ioc.h linux/include/asm-arm/ioc.h
--- v2.4.0-test8/linux/include/asm-arm/ioc.h Wed Oct 20 16:29:08 1999
+++ linux/include/asm-arm/ioc.h Wed Dec 31 16:00:00 1969
@@ -1,59 +0,0 @@
-/*
- * Use these macros to read/write the IOC. All it does is perform the actual
- * read/write.
- */
-
-#ifndef IOC_CONTROL
-
-#ifndef __ASSEMBLY__
-#define __IOC(offset) (IOC_BASE + (offset >> 2))
-#else
-#define __IOC(offset) offset
-#endif
-
-#define IOC_CONTROL __IOC(0x00)
-#define IOC_KARTTX __IOC(0x04)
-#define IOC_KARTRX __IOC(0x04)
-
-#define IOC_IRQSTATA __IOC(0x10)
-#define IOC_IRQREQA __IOC(0x14)
-#define IOC_IRQCLRA __IOC(0x14)
-#define IOC_IRQMASKA __IOC(0x18)
-
-#define IOC_IRQSTATB __IOC(0x20)
-#define IOC_IRQREQB __IOC(0x24)
-#define IOC_IRQMASKB __IOC(0x28)
-
-#define IOC_FIQSTAT __IOC(0x30)
-#define IOC_FIQREQ __IOC(0x34)
-#define IOC_FIQMASK __IOC(0x38)
-
-#define IOC_T0CNTL __IOC(0x40)
-#define IOC_T0LTCHL __IOC(0x40)
-#define IOC_T0CNTH __IOC(0x44)
-#define IOC_T0LTCHH __IOC(0x44)
-#define IOC_T0GO __IOC(0x48)
-#define IOC_T0LATCH __IOC(0x4c)
-
-#define IOC_T1CNTL __IOC(0x50)
-#define IOC_T1LTCHL __IOC(0x50)
-#define IOC_T1CNTH __IOC(0x54)
-#define IOC_T1LTCHH __IOC(0x54)
-#define IOC_T1GO __IOC(0x58)
-#define IOC_T1LATCH __IOC(0x5c)
-
-#define IOC_T2CNTL __IOC(0x60)
-#define IOC_T2LTCHL __IOC(0x60)
-#define IOC_T2CNTH __IOC(0x64)
-#define IOC_T2LTCHH __IOC(0x64)
-#define IOC_T2GO __IOC(0x68)
-#define IOC_T2LATCH __IOC(0x6c)
-
-#define IOC_T3CNTL __IOC(0x70)
-#define IOC_T3LTCHL __IOC(0x70)
-#define IOC_T3CNTH __IOC(0x74)
-#define IOC_T3LTCHH __IOC(0x74)
-#define IOC_T3GO __IOC(0x78)
-#define IOC_T3LATCH __IOC(0x7c)
-
-#endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/iomd.h linux/include/asm-arm/iomd.h
--- v2.4.0-test8/linux/include/asm-arm/iomd.h Fri May 12 11:21:20 2000
+++ linux/include/asm-arm/iomd.h Wed Dec 31 16:00:00 1969
@@ -1,245 +0,0 @@
-/*
- * linux/include/asm-arm/iomd.h
- *
- * Copyright (C) 1999 Russell King
- *
- * This file contains information out the IOMD ASIC used in the
- * Acorn RiscPC and subsequently integrated into the CLPS7500 chips.
- */
-#include <linux/config.h>
-
-#ifndef __ASSEMBLY__
-#define __IOMD(offset) (IO_IOMD_BASE + (offset >> 2))
-#else
-#define __IOMD(offset) offset
-#endif
-
-#define IOMD_CONTROL __IOMD(0x000)
-#define IOMD_KARTTX __IOMD(0x004)
-#define IOMD_KARTRX __IOMD(0x004)
-#define IOMD_KCTRL __IOMD(0x008)
-
-#ifdef CONFIG_ARCH_CLPS7500
-#define IOMD_IOLINES __IOMD(0x00C)
-#endif
-
-#define IOMD_IRQSTATA __IOMD(0x010)
-#define IOMD_IRQREQA __IOMD(0x014)
-#define IOMD_IRQCLRA __IOMD(0x014)
-#define IOMD_IRQMASKA __IOMD(0x018)
-
-#ifdef CONFIG_ARCH_CLPS7500
-#define IOMD_SUSMODE __IOMD(0x01C)
-#endif
-
-#define IOMD_IRQSTATB __IOMD(0x020)
-#define IOMD_IRQREQB __IOMD(0x024)
-#define IOMD_IRQMASKB __IOMD(0x028)
-
-#define IOMD_FIQSTAT __IOMD(0x030)
-#define IOMD_FIQREQ __IOMD(0x034)
-#define IOMD_FIQMASK __IOMD(0x038)
-
-#ifdef CONFIG_ARCH_CLPS7500
-#define IOMD_CLKCTL __IOMD(0x03C)
-#endif
-
-#define IOMD_T0CNTL __IOMD(0x040)
-#define IOMD_T0LTCHL __IOMD(0x040)
-#define IOMD_T0CNTH __IOMD(0x044)
-#define IOMD_T0LTCHH __IOMD(0x044)
-#define IOMD_T0GO __IOMD(0x048)
-#define IOMD_T0LATCH __IOMD(0x04c)
-
-#define IOMD_T1CNTL __IOMD(0x050)
-#define IOMD_T1LTCHL __IOMD(0x050)
-#define IOMD_T1CNTH __IOMD(0x054)
-#define IOMD_T1LTCHH __IOMD(0x054)
-#define IOMD_T1GO __IOMD(0x058)
-#define IOMD_T1LATCH __IOMD(0x05c)


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 103'
echo 'File patch-2.4.0-test9 is continued in part 104'
echo "104" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part104

#!/bin/sh -x
# this is part 104 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 104; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&
-

-#ifdef CONFIG_ARCH_CLPS7500
-#define IOMD_IRQSTATC __IOMD(0x060)
-#define IOMD_IRQREQC __IOMD(0x064)
-#define IOMD_IRQMASKC __IOMD(0x068)
-
-#define IOMD_VIDMUX __IOMD(0x06c)
-
-#define IOMD_IRQSTATD __IOMD(0x070)
-#define IOMD_IRQREQD __IOMD(0x074)
-#define IOMD_IRQMASKD __IOMD(0x078)
-#endif
-
-#define IOMD_ROMCR0 __IOMD(0x080)
-#define IOMD_ROMCR1 __IOMD(0x084)
-#ifdef CONFIG_ARCH_RPC
-#define IOMD_DRAMCR __IOMD(0x088)
-#endif
-#define IOMD_REFCR __IOMD(0x08C)
-
-#define IOMD_FSIZE __IOMD(0x090)
-#define IOMD_ID0 __IOMD(0x094)
-#define IOMD_ID1 __IOMD(0x098)
-#define IOMD_VERSION __IOMD(0x09C)
-
-#ifdef CONFIG_ARCH_RPC
-#define IOMD_MOUSEX __IOMD(0x0A0)
-#define IOMD_MOUSEY __IOMD(0x0A4)
-#endif
-
-#ifdef CONFIG_ARCH_CLPS7500
-#define IOMD_MSEDAT __IOMD(0x0A8)
-#define IOMD_MSECTL __IOMD(0x0Ac)
-#endif
-
-#ifdef CONFIG_ARCH_RPC
-#define IOMD_DMATCR __IOMD(0x0C0)
-#endif
-#define IOMD_IOTCR __IOMD(0x0C4)
-#define IOMD_ECTCR __IOMD(0x0C8)
-#ifdef CONFIG_ARCH_RPC
-#define IOMD_DMAEXT __IOMD(0x0CC)
-#endif
-#ifdef CONFIG_ARCH_CLPS7500
-#define IOMD_ASTCR __IOMD(0x0CC)
-#define IOMD_DRAMCR __IOMD(0x0D0)
-#define IOMD_SELFREF __IOMD(0x0D4)
-#define IOMD_ATODICR __IOMD(0x0E0)
-#define IOMD_ATODSR __IOMD(0x0E4)
-#define IOMD_ATODCC __IOMD(0x0E8)
-#define IOMD_ATODCNT1 __IOMD(0x0EC)
-#define IOMD_ATODCNT2 __IOMD(0x0F0)
-#define IOMD_ATODCNT3 __IOMD(0x0F4)
-#define IOMD_ATODCNT4 __IOMD(0x0F8)
-#endif
-
-#ifdef CONFIG_ARCH_RPC
-#define DMA_EXT_IO0 1
-#define DMA_EXT_IO1 2
-#define DMA_EXT_IO2 4
-#define DMA_EXT_IO3 8
-
-#define IOMD_IO0CURA __IOMD(0x100)
-#define IOMD_IO0ENDA __IOMD(0x104)
-#define IOMD_IO0CURB __IOMD(0x108)
-#define IOMD_IO0ENDB __IOMD(0x10C)
-#define IOMD_IO0CR __IOMD(0x110)
-#define IOMD_IO0ST __IOMD(0x114)
-
-#define IOMD_IO1CURA __IOMD(0x120)
-#define IOMD_IO1ENDA __IOMD(0x124)
-#define IOMD_IO1CURB __IOMD(0x128)
-#define IOMD_IO1ENDB __IOMD(0x12C)
-#define IOMD_IO1CR __IOMD(0x130)
-#define IOMD_IO1ST __IOMD(0x134)
-
-#define IOMD_IO2CURA __IOMD(0x140)
-#define IOMD_IO2ENDA __IOMD(0x144)
-#define IOMD_IO2CURB __IOMD(0x148)
-#define IOMD_IO2ENDB __IOMD(0x14C)
-#define IOMD_IO2CR __IOMD(0x150)
-#define IOMD_IO2ST __IOMD(0x154)
-
-#define IOMD_IO3CURA __IOMD(0x160)
-#define IOMD_IO3ENDA __IOMD(0x164)
-#define IOMD_IO3CURB __IOMD(0x168)
-#define IOMD_IO3ENDB __IOMD(0x16C)
-#define IOMD_IO3CR __IOMD(0x170)
-#define IOMD_IO3ST __IOMD(0x174)
-#endif
-
-#define IOMD_SD0CURA __IOMD(0x180)
-#define IOMD_SD0ENDA __IOMD(0x184)
-#define IOMD_SD0CURB __IOMD(0x188)
-#define IOMD_SD0ENDB __IOMD(0x18C)
-#define IOMD_SD0CR __IOMD(0x190)
-#define IOMD_SD0ST __IOMD(0x194)
-
-#ifdef CONFIG_ARCH_RPC
-#define IOMD_SD1CURA __IOMD(0x1A0)
-#define IOMD_SD1ENDA __IOMD(0x1A4)
-#define IOMD_SD1CURB __IOMD(0x1A8)
-#define IOMD_SD1ENDB __IOMD(0x1AC)
-#define IOMD_SD1CR __IOMD(0x1B0)
-#define IOMD_SD1ST __IOMD(0x1B4)
-#endif
-
-#define IOMD_CURSCUR __IOMD(0x1C0)
-#define IOMD_CURSINIT __IOMD(0x1C4)
-
-#define IOMD_VIDCUR __IOMD(0x1D0)
-#define IOMD_VIDEND __IOMD(0x1D4)
-#define IOMD_VIDSTART __IOMD(0x1D8)
-#define IOMD_VIDINIT __IOMD(0x1DC)
-#define IOMD_VIDCR __IOMD(0x1E0)
-
-#define IOMD_DMASTAT __IOMD(0x1F0)
-#define IOMD_DMAREQ __IOMD(0x1F4)
-#define IOMD_DMAMASK __IOMD(0x1F8)
-
-#define DMA_END_S (1 << 31)
-#define DMA_END_L (1 << 30)
-
-#define DMA_CR_C 0x80
-#define DMA_CR_D 0x40
-#define DMA_CR_E 0x20
-
-#define DMA_ST_OFL 4
-#define DMA_ST_INT 2
-#define DMA_ST_AB 1
-
-#ifndef IOC_CONTROL
-/*
- * IOC compatability
- */
-#define IOC_CONTROL IOMD_CONTROL
-#define IOC_IRQSTATA IOMD_IRQSTATA
-#define IOC_IRQREQA IOMD_IRQREQA
-#define IOC_IRQCLRA IOMD_IRQCLRA
-#define IOC_IRQMASKA IOMD_IRQMASKA
-
-#define IOC_IRQSTATB IOMD_IRQSTATB
-#define IOC_IRQREQB IOMD_IRQREQB
-#define IOC_IRQMASKB IOMD_IRQMASKB
-
-#define IOC_FIQSTAT IOMD_FIQSTAT
-#define IOC_FIQREQ IOMD_FIQREQ
-#define IOC_FIQMASK IOMD_FIQMASK
-
-#define IOC_T0CNTL IOMD_T0CNTL
-#define IOC_T0LTCHL IOMD_T0LTCHL
-#define IOC_T0CNTH IOMD_T0CNTH
-#define IOC_T0LTCHH IOMD_T0LTCHH
-#define IOC_T0GO IOMD_T0GO
-#define IOC_T0LATCH IOMD_T0LATCH
-
-#define IOC_T1CNTL IOMD_T1CNTL
-#define IOC_T1LTCHL IOMD_T1LTCHL
-#define IOC_T1CNTH IOMD_T1CNTH
-#define IOC_T1LTCHH IOMD_T1LTCHH
-#define IOC_T1GO IOMD_T1GO
-#define IOC_T1LATCH IOMD_T1LATCH
-#endif
-
-/*
- * DMA (MEMC) compatability
- */
-#define HALF_SAM vram_half_sam
-#define VDMA_ALIGNMENT (HALF_SAM * 2)
-#define VDMA_XFERSIZE (HALF_SAM)
-#define VDMA_INIT IOMD_VIDINIT
-#define VDMA_START IOMD_VIDSTART
-#define VDMA_END IOMD_VIDEND
-
-#ifndef __ASSEMBLY__
-extern unsigned int vram_half_sam;
-#define video_set_dma(start,end,offset) \
-do { \
- outl (SCREEN_START + start, VDMA_START); \
- outl (SCREEN_START + end - VDMA_XFERSIZE, VDMA_END); \
- if (offset >= end - VDMA_XFERSIZE) \
- offset |= 0x40000000; \
- outl (SCREEN_START + offset, VDMA_INIT); \
-} while (0)
-#endif
-
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/keyboard.h linux/include/asm-arm/keyboard.h
--- v2.4.0-test8/linux/include/asm-arm/keyboard.h Thu Dec 17 09:05:43 1998
+++ linux/include/asm-arm/keyboard.h Mon Sep 18 15:15:23 2000


@@ -1,9 +1,13 @@
X /*

- * linux/include/asm-arm/keyboard.h
+ * linux/include/asm-arm/keyboard.h
X *
- * Keyboard driver definitions for ARM


+ * Copyright (C) 1998 Russell King

X *
- * (C) 1998 Russell King


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Keyboard driver definitions for ARM
X */
X #ifndef __ASM_ARM_KEYBOARD_H
X #define __ASM_ARM_KEYBOARD_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/leds.h linux/include/asm-arm/leds.h
--- v2.4.0-test8/linux/include/asm-arm/leds.h Sun Aug 13 09:54:15 2000
+++ linux/include/asm-arm/leds.h Mon Sep 18 15:15:23 2000
@@ -1,11 +1,14 @@
X /*
- * include/asm-arm/leds.h
+ * linux/include/asm-arm/leds.h
X *
- * Copyright (C) 1998 Russell King
+ * Copyright (C) 1998 Russell King
X *
- * Event-driven interface for LEDs on machines


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X *

- * Added led_start and led_stop- Alex Holden, 28th Dec 1998.
+ * Event-driven interface for LEDs on machines
+ * Added led_start and led_stop- Alex Holden, 28th Dec 1998.
X */
X #ifndef ASM_ARM_LEDS_H
X #define ASM_ARM_LEDS_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/linux_logo.h linux/include/asm-arm/linux_logo.h
--- v2.4.0-test8/linux/include/asm-arm/linux_logo.h Thu Dec 17 09:05:43 1998
+++ linux/include/asm-arm/linux_logo.h Mon Sep 18 15:15:23 2000


@@ -1,9 +1,13 @@
X /*

- * linux/include/asm-arm/linux_logo.h
+ * linux/include/asm-arm/linux_logo.h
X *
- * Copyright (C) 1998 Russell King
+ * Copyright (C) 1998 Russell King
X *
- * Linux console driver logo definitions for ARM


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Linux console driver logo definitions for ARM
X */
X
X #include <linux/init.h>
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/mach/arch.h linux/include/asm-arm/mach/arch.h
--- v2.4.0-test8/linux/include/asm-arm/mach/arch.h Sun Sep 3 11:19:11 2000
+++ linux/include/asm-arm/mach/arch.h Mon Sep 18 15:15:23 2000


@@ -1,7 +1,11 @@
X /*

- * linux/include/asm-arm/mach/arch.h
+ * linux/include/asm-arm/mach/arch.h
X *
- * Copyright (C) 2000 Russell King


+ * Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

X */
X
X /*

diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/mach/dma.h linux/include/asm-arm/mach/dma.h
--- v2.4.0-test8/linux/include/asm-arm/mach/dma.h Sun Sep 3 11:19:11 2000
+++ linux/include/asm-arm/mach/dma.h Mon Sep 18 15:15:23 2000
@@ -1,10 +1,14 @@
X /*
- * linux/arch/arm/kernel/dma.h
+ * linux/include/asm-arm/mach/dma.h
X *
- * Copyright (C) 1998-2000 Russell King
+ * Copyright (C) 1998-2000 Russell King
X *
- * This header file describes the interface between the generic DMA handler
- * (dma.c) and the architecture-specific DMA backends (dma-*.c)


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * This header file describes the interface between the generic DMA handler
+ * (dma.c) and the architecture-specific DMA backends (dma-*.c)
X */
X
X struct dma_struct;
@@ -46,4 +50,6 @@
X * Purpose : Initialise architecture specific DMA
X * Params : dma - pointer to array of DMA structures
X */
-void arch_dma_init(dma_t *dma);
+extern void arch_dma_init(dma_t *dma);
+
+extern void isa_init_dma(dma_t *dma);
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/mach/map.h linux/include/asm-arm/mach/map.h
--- v2.4.0-test8/linux/include/asm-arm/mach/map.h Sun Sep 3 11:19:11 2000
+++ linux/include/asm-arm/mach/map.h Mon Sep 18 15:15:23 2000
@@ -3,6 +3,10 @@
X *
X * Copyright (C) 1999-2000 Russell King
X *


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

X * Page table mapping constructs and function prototypes
X */
X struct map_desc {
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/mach/pci.h linux/include/asm-arm/mach/pci.h
--- v2.4.0-test8/linux/include/asm-arm/mach/pci.h Sun Sep 3 11:19:11 2000
+++ linux/include/asm-arm/mach/pci.h Mon Sep 18 15:15:23 2000
@@ -1,5 +1,11 @@
X /*
- * linux/include/asm-arm/mach/pci.h
+ * linux/include/asm-arm/mach/pci.h


+ *
+ * Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

X */
X #define MAX_NR_BUS 2
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/memc.h linux/include/asm-arm/memc.h
--- v2.4.0-test8/linux/include/asm-arm/memc.h Wed Oct 20 16:29:08 1999
+++ linux/include/asm-arm/memc.h Wed Dec 31 16:00:00 1969
@@ -1,17 +0,0 @@
-#define VDMA_ALIGNMENT PAGE_SIZE
-#define VDMA_XFERSIZE 16
-#define VDMA_INIT 0
-#define VDMA_START 1
-#define VDMA_END 2
-
-#ifndef __ASSEMBLY__
-extern void memc_write(unsigned int reg, unsigned long val);
-
-#define video_set_dma(start,end,offset) \
-do { \
- memc_write (VDMA_START, (start >> 2)); \
- memc_write (VDMA_END, (end - VDMA_XFERSIZE) >> 2); \
- memc_write (VDMA_INIT, (offset >> 2)); \
-} while (0)
-
-#endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/memory.h linux/include/asm-arm/memory.h
--- v2.4.0-test8/linux/include/asm-arm/memory.h Mon Jun 26 12:04:42 2000
+++ linux/include/asm-arm/memory.h Mon Sep 18 15:15:24 2000
@@ -1,11 +1,15 @@
X /*
- * linux/include/asm-arm/memory.h
+ * linux/include/asm-arm/memory.h
X *
- * Copyright (C) 2000 Russell King


+ * Copyright (C) 2000 Russell King

X *
- * Note: this file should not be included by non-asm/.h files


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X *

- * Modifications:
+ * Note: this file should not be included by non-asm/.h files


+ *
+ * Modifications:

X */
X #ifndef __ASM_ARM_MEMORY_H
X #define __ASM_ARM_MEMORY_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/mmu_context.h linux/include/asm-arm/mmu_context.h
--- v2.4.0-test8/linux/include/asm-arm/mmu_context.h Sun Sep 3 11:19:11 2000
+++ linux/include/asm-arm/mmu_context.h Mon Sep 18 15:15:24 2000
@@ -1,10 +1,14 @@
X /*
- * linux/include/asm-arm/mmu_context.h
+ * linux/include/asm-arm/mmu_context.h


X *
- * Copyright (c) 1996 Russell King.

+ * Copyright (C) 1996 Russell King.


X *
- * Changelog:
- * 27-06-1996 RMK Created

+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Changelog:
+ * 27-06-1996 RMK Created

X */
X #ifndef __ASM_ARM_MMU_CONTEXT_H
X #define __ASM_ARM_MMU_CONTEXT_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/mmzone.h linux/include/asm-arm/mmzone.h
--- v2.4.0-test8/linux/include/asm-arm/mmzone.h Mon Jun 19 17:59:35 2000
+++ linux/include/asm-arm/mmzone.h Mon Sep 18 15:15:24 2000
@@ -1,9 +1,12 @@
X /*
- * linux/include/asm-arm/mmzone.h
+ * linux/include/asm-arm/mmzone.h
X *
- * 1999-12-29 Nicolas Pitre Created
+ * 1999-12-29 Nicolas Pitre Created


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X */

-
X #ifndef __ASM_MMZONE_H
X #define __ASM_MMZONE_H
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/param.h linux/include/asm-arm/param.h
--- v2.4.0-test8/linux/include/asm-arm/param.h Wed Oct 20 16:29:08 1999
+++ linux/include/asm-arm/param.h Mon Sep 18 15:15:24 2000


@@ -1,7 +1,11 @@
X /*

- * linux/include/asm-arm/param.h
+ * linux/include/asm-arm/param.h
X *
- * Copyright (C) 1995-1999 Russell King
+ * Copyright (C) 1995-1999 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X */

X #ifndef __ASM_PARAM_H
X #define __ASM_PARAM_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/parport.h linux/include/asm-arm/parport.h
--- v2.4.0-test8/linux/include/asm-arm/parport.h Tue Mar 14 18:04:50 2000
+++ linux/include/asm-arm/parport.h Mon Sep 18 15:15:24 2000
@@ -1,7 +1,7 @@
X /*
- * parport.h: ARM-specific parport initialisation
+ * linux/include/asm-arm/parport.h: ARM-specific parport initialisation
X *
- * Copyright (C) 1999, 2000 Tim Waugh <t...@cyberelk.demon.co.uk>
+ * Copyright (C) 1999, 2000 Tim Waugh <t...@cyberelk.demon.co.uk>
X *
X * This file should only be included by drivers/parport/parport_pc.c.
X */
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/pgalloc.h linux/include/asm-arm/pgalloc.h
--- v2.4.0-test8/linux/include/asm-arm/pgalloc.h Sun Sep 3 11:19:11 2000
+++ linux/include/asm-arm/pgalloc.h Mon Sep 18 15:15:24 2000
@@ -1,5 +1,11 @@
X /*
- * linux/include/asm-arm/pgalloc.h
+ * linux/include/asm-arm/pgalloc.h


+ *
+ * Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

X */
X #ifndef _ASMARM_PGALLOC_H
X #define _ASMARM_PGALLOC_H
@@ -49,7 +55,7 @@
X if ((ret = pgd_quicklist) != NULL) {
X pgd_quicklist = (unsigned long *)__pgd_next(ret);
X ret[1] = ret[2];
- clean_cache_area(ret + 1, 4);
+ clean_dcache_entry(ret + 1);
X pgtable_cache_size--;
X }
X return (pgd_t *)ret;
@@ -76,7 +82,7 @@
X if((ret = pte_quicklist) != NULL) {
X pte_quicklist = (unsigned long *)__pte_next(ret);
X ret[0] = ret[1];
- clean_cache_area(ret, 4);
+ clean_dcache_entry(ret);
X pgtable_cache_size--;
X }
X return (pte_t *)ret;
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/pgtable.h linux/include/asm-arm/pgtable.h
--- v2.4.0-test8/linux/include/asm-arm/pgtable.h Sun Aug 13 09:54:15 2000
+++ linux/include/asm-arm/pgtable.h Mon Sep 18 15:15:24 2000
@@ -1,5 +1,11 @@
X /*
- * linux/include/asm-arm/pgtable.h
+ * linux/include/asm-arm/pgtable.h


+ *
+ * Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

X */
X #ifndef _ASMARM_PGTABLE_H
X #define _ASMARM_PGTABLE_H
@@ -88,7 +94,7 @@
X * which, if __va and __pa are expensive causes twice the expense for
X * zero gain. --rmk
X */
-#define pte_page(x) (mem_map + MAP_NR(__va(pte_val((x)))))
+#define pte_page(x) (virt_to_page(__va(pte_val((x)))))
X #endif
X
X #define pmd_none(pmd) (!pmd_val(pmd))
@@ -172,6 +178,10 @@
X
X #define module_map vmalloc
X #define module_unmap vfree
+
+/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
+/* FIXME: this is not correct */
+#define kern_addr_valid(addr) (1)
X
X #define io_remap_page_range remap_page_range
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/posix_types.h linux/include/asm-arm/posix_types.h
--- v2.4.0-test8/linux/include/asm-arm/posix_types.h Sat Jan 15 22:08:28 2000
+++ linux/include/asm-arm/posix_types.h Mon Sep 18 15:15:24 2000
@@ -1,10 +1,14 @@
X /*
- * linux/include/asm-arm/posix_types.h
+ * linux/include/asm-arm/posix_types.h
X *
- * Copyright (c) 1996-1998 Russell King.
+ * Copyright (C) 1996-1998 Russell King.


X *
- * Changelog:
- * 27-06-1996 RMK Created

+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Changelog:
+ * 27-06-1996 RMK Created

X */
X #ifndef __ARCH_ARM_POSIX_TYPES_H
X #define __ARCH_ARM_POSIX_TYPES_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/proc-armo/assembler.h linux/include/asm-arm/proc-armo/assembler.h
--- v2.4.0-test8/linux/include/asm-arm/proc-armo/assembler.h Sun Sep 3 11:19:11 2000
+++ linux/include/asm-arm/proc-armo/assembler.h Mon Sep 18 15:15:24 2000
@@ -1,10 +1,14 @@
X /*
- * linux/asm-arm/proc-armo/assembler.h
+ * linux/asm-arm/proc-armo/assembler.h


X *
- * Copyright (C) 1996 Russell King
+ * Copyright (C) 1996 Russell King
X *

- * This file contains arm architecture specific defines
- * for the different processors


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * This file contains arm architecture specific defines
+ * for the different processors
X */
X #define MODE_USR USR26_MODE
X #define MODE_FIQ FIQ26_MODE
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/proc-armo/cache.h linux/include/asm-arm/proc-armo/cache.h
--- v2.4.0-test8/linux/include/asm-arm/proc-armo/cache.h Sun Sep 3 11:19:11 2000
+++ linux/include/asm-arm/proc-armo/cache.h Mon Sep 18 15:15:24 2000
@@ -1,5 +1,13 @@
X /*
- * Cache handling for 26-bit ARM processors.
+ * linux/include/asm-arm/proc-armo/cache.h
+ *
+ * Copyright (C) 1999-2000 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Cache handling for 26-bit ARM processors.
X */
X #define flush_cache_all() do { } while (0)
X #define flush_cache_mm(mm) do { } while (0)
@@ -74,6 +82,3 @@
X if (mm == current->active_mm)
X processor._set_pgd(mm->pgd);
X }
-
-#define __flush_entry_to_ram(entry)
-
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/proc-armo/io.h linux/include/asm-arm/proc-armo/io.h
--- v2.4.0-test8/linux/include/asm-arm/proc-armo/io.h Sun Sep 6 10:45:30 1998
+++ linux/include/asm-arm/proc-armo/io.h Wed Dec 31 16:00:00 1969
@@ -1,8 +0,0 @@
-/*
- * linux/include/asm-arm/proc-armo/io.h
- */
-
-/* Nothing to do */
-#define dma_cache_inv(_start,_size) do { } while (0)
-#define dma_cache_wback(_start,_size) do { } while (0)
-#define dma_cache_wback_inv(_start,_size) do { } while (0)
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/proc-armo/locks.h linux/include/asm-arm/proc-armo/locks.h
--- v2.4.0-test8/linux/include/asm-arm/proc-armo/locks.h Sun Sep 3 11:19:11 2000
+++ linux/include/asm-arm/proc-armo/locks.h Mon Sep 18 15:15:24 2000
@@ -1,11 +1,14 @@
X /*
- * linux/include/asm-arm/proc-armo/locks.h
+ * linux/include/asm-arm/proc-armo/locks.h
X *
- * Copyright (C) 2000 Russell King
- * Fixes for 26 bit machines, (C) 2000 Dave Gilbert


+ * Copyright (C) 2000 Russell King

+ * Fixes for 26 bit machines, (C) 2000 Dave Gilbert
X *
- * Interrupt safe locking assembler.

+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X *

+ * Interrupt safe locking assembler.
X */
X #ifndef __ASM_PROC_LOCKS_H
X #define __ASM_PROC_LOCKS_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/proc-armo/page.h linux/include/asm-arm/proc-armo/page.h
--- v2.4.0-test8/linux/include/asm-arm/proc-armo/page.h Wed Oct 20 16:29:08 1999
+++ linux/include/asm-arm/proc-armo/page.h Mon Sep 18 15:15:24 2000


@@ -1,7 +1,11 @@
X /*

- * linux/include/asm-arm/proc-armo/page.h
+ * linux/include/asm-arm/proc-armo/page.h
X *
- * Copyright (C) 1995, 1996 Russell King
+ * Copyright (C) 1995, 1996 Russell King
+ *


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X */

X #ifndef __ASM_PROC_PAGE_H
X #define __ASM_PROC_PAGE_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/proc-armo/pgtable.h linux/include/asm-arm/proc-armo/pgtable.h
--- v2.4.0-test8/linux/include/asm-arm/proc-armo/pgtable.h Thu Oct 28 10:16:02 1999
+++ linux/include/asm-arm/proc-armo/pgtable.h Mon Sep 18 15:15:24 2000


@@ -1,9 +1,13 @@
X /*

- * linux/include/asm-arm/proc-armo/pgtable.h
+ * linux/include/asm-arm/proc-armo/pgtable.h
X *
- * Copyright (C) 1995-1999 Russell King
+ * Copyright (C) 1995-1999 Russell King
X *
- * 18-Oct-1997 RMK Now two-level (32x32)


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * 18-Oct-1997 RMK Now two-level (32x32)
X */
X #ifndef __ASM_PROC_PGTABLE_H
X #define __ASM_PROC_PGTABLE_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/proc-armo/processor.h linux/include/asm-arm/proc-armo/processor.h
--- v2.4.0-test8/linux/include/asm-arm/proc-armo/processor.h Tue Nov 23 22:23:11 1999
+++ linux/include/asm-arm/proc-armo/processor.h Mon Sep 18 15:15:24 2000
@@ -1,16 +1,20 @@
X /*
- * linux/include/asm-arm/proc-armo/processor.h
+ * linux/include/asm-arm/proc-armo/processor.h


X *
- * Copyright (c) 1996 Russell King.

+ * Copyright (C) 1996 Russell King.


X *
- * Changelog:
- * 27-06-1996 RMK Created

- * 10-10-1996 RMK Brought up to date with SA110
- * 26-09-1996 RMK Added 'EXTRA_THREAD_STRUCT*'
- * 28-09-1996 RMK Moved start_thread into the processor dependencies
- * 11-01-1998 RMK Added new uaccess_t
- * 09-09-1998 PJB Delete redundant `wp_works_ok'
- * 30-05-1999 PJB Save sl across context switches


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Changelog:
+ * 27-06-1996 RMK Created

+ * 10-10-1996 RMK Brought up to date with SA110
+ * 26-09-1996 RMK Added 'EXTRA_THREAD_STRUCT*'
+ * 28-09-1996 RMK Moved start_thread into the processor dependencies
+ * 11-01-1998 RMK Added new uaccess_t
+ * 09-09-1998 PJB Delete redundant `wp_works_ok'
+ * 30-05-1999 PJB Save sl across context switches
X */
X #ifndef __ASM_PROC_PROCESSOR_H
X #define __ASM_PROC_PROCESSOR_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/proc-armo/ptrace.h linux/include/asm-arm/proc-armo/ptrace.h
--- v2.4.0-test8/linux/include/asm-arm/proc-armo/ptrace.h Wed Oct 20 16:29:08 1999
+++ linux/include/asm-arm/proc-armo/ptrace.h Mon Sep 18 15:15:24 2000


@@ -1,7 +1,11 @@
X /*

- * linux/include/asm-arm/proc-armo/ptrace.h
+ * linux/include/asm-arm/proc-armo/ptrace.h
X *
- * Copyright (C) 1996-1999 Russell King
+ * Copyright (C) 1996-1999 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X */

X #ifndef __ASM_PROC_PTRACE_H
X #define __ASM_PROC_PTRACE_H
@@ -53,6 +57,8 @@
X
X #define user_mode(regs) \
X (processor_mode(regs) == USR26_MODE)
+
+#define thumb_mode(regs) (0)
X
X #define interrupts_enabled(regs) \
X (!((regs)->ARM_pc & I_BIT))
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/proc-armo/shmparam.h linux/include/asm-arm/proc-armo/shmparam.h
--- v2.4.0-test8/linux/include/asm-arm/proc-armo/shmparam.h Wed Nov 3 11:31:09 1999
+++ linux/include/asm-arm/proc-armo/shmparam.h Mon Sep 18 15:15:24 2000
@@ -1,11 +1,14 @@
X /*
- * linux/include/asm-arm/proc-armo/shmparam.h
+ * linux/include/asm-arm/proc-armo/shmparam.h


X *
- * Copyright (C) 1996 Russell King
+ * Copyright (C) 1996 Russell King
X *

- * definitions for the shared process memory on the ARM3


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * definitions for the shared process memory on the ARM3
X */
-
X #ifndef __ASM_PROC_SHMPARAM_H
X #define __ASM_PROC_SHMPARAM_H
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/proc-armo/system.h linux/include/asm-arm/proc-armo/system.h
--- v2.4.0-test8/linux/include/asm-arm/proc-armo/system.h Sun Aug 13 09:54:15 2000
+++ linux/include/asm-arm/proc-armo/system.h Mon Sep 18 15:15:24 2000
@@ -1,9 +1,12 @@
X /*
- * linux/include/asm-arm/proc-armo/system.h
+ * linux/include/asm-arm/proc-armo/system.h
X *
- * Copyright (C) 1995, 1996 Russell King
+ * Copyright (C) 1995, 1996 Russell King
+ *


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X */

-
X #ifndef __ASM_PROC_SYSTEM_H
X #define __ASM_PROC_SYSTEM_H
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/proc-armo/uaccess.h linux/include/asm-arm/proc-armo/uaccess.h
--- v2.4.0-test8/linux/include/asm-arm/proc-armo/uaccess.h Wed Oct 20 16:29:08 1999
+++ linux/include/asm-arm/proc-armo/uaccess.h Mon Sep 18 15:15:24 2000


@@ -1,7 +1,11 @@
X /*

- * linux/include/asm-arm/proc-armo/segment.h
+ * linux/include/asm-arm/proc-armo/segment.h


X *
- * Copyright (C) 1996 Russell King
+ * Copyright (C) 1996 Russell King

+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X */
X

X /*
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/proc-armo/uncompress.h linux/include/asm-arm/proc-armo/uncompress.h
--- v2.4.0-test8/linux/include/asm-arm/proc-armo/uncompress.h Tue Jan 20 16:39:43 1998
+++ linux/include/asm-arm/proc-armo/uncompress.h Mon Sep 18 15:15:24 2000


@@ -1,7 +1,11 @@
X /*

- * linux/include/asm-arm/proc-armo/uncompress.h
+ * linux/include/asm-arm/proc-armo/uncompress.h
X *
- * (c) 1997 Russell King
+ * Copyright (C) 1997 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X */
X

X #define proc_decomp_setup()
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/proc-armv/assembler.h linux/include/asm-arm/proc-armv/assembler.h
--- v2.4.0-test8/linux/include/asm-arm/proc-armv/assembler.h Sun Sep 3 11:19:11 2000
+++ linux/include/asm-arm/proc-armv/assembler.h Mon Sep 18 15:15:24 2000
@@ -1,10 +1,14 @@
X /*
- * linux/asm-arm/proc-armv/assembler.h
+ * linux/asm-arm/proc-armv/assembler.h


X *
- * Copyright (C) 1996-2000 Russell King
+ * Copyright (C) 1996-2000 Russell King

X *
- * This file contains ARM processor specifics for
- * the ARM6 and better processors.


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * This file contains ARM processor specifics for
+ * the ARM6 and better processors.
X */
X #define MODE_USR USR_MODE
X #define MODE_FIQ FIQ_MODE
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/proc-armv/cache.h linux/include/asm-arm/proc-armv/cache.h
--- v2.4.0-test8/linux/include/asm-arm/proc-armv/cache.h Sun Aug 6 11:43:18 2000
+++ linux/include/asm-arm/proc-armv/cache.h Mon Sep 18 15:15:24 2000
@@ -1,57 +1,98 @@
+/*
+ * linux/include/asm-arm/proc-armv/cache.h
+ *
+ * Copyright (C) 1999-2000 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */

X #include <asm/mman.h>
X
X /*
- * Cache flushing...
+ * Cache handling for 32-bit ARM processors.
+ *
+ * Note that on ARM, we have a more accurate specification than that
+ * Linux's "flush". We therefore do not use "flush" here, but instead
+ * use:
+ *
+ * clean: the act of pushing dirty cache entries out to memory.
+ * invalidate: the act of discarding data held within the cache,
+ * whether it is dirty or not.
+ */
+
+/*
+ * Generic I + D cache
X */
X #define flush_cache_all() \
- cpu_flush_cache_all()
+ do { \
+ cpu_cache_clean_invalidate_all(); \
+ } while (0)
X
+/* This is always called for current->mm */
X #define flush_cache_mm(_mm) \
X do { \
- if ((_mm) == current->mm) \
- cpu_flush_cache_all(); \
+ if ((_mm) == current->active_mm) \
+ cpu_cache_clean_invalidate_all(); \
X } while (0)
X
X #define flush_cache_range(_mm,_start,_end) \
X do { \
X if ((_mm) == current->mm) \
- cpu_flush_cache_area((_start), (_end), 1); \
+ cpu_cache_clean_invalidate_range((_start), (_end), 1); \
X } while (0)
X
X #define flush_cache_page(_vma,_vmaddr) \
X do { \
- if ((_vma)->vm_mm == current->mm) \
- cpu_flush_cache_area((_vmaddr), \
+ if ((_vma)->vm_mm == current->mm) { \
+ cpu_cache_clean_invalidate_range((_vmaddr), \
X (_vmaddr) + PAGE_SIZE, \
X ((_vma)->vm_flags & VM_EXEC)); \
+ } \
X } while (0)
X
-#define clean_cache_range(_start,_end) \
- do { \
- unsigned long _s, _sz; \
- _s = (unsigned long)_start; \
- _sz = (unsigned long)_end - _s; \
- cpu_clean_cache_area(_s, _sz); \
- } while (0)
+/*
+ * This flushes back any buffered write data. We have to clean the entries
+ * in the cache for this page. This does not invalidate either I or D caches.
+ */
+static __inline__ void flush_page_to_ram(struct page *page)
+{
+ cpu_flush_ram_page(page_address(page));
+}
X
-#define clean_cache_area(_start,_size) \
+/*
+ * D cache only
+ */
+
+#define invalidate_dcache_range(_s,_e) cpu_dcache_invalidate_range((_s),(_e))
+#define clean_dcache_range(_s,_e) cpu_dcache_clean_range((_s),(_e))
+#define flush_dcache_range(_s,_e) cpu_cache_clean_invalidate_range((_s),(_e),0)
+
+/*
+ * FIXME: We currently clean the dcache for this page. Should we
+ * also invalidate the Dcache? And what about the Icache? -- rmk
+ */
+#define flush_dcache_page(page) cpu_dcache_clean_page(page_address(page))
+
+#define clean_dcache_entry(_s) cpu_dcache_clean_entry((unsigned long)(_s))
+
+/*
+ * I cache only
+ */
+#define flush_icache_range(_s,_e) \
X do { \
- unsigned long _s; \
- _s = (unsigned long)_start; \
- cpu_clean_cache_area(_s, _size); \
+ cpu_icache_invalidate_range((_s), (_e)); \
X } while (0)
X
-#define flush_icache_range(_start,_end) \
- cpu_flush_icache_area((_start), (_end) - (_start))
-
X #define flush_icache_page(vma,pg) \
X do { \
X if ((vma)->vm_flags & PROT_EXEC) \
- cpu_flush_icache_page((unsigned long) page_address(pg)); \
+ cpu_icache_invalidate_page(page_address(pg)); \
X } while (0)
X
X /*
- * We don't have a MEMC chip...
+ * Old ARM MEMC stuff. This supports the reversed mapping handling that
+ * we have on the older 26-bit machines. We don't have a MEMC chip, so...
X */
X #define memc_update_all() do { } while (0)
X #define memc_update_mm(mm) do { } while (0)
@@ -59,48 +100,57 @@
X #define memc_clear(mm,physaddr) do { } while (0)
X
X /*
- * This flushes back any buffered write data. We have to clean the entries
- * in the cache for this page. This does not invalidate either I or D caches.
- */
-static __inline__ void flush_page_to_ram(struct page *page)
-{
- cpu_flush_ram_page((unsigned long) page_address(page));
-}
-
-/* You guys might need to do something here. -DaveM */
-#define flush_dcache_page(page) do { } while (0)
-
-/*
- * TLB flushing:
+ * TLB flushing.
X *
- * - flush_tlb_all() flushes all processes TLBs
- * - flush_tlb_mm(mm) flushes the specified mm context TLB's
- * - flush_tlb_page(vma, vmaddr) flushes one page
- * - flush_tlb_range(mm, start, end) flushes a range of pages
+ * - flush_tlb_all() flushes all processes TLBs
+ * - flush_tlb_mm(mm) flushes the specified mm context TLB's
+ * - flush_tlb_page(vma, vmaddr) flushes TLB for specified page
+ * - flush_tlb_range(mm, start, end) flushes TLB for specified range of pages
X *
X * We drain the write buffer in here to ensure that the page tables in ram
X * are really up to date. It is more efficient to do this here...
X */
-#define flush_tlb_all() \
- cpu_flush_tlb_all()
X
-#define flush_tlb_mm(_mm) \
- do { \
- if ((_mm) == current->mm) \
- cpu_flush_tlb_all(); \
- } while (0)
-
-#define flush_tlb_range(_mm,_start,_end) \
- do { \
- if ((_mm) == current->mm) \
- cpu_flush_tlb_area((_start), (_end), 1); \
- } while (0)
-
-#define flush_tlb_page(_vma,_vmaddr) \
- do { \
- if ((_vma)->vm_mm == current->mm) \
- cpu_flush_tlb_page((_vmaddr), \
- ((_vma)->vm_flags & VM_EXEC)); \
+/*
+ * Notes:
+ * current->active_mm is the currently active memory description.
+ * current->mm == NULL iff we are lazy.
+ */
+#define flush_tlb_all() \
+ do { \
+ cpu_tlb_invalidate_all(); \
X } while (0)
X
+/*
+ * Flush all user virtual address space translations described by `_mm'.
+ *
+ * Currently, this is always called for current->mm, which should be
+ * the same as current->active_mm. This is currently not be called for
+ * the lazy TLB case.
+ */
+#define flush_tlb_mm(_mm) \
+ do { \
+ if ((_mm) == current->active_mm) \
+ cpu_tlb_invalidate_all(); \
+ } while (0)
+
+/*
+ * Flush the specified range of user virtual address space translations.
+ *
+ * _mm may not be current->active_mm, but may not be NULL.
+ */
+#define flush_tlb_range(_mm,_start,_end) \
+ do { \
+ if ((_mm) == current->active_mm) \
+ cpu_tlb_invalidate_range((_start), (_end)); \
+ } while (0)
X
+/*
+ * Flush the specified user virtual address space translation.
+ */
+#define flush_tlb_page(_vma,_page) \
+ do { \
+ if ((_vma)->vm_mm == current->active_mm) \
+ cpu_tlb_invalidate_page((_page), \
+ ((_vma)->vm_flags & VM_EXEC)); \
+ } while (0)
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/proc-armv/domain.h linux/include/asm-arm/proc-armv/domain.h
--- v2.4.0-test8/linux/include/asm-arm/proc-armv/domain.h Mon Aug 2 10:19:52 1999
+++ linux/include/asm-arm/proc-armv/domain.h Mon Sep 18 15:15:24 2000


@@ -1,7 +1,11 @@
X /*

- * linux/include/asm-arm/proc-armv/domain.h
+ * linux/include/asm-arm/proc-armv/domain.h
X *
- * Copyright (C) 1999 Russell King.
+ * Copyright (C) 1999 Russell King.


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.

X */
X #ifndef __ASM_PROC_DOMAIN_H
X #define __ASM_PROC_DOMAIN_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/proc-armv/io.h linux/include/asm-arm/proc-armv/io.h
--- v2.4.0-test8/linux/include/asm-arm/proc-armv/io.h Mon Aug 30 18:15:21 1999
+++ linux/include/asm-arm/proc-armv/io.h Wed Dec 31 16:00:00 1969
@@ -1,35 +0,0 @@
-/*
- * linux/include/asm-arm/proc-armv/io.h
- */
-
-/*
- * The caches on some architectures aren't dma-coherent and have need to
- * handle this in software. There are two types of operations that
- * can be applied to dma buffers.
- *
- * - dma_cache_wback_inv(start, size) makes caches and RAM coherent by
- * writing the content of the caches back to memory, if necessary.
- * The function also invalidates the affected part of the caches as
- * necessary before DMA transfers from outside to memory.
- * - dma_cache_inv(start, size) invalidates the affected parts of the
- * caches. Dirty lines of the caches may be written back or simply
- * be discarded. This operation is necessary before dma operations
- * to the memory.
- * - dma_cache_wback(start, size) writes back any dirty lines but does
- * not invalidate the cache. This can be used before DMA reads from
- * memory,
- */
-
-#include <asm/proc-fns.h>
-
-#define dma_cache_inv(start, size) \
- do { cpu_cache_purge_area((unsigned long)(start), \
- ((unsigned long)(start)+(size))); } while (0)
-
-#define dma_cache_wback(start, size) \
- do { cpu_cache_wback_area((unsigned long)(start), \
- ((unsigned long)(start)+(size))); } while (0)
-
-#define dma_cache_wback_inv(start, size) \
- do { cpu_flush_cache_area((unsigned long)(start), \
- ((unsigned long)(start)+(size)), 0); } while (0)
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/proc-armv/locks.h linux/include/asm-arm/proc-armv/locks.h
--- v2.4.0-test8/linux/include/asm-arm/proc-armv/locks.h Mon Jun 19 17:59:35 2000
+++ linux/include/asm-arm/proc-armv/locks.h Mon Sep 18 15:15:24 2000


@@ -1,9 +1,13 @@
X /*

- * linux/include/asm-arm/proc-armv/locks.h
+ * linux/include/asm-arm/proc-armv/locks.h
X *
- * Copyright (C) 2000 Russell King


+ * Copyright (C) 2000 Russell King

X *
- * Interrupt safe locking assembler.

+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Interrupt safe locking assembler.
X */
X #ifndef __ASM_PROC_LOCKS_H
X #define __ASM_PROC_LOCKS_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/proc-armv/page.h linux/include/asm-arm/proc-armv/page.h
--- v2.4.0-test8/linux/include/asm-arm/proc-armv/page.h Wed Oct 20 16:29:08 1999
+++ linux/include/asm-arm/proc-armv/page.h Mon Sep 18 15:15:24 2000


@@ -1,7 +1,11 @@
X /*

- * linux/include/asm-arm/proc-armv/page.h
+ * linux/include/asm-arm/proc-armv/page.h
X *
- * Copyright (C) 1995, 1996 Russell King
+ * Copyright (C) 1995, 1996 Russell King
+ *


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X */

X #ifndef __ASM_PROC_PAGE_H
X #define __ASM_PROC_PAGE_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/proc-armv/pgtable.h linux/include/asm-arm/proc-armv/pgtable.h
--- v2.4.0-test8/linux/include/asm-arm/proc-armv/pgtable.h Tue Apr 25 16:54:38 2000
+++ linux/include/asm-arm/proc-armv/pgtable.h Mon Sep 18 15:15:24 2000
@@ -1,11 +1,15 @@
X /*
- * linux/include/asm-arm/proc-armv/pgtable.h
+ * linux/include/asm-arm/proc-armv/pgtable.h
X *
- * Copyright (C) 1995-1999 Russell King
+ * Copyright (C) 1995-1999 Russell King
X *
- * 12-Jan-1997 RMK Altered flushing routines to use function pointers


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * 12-Jan-1997 RMK Altered flushing routines to use function pointers
X * now possible to combine ARM6, ARM7 and StrongARM versions.
- * 17-Apr-1999 RMK Now pass an area size to clean_cache_area and
+ * 17-Apr-1999 RMK Now pass an area size to clean_cache_area and
X * flush_icache_area.
X */
X #ifndef __ASM_PROC_PGTABLE_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/proc-armv/processor.h linux/include/asm-arm/proc-armv/processor.h
--- v2.4.0-test8/linux/include/asm-arm/proc-armv/processor.h Tue Nov 23 22:23:11 1999
+++ linux/include/asm-arm/proc-armv/processor.h Mon Sep 18 15:15:24 2000
@@ -1,15 +1,19 @@
X /*
- * linux/include/asm-arm/proc-armv/processor.h
+ * linux/include/asm-arm/proc-armv/processor.h
X *
- * Copyright (c) 1996-1999 Russell King.
+ * Copyright (C) 1996-1999 Russell King.


X *
- * Changelog:

- * 20-09-1996 RMK Created
- * 26-09-1996 RMK Added 'EXTRA_THREAD_STRUCT*'
- * 28-09-1996 RMK Moved start_thread into the processor dependencies
- * 09-09-1998 PJB Delete redundant `wp_works_ok'
- * 30-05-1999 PJB Save sl across context switches
- * 31-07-1999 RMK Added 'domain' stuff


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Changelog:

+ * 20-09-1996 RMK Created
+ * 26-09-1996 RMK Added 'EXTRA_THREAD_STRUCT*'
+ * 28-09-1996 RMK Moved start_thread into the processor dependencies
+ * 09-09-1998 PJB Delete redundant `wp_works_ok'
+ * 30-05-1999 PJB Save sl across context switches
+ * 31-07-1999 RMK Added 'domain' stuff
X */
X #ifndef __ASM_PROC_PROCESSOR_H
X #define __ASM_PROC_PROCESSOR_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/proc-armv/ptrace.h linux/include/asm-arm/proc-armv/ptrace.h
--- v2.4.0-test8/linux/include/asm-arm/proc-armv/ptrace.h Wed Oct 20 16:29:08 1999
+++ linux/include/asm-arm/proc-armv/ptrace.h Mon Sep 18 15:15:24 2000


@@ -1,7 +1,11 @@
X /*

- * linux/include/asm-arm/proc-armv/ptrace.h
+ * linux/include/asm-arm/proc-armv/ptrace.h
X *
- * Copyright (C) 1996-1999 Russell King
+ * Copyright (C) 1996-1999 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X */

X #ifndef __ASM_PROC_PTRACE_H
X #define __ASM_PROC_PTRACE_H
@@ -18,6 +22,7 @@
X #define UND_MODE 0x1b
X #define SYSTEM_MODE 0x1f
X #define MODE_MASK 0x1f
+#define T_BIT 0x20
X #define F_BIT 0x40
X #define I_BIT 0x80
X #define CC_V_BIT (1 << 28)


@@ -58,6 +63,9 @@
X

X #define user_mode(regs) \
X (((regs)->ARM_cpsr & 0xf) == 0)
+
+#define thumb_mode(regs) \
+ (((regs)->ARM_cpsr & T_BIT))
X
X #define processor_mode(regs) \
X ((regs)->ARM_cpsr & MODE_MASK)
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/proc-armv/shmparam.h linux/include/asm-arm/proc-armv/shmparam.h
--- v2.4.0-test8/linux/include/asm-arm/proc-armv/shmparam.h Wed Nov 3 11:31:09 1999
+++ linux/include/asm-arm/proc-armv/shmparam.h Mon Sep 18 15:15:24 2000
@@ -1,12 +1,15 @@
X /*
- * linux/include/asm-arm/proc-armv/shmparam.h
+ * linux/include/asm-arm/proc-armv/shmparam.h


X *
- * Copyright (C) 1996 Russell King
+ * Copyright (C) 1996 Russell King
X *

- * definitions for the shared process memory on ARM v3 or v4
- * processors


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * definitions for the shared process memory on ARM v3 or v4
+ * processors
X */
-
X #ifndef __ASM_PROC_SHMPARAM_H
X #define __ASM_PROC_SHMPARAM_H
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/proc-armv/system.h linux/include/asm-arm/proc-armv/system.h
--- v2.4.0-test8/linux/include/asm-arm/proc-armv/system.h Sun Sep 3 11:19:11 2000
+++ linux/include/asm-arm/proc-armv/system.h Mon Sep 18 15:15:24 2000
@@ -1,9 +1,12 @@
X /*
- * linux/include/asm-arm/proc-armv/system.h
+ * linux/include/asm-arm/proc-armv/system.h


X *
- * Copyright (C) 1996 Russell King
+ * Copyright (C) 1996 Russell King

+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X */

-
X #ifndef __ASM_PROC_SYSTEM_H
X #define __ASM_PROC_SYSTEM_H
X
@@ -72,36 +75,6 @@
X __asm__ __volatile__( \
X "mrs %0, cpsr @ cli\n" \
X " orr %0, %0, #128\n" \
-" msr cpsr_c, %0" \
- : "=r" (temp) \
- : \
- : "memory"); \
- })
-
-/*
- * Enable FIQs
- */
-#define __stf() \
- ({ \
- unsigned long temp; \
- __asm__ __volatile__( \
- "mrs %0, cpsr @ stf\n" \
-" bic %0, %0, #64\n" \
-" msr cpsr_c, %0" \
- : "=r" (temp) \
- : \
- : "memory"); \
- })
-
-/*
- * Disable FIQs
- */
-#define __clf() \
- ({ \
- unsigned long temp; \
- __asm__ __volatile__( \
- "mrs %0, cpsr @ clf\n" \
-" orr %0, %0, #64\n" \
X " msr cpsr_c, %0" \
X : "=r" (temp) \
X : \
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/proc-armv/uaccess.h linux/include/asm-arm/proc-armv/uaccess.h
--- v2.4.0-test8/linux/include/asm-arm/proc-armv/uaccess.h Sun Aug 13 09:54:15 2000
+++ linux/include/asm-arm/proc-armv/uaccess.h Mon Sep 18 15:15:24 2000
@@ -1,7 +1,10 @@
X /*
- * linux/include/asm-arm/proc-armv/uaccess.h
+ * linux/include/asm-arm/proc-armv/uaccess.h


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X */

-
X #include <asm/arch/memory.h>
X #include <asm/proc/domain.h>
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/proc-armv/uncompress.h linux/include/asm-arm/proc-armv/uncompress.h
--- v2.4.0-test8/linux/include/asm-arm/proc-armv/uncompress.h Thu Jan 13 13:30:31 2000
+++ linux/include/asm-arm/proc-armv/uncompress.h Mon Sep 18 15:15:24 2000


@@ -1,7 +1,11 @@
X /*

- * linux/include/asm-arm/proc-armv/uncompress.h
+ * linux/include/asm-arm/proc-armv/uncompress.h
X *
- * (c) 1997 Russell King
+ * Copyright (C) 1997 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X */
X

X static inline void proc_decomp_setup (void)
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/proc-fns.h linux/include/asm-arm/proc-fns.h
--- v2.4.0-test8/linux/include/asm-arm/proc-fns.h Fri May 12 11:21:20 2000
+++ linux/include/asm-arm/proc-fns.h Mon Sep 18 15:15:24 2000
@@ -1,7 +1,12 @@
X /*
- * linux/include/asm-arm/proc-fns.h
+ * linux/include/asm-arm/proc-fns.h
X *
- * Copyright (C) 1997-1999 Russell King
+ * Copyright (C) 1997-1999 Russell King
+ * Copyright (C) 2000 Deep Blue Solutions Ltd


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X */

X #ifndef __ASM_PROCFNS_H
X #define __ASM_PROCFNS_H
@@ -39,28 +44,36 @@
X # define CPU_NAME arm7
X # endif
X # endif
-# ifdef CONFIG_CPU_SA110
+# ifdef CONFIG_CPU_ARM720
X # ifdef CPU_NAME
X # undef MULTI_CPU
X # define MULTI_CPU
X # else
-# define CPU_NAME sa110
+# define CPU_NAME arm720
X # endif
X # endif
-# ifdef CONFIG_CPU_SA1100
+# ifdef CONFIG_CPU_ARM920
X # ifdef CPU_NAME
X # undef MULTI_CPU
X # define MULTI_CPU
X # else
-# define CPU_NAME sa1100
+# define CPU_NAME arm920
X # endif
X # endif
-# ifdef CONFIG_CPU_ARM720
+# ifdef CONFIG_CPU_SA110
X # ifdef CPU_NAME
X # undef MULTI_CPU
X # define MULTI_CPU
X # else
-# define CPU_NAME arm720
+# define CPU_NAME sa110
+# endif
+# endif
+# ifdef CONFIG_CPU_SA1100
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME sa1100
X # endif
X # endif
X #endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/processor.h linux/include/asm-arm/processor.h
--- v2.4.0-test8/linux/include/asm-arm/processor.h Fri Jan 7 12:59:42 2000
+++ linux/include/asm-arm/processor.h Mon Sep 18 15:15:24 2000


@@ -1,7 +1,11 @@
X /*

- * include/asm-arm/processor.h
+ * linux/include/asm-arm/processor.h
X *
- * Copyright (C) 1995 Russell King
+ * Copyright (C) 1995 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X */
X

X #ifndef __ASM_ARM_PROCESSOR_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/procinfo.h linux/include/asm-arm/procinfo.h
--- v2.4.0-test8/linux/include/asm-arm/procinfo.h Sun Mar 12 19:39:39 2000
+++ linux/include/asm-arm/procinfo.h Mon Sep 18 15:15:24 2000


@@ -1,7 +1,11 @@
X /*

- * linux/include/asm-arm/procinfo.h
+ * linux/include/asm-arm/procinfo.h
X *
- * Copyright (C) 1996-1999 Russell King
+ * Copyright (C) 1996-1999 Russell King


+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
X */

X #ifndef __ASM_PROCINFO_H
X #define __ASM_PROCINFO_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/resource.h linux/include/asm-arm/resource.h
--- v2.4.0-test8/linux/include/asm-arm/resource.h Sun Aug 13 09:54:15 2000
+++ linux/include/asm-arm/resource.h Fri Sep 22 14:21:19 2000
@@ -15,8 +15,9 @@
X #define RLIMIT_NOFILE 7 /* max number of open files */
X #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
X #define RLIMIT_AS 9 /* address space limit */


+#define RLIMIT_LOCKS 10 /* maximum file locks held */
X
-#define RLIM_NLIMITS 10
+#define RLIM_NLIMITS 11
X

X #ifdef __KERNEL__
X
@@ -36,6 +37,7 @@
X { RLIM_INFINITY, RLIM_INFINITY }, \
X { 0, 0 }, \
X { INR_OPEN, INR_OPEN }, \
+ { RLIM_INFINITY, RLIM_INFINITY }, \
X { RLIM_INFINITY, RLIM_INFINITY }, \
X { RLIM_INFINITY, RLIM_INFINITY }, \
X }
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/serial.h linux/include/asm-arm/serial.h
--- v2.4.0-test8/linux/include/asm-arm/serial.h Tue Nov 23 22:23:11 1999
+++ linux/include/asm-arm/serial.h Mon Sep 18 15:15:24 2000
@@ -1,10 +1,14 @@
X /*
- * linux/include/asm-arm/serial.h
+ * linux/include/asm-arm/serial.h


X *
- * Copyright (c) 1996 Russell King.

+ * Copyright (C) 1996 Russell King.


X *
- * Changelog:

- * 15-10-1996 RMK Created


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Changelog:

+ * 15-10-1996 RMK Created
X */
X
X #ifndef __ASM_SERIAL_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/setup.h linux/include/asm-arm/setup.h
--- v2.4.0-test8/linux/include/asm-arm/setup.h Mon Jun 19 17:59:35 2000
+++ linux/include/asm-arm/setup.h Mon Sep 18 15:15:24 2000
@@ -1,11 +1,15 @@
X /*
- * include/asm/setup.h
+ * linux/include/asm/setup.h
X *
- * Structure passed to kernel to tell it about the
- * hardware it's running on. See linux/Documentation/arm/Setup


- * for more info.

+ * Copyright (C) 1997-1999 Russell King
X *


- * Copyright (C) 1997-1999 Russell King

+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Structure passed to kernel to tell it about the
+ * hardware it's running on. See linux/Documentation/arm/Setup
+ * for more info.
X */
X #ifndef __ASMARM_SETUP_H
X #define __ASMARM_SETUP_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-arm/timex.h linux/include/asm-arm/timex.h
--- v2.4.0-test8/linux/include/asm-arm/timex.h Thu Jan 7 15:51:33 1999
+++ linux/include/asm-arm/timex.h Mon Sep 18 15:15:24 2000


@@ -1,9 +1,13 @@
X /*

- * linux/include/asm-arm/timex.h
+ * linux/include/asm-arm/timex.h
X *
- * Architecture Specific TIME specifications
+ * Copyright (C) 1997,1998 Russell King
X *
- * Copyright (C) 1997,1998 Russell King


+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *

+ * Architecture Specific TIME specifications
X */
X #ifndef _ASMARM_TIMEX_H
X #define _ASMARM_TIMEX_H
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-i386/atomic.h linux/include/asm-i386/atomic.h
--- v2.4.0-test8/linux/include/asm-i386/atomic.h Fri Sep 8 12:52:41 2000
+++ linux/include/asm-i386/atomic.h Mon Oct 2 11:01:17 2000
@@ -19,102 +19,96 @@
X * on us. We need to use _exactly_ the address the user gave us,
X * not some alias that contains the same information.
X */
-#define __atomic_fool_gcc(x) (*(volatile struct { int a[100]; } *)x)
-
-#ifdef CONFIG_SMP


X typedef struct { volatile int counter; } atomic_t;
-#else
-typedef struct { int counter; } atomic_t;
-#endif
X

X #define ATOMIC_INIT(i) { (i) }
X
X #define atomic_read(v) ((v)->counter)
X #define atomic_set(v,i) (((v)->counter) = (i))
X
-static __inline__ void atomic_add(int i, volatile atomic_t *v)


+static __inline__ void atomic_add(int i, atomic_t *v)
X {

X __asm__ __volatile__(
X LOCK "addl %1,%0"
- :"=m" (__atomic_fool_gcc(v))
- :"ir" (i), "m" (__atomic_fool_gcc(v)));
+ :"=m" (v->counter)
+ :"ir" (i), "m" (v->counter));
X }
X
-static __inline__ void atomic_sub(int i, volatile atomic_t *v)


+static __inline__ void atomic_sub(int i, atomic_t *v)
X {

X __asm__ __volatile__(
X LOCK "subl %1,%0"
- :"=m" (__atomic_fool_gcc(v))
- :"ir" (i), "m" (__atomic_fool_gcc(v)));
+ :"=m" (v->counter)
+ :"ir" (i), "m" (v->counter));
X }
X
-static __inline__ int atomic_sub_and_test(int i, volatile atomic_t *v)
+static __inline__ int atomic_sub_and_test(int i, atomic_t *v)
X {
X unsigned char c;
X
X __asm__ __volatile__(
X LOCK "subl %2,%0; sete %1"
- :"=m" (__atomic_fool_gcc(v)), "=qm" (c)
- :"ir" (i), "m" (__atomic_fool_gcc(v)));
+ :"=m" (v->counter), "=qm" (c)
+ :"ir" (i), "m" (v->counter) : "memory");
X return c;
X }
X
-static __inline__ void atomic_inc(volatile atomic_t *v)
+static __inline__ void atomic_inc(atomic_t *v)
X {
X __asm__ __volatile__(
X LOCK "incl %0"
- :"=m" (__atomic_fool_gcc(v))
- :"m" (__atomic_fool_gcc(v)));
+ :"=m" (v->counter)
+ :"m" (v->counter));
X }
X
-static __inline__ void atomic_dec(volatile atomic_t *v)
+static __inline__ void atomic_dec(atomic_t *v)
X {
X __asm__ __volatile__(
X LOCK "decl %0"
- :"=m" (__atomic_fool_gcc(v))
- :"m" (__atomic_fool_gcc(v)));
+ :"=m" (v->counter)
+ :"m" (v->counter));
X }
X
-static __inline__ int atomic_dec_and_test(volatile atomic_t *v)
+static __inline__ int atomic_dec_and_test(atomic_t *v)
X {
X unsigned char c;
X
X __asm__ __volatile__(
X LOCK "decl %0; sete %1"
- :"=m" (__atomic_fool_gcc(v)), "=qm" (c)
- :"m" (__atomic_fool_gcc(v)));
+ :"=m" (v->counter), "=qm" (c)
+ :"m" (v->counter) : "memory");
X return c != 0;
X }
X
-static __inline__ int atomic_inc_and_test(volatile atomic_t *v)
+static __inline__ int atomic_inc_and_test(atomic_t *v)
X {
X unsigned char c;
X
X __asm__ __volatile__(
X LOCK "incl %0; sete %1"
- :"=m" (__atomic_fool_gcc(v)), "=qm" (c)
- :"m" (__atomic_fool_gcc(v)));
+ :"=m" (v->counter), "=qm" (c)
+ :"m" (v->counter) : "memory");
X return c != 0;
X }
X
-extern __inline__ int atomic_add_negative(int i, volatile atomic_t *v)
+static __inline__ int atomic_add_negative(int i, atomic_t *v)
X {
X unsigned char c;
X
X __asm__ __volatile__(
X LOCK "addl %2,%0; sets %1"
- :"=m" (__atomic_fool_gcc(v)), "=qm" (c)
- :"ir" (i), "m" (__atomic_fool_gcc(v)));
+ :"=m" (v->counter), "=qm" (c)
+ :"ir" (i), "m" (v->counter) : "memory");
X return c;
X }
X
X /* These are x86-specific, used by some header files */
X #define atomic_clear_mask(mask, addr) \
X __asm__ __volatile__(LOCK "andl %0,%1" \
-: : "r" (~(mask)),"m" (__atomic_fool_gcc(addr)) : "memory")
+: : "r" (~(mask)),"m" (*addr) : "memory")
X
X #define atomic_set_mask(mask, addr) \
X __asm__ __volatile__(LOCK "orl %0,%1" \
-: : "r" (mask),"m" (__atomic_fool_gcc(addr)) : "memory")
+: : "r" (mask),"m" (*addr) : "memory")
X
X #endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-i386/bitops.h linux/include/asm-i386/bitops.h
--- v2.4.0-test8/linux/include/asm-i386/bitops.h Fri Sep 8 12:52:41 2000
+++ linux/include/asm-i386/bitops.h Mon Oct 2 11:01:17 2000
@@ -21,29 +21,9 @@
X #define LOCK_PREFIX ""
X #endif
X
-/*
- * Function prototypes to keep gcc -Wall happy
- */
-extern void set_bit(int nr, volatile void * addr);
-extern void clear_bit(int nr, volatile void * addr);
-extern void change_bit(int nr, volatile void * addr);
-extern int test_and_set_bit(int nr, volatile void * addr);
-extern int test_and_clear_bit(int nr, volatile void * addr);
-extern int test_and_change_bit(int nr, volatile void * addr);
-extern int __constant_test_bit(int nr, const volatile void * addr);


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 104'
echo 'File patch-2.4.0-test9 is continued in part 105'
echo "105" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part109

#!/bin/sh -x
# this is part 109 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 109; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ __u8 bSynchAddress __attribute__ ((packed));
X
X unsigned char *extra; /* Extra descriptors */
X int extralen;
-} __attribute__ ((packed));
+};
X
X /* Interface descriptor */
X struct usb_interface_descriptor {
- __u8 bLength;
- __u8 bDescriptorType;
- __u8 bInterfaceNumber;
- __u8 bAlternateSetting;
- __u8 bNumEndpoints;
- __u8 bInterfaceClass;
- __u8 bInterfaceSubClass;
- __u8 bInterfaceProtocol;
- __u8 iInterface;
+ __u8 bLength __attribute__ ((packed));
+ __u8 bDescriptorType __attribute__ ((packed));
+ __u8 bInterfaceNumber __attribute__ ((packed));
+ __u8 bAlternateSetting __attribute__ ((packed));
+ __u8 bNumEndpoints __attribute__ ((packed));
+ __u8 bInterfaceClass __attribute__ ((packed));
+ __u8 bInterfaceSubClass __attribute__ ((packed));
+ __u8 bInterfaceProtocol __attribute__ ((packed));
+ __u8 iInterface __attribute__ ((packed));
X
X struct usb_endpoint_descriptor *endpoint;
X
X unsigned char *extra; /* Extra descriptors */
X int extralen;
-} __attribute__ ((packed));
+};
X
X struct usb_interface {
X struct usb_interface_descriptor *altsetting;
@@ -278,20 +279,20 @@
X
X /* Configuration descriptor information.. */
X struct usb_config_descriptor {
- __u8 bLength;
- __u8 bDescriptorType;
- __u16 wTotalLength;
- __u8 bNumInterfaces;
- __u8 bConfigurationValue;
- __u8 iConfiguration;
- __u8 bmAttributes;
- __u8 MaxPower;
+ __u8 bLength __attribute__ ((packed));
+ __u8 bDescriptorType __attribute__ ((packed));
+ __u16 wTotalLength __attribute__ ((packed));
+ __u8 bNumInterfaces __attribute__ ((packed));
+ __u8 bConfigurationValue __attribute__ ((packed));
+ __u8 iConfiguration __attribute__ ((packed));
+ __u8 bmAttributes __attribute__ ((packed));
+ __u8 MaxPower __attribute__ ((packed));
X
X struct usb_interface *interface;
X
X unsigned char *extra; /* Extra descriptors */
X int extralen;
-} __attribute__ ((packed));
+};
X
X /* String descriptor */
X struct usb_string_descriptor {
@@ -345,9 +346,9 @@
X */
X #define USB_DISABLE_SPD 0x0001
X #define USB_ISO_ASAP 0x0002
-#define USB_URB_EARLY_COMPLETE 0x0004
X #define USB_ASYNC_UNLINK 0x0008
X #define USB_QUEUE_BULK 0x0010
+#define USB_NO_FSBR 0x0020
X #define USB_TIMEOUT_KILLED 0x1000 // only set by HCD!
X
X typedef struct
@@ -553,6 +554,7 @@
X };
X
X extern struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, unsigned ifnum);
+extern struct usb_endpoint_descriptor *usb_epnum_to_ep_desc(struct usb_device *dev, unsigned epnum);
X
X extern int usb_register(struct usb_driver *);
X extern void usb_deregister(struct usb_driver *);
@@ -775,13 +777,13 @@
X
X #else /* CONFIG_USB_DEVICEFS */
X
-extern inline void usbdevfs_add_bus(struct usb_bus *bus) {}
-extern inline void usbdevfs_remove_bus(struct usb_bus *bus) {}
-extern inline void usbdevfs_add_device(struct usb_device *dev) {}
-extern inline void usbdevfs_remove_device(struct usb_device *dev) {}
+static inline void usbdevfs_add_bus(struct usb_bus *bus) {}
+static inline void usbdevfs_remove_bus(struct usb_bus *bus) {}
+static inline void usbdevfs_add_device(struct usb_device *dev) {}
+static inline void usbdevfs_remove_device(struct usb_device *dev) {}
X
-extern inline int usbdevfs_init(void) { return 0; }
-extern inline void usbdevfs_cleanup(void) { }
+static inline int usbdevfs_init(void) { return 0; }
+static inline void usbdevfs_cleanup(void) { }
X
X #endif /* CONFIG_USB_DEVICEFS */
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/usbdevice_fs.h linux/include/linux/usbdevice_fs.h
--- v2.4.0-test8/linux/include/linux/usbdevice_fs.h Wed Jul 5 11:16:40 2000
+++ linux/include/linux/usbdevice_fs.h Mon Oct 2 11:02:52 2000


@@ -80,6 +80,7 @@
X

X #define USBDEVFS_URB_DISABLE_SPD 1
X #define USBDEVFS_URB_ISO_ASAP 2
+#define USBDEVFS_URB_QUEUE_BULK 0x10
X
X #define USBDEVFS_URB_TYPE_ISO 0
X #define USBDEVFS_URB_TYPE_INTERRUPT 1
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/vmalloc.h linux/include/linux/vmalloc.h
--- v2.4.0-test8/linux/include/linux/vmalloc.h Fri Sep 8 12:52:42 2000
+++ linux/include/linux/vmalloc.h Mon Oct 2 11:58:47 2000
@@ -26,9 +26,6 @@
X extern int vmalloc_area_pages(unsigned long address, unsigned long size,
X int gfp_mask, pgprot_t prot);
X
-extern struct vm_struct * vmlist;
-
-
X /*
X * Allocate any pages
X */
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/vt_buffer.h linux/include/linux/vt_buffer.h
--- v2.4.0-test8/linux/include/linux/vt_buffer.h Fri Sep 8 12:53:46 2000
+++ linux/include/linux/vt_buffer.h Mon Oct 2 11:01:50 2000
@@ -32,7 +32,7 @@
X #endif
X
X #ifndef VT_BUF_HAVE_MEMSETW
-extern inline void scr_memsetw(u16 *s, u16 c, unsigned int count)
+static inline void scr_memsetw(u16 *s, u16 c, unsigned int count)
X {
X count /= 2;
X while (count--)
@@ -41,7 +41,7 @@
X #endif
X
X #ifndef VT_BUF_HAVE_MEMCPYW
-extern inline void scr_memcpyw(u16 *d, const u16 *s, unsigned int count)
+static inline void scr_memcpyw(u16 *d, const u16 *s, unsigned int count)
X {
X count /= 2;
X while (count--)
@@ -50,7 +50,7 @@
X #endif
X
X #ifndef VT_BUF_HAVE_MEMMOVEW
-extern inline void scr_memmovew(u16 *d, const u16 *s, unsigned int count)
+static inline void scr_memmovew(u16 *d, const u16 *s, unsigned int count)
X {
X if (d < s)
X scr_memcpyw(d, s, count);
@@ -65,14 +65,14 @@
X #endif
X
X #ifndef VT_BUF_HAVE_MEMCPYF
-extern inline void scr_memcpyw_from(u16 *d, const u16 *s, unsigned int count)
+static inline void scr_memcpyw_from(u16 *d, const u16 *s, unsigned int count)
X {
X count /= 2;
X while (count--)
X *d++ = scr_readw(s++);
X }
X
-extern inline void scr_memcpyw_to(u16 *d, const u16 *s, unsigned int count)
+static inline void scr_memcpyw_to(u16 *d, const u16 *s, unsigned int count)
X {
X count /= 2;
X while (count--)
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/wait.h linux/include/linux/wait.h
--- v2.4.0-test8/linux/include/linux/wait.h Fri Sep 8 12:52:41 2000
+++ linux/include/linux/wait.h Mon Oct 2 11:01:17 2000
@@ -158,7 +158,7 @@
X return !list_empty(&q->task_list);
X }
X
-extern inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new)
+static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new)
X {
X #if WAITQUEUE_DEBUG
X if (!head || !new)
@@ -174,7 +174,7 @@
X /*
X * Used for wake-one threads:
X */
-extern inline void __add_wait_queue_tail(wait_queue_head_t *head,
+static inline void __add_wait_queue_tail(wait_queue_head_t *head,
X wait_queue_t *new)
X {
X #if WAITQUEUE_DEBUG
@@ -188,7 +188,7 @@
X list_add_tail(&new->task_list, &head->task_list);
X }
X
-extern inline void __remove_wait_queue(wait_queue_head_t *head,
+static inline void __remove_wait_queue(wait_queue_head_t *head,
X wait_queue_t *old)
X {
X #if WAITQUEUE_DEBUG
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/zftape.h linux/include/linux/zftape.h
--- v2.4.0-test8/linux/include/linux/zftape.h Tue Nov 25 14:45:28 1997
+++ linux/include/linux/zftape.h Sun Sep 17 09:37:02 2000
@@ -56,7 +56,7 @@
X
X extern int zft_init(void);
X
-extern inline __s64 zft_div_blksz(__s64 value, __u32 blk_sz)
+static inline __s64 zft_div_blksz(__s64 value, __u32 blk_sz)
X {
X if (blk_sz == 1) {
X return value;
@@ -66,7 +66,7 @@
X }
X }
X
-extern inline __s64 zft_mul_blksz(__s64 value, __u32 blk_sz)
+static inline __s64 zft_mul_blksz(__s64 value, __u32 blk_sz)
X {
X if (blk_sz == 1) {
X return value;
diff -u --recursive --new-file v2.4.0-test8/linux/include/net/addrconf.h linux/include/net/addrconf.h
--- v2.4.0-test8/linux/include/net/addrconf.h Mon Aug 23 10:01:02 1999
+++ linux/include/net/addrconf.h Sun Sep 17 10:03:43 2000
@@ -87,7 +87,7 @@
X extern void addrconf_prefix_rcv(struct net_device *dev,
X u8 *opt, int len);
X
-extern __inline__ struct inet6_dev *
+static inline struct inet6_dev *
X __in6_dev_get(struct net_device *dev)
X {
X return (struct inet6_dev *)dev->ip6_ptr;
@@ -95,7 +95,7 @@
X
X extern rwlock_t addrconf_lock;
X
-extern __inline__ struct inet6_dev *
+static inline struct inet6_dev *
X in6_dev_get(struct net_device *dev)
X {
X struct inet6_dev *idev = NULL;
@@ -109,7 +109,7 @@
X
X extern void in6_dev_finish_destroy(struct inet6_dev *idev);
X
-extern __inline__ void
+static inline void
X in6_dev_put(struct inet6_dev *idev)
X {
X if (atomic_dec_and_test(&idev->refcnt))
@@ -122,7 +122,7 @@
X
X extern void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp);
X
-extern __inline__ void in6_ifa_put(struct inet6_ifaddr *ifp)
+static inline void in6_ifa_put(struct inet6_ifaddr *ifp)
X {
X if (atomic_dec_and_test(&ifp->refcnt))
X inet6_ifa_finish_destroy(ifp);
@@ -157,7 +157,7 @@
X * compute link-local solicited-node multicast address
X */
X
-extern __inline__ void addrconf_addr_solict_mult_old(struct in6_addr *addr,
+static inline void addrconf_addr_solict_mult_old(struct in6_addr *addr,
X struct in6_addr *solicited)
X {
X ipv6_addr_set(solicited,
@@ -165,7 +165,7 @@
X __constant_htonl(0x1), addr->s6_addr32[3]);
X }
X
-extern __inline__ void addrconf_addr_solict_mult_new(struct in6_addr *addr,
+static inline void addrconf_addr_solict_mult_new(struct in6_addr *addr,
X struct in6_addr *solicited)
X {
X ipv6_addr_set(solicited,
@@ -175,21 +175,21 @@
X }
X
X
-extern __inline__ void ipv6_addr_all_nodes(struct in6_addr *addr)
+static inline void ipv6_addr_all_nodes(struct in6_addr *addr)
X {
X ipv6_addr_set(addr,
X __constant_htonl(0xFF020000), 0, 0,
X __constant_htonl(0x1));
X }
X
-extern __inline__ void ipv6_addr_all_routers(struct in6_addr *addr)
+static inline void ipv6_addr_all_routers(struct in6_addr *addr)
X {
X ipv6_addr_set(addr,
X __constant_htonl(0xFF020000), 0, 0,
X __constant_htonl(0x2));
X }
X
-extern __inline__ int ipv6_addr_is_multicast(struct in6_addr *addr)
+static inline int ipv6_addr_is_multicast(struct in6_addr *addr)
X {
X return (addr->s6_addr32[0] & __constant_htonl(0xFF000000)) == __constant_htonl(0xFF000000);
X }
diff -u --recursive --new-file v2.4.0-test8/linux/include/net/checksum.h linux/include/net/checksum.h
--- v2.4.0-test8/linux/include/net/checksum.h Fri Sep 8 12:53:54 2000
+++ linux/include/net/checksum.h Mon Oct 2 12:06:33 2000
@@ -93,7 +93,7 @@
X #endif
X
X #ifndef _HAVE_ARCH_COPY_AND_CSUM_FROM_USER
-extern __inline__
+static inline
X unsigned int csum_and_copy_from_user (const char *src, char *dst,
X int len, int sum, int *err_ptr)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/include/net/dn_route.h linux/include/net/dn_route.h
--- v2.4.0-test8/linux/include/net/dn_route.h Sat Jan 8 21:36:20 2000
+++ linux/include/net/dn_route.h Sun Sep 17 10:03:43 2000
@@ -91,12 +91,12 @@
X #include <net/sock.h>
X #include <linux/if_arp.h>
X
-extern __inline__ void dn_rt_send(struct sk_buff *skb)
+static inline void dn_rt_send(struct sk_buff *skb)
X {
X dev_queue_xmit(skb);
X }
X
-extern __inline__ void dn_rt_finish_output(struct sk_buff *skb, char *dst)
+static inline void dn_rt_finish_output(struct sk_buff *skb, char *dst)
X {
X struct net_device *dev = skb->dev;
X
@@ -110,7 +110,7 @@
X kfree_skb(skb);
X }
X
-extern __inline__ void dn_nsp_send(struct sk_buff *skb)
+static inline void dn_nsp_send(struct sk_buff *skb)
X {
X struct sock *sk = skb->sk;
X struct dn_scp *scp = &sk->protinfo.dn;
diff -u --recursive --new-file v2.4.0-test8/linux/include/net/dsfield.h linux/include/net/dsfield.h
--- v2.4.0-test8/linux/include/net/dsfield.h Tue Feb 8 18:23:13 2000
+++ linux/include/net/dsfield.h Mon Sep 18 15:04:13 2000
@@ -12,19 +12,19 @@
X #include <asm/byteorder.h>
X
X
-extern __inline__ __u8 ipv4_get_dsfield(struct iphdr *iph)
+static inline __u8 ipv4_get_dsfield(struct iphdr *iph)
X {
X return iph->tos;
X }
X
X
-extern __inline__ __u8 ipv6_get_dsfield(struct ipv6hdr *ipv6h)
+static inline __u8 ipv6_get_dsfield(struct ipv6hdr *ipv6h)
X {
X return ntohs(*(__u16 *) ipv6h) >> 4;
X }
X
X
-extern __inline__ void ipv4_change_dsfield(struct iphdr *iph,__u8 mask,
+static inline void ipv4_change_dsfield(struct iphdr *iph,__u8 mask,
X __u8 value)
X {
X __u32 check = ntohs(iph->check);


@@ -40,7 +40,7 @@
X }

X
X
-extern __inline__ void ipv6_change_dsfield(struct ipv6hdr *ipv6h,__u8 mask,
+static inline void ipv6_change_dsfield(struct ipv6hdr *ipv6h,__u8 mask,
X __u8 value)
X {
X __u16 tmp;


@@ -53,7 +53,7 @@
X

X #if 0 /* put this later into asm-i386 or such ... */
X
-extern __inline__ void ip_change_dsfield(struct iphdr *iph,__u16 dsfield)
+static inline void ip_change_dsfield(struct iphdr *iph,__u16 dsfield)
X {
X __u16 check;
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/net/dst.h linux/include/net/dst.h
--- v2.4.0-test8/linux/include/net/dst.h Fri Sep 8 12:53:54 2000
+++ linux/include/net/dst.h Mon Oct 2 12:06:32 2000
@@ -88,12 +88,12 @@


X
X #ifdef __KERNEL__
X

-extern __inline__ void dst_hold(struct dst_entry * dst)
+static inline void dst_hold(struct dst_entry * dst)
X {
X atomic_inc(&dst->__refcnt);
X }
X
-extern __inline__
+static inline
X struct dst_entry * dst_clone(struct dst_entry * dst)
X {
X if (dst)
@@ -101,7 +101,7 @@
X return dst;
X }
X
-extern __inline__
+static inline
X void dst_release(struct dst_entry * dst)
X {
X if (dst)
@@ -112,7 +112,7 @@
X extern void __dst_free(struct dst_entry * dst);
X extern void dst_destroy(struct dst_entry * dst);
X
-extern __inline__
+static inline
X void dst_free(struct dst_entry * dst)
X {
X if (dst->obsolete > 1)
@@ -124,27 +124,27 @@
X __dst_free(dst);
X }
X
-extern __inline__ void dst_confirm(struct dst_entry *dst)
+static inline void dst_confirm(struct dst_entry *dst)
X {
X if (dst)
X neigh_confirm(dst->neighbour);
X }
X
-extern __inline__ void dst_negative_advice(struct dst_entry **dst_p)
+static inline void dst_negative_advice(struct dst_entry **dst_p)
X {
X struct dst_entry * dst = *dst_p;
X if (dst && dst->ops->negative_advice)
X *dst_p = dst->ops->negative_advice(dst);
X }
X
-extern __inline__ void dst_link_failure(struct sk_buff *skb)
+static inline void dst_link_failure(struct sk_buff *skb)
X {
X struct dst_entry * dst = skb->dst;
X if (dst && dst->ops && dst->ops->link_failure)
X dst->ops->link_failure(skb);
X }
X
-extern __inline__ void dst_set_expires(struct dst_entry *dst, int timeout)
+static inline void dst_set_expires(struct dst_entry *dst, int timeout)
X {
X unsigned long expires = jiffies + timeout;
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/net/if_inet6.h linux/include/net/if_inet6.h
--- v2.4.0-test8/linux/include/net/if_inet6.h Thu Jun 22 07:23:26 2000
+++ linux/include/net/if_inet6.h Mon Sep 18 15:04:13 2000
@@ -108,7 +108,7 @@
X
X extern struct ipv6_devconf ipv6_devconf;
X
-extern __inline__ void ipv6_eth_mc_map(struct in6_addr *addr, char *buf)
+static inline void ipv6_eth_mc_map(struct in6_addr *addr, char *buf)
X {
X /*
X * +-------+-------+-------+-------+-------+-------+
@@ -122,7 +122,7 @@
X memcpy(buf + 2, &addr->s6_addr32[3], sizeof(__u32));
X }
X
-extern __inline__ void ipv6_tr_mc_map(struct in6_addr *addr, char *buf)
+static inline void ipv6_tr_mc_map(struct in6_addr *addr, char *buf)
X {
X /* All nodes FF01::1, FF02::1, FF02::1:FFxx:xxxx */
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/net/ip.h linux/include/net/ip.h
--- v2.4.0-test8/linux/include/net/ip.h Fri Sep 8 12:53:54 2000
+++ linux/include/net/ip.h Mon Oct 2 12:06:33 2000
@@ -115,7 +115,7 @@
X * multicast packets.
X */
X
-extern __inline__ void ip_tr_mc_map(u32 addr, char *buf)
+static inline void ip_tr_mc_map(u32 addr, char *buf)
X {
X buf[0]=0xC0;
X buf[1]=0x00;
@@ -159,7 +159,7 @@
X extern int sysctl_ip_default_ttl;
X
X #ifdef CONFIG_INET
-extern __inline__ int ip_send(struct sk_buff *skb)
+static inline int ip_send(struct sk_buff *skb)
X {
X if (skb->len > skb->dst->pmtu)
X return ip_fragment(skb, ip_finish_output);
@@ -169,7 +169,7 @@
X
X /* The function in 2.2 was invalid, producing wrong result for
X * check=0xFEFF. It was noticed by Arthur Skawina _year_ ago. --ANK(000625) */
-extern __inline__
+static inline
X int ip_decrease_ttl(struct iphdr *iph)
X {
X u32 check = iph->check;
@@ -178,7 +178,7 @@
X return --iph->ttl;
X }
X
-extern __inline__
+static inline
X int ip_dont_fragment(struct sock *sk, struct dst_entry *dst)
X {
X return (sk->protinfo.af_inet.pmtudisc == IP_PMTUDISC_DO ||
@@ -188,7 +188,7 @@
X
X extern void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst);
X
-extern __inline__ void ip_select_ident(struct iphdr *iph, struct dst_entry *dst)
+static inline void ip_select_ident(struct iphdr *iph, struct dst_entry *dst)
X {
X if (iph->frag_off&__constant_htons(IP_DF))
X iph->id = 0;
@@ -200,7 +200,7 @@
X * Map a multicast IP onto multicast MAC for type ethernet.
X */
X
-extern __inline__ void ip_eth_mc_map(u32 addr, char *buf)
+static inline void ip_eth_mc_map(u32 addr, char *buf)
X {
X addr=ntohl(addr);
X buf[0]=0x01;
diff -u --recursive --new-file v2.4.0-test8/linux/include/net/ip6_fib.h linux/include/net/ip6_fib.h
--- v2.4.0-test8/linux/include/net/ip6_fib.h Mon Aug 23 10:01:02 1999
+++ linux/include/net/ip6_fib.h Mon Sep 18 15:04:13 2000
@@ -96,7 +96,7 @@
X extern struct fib6_walker_t fib6_walker_list;
X extern rwlock_t fib6_walker_lock;
X
-extern __inline__ void fib6_walker_link(struct fib6_walker_t *w)
+static inline void fib6_walker_link(struct fib6_walker_t *w)
X {
X write_lock_bh(&fib6_walker_lock);
X w->next = fib6_walker_list.next;
@@ -106,7 +106,7 @@
X write_unlock_bh(&fib6_walker_lock);
X }
X
-extern __inline__ void fib6_walker_unlink(struct fib6_walker_t *w)
+static inline void fib6_walker_unlink(struct fib6_walker_t *w)
X {
X write_lock_bh(&fib6_walker_lock);
X w->next->prev = w->prev;
diff -u --recursive --new-file v2.4.0-test8/linux/include/net/ip6_route.h linux/include/net/ip6_route.h
--- v2.4.0-test8/linux/include/net/ip6_route.h Mon Aug 23 10:01:02 1999
+++ linux/include/net/ip6_route.h Mon Sep 18 15:04:13 2000
@@ -94,7 +94,7 @@
X * For UDP/RAW sockets this is done on udp_connect.
X */
X
-extern __inline__ void ip6_dst_store(struct sock *sk, struct dst_entry *dst,
+static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst,
X struct in6_addr *daddr)
X {
X struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
diff -u --recursive --new-file v2.4.0-test8/linux/include/net/ip_fib.h linux/include/net/ip_fib.h
--- v2.4.0-test8/linux/include/net/ip_fib.h Mon Aug 23 10:01:02 1999
+++ linux/include/net/ip_fib.h Mon Sep 18 15:04:13 2000
@@ -140,19 +140,19 @@
X extern struct fib_table *local_table;
X extern struct fib_table *main_table;
X
-extern __inline__ struct fib_table *fib_get_table(int id)
+static inline struct fib_table *fib_get_table(int id)
X {
X if (id != RT_TABLE_LOCAL)
X return main_table;
X return local_table;
X }
X
-extern __inline__ struct fib_table *fib_new_table(int id)
+static inline struct fib_table *fib_new_table(int id)
X {
X return fib_get_table(id);
X }
X
-extern __inline__ int fib_lookup(const struct rt_key *key, struct fib_result *res)
+static inline int fib_lookup(const struct rt_key *key, struct fib_result *res)
X {
X if (local_table->tb_lookup(local_table, key, res) &&
X main_table->tb_lookup(main_table, key, res))
@@ -160,7 +160,7 @@
X return 0;
X }
X
-extern __inline__ void fib_select_default(const struct rt_key *key, struct fib_result *res)
+static inline void fib_select_default(const struct rt_key *key, struct fib_result *res)
X {
X if (FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
X main_table->tb_select_default(main_table, key, res);
@@ -175,7 +175,7 @@
X extern struct fib_table *__fib_new_table(int id);
X extern void fib_rule_put(struct fib_rule *r);
X
-extern __inline__ struct fib_table *fib_get_table(int id)
+static inline struct fib_table *fib_get_table(int id)
X {
X if (id == 0)
X id = RT_TABLE_MAIN;
@@ -183,7 +183,7 @@
X return fib_tables[id];
X }
X
-extern __inline__ struct fib_table *fib_new_table(int id)
+static inline struct fib_table *fib_new_table(int id)
X {
X if (id == 0)
X id = RT_TABLE_MAIN;
@@ -241,7 +241,7 @@
X extern void fib_rules_init(void);
X #endif
X
-extern __inline__ void fib_combine_itag(u32 *itag, struct fib_result *res)
+static inline void fib_combine_itag(u32 *itag, struct fib_result *res)
X {
X #ifdef CONFIG_NET_CLS_ROUTE
X #ifdef CONFIG_IP_MULTIPLE_TABLES
@@ -259,13 +259,13 @@
X
X extern void free_fib_info(struct fib_info *fi);
X
-extern __inline__ void fib_info_put(struct fib_info *fi)
+static inline void fib_info_put(struct fib_info *fi)
X {
X if (atomic_dec_and_test(&fi->fib_clntref))
X free_fib_info(fi);
X }
X
-extern __inline__ void fib_res_put(struct fib_result *res)
+static inline void fib_res_put(struct fib_result *res)
X {
X if (res->fi)
X fib_info_put(res->fi);
diff -u --recursive --new-file v2.4.0-test8/linux/include/net/ipv6.h linux/include/net/ipv6.h
--- v2.4.0-test8/linux/include/net/ipv6.h Fri Sep 8 12:53:54 2000
+++ linux/include/net/ipv6.h Mon Oct 2 12:06:41 2000
@@ -4,7 +4,7 @@
X * Authors:
X * Pedro Roque <ro...@di.fc.ul.pt>
X *
- * $Id: ipv6.h,v 1.21 2000/07/07 22:29:42 davem Exp $
+ * $Id: ipv6.h,v 1.22 2000/09/18 05:54:13 davem Exp $
X *
X * This program is free software; you can redistribute it and/or
X * modify it under the terms of the GNU General Public License
@@ -169,7 +169,7 @@
X extern void ip6_flowlabel_init(void);
X extern void ip6_flowlabel_cleanup(void);
X
-extern __inline__ void fl6_sock_release(struct ip6_flowlabel *fl)
+static inline void fl6_sock_release(struct ip6_flowlabel *fl)
X {
X if (fl)
X atomic_dec(&fl->users);
@@ -206,23 +206,23 @@
X
X extern int ipv6_addr_type(struct in6_addr *addr);
X
-extern __inline__ int ipv6_addr_scope(struct in6_addr *addr)
+static inline int ipv6_addr_scope(struct in6_addr *addr)
X {
X return ipv6_addr_type(addr) & IPV6_ADDR_SCOPE_MASK;
X }
X
-extern __inline__ int ipv6_addr_cmp(struct in6_addr *a1, struct in6_addr *a2)
+static inline int ipv6_addr_cmp(struct in6_addr *a1, struct in6_addr *a2)
X {
X return memcmp((void *) a1, (void *) a2, sizeof(struct in6_addr));
X }
X
-extern __inline__ void ipv6_addr_copy(struct in6_addr *a1, struct in6_addr *a2)
+static inline void ipv6_addr_copy(struct in6_addr *a1, struct in6_addr *a2)
X {
X memcpy((void *) a1, (void *) a2, sizeof(struct in6_addr));
X }
X
X #ifndef __HAVE_ARCH_ADDR_SET
-extern __inline__ void ipv6_addr_set(struct in6_addr *addr,
+static inline void ipv6_addr_set(struct in6_addr *addr,
X __u32 w1, __u32 w2,
X __u32 w3, __u32 w4)
X {
@@ -233,7 +233,7 @@
X }
X #endif
X
-extern __inline__ int ipv6_addr_any(struct in6_addr *a)
+static inline int ipv6_addr_any(struct in6_addr *a)
X {
X return ((a->s6_addr32[0] | a->s6_addr32[1] |
X a->s6_addr32[2] | a->s6_addr32[3] ) == 0);
diff -u --recursive --new-file v2.4.0-test8/linux/include/net/ndisc.h linux/include/net/ndisc.h
--- v2.4.0-test8/linux/include/net/ndisc.h Fri Sep 8 12:53:54 2000
+++ linux/include/net/ndisc.h Mon Oct 2 12:06:41 2000
@@ -101,7 +101,7 @@
X
X extern void igmp6_cleanup(void);
X
-extern __inline__ struct neighbour * ndisc_get_neigh(struct net_device *dev, struct in6_addr *addr)
+static inline struct neighbour * ndisc_get_neigh(struct net_device *dev, struct in6_addr *addr)
X {
X
X if (dev)
diff -u --recursive --new-file v2.4.0-test8/linux/include/net/neighbour.h linux/include/net/neighbour.h
--- v2.4.0-test8/linux/include/net/neighbour.h Fri Sep 8 12:53:53 2000
+++ linux/include/net/neighbour.h Mon Oct 2 12:06:32 2000
@@ -212,13 +212,13 @@
X * Neighbour references
X */
X
-extern __inline__ void neigh_release(struct neighbour *neigh)
+static inline void neigh_release(struct neighbour *neigh)
X {
X if (atomic_dec_and_test(&neigh->refcnt))
X neigh_destroy(neigh);
X }
X
-extern __inline__ struct neighbour * neigh_clone(struct neighbour *neigh)
+static inline struct neighbour * neigh_clone(struct neighbour *neigh)
X {
X if (neigh)
X atomic_inc(&neigh->refcnt);
@@ -227,23 +227,23 @@
X
X #define neigh_hold(n) atomic_inc(&(n)->refcnt)
X
-extern __inline__ void neigh_confirm(struct neighbour *neigh)
+static inline void neigh_confirm(struct neighbour *neigh)
X {
X if (neigh)
X neigh->confirmed = jiffies;
X }
X
-extern __inline__ int neigh_is_connected(struct neighbour *neigh)
+static inline int neigh_is_connected(struct neighbour *neigh)
X {
X return neigh->nud_state&NUD_CONNECTED;
X }
X
-extern __inline__ int neigh_is_valid(struct neighbour *neigh)
+static inline int neigh_is_valid(struct neighbour *neigh)
X {
X return neigh->nud_state&NUD_VALID;
X }
X
-extern __inline__ int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
+static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
X {
X neigh->used = jiffies;
X if (!(neigh->nud_state&(NUD_CONNECTED|NUD_DELAY|NUD_PROBE)))
@@ -251,7 +251,7 @@
X return 0;
X }
X
-extern __inline__ struct neighbour *
+static inline struct neighbour *
X __neigh_lookup(struct neigh_table *tbl, const void *pkey, struct net_device *dev, int creat)
X {
X struct neighbour *n = neigh_lookup(tbl, pkey, dev);
@@ -263,7 +263,7 @@
X return IS_ERR(n) ? NULL : n;
X }
X
-extern __inline__ struct neighbour *
+static inline struct neighbour *
X __neigh_lookup_errno(struct neigh_table *tbl, const void *pkey,
X struct net_device *dev)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/include/net/pkt_cls.h linux/include/net/pkt_cls.h
--- v2.4.0-test8/linux/include/net/pkt_cls.h Fri Jan 7 18:11:45 2000
+++ linux/include/net/pkt_cls.h Mon Sep 18 15:04:13 2000
@@ -63,7 +63,7 @@
X specific classifiers.
X */
X
-extern __inline__ int tc_classify(struct sk_buff *skb, struct tcf_proto *tp, struct tcf_result *res)
+static inline int tc_classify(struct sk_buff *skb, struct tcf_proto *tp, struct tcf_result *res)
X {
X int err = 0;
X u32 protocol = skb->protocol;
diff -u --recursive --new-file v2.4.0-test8/linux/include/net/pkt_sched.h linux/include/net/pkt_sched.h
--- v2.4.0-test8/linux/include/net/pkt_sched.h Fri Sep 8 12:53:56 2000
+++ linux/include/net/pkt_sched.h Mon Oct 2 11:01:58 2000
@@ -104,32 +104,32 @@
X int refcnt;
X };
X
-extern __inline__ void sch_tree_lock(struct Qdisc *q)
+static inline void sch_tree_lock(struct Qdisc *q)
X {
X write_lock(&qdisc_tree_lock);
X spin_lock_bh(&q->dev->queue_lock);
X }
X
-extern __inline__ void sch_tree_unlock(struct Qdisc *q)
+static inline void sch_tree_unlock(struct Qdisc *q)
X {
X spin_unlock_bh(&q->dev->queue_lock);
X write_unlock(&qdisc_tree_lock);
X }
X
-extern __inline__ void tcf_tree_lock(struct tcf_proto *tp)
+static inline void tcf_tree_lock(struct tcf_proto *tp)
X {
X write_lock(&qdisc_tree_lock);
X spin_lock_bh(&tp->q->dev->queue_lock);
X }
X
-extern __inline__ void tcf_tree_unlock(struct tcf_proto *tp)
+static inline void tcf_tree_unlock(struct tcf_proto *tp)
X {
X spin_unlock_bh(&tp->q->dev->queue_lock);
X write_unlock(&qdisc_tree_lock);
X }
X
X
-extern __inline__ unsigned long
+static inline unsigned long
X cls_set_class(struct tcf_proto *tp, unsigned long *clp, unsigned long cl)
X {
X unsigned long old_cl;
@@ -141,7 +141,7 @@
X return old_cl;
X }
X
-extern __inline__ unsigned long
+static inline unsigned long
X __cls_set_class(unsigned long *clp, unsigned long cl)
X {
X unsigned long old_cl;
@@ -401,7 +401,7 @@
X extern int tcf_police_dump(struct sk_buff *skb, struct tcf_police *p);
X extern int tcf_police(struct sk_buff *skb, struct tcf_police *p);
X
-extern __inline__ void tcf_police_release(struct tcf_police *p)
+static inline void tcf_police_release(struct tcf_police *p)
X {
X if (p && --p->refcnt == 0)
X tcf_police_destroy(p);


@@ -433,7 +433,7 @@
X

X extern int qdisc_restart(struct net_device *dev);
X
-extern __inline__ void qdisc_run(struct net_device *dev)
+static inline void qdisc_run(struct net_device *dev)
X {
X while (!netif_queue_stopped(dev) &&
X qdisc_restart(dev)<0)
@@ -443,7 +443,7 @@
X /* Calculate maximal size of packet seen by hard_start_xmit
X routine of this device.
X */
-extern __inline__ unsigned psched_mtu(struct net_device *dev)
+static inline unsigned psched_mtu(struct net_device *dev)
X {
X unsigned mtu = dev->mtu;
X return dev->hard_header ? mtu + dev->hard_header_len : mtu;
diff -u --recursive --new-file v2.4.0-test8/linux/include/net/profile.h linux/include/net/profile.h
--- v2.4.0-test8/linux/include/net/profile.h Fri Sep 8 12:52:42 2000
+++ linux/include/net/profile.h Mon Oct 2 11:01:18 2000
@@ -31,12 +31,12 @@
X
X #ifdef CONFIG_X86_TSC
X
-extern __inline__ void net_profile_stamp(struct timeval *pstamp)
+static inline void net_profile_stamp(struct timeval *pstamp)
X {
X rdtsc(pstamp->tv_usec, pstamp->tv_sec);
X }
X
-extern __inline__ void net_profile_accumulate(struct timeval *entered,
+static inline void net_profile_accumulate(struct timeval *entered,
X struct timeval *leaved,
X struct timeval *acc)
X {
@@ -52,7 +52,7 @@
X "0" (acc->tv_usec), "1" (acc->tv_sec));
X }
X
-extern __inline__ void net_profile_sub(struct timeval *sub,
+static inline void net_profile_sub(struct timeval *sub,
X struct timeval *acc)
X {
X __asm__ __volatile__ ("subl %2,%0\n\t"
@@ -62,7 +62,7 @@
X "0" (acc->tv_usec), "1" (acc->tv_sec));
X }
X
-extern __inline__ void net_profile_add(struct timeval *add,
+static inline void net_profile_add(struct timeval *add,
X struct timeval *acc)
X {
X __asm__ __volatile__ ("addl %2,%0\n\t"

@@ -80,7 +80,7 @@
X

X /* On alpha cycle counter has only 32 bits :-( :-( */
X
-extern __inline__ void net_profile_stamp(struct timeval *pstamp)
+static inline void net_profile_stamp(struct timeval *pstamp)
X {
X __u32 result;
X __asm__ __volatile__ ("rpcc %0" : "r="(result));
@@ -91,7 +91,7 @@
X pstamp->tv_usec = alpha_lo;
X }
X
-extern __inline__ void net_profile_accumulate(struct timeval *entered,
+static inline void net_profile_accumulate(struct timeval *entered,
X struct timeval *leaved,
X struct timeval *acc)
X {
@@ -113,7 +113,7 @@
X acc->tv_usec = usecs;
X }
X
-extern __inline__ void net_profile_sub(struct timeval *entered,
+static inline void net_profile_sub(struct timeval *entered,
X struct timeval *leaved)
X {
X time_t usecs = leaved->tv_usec - entered->tv_usec;
@@ -127,7 +127,7 @@
X leaved->tv_usec = usecs;
X }
X
-extern __inline__ void net_profile_add(struct timeval *entered, struct timeval *leaved)
+static inline void net_profile_add(struct timeval *entered, struct timeval *leaved)
X {
X time_t usecs = leaved->tv_usec + entered->tv_usec;
X time_t secs = leaved->tv_sec + entered->tv_sec;


@@ -143,18 +143,18 @@
X

X #else
X
-extern __inline__ void net_profile_stamp(struct timeval *pstamp)
+static inline void net_profile_stamp(struct timeval *pstamp)
X {
X /* Not "fast" counterpart! On architectures without
X cpu clock "fast" routine is absolutely useless in this
X situation. do_gettimeofday still says something on slow-slow-slow
- boxes, though it eats more cpu time than the sobject of
+ boxes, though it eats more cpu time than the subject of
X investigation :-) :-)
X */
X do_gettimeofday(pstamp);
X }
X
-extern __inline__ void net_profile_accumulate(struct timeval *entered,
+static inline void net_profile_accumulate(struct timeval *entered,
X struct timeval *leaved,
X struct timeval *acc)
X {
@@ -176,7 +176,7 @@
X acc->tv_usec = usecs;
X }
X
-extern __inline__ void net_profile_sub(struct timeval *entered,
+static inline void net_profile_sub(struct timeval *entered,
X struct timeval *leaved)
X {
X time_t usecs = leaved->tv_usec - entered->tv_usec;
@@ -190,7 +190,7 @@
X leaved->tv_usec = usecs;
X }
X
-extern __inline__ void net_profile_add(struct timeval *entered, struct timeval *leaved)
+static inline void net_profile_add(struct timeval *entered, struct timeval *leaved)
X {
X time_t usecs = leaved->tv_usec + entered->tv_usec;
X time_t secs = leaved->tv_sec + entered->tv_sec;
@@ -207,7 +207,7 @@
X
X #endif
X
-extern __inline__ void net_profile_enter(struct net_profile_slot *s)
+static inline void net_profile_enter(struct net_profile_slot *s)


X {
X unsigned long flags;

X
@@ -220,7 +220,7 @@
X restore_flags(flags);
X }
X
-extern __inline__ void net_profile_leave_irq(struct net_profile_slot *s)
+static inline void net_profile_leave_irq(struct net_profile_slot *s)


X {
X unsigned long flags;

X
@@ -241,7 +241,7 @@
X restore_flags(flags);
X }
X
-extern __inline__ void net_profile_leave(struct net_profile_slot *s)
+static inline void net_profile_leave(struct net_profile_slot *s)


X {
X unsigned long flags;

X save_flags(flags);
diff -u --recursive --new-file v2.4.0-test8/linux/include/net/route.h linux/include/net/route.h
--- v2.4.0-test8/linux/include/net/route.h Fri Sep 8 12:53:54 2000
+++ linux/include/net/route.h Mon Oct 2 12:06:32 2000
@@ -113,7 +113,7 @@
X extern int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb);
X
X /* Deprecated: use ip_route_output_key directly */
-extern __inline__ int ip_route_output(struct rtable **rp,
+static inline int ip_route_output(struct rtable **rp,
X u32 daddr, u32 saddr, u32 tos, int oif)
X {
X struct rt_key key = { dst:daddr, src:saddr, oif:oif, tos:tos };
@@ -122,7 +122,7 @@
X }
X
X
-extern __inline__ void ip_rt_put(struct rtable * rt)
+static inline void ip_rt_put(struct rtable * rt)
X {
X if (rt)
X dst_release(&rt->u.dst);
@@ -137,12 +137,12 @@
X
X extern __u8 ip_tos2prio[16];
X
-extern __inline__ char rt_tos2priority(u8 tos)
+static inline char rt_tos2priority(u8 tos)
X {
X return ip_tos2prio[IPTOS_TOS(tos)>>1];
X }
X
-extern __inline__ int ip_route_connect(struct rtable **rp, u32 dst, u32 src, u32 tos, int oif)
+static inline int ip_route_connect(struct rtable **rp, u32 dst, u32 src, u32 tos, int oif)
X {
X int err;
X err = ip_route_output(rp, dst, src, tos, oif);


@@ -157,7 +157,7 @@
X

X extern void rt_bind_peer(struct rtable *rt, int create);
X
-extern __inline__ struct inet_peer *rt_get_peer(struct rtable *rt)
+static inline struct inet_peer *rt_get_peer(struct rtable *rt)
X {
X if (rt->peer)
X return rt->peer;
diff -u --recursive --new-file v2.4.0-test8/linux/include/net/snmp.h linux/include/net/snmp.h
--- v2.4.0-test8/linux/include/net/snmp.h Thu Aug 10 13:01:26 2000
+++ linux/include/net/snmp.h Mon Oct 2 11:01:18 2000
@@ -14,17 +14,34 @@
X * as published by the Free Software Foundation; either version
X * 2 of the License, or (at your option) any later version.
X *
+ * $Id: snmp.h,v 1.17 2000/09/21 01:31:50 davem Exp $
+ *
X */
X
X #ifndef _SNMP_H
X #define _SNMP_H
+
+#include <linux/cache.h>
X
X /*
X * We use all unsigned longs. Linux will soon be so reliable that even these
X * will rapidly get too small 8-). Seriously consider the IpInReceives count
X * on the 20Gb/s + networks people expect in a few years time!
X */
-
+
+/*
+ * The rule for padding:
+ * Best is power of two because then the right structure can be found by a simple
+ * shift. The structure should be always cache line aligned.
+ * gcc needs n=alignto(cachelinesize, popcnt(sizeof(bla_mib))) shift/add instructions
+ * to emulate multiply in case it is not power-of-two. Currently n is always <=3 for
+ * all sizes so simple cache line alignment is enough.
+ *
+ * The best solution would be a global CPU local area , especially on 64 and 128byte
+ * cacheline machine it makes a *lot* of sense -AK
+ */
+
+
X struct ip_mib
X {
X unsigned long IpInReceives;
@@ -44,8 +61,8 @@
X unsigned long IpFragOKs;
X unsigned long IpFragFails;
X unsigned long IpFragCreates;
- unsigned long __pad[32-19];
-};
+ unsigned long __pad[0];
+} ____cacheline_aligned;
X
X struct ipv6_mib
X {
@@ -71,8 +88,8 @@
X unsigned long Ip6FragCreates;
X unsigned long Ip6InMcastPkts;
X unsigned long Ip6OutMcastPkts;
- unsigned long __pad[32-22];
-};
+ unsigned long __pad[0];
+} ____cacheline_aligned;
X
X struct icmp_mib
X {
@@ -102,8 +119,8 @@
X unsigned long IcmpOutTimestampReps;
X unsigned long IcmpOutAddrMasks;
X unsigned long IcmpOutAddrMaskReps;
- unsigned long __pad[32-26];
-};
+ unsigned long __pad[0];
+} ____cacheline_aligned;
X
X struct icmpv6_mib
X {
@@ -140,8 +157,8 @@
X unsigned long Icmp6OutRedirects;
X unsigned long Icmp6OutGroupMembResponses;
X unsigned long Icmp6OutGroupMembReductions;
- unsigned long __pad[32-28];
-};
+ unsigned long __pad[0];
+} ____cacheline_aligned;
X
X struct tcp_mib
X {
@@ -159,8 +176,8 @@
X unsigned long TcpRetransSegs;
X unsigned long TcpInErrs;
X unsigned long TcpOutRsts;
- unsigned long __pad[16-14];
-};
+ unsigned long __pad[0];
+} ____cacheline_aligned;
X
X struct udp_mib
X {
@@ -168,8 +185,8 @@
X unsigned long UdpNoPorts;
X unsigned long UdpInErrors;
X unsigned long UdpOutDatagrams;
- unsigned long __pad[0];
-};
+ unsigned long __pad[0];
+} ____cacheline_aligned;
X
X struct linux_mib
X {
@@ -237,9 +254,15 @@
X unsigned long TCPAbortOnLinger;
X unsigned long TCPAbortFailed;
X unsigned long TCPMemoryPressures;
- unsigned long __pad[64-64];
-};
+ unsigned long __pad[0];
+} ____cacheline_aligned;
+
X
+/*
+ * FIXME: On x86 and some other CPUs the split into user and softirq parts is not needed because
+ * addl $1,memory is atomic against interrupts (but atomic_inc would be overkill because of the lock
+ * cycles). Wants new nonlocked_atomic_inc() primitives -AK
+ */
X #define SNMP_INC_STATS(mib, field) ((mib)[2*smp_processor_id()+!in_softirq()].field++)
X #define SNMP_INC_STATS_BH(mib, field) ((mib)[2*smp_processor_id()].field++)
X #define SNMP_INC_STATS_USER(mib, field) ((mib)[2*smp_processor_id()+1].field++)
diff -u --recursive --new-file v2.4.0-test8/linux/include/net/sock.h linux/include/net/sock.h
--- v2.4.0-test8/linux/include/net/sock.h Fri Sep 8 12:53:54 2000
+++ linux/include/net/sock.h Mon Oct 2 12:06:33 2000
@@ -470,7 +470,6 @@
X
X #define sock_lock_init(__sk) \
X do { spin_lock_init(&((__sk)->lock.slock)); \
- (__sk)->dst_lock = RW_LOCK_UNLOCKED; \
X (__sk)->lock.users = 0; \
X init_waitqueue_head(&((__sk)->lock.wq)); \
X } while(0);
@@ -749,6 +748,7 @@
X #define SOCK_SNDBUF_LOCK 1
X #define SOCK_RCVBUF_LOCK 2
X #define SOCK_BINDADDR_LOCK 4
+#define SOCK_BINDPORT_LOCK 8
X
X
X /* Used by processes to "lock" a socket state, so that
@@ -818,7 +818,6 @@
X int priority);
X extern void sock_wfree(struct sk_buff *skb);
X extern void sock_rfree(struct sk_buff *skb);
-extern unsigned long sock_wspace(struct sock *sk);
X
X extern int sock_setsockopt(struct socket *sock, int level,
X int op, char *optval,
@@ -901,7 +900,7 @@
X * be accepted or 1 if the packet should be tossed.
X */
X
-extern __inline__ int sk_filter(struct sk_buff *skb, struct sk_filter *filter)
+static inline int sk_filter(struct sk_buff *skb, struct sk_filter *filter)
X {
X int pkt_len;
X
@@ -922,7 +921,7 @@
X * Remove a filter from a socket and release its resources.
X */
X
-extern __inline__ void sk_filter_release(struct sock *sk, struct sk_filter *fp)
+static inline void sk_filter_release(struct sock *sk, struct sk_filter *fp)
X {
X unsigned int size = sk_filter_len(fp);
X
@@ -932,7 +931,7 @@
X kfree(fp);
X }
X
-extern __inline__ void sk_filter_charge(struct sock *sk, struct sk_filter *fp)
+static inline void sk_filter_charge(struct sock *sk, struct sk_filter *fp)
X {
X atomic_inc(&fp->refcnt);
X atomic_add(sk_filter_len(fp), &sk->omem_alloc);
@@ -971,7 +970,7 @@
X modifications.
X */
X
-extern __inline__ void sock_hold(struct sock *sk)
+static inline void sock_hold(struct sock *sk)
X {
X atomic_inc(&sk->refcnt);
X }
@@ -979,13 +978,13 @@
X /* Ungrab socket in the context, which assumes that socket refcnt
X cannot hit zero, f.e. it is true in context of any socketcall.
X */
-extern __inline__ void __sock_put(struct sock *sk)
+static inline void __sock_put(struct sock *sk)
X {
X atomic_dec(&sk->refcnt);
X }
X
X /* Ungrab socket and destroy it, if it was the last reference. */
-extern __inline__ void sock_put(struct sock *sk)
+static inline void sock_put(struct sock *sk)
X {
X if (atomic_dec_and_test(&sk->refcnt))
X sk_free(sk);
@@ -998,7 +997,7 @@
X * probably wants some additional cleanups or even continuing
X * to work with this socket (TCP).
X */
-extern __inline__ void sock_orphan(struct sock *sk)
+static inline void sock_orphan(struct sock *sk)
X {
X write_lock_bh(&sk->callback_lock);
X sk->dead = 1;
@@ -1007,7 +1006,7 @@
X write_unlock_bh(&sk->callback_lock);
X }
X
-extern __inline__ void sock_graft(struct sock *sk, struct socket *parent)
+static inline void sock_graft(struct sock *sk, struct socket *parent)
X {
X write_lock_bh(&sk->callback_lock);
X sk->sleep = &parent->wait;
@@ -1036,13 +1035,13 @@
X return ino;
X }
X
-extern __inline__ struct dst_entry *
+static inline struct dst_entry *
X __sk_dst_get(struct sock *sk)
X {
X return sk->dst_cache;
X }
X
-extern __inline__ struct dst_entry *
+static inline struct dst_entry *
X sk_dst_get(struct sock *sk)
X {
X struct dst_entry *dst;
@@ -1055,7 +1054,7 @@
X return dst;


X }
X
-extern __inline__ void

+static inline void
X __sk_dst_set(struct sock *sk, struct dst_entry *dst)
X {
X struct dst_entry *old_dst;
@@ -1065,7 +1064,7 @@
X dst_release(old_dst);


X }
X
-extern __inline__ void

+static inline void
X sk_dst_set(struct sock *sk, struct dst_entry *dst)
X {
X write_lock(&sk->dst_lock);
@@ -1073,7 +1072,7 @@
X write_unlock(&sk->dst_lock);


X }
X
-extern __inline__ void

+static inline void
X __sk_dst_reset(struct sock *sk)
X {
X struct dst_entry *old_dst;
@@ -1083,7 +1082,7 @@
X dst_release(old_dst);


X }
X
-extern __inline__ void

+static inline void
X sk_dst_reset(struct sock *sk)
X {
X write_lock(&sk->dst_lock);
@@ -1091,7 +1090,7 @@
X write_unlock(&sk->dst_lock);
X }
X
-extern __inline__ struct dst_entry *
+static inline struct dst_entry *
X __sk_dst_check(struct sock *sk, u32 cookie)
X {
X struct dst_entry *dst = sk->dst_cache;
@@ -1104,7 +1103,7 @@
X return dst;
X }
X
-extern __inline__ struct dst_entry *
+static inline struct dst_entry *
X sk_dst_check(struct sock *sk, u32 cookie)
X {
X struct dst_entry *dst = sk_dst_get(sk);
@@ -1127,7 +1126,7 @@
X * packet ever received.
X */
X
-extern __inline__ void skb_set_owner_w(struct sk_buff *skb, struct sock *sk)
+static inline void skb_set_owner_w(struct sk_buff *skb, struct sock *sk)
X {
X sock_hold(sk);
X skb->sk = sk;
@@ -1135,14 +1134,14 @@
X atomic_add(skb->truesize, &sk->wmem_alloc);
X }
X
-extern __inline__ void skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
+static inline void skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
X {
X skb->sk = sk;
X skb->destructor = sock_rfree;
X atomic_add(skb->truesize, &sk->rmem_alloc);
X }
X
-extern __inline__ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
+static inline int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
X {
X /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces
X number of warnings when compiling with -W --ANK
@@ -1175,7 +1174,7 @@
X return 0;
X }
X
-extern __inline__ int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
+static inline int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
X {
X /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces
X number of warnings when compiling with -W --ANK
@@ -1193,13 +1192,13 @@
X * Recover an error report and clear atomically
X */
X
-extern __inline__ int sock_error(struct sock *sk)
+static inline int sock_error(struct sock *sk)
X {
X int err=xchg(&sk->err,0);
X return -err;
X }
X
-extern __inline__ unsigned long sock_wspace(struct sock *sk)
+static inline unsigned long sock_wspace(struct sock *sk)
X {
X int amt = 0;
X
@@ -1211,7 +1210,7 @@
X return amt;
X }
X
-extern __inline__ void sk_wake_async(struct sock *sk, int how, int band)
+static inline void sk_wake_async(struct sock *sk, int how, int band)
X {
X if (sk->socket && sk->socket->fasync_list)
X sock_wake_async(sk->socket, how, band);
@@ -1226,27 +1225,27 @@
X * Default write policy as shown to user space via poll/select/SIGIO
X * Kernel internally doesn't use the MIN_WRITE_SPACE threshold.
X */
-extern __inline__ int sock_writeable(struct sock *sk)
+static inline int sock_writeable(struct sock *sk)
X {
X return sock_wspace(sk) >= SOCK_MIN_WRITE_SPACE;
X }
X
-extern __inline__ int gfp_any(void)
+static inline int gfp_any(void)
X {
X return in_softirq() ? GFP_ATOMIC : GFP_KERNEL;
X }
X
-extern __inline__ long sock_rcvtimeo(struct sock *sk, int noblock)
+static inline long sock_rcvtimeo(struct sock *sk, int noblock)
X {
X return noblock ? 0 : sk->rcvtimeo;
X }
X
-extern __inline__ long sock_sndtimeo(struct sock *sk, int noblock)
+static inline long sock_sndtimeo(struct sock *sk, int noblock)
X {
X return noblock ? 0 : sk->sndtimeo;
X }
X
-extern __inline__ int sock_rcvlowat(struct sock *sk, int waitall, int len)
+static inline int sock_rcvlowat(struct sock *sk, int waitall, int len)
X {
X return (waitall ? len : min(sk->rcvlowat, len)) ? : 1;
X }
@@ -1254,7 +1253,7 @@
X /* Alas, with timeout socket operations are not restartable.
X * Compare this to poll().
X */
-extern __inline__ int sock_intr_errno(long timeo)
+static inline int sock_intr_errno(long timeo)
X {
X return timeo == MAX_SCHEDULE_TIMEOUT ? -ERESTARTSYS : -EINTR;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/include/net/tcp.h linux/include/net/tcp.h
--- v2.4.0-test8/linux/include/net/tcp.h Fri Sep 8 12:54:06 2000
+++ linux/include/net/tcp.h Mon Oct 2 12:06:41 2000
@@ -166,7 +166,7 @@
X
X extern kmem_cache_t *tcp_timewait_cachep;
X
-extern __inline__ void tcp_tw_put(struct tcp_tw_bucket *tw)
+static inline void tcp_tw_put(struct tcp_tw_bucket *tw)
X {
X if (atomic_dec_and_test(&tw->refcnt)) {
X #ifdef INET_REFCNT_DEBUG
@@ -495,7 +495,7 @@
X #define tcp_openreq_alloc() kmem_cache_alloc(tcp_openreq_cachep, SLAB_ATOMIC)
X #define tcp_openreq_fastfree(req) kmem_cache_free(tcp_openreq_cachep, req)
X
-extern __inline__ void tcp_openreq_free(struct open_request *req)
+static inline void tcp_openreq_free(struct open_request *req)
X {
X req->class->destructor(req);
X tcp_openreq_fastfree(req);
@@ -656,20 +656,6 @@
X memset(&tp->ack, 0, sizeof(tp->ack));
X }
X
-enum tcp_ca_state
-{
- TCP_CA_Open = 0,
-#define TCPF_CA_Open (1<<TCP_CA_Open)
- TCP_CA_Disorder = 1,
-#define TCPF_CA_Disorder (1<<TCP_CA_Disorder)
- TCP_CA_CWR = 2,
-#define TCPF_CA_CWR (1<<TCP_CA_CWR)
- TCP_CA_Recovery = 3,
-#define TCPF_CA_Recovery (1<<TCP_CA_Recovery)
- TCP_CA_Loss = 4
-#define TCPF_CA_Loss (1<<TCP_CA_Loss)
-};
-
X
X enum tcp_tw_status
X {
@@ -893,7 +879,7 @@
X * Underestimations are more easy to detect and fix by tcp_measure_rcv_mss().
X */
X
-extern __inline__ void tcp_initialize_rcv_mss(struct sock *sk)
+static inline void tcp_initialize_rcv_mss(struct sock *sk)
X {
X struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
X
@@ -1034,7 +1020,7 @@
X * one half the current congestion window, but no
X * less than two segments
X */
-extern __inline__ __u32 tcp_recalc_ssthresh(struct tcp_opt *tp)
+static inline __u32 tcp_recalc_ssthresh(struct tcp_opt *tp)
X {
X return max(tp->snd_cwnd>>1, 2);
X }
@@ -1043,7 +1029,7 @@
X * The exception is rate halving phase, when cwnd is decreasing towards
X * ssthresh.
X */
-extern __inline__ __u32 tcp_current_ssthresh(struct tcp_opt *tp)
+static inline __u32 tcp_current_ssthresh(struct tcp_opt *tp)
X {
X if ((1<<tp->ca_state)&(TCPF_CA_CWR|TCPF_CA_Recovery))
X return tp->snd_ssthresh;
@@ -1072,7 +1058,7 @@
X }
X
X /* Set slow start threshould and cwnd not falling to slow start */
-extern __inline__ void __tcp_enter_cwr(struct tcp_opt *tp)
+static inline void __tcp_enter_cwr(struct tcp_opt *tp)
X {
X tp->undo_marker = 0;
X tp->snd_ssthresh = tcp_recalc_ssthresh(tp);
@@ -1083,7 +1069,7 @@
X TCP_ECN_queue_cwr(tp);
X }
X
-extern __inline__ void tcp_enter_cwr(struct tcp_opt *tp)
+static inline void tcp_enter_cwr(struct tcp_opt *tp)
X {
X tp->prior_ssthresh = 0;
X if (tp->ca_state < TCP_CA_CWR) {
@@ -1307,6 +1293,8 @@
X
X case TCP_CLOSE:
X sk->prot->unhash(sk);
+ if (sk->prev && !(sk->userlocks&SOCK_BINDPORT_LOCK))
+ tcp_put_port(sk);
X /* fall through */
X default:
X if (oldstate==TCP_ESTABLISHED)
@@ -1378,7 +1366,7 @@
X * MAX_SYN_SIZE to match the new maximum number of options that you
X * can generate.
X */
-extern __inline__ void tcp_syn_build_options(__u32 *ptr, int mss, int ts, int sack,
+static inline void tcp_syn_build_options(__u32 *ptr, int mss, int ts, int sack,
X int offer_wscale, int wscale, __u32 tstamp, __u32 ts_recent)
X {
X /* We always get an MSS option.
@@ -1418,7 +1406,7 @@
X * be a multiple of mss if possible. We assume here that mss >= 1.
X * This MUST be enforced by all callers.
X */
-extern __inline__ void tcp_select_initial_window(int space, __u32 mss,
+static inline void tcp_select_initial_window(int space, __u32 mss,
X __u32 *rcv_wnd,
X __u32 *window_clamp,
X int wscale_ok,
@@ -1477,32 +1465,32 @@
X }
X
X /* Note: caller must be prepared to deal with negative returns */
-extern __inline__ int tcp_space(struct sock *sk)
+static inline int tcp_space(struct sock *sk)
X {
X return tcp_win_from_space(sk->rcvbuf - atomic_read(&sk->rmem_alloc));
X }
X
-extern __inline__ int tcp_full_space( struct sock *sk)
+static inline int tcp_full_space( struct sock *sk)
X {
X return tcp_win_from_space(sk->rcvbuf);
X }
X
-extern __inline__ void tcp_acceptq_removed(struct sock *sk)
+static inline void tcp_acceptq_removed(struct sock *sk)
X {
X sk->ack_backlog--;
X }
X
-extern __inline__ void tcp_acceptq_added(struct sock *sk)
+static inline void tcp_acceptq_added(struct sock *sk)
X {
X sk->ack_backlog++;
X }
X
-extern __inline__ int tcp_acceptq_is_full(struct sock *sk)
+static inline int tcp_acceptq_is_full(struct sock *sk)
X {
X return sk->ack_backlog > sk->max_ack_backlog;
X }
X
-extern __inline__ void tcp_acceptq_queue(struct sock *sk, struct open_request *req,
+static inline void tcp_acceptq_queue(struct sock *sk, struct open_request *req,
X struct sock *child)
X {
X struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
@@ -1528,7 +1516,7 @@
X struct open_request *syn_table[TCP_SYNQ_HSIZE];


X };
X
-extern __inline__ void

+static inline void
X tcp_synq_removed(struct sock *sk, struct open_request *req)
X {
X struct tcp_listen_opt *lopt = sk->tp_pinfo.af_tcp.listen_opt;
@@ -1539,7 +1527,7 @@
X lopt->qlen_young--;
X }
X
-extern __inline__ void tcp_synq_added(struct sock *sk)
+static inline void tcp_synq_added(struct sock *sk)
X {
X struct tcp_listen_opt *lopt = sk->tp_pinfo.af_tcp.listen_opt;
X
@@ -1548,22 +1536,22 @@
X lopt->qlen_young++;
X }
X
-extern __inline__ int tcp_synq_len(struct sock *sk)
+static inline int tcp_synq_len(struct sock *sk)
X {
X return sk->tp_pinfo.af_tcp.listen_opt->qlen;
X }
X
-extern __inline__ int tcp_synq_young(struct sock *sk)
+static inline int tcp_synq_young(struct sock *sk)
X {
X return sk->tp_pinfo.af_tcp.listen_opt->qlen_young;
X }
X
-extern __inline__ int tcp_synq_is_full(struct sock *sk)
+static inline int tcp_synq_is_full(struct sock *sk)
X {
X return tcp_synq_len(sk)>>sk->tp_pinfo.af_tcp.listen_opt->max_qlen_log;
X }
X
-extern __inline__ void tcp_synq_unlink(struct tcp_opt *tp, struct open_request *req,
+static inline void tcp_synq_unlink(struct tcp_opt *tp, struct open_request *req,
X struct open_request **prev)
X {
X write_lock(&tp->syn_wait_lock);
@@ -1571,7 +1559,7 @@
X write_unlock(&tp->syn_wait_lock);
X }
X
-extern __inline__ void tcp_synq_drop(struct sock *sk, struct open_request *req,
+static inline void tcp_synq_drop(struct sock *sk, struct open_request *req,
X struct open_request **prev)
X {
X tcp_synq_unlink(&sk->tp_pinfo.af_tcp, req, prev);
@@ -1679,7 +1667,7 @@
X * use plain read_(un)lock(&tcp_lhash_lock).
X */
X
-extern __inline__ void tcp_listen_lock(void)
+static inline void tcp_listen_lock(void)
X {
X /* read_lock synchronizes to candidates to writers */
X read_lock(&tcp_lhash_lock);
@@ -1687,7 +1675,7 @@
X read_unlock(&tcp_lhash_lock);
X }
X
-extern __inline__ void tcp_listen_unlock(void)
+static inline void tcp_listen_unlock(void)
X {
X if (atomic_dec_and_test(&tcp_lhash_users))
X wake_up(&tcp_lhash_wait);
diff -u --recursive --new-file v2.4.0-test8/linux/include/net/x25.h linux/include/net/x25.h
--- v2.4.0-test8/linux/include/net/x25.h Fri Apr 14 09:37:20 2000
+++ linux/include/net/x25.h Sun Sep 17 10:03:43 2000
@@ -188,7 +188,7 @@
X extern void x25_link_free(void);
X
X /* x25_out.c */
-extern void x25_output(struct sock *, struct sk_buff *);
+extern int x25_output(struct sock *, struct sk_buff *);
X extern void x25_kick(struct sock *);
X extern void x25_enquiry_response(struct sock *);
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/pcmcia/ss.h linux/include/pcmcia/ss.h
--- v2.4.0-test8/linux/include/pcmcia/ss.h Sat Sep 2 00:13:49 2000
+++ linux/include/pcmcia/ss.h Fri Sep 15 16:31:09 2000
@@ -82,6 +82,7 @@
X #define SS_DMA_MODE 0x0080
X #define SS_SPKR_ENA 0x0100
X #define SS_OUTPUT_ENA 0x0200
+#define SS_DEBOUNCED 0x0400 /* Tell driver that the debounce delay has ended */
X
X /* Flags for I/O port and memory windows */
X #define MAP_ACTIVE 0x01
diff -u --recursive --new-file v2.4.0-test8/linux/include/scsi/scsi_ioctl.h linux/include/scsi/scsi_ioctl.h
--- v2.4.0-test8/linux/include/scsi/scsi_ioctl.h Fri May 1 11:19:58 1998
+++ linux/include/scsi/scsi_ioctl.h Tue Sep 19 08:01:34 2000
@@ -32,6 +32,13 @@
X __u32 host_unique_id;
X } Scsi_Idlun;
X
+/* Fibre Channel WWN, port_id struct */
+typedef struct scsi_fctargaddress
+{
+ __u32 host_port_id;
+ unsigned char host_wwn[8]; // include NULL term.
+} Scsi_FCTargAddress;
+
X extern int scsi_ioctl (Scsi_Device *dev, int cmd, void *arg);
X extern int kernel_scsi_ioctl (Scsi_Device *dev, int cmd, void *arg);
X extern int scsi_ioctl_send_command(Scsi_Device *dev,
diff -u --recursive --new-file v2.4.0-test8/linux/include/scsi/sg.h linux/include/scsi/sg.h
--- v2.4.0-test8/linux/include/scsi/sg.h Mon Jul 31 11:26:27 2000
+++ linux/include/scsi/sg.h Thu Sep 21 20:48:05 2000
@@ -11,9 +11,13 @@
X Version 2 and 3 extensions to driver:
X * Copyright (C) 1998 - 2000 Douglas Gilbert
X
- Version: 3.1.16 (20000716)
- This version is for 2.3/2.4 series kernels.
+ Version: 3.1.17 (20000921)
+ This version is for 2.4 series kernels.
X
+ Changes since 3.1.16 (20000716)
+ - changes for new scsi subsystem initialization
+ - change Scsi_Cmnd usage to Scsi_Request
+ - cleanup for no procfs
X Changes since 3.1.15 (20000528)
X - further (scatter gather) buffer length changes
X Changes since 3.1.14 (20000503)
diff -u --recursive --new-file v2.4.0-test8/linux/init/main.c linux/init/main.c
--- v2.4.0-test8/linux/init/main.c Fri Sep 1 14:25:26 2000
+++ linux/init/main.c Fri Sep 22 14:11:21 2000
@@ -727,9 +727,6 @@
X while (pid != wait(&i));
X if (MAJOR(real_root_dev) != RAMDISK_MAJOR
X || MINOR(real_root_dev) != 0) {
-#ifdef CONFIG_BLK_DEV_MD
- md_run_setup();
-#endif
X error = change_root(real_root_dev,"/initrd");
X if (error)
X printk(KERN_ERR "Change root to /initrd: "
diff -u --recursive --new-file v2.4.0-test8/linux/init/version.c linux/init/version.c
--- v2.4.0-test8/linux/init/version.c Mon Jan 5 01:41:01 1998
+++ linux/init/version.c Mon Oct 2 11:57:01 2000
@@ -14,7 +14,7 @@
X #define version(a) Version_ ## a
X #define version_string(a) version(a)
X
-int version_string(LINUX_VERSION_CODE) = 0;
+int version_string(LINUX_VERSION_CODE);
X
X struct new_utsname system_utsname = {
X UTS_SYSNAME, UTS_NODENAME, UTS_RELEASE, UTS_VERSION,
diff -u --recursive --new-file v2.4.0-test8/linux/ipc/shm.c linux/ipc/shm.c
--- v2.4.0-test8/linux/ipc/shm.c Thu Sep 7 08:34:28 2000
+++ linux/ipc/shm.c Mon Sep 25 08:59:38 2000
@@ -206,7 +206,6 @@
X /* some statistics */
X static ulong swap_attempts;
X static ulong swap_successes;
-static ulong used_segs;
X
X void __init shm_init (void)
X {
@@ -364,7 +363,9 @@
X buf->f_blocks = shm_ctlall;
X buf->f_bavail = buf->f_bfree = shm_ctlall - shm_tot;
X buf->f_files = shm_ctlmni;
- buf->f_ffree = shm_ctlmni - used_segs;
+ shm_lockall();
+ buf->f_ffree = shm_ctlmni - shm_ids.in_use + 1;
+ shm_unlockall();
X buf->f_namelen = SHM_NAME_LEN;
X return 0;
X }
@@ -593,7 +594,6 @@
X if (doacc) {
X shm_lockall();
X shm_tot += pages;
- used_segs++;
X shm_unlockall();
X }
X return ret;
@@ -646,7 +646,6 @@
X shm_rss -= rss;
X shm_swp -= swp;
X shm_tot -= pages;
- used_segs--;
X shm_unlockall();
X }
X }
@@ -970,7 +969,7 @@
X
X memset(&shm_info,0,sizeof(shm_info));
X shm_lockall();
- shm_info.used_ids = shm_ids.in_use;
+ shm_info.used_ids = shm_ids.in_use - 1; /* correct the /dev/zero hack */
X shm_info.shm_rss = shm_rss;
X shm_info.shm_tot = shm_tot;
X shm_info.shm_swp = shm_swp;
@@ -1522,7 +1521,7 @@
X }
X
X /*
- * Goes through counter = (shm_rss / (prio + 1)) present shm pages.
+ * Goes through counter = (shm_rss >> prio) present shm pages.
X */
X static unsigned long swap_id; /* currently being swapped */
X static unsigned long swap_idx; /* next to swap */
@@ -1536,8 +1535,14 @@
X int counter;
X struct page * page_map;
X
+ /*
+ * Push this inside:


+ */
+ if (!(gfp_mask & __GFP_IO))

+ return 0;
+
X zshm_swap(prio, gfp_mask);
- counter = shm_rss / (prio + 1);
+ counter = shm_rss >> prio;
X if (!counter)
X return 0;
X if (shm_swap_preop(&swap_entry))
@@ -1863,7 +1868,7 @@
X int counter;
X struct page * page_map;
X
- counter = zshm_rss / (prio + 1);
+ counter = zshm_rss >> prio;


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 109'
echo 'File patch-2.4.0-test9 is continued in part 110'
echo "110" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part105

#!/bin/sh -x
# this is part 105 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 105; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

-extern int __test_bit(int nr, volatile void * addr);
-extern int find_first_zero_bit(void * addr, unsigned size);
-extern int find_next_zero_bit (void * addr, int size, int offset);
-extern unsigned long ffz(unsigned long word);
-
-/*
- * Some hacks to defeat gcc over-optimizations..
- */
-struct __dummy { unsigned long a[100]; };
-#define ADDR (*(volatile struct __dummy *) addr)
-#define CONST_ADDR (*(volatile const struct __dummy *) addr)
+#define ADDR (*(volatile long *) addr)
X
-extern __inline__ void set_bit(int nr, volatile void * addr)
+static __inline__ void set_bit(int nr, volatile void * addr)
X {
X __asm__ __volatile__( LOCK_PREFIX
X "btsl %1,%0"
@@ -51,7 +31,21 @@
X :"Ir" (nr));
X }
X
-extern __inline__ void clear_bit(int nr, volatile void * addr)
+/* WARNING: non atomic and it can be reordered! */
+static __inline__ void __set_bit(int nr, volatile void * addr)
+{
+ __asm__(
+ "btsl %1,%0"
+ :"=m" (ADDR)
+ :"Ir" (nr));
+}
+
+/*
+ * clear_bit() doesn't provide any barrier for the compiler.
+ */
+#define smp_mb__before_clear_bit() barrier()
+#define smp_mb__after_clear_bit() barrier()
+static __inline__ void clear_bit(int nr, volatile void * addr)
X {
X __asm__ __volatile__( LOCK_PREFIX
X "btrl %1,%0"
@@ -59,7 +53,7 @@
X :"Ir" (nr));
X }
X
-extern __inline__ void change_bit(int nr, volatile void * addr)
+static __inline__ void change_bit(int nr, volatile void * addr)
X {
X __asm__ __volatile__( LOCK_PREFIX
X "btcl %1,%0"
@@ -67,48 +61,77 @@
X :"Ir" (nr));
X }
X
-extern __inline__ int test_and_set_bit(int nr, volatile void * addr)
+/*
+ * It will also imply a memory barrier, thus it must clobber memory
+ * to make sure to reload anything that was cached into registers
+ * outside _this_ critical section.
+ */
+static __inline__ int test_and_set_bit(int nr, volatile void * addr)
X {
X int oldbit;
X
X __asm__ __volatile__( LOCK_PREFIX
X "btsl %2,%1\n\tsbbl %0,%0"
X :"=r" (oldbit),"=m" (ADDR)
+ :"Ir" (nr) : "memory");
+ return oldbit;
+}
+
+/* WARNING: non atomic and it can be reordered! */
+static __inline__ int __test_and_set_bit(int nr, volatile void * addr)
+{
+ int oldbit;
+
+ __asm__(
+ "btsl %2,%1\n\tsbbl %0,%0"
+ :"=r" (oldbit),"=m" (ADDR)
X :"Ir" (nr));
X return oldbit;
X }
X
-extern __inline__ int test_and_clear_bit(int nr, volatile void * addr)
+static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
X {
X int oldbit;
X
X __asm__ __volatile__( LOCK_PREFIX
X "btrl %2,%1\n\tsbbl %0,%0"
X :"=r" (oldbit),"=m" (ADDR)
+ :"Ir" (nr) : "memory");
+ return oldbit;
+}
+
+/* WARNING: non atomic and it can be reordered! */
+static __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
+{
+ int oldbit;
+
+ __asm__(
+ "btrl %2,%1\n\tsbbl %0,%0"
+ :"=r" (oldbit),"=m" (ADDR)
X :"Ir" (nr));
X return oldbit;
X }
X
-extern __inline__ int test_and_change_bit(int nr, volatile void * addr)
+static __inline__ int test_and_change_bit(int nr, volatile void * addr)
X {
X int oldbit;
X
X __asm__ __volatile__( LOCK_PREFIX
X "btcl %2,%1\n\tsbbl %0,%0"
X :"=r" (oldbit),"=m" (ADDR)
- :"Ir" (nr));
+ :"Ir" (nr) : "memory");
X return oldbit;
X }
X
X /*
X * This routine doesn't need to be atomic.
X */
-extern __inline__ int __constant_test_bit(int nr, const volatile void * addr)
+static __inline__ int constant_test_bit(int nr, const volatile void * addr)
X {
X return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
X }
X
-extern __inline__ int __test_bit(int nr, volatile void * addr)
+static __inline__ int variable_test_bit(int nr, volatile void * addr)
X {
X int oldbit;
X
@@ -121,13 +144,13 @@
X
X #define test_bit(nr,addr) \
X (__builtin_constant_p(nr) ? \
- __constant_test_bit((nr),(addr)) : \
- __test_bit((nr),(addr)))
+ constant_test_bit((nr),(addr)) : \
+ variable_test_bit((nr),(addr)))
X
X /*
X * Find-bit routines..
X */
-extern __inline__ int find_first_zero_bit(void * addr, unsigned size)
+static __inline__ int find_first_zero_bit(void * addr, unsigned size)
X {
X int d0, d1, d2;
X int res;
@@ -151,7 +174,7 @@
X return res;
X }
X
-extern __inline__ int find_next_zero_bit (void * addr, int size, int offset)
+static __inline__ int find_next_zero_bit (void * addr, int size, int offset)
X {
X unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
X int set = 0, bit = offset & 31, res;
@@ -182,7 +205,7 @@
X * ffz = Find First Zero in word. Undefined if no zero exists,
X * so code should check against ~0UL first..
X */
-extern __inline__ unsigned long ffz(unsigned long word)
+static __inline__ unsigned long ffz(unsigned long word)
X {
X __asm__("bsfl %1,%0"
X :"=r" (word)
@@ -198,7 +221,7 @@
X * differs in spirit from the above ffz (man ffs).
X */
X
-extern __inline__ int ffs(int x)
+static __inline__ int ffs(int x)
X {
X int r;
X
@@ -222,16 +245,16 @@


X
X #ifdef __KERNEL__
X

-#define ext2_set_bit test_and_set_bit
-#define ext2_clear_bit test_and_clear_bit
+#define ext2_set_bit __test_and_set_bit
+#define ext2_clear_bit __test_and_clear_bit
X #define ext2_test_bit test_bit
X #define ext2_find_first_zero_bit find_first_zero_bit
X #define ext2_find_next_zero_bit find_next_zero_bit
X
X /* Bitmap functions for the minix filesystem. */
-#define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
-#define minix_set_bit(nr,addr) set_bit(nr,addr)
-#define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
+#define minix_test_and_set_bit(nr,addr) __test_and_set_bit(nr,addr)
+#define minix_set_bit(nr,addr) __set_bit(nr,addr)
+#define minix_test_and_clear_bit(nr,addr) __test_and_clear_bit(nr,addr)
X #define minix_test_bit(nr,addr) test_bit(nr,addr)
X #define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)

X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-i386/fcntl.h linux/include/asm-i386/fcntl.h
--- v2.4.0-test8/linux/include/asm-i386/fcntl.h Fri Aug 11 14:37:49 2000
+++ linux/include/asm-i386/fcntl.h Fri Sep 22 14:21:19 2000


@@ -51,6 +51,9 @@
X #define F_EXLCK 4 /* or 3 */
X #define F_SHLCK 8 /* or 4 */
X
+/* for leases */
+#define F_INPROGRESS 16
+
X /* operations for bsd flock(), also used by the kernel implementation */
X #define LOCK_SH 1 /* shared lock */
X #define LOCK_EX 2 /* exclusive lock */
@@ -58,6 +61,11 @@
X blocking */
X #define LOCK_UN 8 /* remove lock */
X
+#define LOCK_MAND 32 /* This is a mandatory flock */
+#define LOCK_READ 64 /* ... Which allows concurrent read operations */
+#define LOCK_WRITE 128 /* ... Which allows concurrent write operations */
+#define LOCK_RW 192 /* ... Which allows concurrent read & write ops */
+
X struct flock {
X short l_type;
X short l_whence;

@@ -73,5 +81,7 @@
X loff_t l_len;
X pid_t l_pid;
X };
+
+#define F_LINUX_SPECIFIC_BASE 1024
X
X #endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-i386/resource.h linux/include/asm-i386/resource.h
--- v2.4.0-test8/linux/include/asm-i386/resource.h Thu Feb 17 09:35:07 2000
+++ linux/include/asm-i386/resource.h Fri Sep 22 14:21:19 2000


@@ -15,8 +15,9 @@
X #define RLIMIT_NOFILE 7 /* max number of open files */
X #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
X #define RLIMIT_AS 9 /* address space limit */
+#define RLIMIT_LOCKS 10 /* maximum file locks held */
X
-#define RLIM_NLIMITS 10
+#define RLIM_NLIMITS 11
X

X /*
X * SuS says limits have to be unsigned.

@@ -38,6 +39,7 @@
X { INR_OPEN, INR_OPEN }, \


X { RLIM_INFINITY, RLIM_INFINITY }, \
X { RLIM_INFINITY, RLIM_INFINITY }, \
+ { RLIM_INFINITY, RLIM_INFINITY }, \
X }

X
X #endif /* __KERNEL__ */
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-i386/rwlock.h linux/include/asm-i386/rwlock.h
--- v2.4.0-test8/linux/include/asm-i386/rwlock.h Sat Nov 27 16:04:04 1999
+++ linux/include/asm-i386/rwlock.h Fri Sep 22 14:07:43 2000
@@ -17,9 +17,6 @@
X #ifndef _ASM_I386_RWLOCK_H
X #define _ASM_I386_RWLOCK_H


X
-typedef struct { unsigned long a[100]; } __dummy_lock_t;
-#define __dummy_lock(lock) (*(__dummy_lock_t *)(lock))
-

X #define RW_LOCK_BIAS 0x01000000
X #define RW_LOCK_BIAS_STR "0x01000000"
X
@@ -44,7 +41,7 @@
X "popl %%eax\n\t" \
X "jmp 1b\n" \
X ".previous" \
- :"=m" (__dummy_lock(rw)))
+ :"=m" (*(volatile int *)rw) : : "memory")
X
X #define __build_read_lock(rw, helper) do { \
X if (__builtin_constant_p(rw)) \
@@ -74,7 +71,7 @@
X "popl %%eax\n\t" \
X "jmp 1b\n" \
X ".previous" \
- :"=m" (__dummy_lock(rw)))
+ :"=m" (*(volatile int *)rw) : : "memory")
X
X #define __build_write_lock(rw, helper) do { \
X if (__builtin_constant_p(rw)) \
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-i386/semaphore.h linux/include/asm-i386/semaphore.h
--- v2.4.0-test8/linux/include/asm-i386/semaphore.h Fri Sep 8 12:52:41 2000
+++ linux/include/asm-i386/semaphore.h Mon Oct 2 11:01:18 2000
@@ -64,7 +64,7 @@
X #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
X #define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
X
-extern inline void sema_init (struct semaphore *sem, int val)
+static inline void sema_init (struct semaphore *sem, int val)
X {
X /*
X * *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
@@ -105,7 +105,7 @@
X * "__down_failed" is a special asm handler that calls the C
X * routine that actually waits. See arch/i386/kernel/semaphore.c
X */
-extern inline void down(struct semaphore * sem)
+static inline void down(struct semaphore * sem)
X {
X #if WAITQUEUE_DEBUG
X CHECK_MAGIC(sem->__magic);
@@ -125,7 +125,7 @@
X :"memory");
X }
X
-extern inline int down_interruptible(struct semaphore * sem)
+static inline int down_interruptible(struct semaphore * sem)


X {
X int result;
X

@@ -149,7 +149,7 @@


X return result;
X }
X

-extern inline int down_trylock(struct semaphore * sem)
+static inline int down_trylock(struct semaphore * sem)


X {
X int result;
X

@@ -179,7 +179,7 @@
X * The default case (no contention) will result in NO
X * jumps for both down() and up().
X */
-extern inline void up(struct semaphore * sem)
+static inline void up(struct semaphore * sem)
X {
X #if WAITQUEUE_DEBUG
X CHECK_MAGIC(sem->__magic);
@@ -252,7 +252,7 @@
X #define DECLARE_RWSEM_READ_LOCKED(name) __DECLARE_RWSEM_GENERIC(name,RW_LOCK_BIAS-1)
X #define DECLARE_RWSEM_WRITE_LOCKED(name) __DECLARE_RWSEM_GENERIC(name,0)
X
-extern inline void init_rwsem(struct rw_semaphore *sem)
+static inline void init_rwsem(struct rw_semaphore *sem)
X {
X atomic_set(&sem->count, RW_LOCK_BIAS);
X sem->read_bias_granted = 0;
@@ -271,7 +271,7 @@
X extern struct rw_semaphore *FASTCALL(__down_write_failed(struct rw_semaphore *sem));
X extern struct rw_semaphore *FASTCALL(__rwsem_wake(struct rw_semaphore *sem));
X
-extern inline void down_read(struct rw_semaphore *sem)
+static inline void down_read(struct rw_semaphore *sem)
X {
X #if WAITQUEUE_DEBUG
X if (sem->__magic != (long)&sem->__magic)
@@ -287,7 +287,7 @@
X #endif
X }
X
-extern inline void down_write(struct rw_semaphore *sem)
+static inline void down_write(struct rw_semaphore *sem)
X {
X #if WAITQUEUE_DEBUG
X if (sem->__magic != (long)&sem->__magic)
@@ -311,7 +311,7 @@
X * case is when there was a writer waiting, and we've
X * bumped the count to 0: we must wake the writer up.
X */
-extern inline void __up_read(struct rw_semaphore *sem)
+static inline void __up_read(struct rw_semaphore *sem)
X {
X __asm__ __volatile__(
X "# up_read\n\t"
@@ -330,7 +330,7 @@
X /* releasing the writer is easy -- just release it and
X * wake up any sleepers.
X */
-extern inline void __up_write(struct rw_semaphore *sem)
+static inline void __up_write(struct rw_semaphore *sem)
X {
X __asm__ __volatile__(
X "# up_write\n\t"
@@ -346,7 +346,7 @@
X );
X }
X
-extern inline void up_read(struct rw_semaphore *sem)
+static inline void up_read(struct rw_semaphore *sem)
X {
X #if WAITQUEUE_DEBUG
X if (sem->write_bias_granted)
@@ -358,7 +358,7 @@
X __up_read(sem);
X }
X
-extern inline void up_write(struct rw_semaphore *sem)
+static inline void up_write(struct rw_semaphore *sem)
X {
X #if WAITQUEUE_DEBUG
X if (sem->read_bias_granted)
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-i386/spinlock.h linux/include/asm-i386/spinlock.h
--- v2.4.0-test8/linux/include/asm-i386/spinlock.h Fri Sep 8 12:52:41 2000
+++ linux/include/asm-i386/spinlock.h Mon Oct 2 11:01:17 2000
@@ -70,13 +70,12 @@
X char oldval;
X __asm__ __volatile__(
X "xchgb %b0,%1"
- :"=q" (oldval), "=m" (__dummy_lock(lock))
- :"0" (0)
- :"memory");
+ :"=q" (oldval), "=m" (lock->lock)
+ :"0" (0) : "memory");
X return oldval > 0;
X }
X
-extern inline void spin_lock(spinlock_t *lock)
+static inline void spin_lock(spinlock_t *lock)
X {
X #if SPINLOCK_DEBUG
X __label__ here;
@@ -88,11 +87,10 @@
X #endif
X __asm__ __volatile__(
X spin_lock_string
- :"=m" (__dummy_lock(lock))
- : :"memory");
+ :"=m" (lock->lock) : : "memory");
X }
X
-extern inline void spin_unlock(spinlock_t *lock)
+static inline void spin_unlock(spinlock_t *lock)
X {
X #if SPINLOCK_DEBUG
X if (lock->magic != SPINLOCK_MAGIC)
@@ -102,8 +100,7 @@
X #endif
X __asm__ __volatile__(
X spin_unlock_string
- :"=m" (__dummy_lock(lock))
- : :"memory");
+ :"=m" (lock->lock) : : "memory");
X }
X
X /*
@@ -146,7 +143,7 @@
X */
X /* the spinlock helpers are in arch/i386/kernel/semaphore.S */
X
-extern inline void read_lock(rwlock_t *rw)
+static inline void read_lock(rwlock_t *rw)
X {
X #if SPINLOCK_DEBUG
X if (rw->magic != RWLOCK_MAGIC)
@@ -155,7 +152,7 @@
X __build_read_lock(rw, "__read_lock_failed");
X }
X
-extern inline void write_lock(rwlock_t *rw)
+static inline void write_lock(rwlock_t *rw)
X {
X #if SPINLOCK_DEBUG
X if (rw->magic != RWLOCK_MAGIC)
@@ -164,10 +161,10 @@
X __build_write_lock(rw, "__write_lock_failed");
X }
X
-#define read_unlock(rw) asm volatile("lock ; incl %0" :"=m" (__dummy_lock(&(rw)->lock)))
-#define write_unlock(rw) asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ",%0":"=m" (__dummy_lock(&(rw)->lock)))
+#define read_unlock(rw) asm volatile("lock ; incl %0" :"=m" ((rw)->lock) : : "memory")
+#define write_unlock(rw) asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ",%0":"=m" ((rw)->lock) : : "memory")
X
-extern inline int write_trylock(rwlock_t *lock)
+static inline int write_trylock(rwlock_t *lock)
X {
X atomic_t *count = (atomic_t *)lock;
X if (atomic_sub_and_test(RW_LOCK_BIAS, count))
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-i386/system.h linux/include/asm-i386/system.h
--- v2.4.0-test8/linux/include/asm-i386/system.h Fri Sep 8 12:52:41 2000
+++ linux/include/asm-i386/system.h Mon Oct 2 11:01:18 2000
@@ -278,11 +278,22 @@
X #endif
X #define rmb() mb()
X #define wmb() __asm__ __volatile__ ("": : :"memory")
+


+#ifdef CONFIG_SMP
+#define smp_mb() mb()
+#define smp_rmb() rmb()
+#define smp_wmb() wmb()
+#else
+#define smp_mb() barrier()
+#define smp_rmb() barrier()
+#define smp_wmb() barrier()
+#endif
+

X #define set_mb(var, value) do { xchg(&var, value); } while (0)
X #define set_wmb(var, value) do { var = value; wmb(); } while (0)
X
X /* interrupt control.. */
-#define __save_flags(x) __asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */ :"memory")
+#define __save_flags(x) __asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */)
X #define __restore_flags(x) __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory")
X #define __cli() __asm__ __volatile__("cli": : :"memory")
X #define __sti() __asm__ __volatile__("sti": : :"memory")


@@ -291,9 +302,9 @@
X

X /* For spinlocks etc */
X #define local_irq_save(x) __asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (x): /* no input */ :"memory")
-#define local_irq_restore(x) __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory")
-#define local_irq_disable() __asm__ __volatile__("cli": : :"memory")
-#define local_irq_enable() __asm__ __volatile__("sti": : :"memory")
+#define local_irq_restore(x) __restore_flags(x)
+#define local_irq_disable() __cli()
+#define local_irq_enable() __sti()
X
X #ifdef CONFIG_SMP
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ia64/fcntl.h linux/include/asm-ia64/fcntl.h
--- v2.4.0-test8/linux/include/asm-ia64/fcntl.h Wed Jul 5 11:13:39 2000
+++ linux/include/asm-ia64/fcntl.h Fri Sep 22 14:21:19 2000
@@ -55,6 +55,9 @@


X #define F_EXLCK 4 /* or 3 */
X #define F_SHLCK 8 /* or 4 */
X
+/* for leases */
+#define F_INPROGRESS 16
+
X /* operations for bsd flock(), also used by the kernel implementation */
X #define LOCK_SH 1 /* shared lock */
X #define LOCK_EX 2 /* exclusive lock */

@@ -62,6 +65,11 @@


X blocking */
X #define LOCK_UN 8 /* remove lock */
X
+#define LOCK_MAND 32 /* This is a mandatory flock */
+#define LOCK_READ 64 /* ... Which allows concurrent read operations */
+#define LOCK_WRITE 128 /* ... Which allows concurrent write operations */
+#define LOCK_RW 192 /* ... Which allows concurrent read & write ops */
+
X struct flock {
X short l_type;
X short l_whence;

@@ -70,4 +78,5 @@


X pid_t l_pid;
X };
X
+#define F_LINUX_SPECIFIC_BASE 1024

X #endif /* _ASM_IA64_FCNTL_H */
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ia64/resource.h linux/include/asm-ia64/resource.h
--- v2.4.0-test8/linux/include/asm-ia64/resource.h Sun Feb 6 18:42:40 2000
+++ linux/include/asm-ia64/resource.h Fri Sep 22 14:21:19 2000
@@ -18,8 +18,9 @@


X #define RLIMIT_NOFILE 7 /* max number of open files */
X #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
X #define RLIMIT_AS 9 /* address space limit */
+#define RLIMIT_LOCKS 10 /* maximum file locks held */
X
-#define RLIM_NLIMITS 10
+#define RLIM_NLIMITS 11
X

X /*
X * SuS says limits have to be unsigned.

@@ -39,6 +40,7 @@


X { RLIM_INFINITY, RLIM_INFINITY }, \
X { 0, 0 }, \
X { INR_OPEN, INR_OPEN }, \
+ { RLIM_INFINITY, RLIM_INFINITY }, \
X { RLIM_INFINITY, RLIM_INFINITY }, \
X { RLIM_INFINITY, RLIM_INFINITY }, \
X }

diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-m68k/fcntl.h linux/include/asm-m68k/fcntl.h
--- v2.4.0-test8/linux/include/asm-m68k/fcntl.h Wed Jul 5 11:13:39 2000
+++ linux/include/asm-m68k/fcntl.h Fri Sep 22 14:21:20 2000
@@ -47,6 +47,9 @@


X #define F_EXLCK 4 /* or 3 */
X #define F_SHLCK 8 /* or 4 */
X
+/* for leases */
+#define F_INPROGRESS 16
+
X /* operations for bsd flock(), also used by the kernel implementation */
X #define LOCK_SH 1 /* shared lock */
X #define LOCK_EX 2 /* exclusive lock */

@@ -54,6 +57,11 @@


X blocking */
X #define LOCK_UN 8 /* remove lock */
X
+#define LOCK_MAND 32 /* This is a mandatory flock */
+#define LOCK_READ 64 /* ... Which allows concurrent read operations */
+#define LOCK_WRITE 128 /* ... Which allows concurrent write operations */
+#define LOCK_RW 192 /* ... Which allows concurrent read & write ops */
+
X struct flock {
X short l_type;
X short l_whence;

@@ -62,4 +70,5 @@


X pid_t l_pid;
X };
X
+#define F_LINUX_SPECIFIC_BASE 1024

X #endif /* _M68K_FCNTL_H */
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-m68k/resource.h linux/include/asm-m68k/resource.h
--- v2.4.0-test8/linux/include/asm-m68k/resource.h Thu Feb 17 09:35:07 2000
+++ linux/include/asm-m68k/resource.h Fri Sep 22 14:21:20 2000


@@ -15,8 +15,9 @@
X #define RLIMIT_NOFILE 7 /* max number of open files */
X #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space*/
X #define RLIMIT_AS 9 /* address space limit */
+#define RLIMIT_LOCKS 10 /* maximum file locks held */
X
-#define RLIM_NLIMITS 10
+#define RLIM_NLIMITS 11
X

X /*
X * SuS says limits have to be unsigned.

@@ -36,6 +37,7 @@
X {LONG_MAX, LONG_MAX}, \


X {0, 0}, \
X {INR_OPEN, INR_OPEN}, \

+ {LONG_MAX, LONG_MAX}, \
X {LONG_MAX, LONG_MAX}, \
X {LONG_MAX, LONG_MAX} \
X }
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-mips/fcntl.h linux/include/asm-mips/fcntl.h
--- v2.4.0-test8/linux/include/asm-mips/fcntl.h Wed Jul 5 11:13:39 2000
+++ linux/include/asm-mips/fcntl.h Fri Sep 22 14:21:20 2000
@@ -56,6 +56,9 @@


X #define F_EXLCK 4 /* or 3 */
X #define F_SHLCK 8 /* or 4 */
X
+/* for leases */
+#define F_INPROGRESS 16
+
X /* operations for bsd flock(), also used by the kernel implementation */
X #define LOCK_SH 1 /* shared lock */
X #define LOCK_EX 2 /* exclusive lock */

@@ -63,6 +66,11 @@


X blocking */
X #define LOCK_UN 8 /* remove lock */
X
+#define LOCK_MAND 32 /* This is a mandatory flock */
+#define LOCK_READ 64 /* ... Which allows concurrent read operations */
+#define LOCK_WRITE 128 /* ... Which allows concurrent write operations */
+#define LOCK_RW 192 /* ... Which allows concurrent read & write ops */
+

X typedef struct flock {


X short l_type;
X short l_whence;

@@ -73,4 +81,5 @@
X long pad[4]; /* ZZZZZZZZZZZZZZZZZZZZZZZZZZ */
X } flock_t;
X
+#define F_LINUX_SPECIFIC_BASE 1024
X #endif /* __ASM_MIPS_FCNTL_H */
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-mips/resource.h linux/include/asm-mips/resource.h
--- v2.4.0-test8/linux/include/asm-mips/resource.h Sat May 13 08:31:25 2000
+++ linux/include/asm-mips/resource.h Fri Sep 22 14:21:20 2000
@@ -22,8 +22,9 @@
X #define RLIMIT_RSS 7 /* max resident set size */


X #define RLIMIT_NPROC 8 /* max number of processes */

X #define RLIMIT_MEMLOCK 9 /* max locked-in-memory address space */


+#define RLIMIT_LOCKS 10 /* maximum file locks held */
X

-#define RLIM_NLIMITS 10 /* Number of limit flavors. */
+#define RLIM_NLIMITS 11 /* Number of limit flavors. */
X
X /*


X * SuS says limits have to be unsigned.

@@ -44,6 +45,7 @@


X { RLIM_INFINITY, RLIM_INFINITY }, \
X { RLIM_INFINITY, RLIM_INFINITY }, \
X { 0, 0 }, \

+ { RLIM_INFINITY, RLIM_INFINITY }, \
X { RLIM_INFINITY, RLIM_INFINITY }, \
X }

X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-mips64/fcntl.h linux/include/asm-mips64/fcntl.h
--- v2.4.0-test8/linux/include/asm-mips64/fcntl.h Wed Jul 5 11:13:39 2000
+++ linux/include/asm-mips64/fcntl.h Fri Sep 22 14:21:20 2000
@@ -56,6 +56,9 @@


X #define F_EXLCK 4 /* or 3 */
X #define F_SHLCK 8 /* or 4 */
X
+/* for leases */
+#define F_INPROGRESS 16
+
X /* operations for bsd flock(), also used by the kernel implementation */
X #define LOCK_SH 1 /* shared lock */
X #define LOCK_EX 2 /* exclusive lock */

@@ -63,6 +66,11 @@


X blocking */
X #define LOCK_UN 8 /* remove lock */
X
+#define LOCK_MAND 32 /* This is a mandatory flock */
+#define LOCK_READ 64 /* ... Which allows concurrent read operations */
+#define LOCK_WRITE 128 /* ... Which allows concurrent write operations */
+#define LOCK_RW 192 /* ... Which allows concurrent read & write ops */
+

X typedef struct flock {


X short l_type;
X short l_whence;

@@ -73,4 +81,5 @@
X long pad[4]; /* ZZZZZZZZZZZZZZZZZZZZZZZZZZ */
X } flock_t;
X
+#define F_LINUX_SPECIFIC_BASE 1024
X #endif /* _ASM_FCNTL_H */
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-mips64/resource.h linux/include/asm-mips64/resource.h
--- v2.4.0-test8/linux/include/asm-mips64/resource.h Sun Jul 9 22:18:15 2000
+++ linux/include/asm-mips64/resource.h Fri Sep 22 14:21:20 2000
@@ -23,8 +23,9 @@
X #define RLIMIT_RSS 7 /* max resident set size */


X #define RLIMIT_NPROC 8 /* max number of processes */

X #define RLIMIT_MEMLOCK 9 /* max locked-in-memory address space */


+#define RLIMIT_LOCKS 10 /* maximum file locks held */
X

-#define RLIM_NLIMITS 10 /* Number of limit flavors. */
+#define RLIM_NLIMITS 11 /* Number of limit flavors. */
X
X /*


X * SuS says limits have to be unsigned.

@@ -45,6 +46,7 @@


X { RLIM_INFINITY, RLIM_INFINITY }, \
X { RLIM_INFINITY, RLIM_INFINITY }, \
X { 0, 0 }, \

+ { RLIM_INFINITY, RLIM_INFINITY }, \
X { RLIM_INFINITY, RLIM_INFINITY }, \
X }

X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/atomic.h linux/include/asm-ppc/atomic.h
--- v2.4.0-test8/linux/include/asm-ppc/atomic.h Tue May 2 13:05:40 2000
+++ linux/include/asm-ppc/atomic.h Mon Oct 2 11:54:51 2000
@@ -5,13 +5,7 @@
X #ifndef _ASM_PPC_ATOMIC_H_
X #define _ASM_PPC_ATOMIC_H_
X
-#include <linux/config.h>


-
-#ifdef CONFIG_SMP
X typedef struct { volatile int counter; } atomic_t;
-#else
-typedef struct { int counter; } atomic_t;
-#endif
X
X #define ATOMIC_INIT(i) { (i) }
X

@@ -21,7 +15,7 @@
X extern void atomic_clear_mask(unsigned long mask, unsigned long *addr);
X extern void atomic_set_mask(unsigned long mask, unsigned long *addr);
X
-extern __inline__ int atomic_add_return(int a, atomic_t *v)
+static __inline__ int atomic_add_return(int a, atomic_t *v)
X {
X int t;
X
@@ -30,14 +24,14 @@
X add %0,%2,%0\n\
X stwcx. %0,0,%3\n\
X bne- 1b"
- : "=&r" (t), "=m" (*v)
- : "r" (a), "r" (v), "m" (*v)
+ : "=&r" (t), "=m" (v->counter)
+ : "r" (a), "r" (v), "m" (v->counter)
X : "cc");
X
X return t;
X }
X
-extern __inline__ int atomic_sub_return(int a, atomic_t *v)
+static __inline__ int atomic_sub_return(int a, atomic_t *v)
X {
X int t;
X
@@ -46,14 +40,14 @@
X subf %0,%2,%0\n\
X stwcx. %0,0,%3\n\
X bne- 1b"
- : "=&r" (t), "=m" (*v)
- : "r" (a), "r" (v), "m" (*v)
+ : "=&r" (t), "=m" (v->counter)
+ : "r" (a), "r" (v), "m" (v->counter)
X : "cc");
X
X return t;
X }
X
-extern __inline__ int atomic_inc_return(atomic_t *v)
+static __inline__ int atomic_inc_return(atomic_t *v)
X {
X int t;
X
@@ -62,14 +56,14 @@
X addic %0,%0,1\n\
X stwcx. %0,0,%2\n\
X bne- 1b"
- : "=&r" (t), "=m" (*v)
- : "r" (v), "m" (*v)
+ : "=&r" (t), "=m" (v->counter)
+ : "r" (v), "m" (v->counter)
X : "cc");
X
X return t;
X }
X
-extern __inline__ int atomic_dec_return(atomic_t *v)
+static __inline__ int atomic_dec_return(atomic_t *v)
X {
X int t;
X
@@ -78,8 +72,8 @@
X addic %0,%0,-1\n\
X stwcx. %0,0,%2\n\
X bne 1b"
- : "=&r" (t), "=m" (*v)
- : "r" (v), "m" (*v)
+ : "=&r" (t), "=m" (v->counter)
+ : "r" (v), "m" (v->counter)
X : "cc");
X
X return t;
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/backlight.h linux/include/asm-ppc/backlight.h
--- v2.4.0-test8/linux/include/asm-ppc/backlight.h Thu Jul 13 09:42:51 2000
+++ linux/include/asm-ppc/backlight.h Sun Sep 17 09:48:07 2000
@@ -25,4 +25,4 @@
X extern int set_backlight_level(int level);
X extern int get_backlight_level(void);
X
-#endif
\ No newline at end of file
+#endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/bitops.h linux/include/asm-ppc/bitops.h
--- v2.4.0-test8/linux/include/asm-ppc/bitops.h Wed Jul 5 22:15:26 2000
+++ linux/include/asm-ppc/bitops.h Wed Sep 27 13:41:33 2000
@@ -9,17 +9,9 @@
X #include <linux/config.h>
X #include <asm/byteorder.h>
X

-extern void set_bit(int nr, volatile void *addr);
-extern void clear_bit(int nr, volatile void *addr);
-extern void change_bit(int nr, volatile void *addr);
-extern int test_and_set_bit(int nr, volatile void *addr);
-extern int test_and_clear_bit(int nr, volatile void *addr);
-extern int test_and_change_bit(int nr, volatile void *addr);

-
X /*
- * Arguably these bit operations don't imply any memory barrier or
- * SMP ordering, but in fact a lot of drivers expect them to imply
- * both, since they do on x86 cpus.
+ * The test_and_*_bit operations are taken to imply a memory barrier
+ * on SMP systems.
X */
X #ifdef CONFIG_SMP
X #define SMP_WMB "eieio\n"
@@ -36,58 +28,75 @@
X * These used to be if'd out here because using : "cc" as a constraint
X * resulted in errors from egcs. Things may be OK with gcc-2.95.
X */
-extern __inline__ void set_bit(int nr, volatile void * addr)
+static __inline__ void set_bit(int nr, volatile void * addr)
X {
X unsigned long old;
X unsigned long mask = 1 << (nr & 0x1f);
X unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
X
- __asm__ __volatile__(SMP_WMB "\
+ __asm__ __volatile__("\
X 1: lwarx %0,0,%3
X or %0,%0,%2
X stwcx. %0,0,%3
- bne 1b"
- SMP_MB
+ bne- 1b"
X : "=&r" (old), "=m" (*p)
X : "r" (mask), "r" (p), "m" (*p)
X : "cc" );
X }
X
-extern __inline__ void clear_bit(int nr, volatile void *addr)
+/*
+ * non-atomic version
+ */
+static __inline__ void __set_bit(int nr, volatile void *addr)
+{
+ unsigned long mask = 1 << (nr & 0x1f);
+ unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
+
+ *p |= mask;
+}
+
+/*
+ * clear_bit doesn't imply a memory barrier
+ */


+#define smp_mb__before_clear_bit() smp_mb()
+#define smp_mb__after_clear_bit() smp_mb()

+
+static __inline__ void clear_bit(int nr, volatile void *addr)
X {
X unsigned long old;
X unsigned long mask = 1 << (nr & 0x1f);
X unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
X
- __asm__ __volatile__(SMP_WMB "\
+ __asm__ __volatile__("\
X 1: lwarx %0,0,%3
X andc %0,%0,%2
X stwcx. %0,0,%3
- bne 1b"
- SMP_MB
+ bne- 1b"
X : "=&r" (old), "=m" (*p)
X : "r" (mask), "r" (p), "m" (*p)
X : "cc");
X }
X
-extern __inline__ void change_bit(int nr, volatile void *addr)
+static __inline__ void change_bit(int nr, volatile void *addr)
X {
X unsigned long old;
X unsigned long mask = 1 << (nr & 0x1f);
X unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
X
- __asm__ __volatile__(SMP_WMB "\
+ __asm__ __volatile__("\
X 1: lwarx %0,0,%3
X xor %0,%0,%2
X stwcx. %0,0,%3
- bne 1b"
- SMP_MB
+ bne- 1b"
X : "=&r" (old), "=m" (*p)
X : "r" (mask), "r" (p), "m" (*p)
X : "cc");
X }
X
-extern __inline__ int test_and_set_bit(int nr, volatile void *addr)
+/*
+ * test_and_*_bit do imply a memory barrier (?)
+ */
+static __inline__ int test_and_set_bit(int nr, volatile void *addr)
X {
X unsigned int old, t;
X unsigned int mask = 1 << (nr & 0x1f);
@@ -101,12 +110,25 @@
X SMP_MB
X : "=&r" (old), "=&r" (t), "=m" (*p)
X : "r" (mask), "r" (p), "m" (*p)
- : "cc");
+ : "cc", "memory");
+
+ return (old & mask) != 0;
+}
X
+/*
+ * non-atomic version
+ */
+static __inline__ int __test_and_set_bit(int nr, volatile void *addr)
+{
+ unsigned long mask = 1 << (nr & 0x1f);
+ unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
+ unsigned long old = *p;
+
+ *p = old | mask;
X return (old & mask) != 0;
X }
X
-extern __inline__ int test_and_clear_bit(int nr, volatile void *addr)
+static __inline__ int test_and_clear_bit(int nr, volatile void *addr)
X {
X unsigned int old, t;
X unsigned int mask = 1 << (nr & 0x1f);
@@ -120,12 +142,25 @@
X SMP_MB
X : "=&r" (old), "=&r" (t), "=m" (*p)
X : "r" (mask), "r" (p), "m" (*p)
- : "cc");
+ : "cc", "memory");
X
X return (old & mask) != 0;
X }
X
-extern __inline__ int test_and_change_bit(int nr, volatile void *addr)
+/*
+ * non-atomic version
+ */
+static __inline__ int __test_and_clear_bit(int nr, volatile void *addr)
+{
+ unsigned long mask = 1 << (nr & 0x1f);
+ unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
+ unsigned long old = *p;
+
+ *p = old & ~mask;
+ return (old & mask) != 0;
+}
+
+static __inline__ int test_and_change_bit(int nr, volatile void *addr)
X {
X unsigned int old, t;
X unsigned int mask = 1 << (nr & 0x1f);
@@ -139,13 +174,22 @@
X SMP_MB
X : "=&r" (old), "=&r" (t), "=m" (*p)
X : "r" (mask), "r" (p), "m" (*p)
- : "cc");
+ : "cc", "memory");
X
X return (old & mask) != 0;
X }
+#else /* __INLINE_BITOPS */
+
+extern void set_bit(int nr, volatile void *addr);
+extern void clear_bit(int nr, volatile void *addr);
+extern void change_bit(int nr, volatile void *addr);
+extern int test_and_set_bit(int nr, volatile void *addr);
+extern int test_and_clear_bit(int nr, volatile void *addr);
+extern int test_and_change_bit(int nr, volatile void *addr);
+
X #endif /* __INLINE_BITOPS */
X
-extern __inline__ int test_bit(int nr, __const__ volatile void *addr)
+static __inline__ int test_bit(int nr, __const__ volatile void *addr)
X {
X __const__ unsigned int *p = (__const__ unsigned int *) addr;
X
@@ -153,7 +197,7 @@
X }
X
X /* Return the bit position of the most significant 1 bit in a word */
-extern __inline__ int __ilog2(unsigned int x)
+static __inline__ int __ilog2(unsigned int x)
X {
X int lz;
X
@@ -161,7 +205,7 @@
X return 31 - lz;
X }
X
-extern __inline__ int ffz(unsigned int x)
+static __inline__ int ffz(unsigned int x)
X {
X if ((x = ~x) == 0)
X return 32;
@@ -175,7 +219,7 @@
X * the libc and compiler builtin ffs routines, therefore
X * differs in spirit from the above ffz (man ffs).
X */
-extern __inline__ int ffs(int x)
+static __inline__ int ffs(int x)
X {
X return __ilog2(x & -x) + 1;
X }
@@ -198,7 +242,7 @@
X #define find_first_zero_bit(addr, size) \
X find_next_zero_bit((addr), (size), 0)
X
-extern __inline__ unsigned long find_next_zero_bit(void * addr,
+static __inline__ unsigned long find_next_zero_bit(void * addr,
X unsigned long size, unsigned long offset)
X {
X unsigned int * p = ((unsigned int *) addr) + (offset >> 5);
@@ -230,6 +274,8 @@
X tmp = *p;
X found_first:
X tmp |= ~0UL << size;
+ if (tmp == ~0UL) /* Are any bits zero? */
+ return result + size; /* Nope. */
X found_middle:
X return result + ffz(tmp);
X }
@@ -238,42 +284,11 @@
X #define _EXT2_HAVE_ASM_BITOPS_
X
X #ifdef __KERNEL__
-/*
- * test_and_{set,clear}_bit guarantee atomicity without
- * disabling interrupts.
- */
-#define ext2_set_bit(nr, addr) test_and_set_bit((nr) ^ 0x18, addr)
-#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr) ^ 0x18, addr)
X
-#else
-extern __inline__ int ext2_set_bit(int nr, void * addr)
-{
- int mask;
- unsigned char *ADDR = (unsigned char *) addr;
- int oldbit;
-
- ADDR += nr >> 3;
- mask = 1 << (nr & 0x07);
- oldbit = (*ADDR & mask) ? 1 : 0;
- *ADDR |= mask;
- return oldbit;
-}
-
-extern __inline__ int ext2_clear_bit(int nr, void * addr)
-{
- int mask;
- unsigned char *ADDR = (unsigned char *) addr;
- int oldbit;
-
- ADDR += nr >> 3;
- mask = 1 << (nr & 0x07);
- oldbit = (*ADDR & mask) ? 1 : 0;
- *ADDR = *ADDR & ~mask;
- return oldbit;
-}
-#endif /* __KERNEL__ */
+#define ext2_set_bit(nr, addr) __test_and_set_bit((nr) ^ 0x18, addr)
+#define ext2_clear_bit(nr, addr) __test_and_clear_bit((nr) ^ 0x18, addr)
X
-extern __inline__ int ext2_test_bit(int nr, __const__ void * addr)
+static __inline__ int ext2_test_bit(int nr, __const__ void * addr)
X {
X __const__ unsigned char *ADDR = (__const__ unsigned char *) addr;
X
@@ -288,7 +303,7 @@
X #define ext2_find_first_zero_bit(addr, size) \
X ext2_find_next_zero_bit((addr), (size), 0)
X
-extern __inline__ unsigned long ext2_find_next_zero_bit(void *addr,
+static __inline__ unsigned long ext2_find_next_zero_bit(void *addr,
X unsigned long size, unsigned long offset)
X {
X unsigned int *p = ((unsigned int *) addr) + (offset >> 5);
@@ -320,6 +335,8 @@
X tmp = cpu_to_le32p(p);
X found_first:
X tmp |= ~0U << size;
+ if (tmp == ~0UL) /* Are any bits zero? */
+ return result + size; /* Nope. */
X found_middle:
X return result + ffz(tmp);
X }
@@ -330,5 +347,7 @@
X #define minix_test_and_clear_bit(nr,addr) ext2_clear_bit(nr,addr)
X #define minix_test_bit(nr,addr) ext2_test_bit(nr,addr)
X #define minix_find_first_zero_bit(addr,size) ext2_find_first_zero_bit(addr,size)
+
+#endif /* __KERNEL__ */
X
X #endif /* _PPC_BITOPS_H */
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/bootx.h linux/include/asm-ppc/bootx.h
--- v2.4.0-test8/linux/include/asm-ppc/bootx.h Sat Nov 27 15:42:33 1999
+++ linux/include/asm-ppc/bootx.h Sun Sep 17 09:48:08 2000
@@ -133,4 +133,3 @@
X #endif
X
X #endif
-
\ No newline at end of file
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/cpm_8260.h linux/include/asm-ppc/cpm_8260.h
--- v2.4.0-test8/linux/include/asm-ppc/cpm_8260.h Mon May 15 14:53:31 2000
+++ linux/include/asm-ppc/cpm_8260.h Sun Sep 17 09:48:08 2000
@@ -85,6 +85,7 @@
X #define CPM_DATAONLY_BASE ((uint)128)
X #define CPM_DATAONLY_SIZE ((uint)(16 * 1024) - CPM_DATAONLY_BASE)
X #define CPM_DP_NOSPACE ((uint)0x7fffffff)
+#define CPM_FCC_SPECIAL_BASE ((uint)0x0000b000)
X
X /* The number of pages of host memory we allocate for CPM. This is
X * done early in kernel initialization to get physically contiguous
@@ -97,8 +98,8 @@
X * and dual port ram.
X */
X extern cpm8260_t *cpmp; /* Pointer to comm processor */
-uint m8260_cpm_dpalloc(uint size);
-uint m8260_cpm_hostalloc(uint size);
+uint m8260_cpm_dpalloc(uint size, uint align);
+uint m8260_cpm_hostalloc(uint size, uint align);
X void m8260_cpm_setbrg(uint brg, uint rate);
X void m8260_cpm_fastbrg(uint brg, uint rate, int div16);
X
@@ -153,7 +154,7 @@
X #define PROFF_REVNUM ((uint)0x8af0)
X #define PROFF_RAND ((uint)0x8af8)
X #define PROFF_I2C_BASE ((uint)0x8afc)
-#define PROFF_IDMA4_BASE ((uint)0x89fe)
+#define PROFF_IDMA4_BASE ((uint)0x8afe)
X
X /* The SMCs are relocated to any of the first eight DPRAM pages.
X * We will fix these at the first locations of DPRAM, until we
@@ -403,40 +404,44 @@
X #define SCCE_ENET_TXB ((ushort)0x0002) /* A buffer was transmitted */
X #define SCCE_ENET_RXB ((ushort)0x0001) /* A buffer was received */
X
-/* SCC Mode Register (PMSR) as used by Ethernet.
+/* SCC Mode Register (PSMR) as used by Ethernet.
X */
-#define SCC_PMSR_HBC ((ushort)0x8000) /* Enable heartbeat */
-#define SCC_PMSR_FC ((ushort)0x4000) /* Force collision */
-#define SCC_PMSR_RSH ((ushort)0x2000) /* Receive short frames */
-#define SCC_PMSR_IAM ((ushort)0x1000) /* Check individual hash */
-#define SCC_PMSR_ENCRC ((ushort)0x0800) /* Ethernet CRC mode */
-#define SCC_PMSR_PRO ((ushort)0x0200) /* Promiscuous mode */
-#define SCC_PMSR_BRO ((ushort)0x0100) /* Catch broadcast pkts */
-#define SCC_PMSR_SBT ((ushort)0x0080) /* Special backoff timer */
-#define SCC_PMSR_LPB ((ushort)0x0040) /* Set Loopback mode */
-#define SCC_PMSR_SIP ((ushort)0x0020) /* Sample Input Pins */
-#define SCC_PMSR_LCW ((ushort)0x0010) /* Late collision window */
-#define SCC_PMSR_NIB22 ((ushort)0x000a) /* Start frame search */
-#define SCC_PMSR_FDE ((ushort)0x0001) /* Full duplex enable */
+#define SCC_PSMR_HBC ((ushort)0x8000) /* Enable heartbeat */
+#define SCC_PSMR_FC ((ushort)0x4000) /* Force collision */
+#define SCC_PSMR_RSH ((ushort)0x2000) /* Receive short frames */
+#define SCC_PSMR_IAM ((ushort)0x1000) /* Check individual hash */
+#define SCC_PSMR_ENCRC ((ushort)0x0800) /* Ethernet CRC mode */
+#define SCC_PSMR_PRO ((ushort)0x0200) /* Promiscuous mode */
+#define SCC_PSMR_BRO ((ushort)0x0100) /* Catch broadcast pkts */
+#define SCC_PSMR_SBT ((ushort)0x0080) /* Special backoff timer */
+#define SCC_PSMR_LPB ((ushort)0x0040) /* Set Loopback mode */
+#define SCC_PSMR_SIP ((ushort)0x0020) /* Sample Input Pins */
+#define SCC_PSMR_LCW ((ushort)0x0010) /* Late collision window */
+#define SCC_PSMR_NIB22 ((ushort)0x000a) /* Start frame search */
+#define SCC_PSMR_FDE ((ushort)0x0001) /* Full duplex enable */
X
X /* Buffer descriptor control/status used by Ethernet receive.
-*/
+ * Common to SCC and FCC.
+ */
X #define BD_ENET_RX_EMPTY ((ushort)0x8000)
X #define BD_ENET_RX_WRAP ((ushort)0x2000)
X #define BD_ENET_RX_INTR ((ushort)0x1000)
X #define BD_ENET_RX_LAST ((ushort)0x0800)
X #define BD_ENET_RX_FIRST ((ushort)0x0400)
X #define BD_ENET_RX_MISS ((ushort)0x0100)
+#define BD_ENET_RX_BC ((ushort)0x0080) /* FCC Only */
+#define BD_ENET_RX_MC ((ushort)0x0040) /* FCC Only */
X #define BD_ENET_RX_LG ((ushort)0x0020)
X #define BD_ENET_RX_NO ((ushort)0x0010)
X #define BD_ENET_RX_SH ((ushort)0x0008)
X #define BD_ENET_RX_CR ((ushort)0x0004)
X #define BD_ENET_RX_OV ((ushort)0x0002)
X #define BD_ENET_RX_CL ((ushort)0x0001)
-#define BD_ENET_RX_STATS ((ushort)0x013f) /* All status bits */
+#define BD_ENET_RX_STATS ((ushort)0x01ff) /* All status bits */
X
X /* Buffer descriptor control/status used by Ethernet transmit.
-*/
+ * Common to SCC and FCC.
+ */
X #define BD_ENET_TX_READY ((ushort)0x8000)
X #define BD_ENET_TX_PAD ((ushort)0x4000)
X #define BD_ENET_TX_WRAP ((ushort)0x2000)
@@ -522,6 +527,152 @@
X } scc_trans_t;
X
X #define BD_SCC_TX_LAST ((ushort)0x0800)
+
+/* How about some FCCs.....
+*/
+#define FCC_GFMR_DIAG_NORM ((uint)0x00000000)
+#define FCC_GFMR_DIAG_LE ((uint)0x40000000)
+#define FCC_GFMR_DIAG_AE ((uint)0x80000000)
+#define FCC_GFMR_DIAG_ALE ((uint)0xc0000000)
+#define FCC_GFMR_TCI ((uint)0x20000000)
+#define FCC_GFMR_TRX ((uint)0x10000000)
+#define FCC_GFMR_TTX ((uint)0x08000000)
+#define FCC_GFMR_TTX ((uint)0x08000000)
+#define FCC_GFMR_CDP ((uint)0x04000000)
+#define FCC_GFMR_CTSP ((uint)0x02000000)
+#define FCC_GFMR_CDS ((uint)0x01000000)
+#define FCC_GFMR_CTSS ((uint)0x00800000)
+#define FCC_GFMR_SYNL_NONE ((uint)0x00000000)
+#define FCC_GFMR_SYNL_AUTO ((uint)0x00004000)
+#define FCC_GFMR_SYNL_8 ((uint)0x00008000)
+#define FCC_GFMR_SYNL_16 ((uint)0x0000c000)
+#define FCC_GFMR_RTSM ((uint)0x00002000)
+#define FCC_GFMR_RENC_NRZ ((uint)0x00000000)
+#define FCC_GFMR_RENC_NRZI ((uint)0x00000800)
+#define FCC_GFMR_REVD ((uint)0x00000400)
+#define FCC_GFMR_TENC_NRZ ((uint)0x00000000)
+#define FCC_GFMR_TENC_NRZI ((uint)0x00000100)
+#define FCC_GFMR_TCRC_16 ((uint)0x00000000)
+#define FCC_GFMR_TCRC_32 ((uint)0x00000080)
+#define FCC_GFMR_ENR ((uint)0x00000020)
+#define FCC_GFMR_ENT ((uint)0x00000010)
+#define FCC_GFMR_MODE_ENET ((uint)0x0000000c)
+#define FCC_GFMR_MODE_ATM ((uint)0x0000000a)
+#define FCC_GFMR_MODE_HDLC ((uint)0x00000000)
+
+/* Generic FCC parameter ram.
+*/
+typedef struct fcc_param {
+ ushort fcc_riptr; /* Rx Internal temp pointer */
+ ushort fcc_tiptr; /* Tx Internal temp pointer */
+ ushort fcc_res1;
+ ushort fcc_mrblr; /* Max receive buffer length, mod 32 bytes */
+ uint fcc_rstate; /* Upper byte is Func code, must be set */
+ uint fcc_rbase; /* Receive BD base */
+ ushort fcc_rbdstat; /* RxBD status */
+ ushort fcc_rbdlen; /* RxBD down counter */
+ uint fcc_rdptr; /* RxBD internal data pointer */
+ uint fcc_tstate; /* Upper byte is Func code, must be set */
+ uint fcc_tbase; /* Transmit BD base */
+ ushort fcc_tbdstat; /* TxBD status */
+ ushort fcc_tbdlen; /* TxBD down counter */
+ uint fcc_tdptr; /* TxBD internal data pointer */
+ uint fcc_rbptr; /* Rx BD Internal buf pointer */
+ uint fcc_tbptr; /* Tx BD Internal buf pointer */
+ uint fcc_rcrc; /* Rx temp CRC */
+ uint fcc_res2;
+ uint fcc_tcrc; /* Tx temp CRC */
+} fccp_t;
+
+
+/* Ethernet controller through FCC.
+*/
+typedef struct fcc_enet {
+ fccp_t fen_genfcc;
+ uint fen_statbuf; /* Internal status buffer */
+ uint fen_camptr; /* CAM address */
+ uint fen_cmask; /* Constant mask for CRC */
+ uint fen_cpres; /* Preset CRC */
+ uint fen_crcec; /* CRC Error counter */
+ uint fen_alec; /* alignment error counter */
+ uint fen_disfc; /* discard frame counter */
+ ushort fen_retlim; /* Retry limit */
+ ushort fen_retcnt; /* Retry counter */
+ ushort fen_pper; /* Persistence */
+ ushort fen_boffcnt; /* backoff counter */
+ uint fen_gaddrh; /* Group address filter, high 32-bits */
+ uint fen_gaddrl; /* Group address filter, low 32-bits */
+ ushort fen_tfcstat; /* out of sequence TxBD */
+ ushort fen_tfclen;
+ uint fen_tfcptr;
+ ushort fen_mflr; /* Maximum frame length (1518) */
+ ushort fen_paddrh; /* MAC address */
+ ushort fen_paddrm;
+ ushort fen_paddrl;
+ ushort fen_ibdcount; /* Internal BD counter */
+ ushort fen_idbstart; /* Internal BD start pointer */
+ ushort fen_ibdend; /* Internal BD end pointer */
+ ushort fen_txlen; /* Internal Tx frame length counter */
+ uint fen_ibdbase[8]; /* Internal use */
+ uint fen_iaddrh; /* Individual address filter */
+ uint fen_iaddrl;
+ ushort fen_minflr; /* Minimum frame length (64) */
+ ushort fen_taddrh; /* Filter transfer MAC address */
+ ushort fen_taddrm;
+ ushort fen_taddrl;
+ ushort fen_padptr; /* Pointer to pad byte buffer */
+ ushort fen_cftype; /* control frame type */
+ ushort fen_cfrange; /* control frame range */
+ ushort fen_maxb; /* maximum BD count */
+ ushort fen_maxd1; /* Max DMA1 length (1520) */
+ ushort fen_maxd2; /* Max DMA2 length (1520) */
+ ushort fen_maxd; /* internal max DMA count */
+ ushort fen_dmacnt; /* internal DMA counter */
+ uint fen_octc; /* Total octect counter */
+ uint fen_colc; /* Total collision counter */
+ uint fen_broc; /* Total broadcast packet counter */
+ uint fen_mulc; /* Total multicast packet count */
+ uint fen_uspc; /* Total packets < 64 bytes */
+ uint fen_frgc; /* Total packets < 64 bytes with errors */
+ uint fen_ospc; /* Total packets > 1518 */
+ uint fen_jbrc; /* Total packets > 1518 with errors */
+ uint fen_p64c; /* Total packets == 64 bytes */
+ uint fen_p65c; /* Total packets 64 < bytes <= 127 */
+ uint fen_p128c; /* Total packets 127 < bytes <= 255 */
+ uint fen_p256c; /* Total packets 256 < bytes <= 511 */
+ uint fen_p512c; /* Total packets 512 < bytes <= 1023 */
+ uint fen_p1024c; /* Total packets 1024 < bytes <= 1518 */
+ uint fen_cambuf; /* Internal CAM buffer poiner */
+ ushort fen_rfthr; /* Received frames threshold */
+ ushort fen_rfcnt; /* Received frames count */
+} fcc_enet_t;
+
+/* FCC Event/Mask register as used by Ethernet.
+*/
+#define FCC_ENET_GRA ((ushort)0x0080) /* Graceful stop complete */
+#define FCC_ENET_RXC ((ushort)0x0040) /* Control Frame Received */
+#define FCC_ENET_TXC ((ushort)0x0020) /* Out of seq. Tx sent */
+#define FCC_ENET_TXE ((ushort)0x0010) /* Transmit Error */
+#define FCC_ENET_RXF ((ushort)0x0008) /* Full frame received */
+#define FCC_ENET_BSY ((ushort)0x0004) /* Busy. Rx Frame dropped */
+#define FCC_ENET_TXB ((ushort)0x0002) /* A buffer was transmitted */
+#define FCC_ENET_RXB ((ushort)0x0001) /* A buffer was received */
+
+/* FCC Mode Register (FPSMR) as used by Ethernet.
+*/
+#define FCC_PSMR_HBC ((uint)0x80000000) /* Enable heartbeat */
+#define FCC_PSMR_FC ((uint)0x40000000) /* Force Collision */
+#define FCC_PSMR_SBT ((uint)0x20000000) /* Stop backoff timer */
+#define FCC_PSMR_LPB ((uint)0x10000000) /* Local protect. 1 = FDX */
+#define FCC_PSMR_LCW ((uint)0x08000000) /* Late collision select */
+#define FCC_PSMR_FDE ((uint)0x04000000) /* Full Duplex Enable */
+#define FCC_PSMR_MON ((uint)0x02000000) /* RMON Enable */
+#define FCC_PSMR_PRO ((uint)0x00400000) /* Promiscuous Enable */
+#define FCC_PSMR_FCE ((uint)0x00200000) /* Flow Control Enable */
+#define FCC_PSMR_RSH ((uint)0x00100000) /* Receive Short Frames */
+#define FCC_PSMR_CAM ((uint)0x00000400) /* CAM enable */
+#define FCC_PSMR_BRO ((uint)0x00000200) /* Broadcast pkt discard */
+#define FCC_PSMR_ENCRC ((uint)0x00000080) /* Use 32-bit CRC */
X
X /* IIC parameter RAM.
X */
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/fcntl.h linux/include/asm-ppc/fcntl.h
--- v2.4.0-test8/linux/include/asm-ppc/fcntl.h Wed Jul 5 11:13:39 2000
+++ linux/include/asm-ppc/fcntl.h Fri Sep 22 14:21:20 2000
@@ -35,6 +35,10 @@
X #define F_SETSIG 10 /* for sockets. */
X #define F_GETSIG 11 /* for sockets. */
X
+#define F_GETLK64 12 /* using 'struct flock64' */
+#define F_SETLK64 13
+#define F_SETLKW64 14
+
X /* for F_[GET|SET]FL */
X #define FD_CLOEXEC 1 /* actually anything with low bit set goes */
X
@@ -47,6 +51,9 @@


X #define F_EXLCK 4 /* or 3 */
X #define F_SHLCK 8 /* or 4 */
X
+/* for leases */
+#define F_INPROGRESS 16
+
X /* operations for bsd flock(), also used by the kernel implementation */
X #define LOCK_SH 1 /* shared lock */
X #define LOCK_EX 2 /* exclusive lock */

@@ -54,6 +61,11 @@


X blocking */
X #define LOCK_UN 8 /* remove lock */
X
+#define LOCK_MAND 32 /* This is a mandatory flock */
+#define LOCK_READ 64 /* ... Which allows concurrent read operations */
+#define LOCK_WRITE 128 /* ... Which allows concurrent write operations */
+#define LOCK_RW 192 /* ... Which allows concurrent read & write ops */
+

X #ifdef __KERNEL__
X #define F_POSIX 1
X #define F_FLOCK 2
@@ -68,4 +80,13 @@


X pid_t l_pid;
X };
X

+struct flock64 {
+ short l_type;
+ short l_whence;
+ loff_t l_start;
+ loff_t l_len;
+ pid_t l_pid;
+};
+
+#define F_LINUX_SPECIFIC_BASE 1024
X #endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/feature.h linux/include/asm-ppc/feature.h
--- v2.4.0-test8/linux/include/asm-ppc/feature.h Thu Jul 13 09:42:51 2000
+++ linux/include/asm-ppc/feature.h Sun Sep 17 09:48:08 2000
@@ -7,7 +7,9 @@


X * License. See the file "COPYING" in the main directory of this archive

X * for more details.
X *
- * Copyright (C) 1998 Paul Mackerras.
+ * Copyright (C) 1998 Paul Mackerras &
+ * Ben. Herrenschmidt.
+ *
X *
X */
X #ifndef __ASM_PPC_FEATURE_H
@@ -75,6 +77,9 @@
X * Additional functions related to Core99 machines
X */
X extern void feature_set_gmac_power(struct device_node* device, int power);
+
+ /* use constants in KeyLargo.h for the reset parameter */
+extern void feature_set_gmac_phy_reset(struct device_node* device, int reset);
X
X extern void feature_set_usb_power(struct device_node* device, int power);
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/hardirq.h linux/include/asm-ppc/hardirq.h
--- v2.4.0-test8/linux/include/asm-ppc/hardirq.h Fri Aug 4 16:15:37 2000
+++ linux/include/asm-ppc/hardirq.h Sun Sep 17 09:48:08 2000
@@ -5,16 +5,23 @@
X #include <asm/smp.h>
X
X /* entry.S is sensitive to the offsets of these fields */
+/* The __last_jiffy_stamp field is needed to ensure that no decrementer
+ * interrupt is lost on SMP machines. Since on most CPUs it is in the same
+ * cache line as local_irq_count, it is cheap to access and is also used on UP
+ * for uniformity.


+ */
X typedef struct {

X unsigned int __softirq_active;
X unsigned int __softirq_mask;
X unsigned int __local_irq_count;
X unsigned int __local_bh_count;
X unsigned int __syscall_count;
+ unsigned int __last_jiffy_stamp;
X } ____cacheline_aligned irq_cpustat_t;
X
X #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
X
+#define last_jiffy_stamp(cpu) __IRQ_STAT((cpu), __last_jiffy_stamp)
X /*
X * Are we in an interrupt context? Either doing bottom half
X * or hardware interrupt processing?
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/heathrow.h linux/include/asm-ppc/heathrow.h
--- v2.4.0-test8/linux/include/asm-ppc/heathrow.h Thu Jul 13 09:42:51 2000
+++ linux/include/asm-ppc/heathrow.h Sun Sep 17 09:48:08 2000
@@ -44,4 +44,9 @@
X #define HRW_BMAC_IO_ENABLE 0x60000000 /* two bits, not documented in OF */
X #define HRW_BMAC_RESET 0x80000000 /* not documented in OF */
X
+/* We OR those features at boot on desktop G3s */
+#define HRW_DEFAULTS (HRW_SCCA_IO | HRW_SCCB_IO | HRW_SCC_ENABLE)
+
+/* Those seem to be different on paddington */
X #define PADD_MODEM_POWER_N 0x00000001 /* modem power on paddington */
+#define PADD_RESET_SCC 0x02000000 /* check this please */
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/highmem.h linux/include/asm-ppc/highmem.h
--- v2.4.0-test8/linux/include/asm-ppc/highmem.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-ppc/highmem.h Sun Sep 17 09:48:08 2000
@@ -0,0 +1,121 @@
+/*
+ * highmem.h: virtual kernel memory mappings for high memory
+ *
+ * PowerPC version, stolen from the i386 version.
+ *
+ * Used in CONFIG_HIGHMEM systems for memory pages which
+ * are not addressable by direct kernel virtual adresses.
+ *
+ * Copyright (C) 1999 Gerhard Wichert, Siemens AG
+ * Gerhard...@pdb.siemens.de
+ *
+ *
+ * Redesigned the x86 32-bit VM architecture to deal with
+ * up to 16 Terrabyte physical memory. With current x86 CPUs
+ * we now support up to 64 Gigabytes physical RAM.
+ *
+ * Copyright (C) 1999 Ingo Molnar <mi...@redhat.com>
+ */
+
+#ifndef _ASM_HIGHMEM_H
+#define _ASM_HIGHMEM_H
+
+#ifdef __KERNEL__
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <asm/kmap_types.h>
+#include <asm/pgtable.h>
+
+/* undef for production */
+#define HIGHMEM_DEBUG 1
+
+extern pte_t *kmap_pte;
+extern pgprot_t kmap_prot;
+extern pte_t *pkmap_page_table;
+
+extern void kmap_init(void) __init;
+
+/*
+ * Right now we initialize only a single pte table. It can be extended
+ * easily, subsequent pte tables have to be allocated in one physical
+ * chunk of RAM.
+ */
+#define PKMAP_BASE (0xfe000000UL)
+#define LAST_PKMAP 1024
+#define LAST_PKMAP_MASK (LAST_PKMAP-1)
+#define PKMAP_NR(virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT)
+#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))
+
+#define KMAP_FIX_BEGIN (0xfe400000UL)
+
+extern unsigned long kmap_high(struct page *page);
+extern void kunmap_high(struct page *page);
+
+extern inline unsigned long kmap(struct page *page)
+{
+ if (in_interrupt())
+ BUG();
+ if (page < highmem_start_page)
+ return (unsigned long) page_address(page);
+ return kmap_high(page);
+}
+
+extern inline void kunmap(struct page *page)
+{
+ if (in_interrupt())
+ BUG();
+ if (page < highmem_start_page)
+ return;
+ kunmap_high(page);
+}
+
+/*
+ * The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap
+ * gives a more generic (and caching) interface. But kmap_atomic can
+ * be used in IRQ contexts, so in some (very limited) cases we need
+ * it.
+ */
+extern inline unsigned long kmap_atomic(struct page *page, enum km_type type)
+{
+ unsigned int idx;
+ unsigned long vaddr;
+
+ if (page < highmem_start_page)
+ return (unsigned long) page_address(page);
+
+ idx = type + KM_TYPE_NR*smp_processor_id();
+ vaddr = KMAP_FIX_BEGIN + idx * PAGE_SIZE;
+#if HIGHMEM_DEBUG
+ if (!pte_none(*(kmap_pte+idx)))
+ BUG();
+#endif
+ set_pte(kmap_pte+idx, mk_pte(page, kmap_prot));
+ flush_hash_page(0, vaddr);
+
+ return vaddr;
+}
+
+extern inline void kunmap_atomic(unsigned long vaddr, enum km_type type)
+{
+#if HIGHMEM_DEBUG
+ unsigned int idx = type + KM_TYPE_NR*smp_processor_id();
+
+ if (vaddr < KMAP_FIX_BEGIN) // FIXME
+ return;
+
+ if (vaddr != KMAP_FIX_BEGIN + idx * PAGE_SIZE)
+ BUG();
+
+ /*
+ * force other mappings to Oops if they'll try to access
+ * this pte without first remap it
+ */
+ pte_clear(kmap_pte+idx);
+ flush_hash_page(0, vaddr);
+#endif
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_HIGHMEM_H */
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/ide.h linux/include/asm-ppc/ide.h
--- v2.4.0-test8/linux/include/asm-ppc/ide.h Tue May 2 13:05:40 2000
+++ linux/include/asm-ppc/ide.h Sun Sep 17 09:48:08 2000
@@ -63,7 +63,6 @@
X void ide_outsw(ide_ioreg_t port, void *buf, int ns);
X void ppc_generic_ide_fix_driveid(struct hd_driveid *id);
X
-#if 0
X #undef insw
X #define insw(port, buf, ns) do { \
X ppc_ide_md.insw((port), (buf), (ns)); \
@@ -73,7 +72,6 @@
X #define outsw(port, buf, ns) do { \
X ppc_ide_md.outsw((port), (buf), (ns)); \
X } while (0)
-#endif
X
X #undef SUPPORT_SLOW_DATA_PORTS
X #define SUPPORT_SLOW_DATA_PORTS 0
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/immap_8260.h linux/include/asm-ppc/immap_8260.h
--- v2.4.0-test8/linux/include/asm-ppc/immap_8260.h Tue May 2 13:05:40 2000
+++ linux/include/asm-ppc/immap_8260.h Sun Sep 17 09:48:08 2000
@@ -241,10 +241,12 @@
X char res1[2];
X ushort fcc_fdsr;
X char res2[2];
- uint fcc_fcce;
- uint fcc_fccm;
+ ushort fcc_fcce;
+ char res3[2];
+ ushort fcc_fccm;
+ char res4[2];
X u_char fcc_fccs;
- char res3[3];
+ char res5[3];
X u_char fcc_ftirr_phy[4];
X } fcc_t;
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/io.h linux/include/asm-ppc/io.h
--- v2.4.0-test8/linux/include/asm-ppc/io.h Mon Jun 19 17:59:37 2000
+++ linux/include/asm-ppc/io.h Sun Sep 17 09:48:08 2000
@@ -25,12 +25,12 @@
X #include <asm/mpc8xx.h>
X #elif defined(CONFIG_8260)
X #include <asm/mpc8260.h>
-#else
+#else /* 4xx/8xx/8260 */
X #ifdef CONFIG_APUS
X #define _IO_BASE 0
X #define _ISA_MEM_BASE 0
X #define PCI_DRAM_OFFSET 0
-#else
+#else /* CONFIG_APUS */
X extern unsigned long isa_io_base;
X extern unsigned long isa_mem_base;
X extern unsigned long pci_dram_offset;
@@ -54,6 +54,14 @@
X #define writel(b,addr) out_le32((volatile u32 *)(addr),(b))
X #endif
X
+
+#define __raw_readb(addr) (*(volatile unsigned char *)(addr))
+#define __raw_readw(addr) (*(volatile unsigned short *)(addr))
+#define __raw_readl(addr) (*(volatile unsigned int *)(addr))
+#define __raw_writeb(v, addr) (*(volatile unsigned char *)(addr) = (v))
+#define __raw_writew(v, addr) (*(volatile unsigned short *)(addr) = (v))
+#define __raw_writel(v, addr) (*(volatile unsigned int *)(addr) = (v))
+
X /*
X * The insw/outsw/insl/outsl macros don't do byte-swapping.
X * They are only used in practice for transferring buffers which
@@ -67,26 +75,76 @@
X #define insl(port, buf, nl) _insl_ns((u32 *)((port)+_IO_BASE), (buf), (nl))
X #define outsl(port, buf, nl) _outsl_ns((u32 *)((port)+_IO_BASE), (buf), (nl))
X
+#ifdef CONFIG_ALL_PPC
+/*
+ * We have to handle possible machine checks here on powermacs
+ * and potentially some CHRPs -- paulus.
+ */
+#define __do_in_asm(name, op) \
+extern __inline__ unsigned int name(unsigned int port) \
+{ \
+ unsigned int x; \
+ __asm__ __volatile__( \
+ op " %0,0,%1\n" \
+ "1: sync\n" \
+ "2:\n" \
+ ".section .fixup,\"ax\"\n" \
+ "3: li %0,-1\n" \
+ " b 2b\n" \
+ ".previous\n" \
+ ".section __ex_table,\"ax\"\n" \
+ " .align 2\n" \
+ " .long 1b,3b\n" \
+ ".previous" \
+ : "=&r" (x) \
+ : "r" (port + _IO_BASE)); \
+ return x; \
+}
+
+#define __do_out_asm(name, op) \
+extern __inline__ void name(unsigned int val, unsigned int port) \
+{ \
+ __asm__ __volatile__( \
+ op " %0,0,%1\n" \
+ "1: sync\n" \
+ "2:\n" \
+ ".section __ex_table,\"ax\"\n" \
+ " .align 2\n" \
+ " .long 1b,2b\n" \
+ ".previous" \
+ : : "r" (val), "r" (port + _IO_BASE)); \
+}
+
+__do_in_asm(inb, "lbzx")
+__do_in_asm(inw, "lhbrx")
+__do_in_asm(inl, "lwbrx")
+__do_out_asm(outb, "stbx")
+__do_out_asm(outw, "sthbrx")
+__do_out_asm(outl, "stwbrx")
+
+#elif defined(CONFIG_APUS)
X #define inb(port) in_8((u8 *)((port)+_IO_BASE))
X #define outb(val, port) out_8((u8 *)((port)+_IO_BASE), (val))
-#if defined(CONFIG_APUS)
X #define inw(port) in_be16((u16 *)((port)+_IO_BASE))
X #define outw(val, port) out_be16((u16 *)((port)+_IO_BASE), (val))
X #define inl(port) in_be32((u32 *)((port)+_IO_BASE))


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 105'
echo 'File patch-2.4.0-test9 is continued in part 106'
echo "106" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part110

#!/bin/sh -x
# this is part 110 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 110; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

X if (!counter)
X return;
X next:
diff -u --recursive --new-file v2.4.0-test8/linux/kernel/exit.c linux/kernel/exit.c
--- v2.4.0-test8/linux/kernel/exit.c Fri Sep 1 18:08:46 2000
+++ linux/kernel/exit.c Sun Sep 17 09:51:57 2000
@@ -229,6 +229,7 @@
X {
X __exit_files(tsk);
X }
+
X static inline void __put_fs_struct(struct fs_struct *fs)
X {
X /* No need to hold fs->lock if we are killing it */
diff -u --recursive --new-file v2.4.0-test8/linux/kernel/kmod.c linux/kernel/kmod.c
--- v2.4.0-test8/linux/kernel/kmod.c Sat Aug 5 22:58:59 2000
+++ linux/kernel/kmod.c Mon Sep 25 16:18:55 2000
@@ -247,5 +247,44 @@
X */
X char hotplug_path[256] = "/sbin/hotplug";
X
+
+static int exec_helper (void *arg)
+{
+ void **params = (void **) arg;
+ char *path = (char *) params [0];
+ char **argv = (char **) params [1];
+ char **envp = (char **) params [2];
+ return exec_usermodehelper (path, argv, envp);
+}
+
+
+int call_usermodehelper (char *path, char **argv, char **envp)
+{
+ void *params [3] = { path, argv, envp };
+ int pid, pid2, retval;
+ mm_segment_t fs;
+
+ if ( ! current->fs->root ) {
+ printk(KERN_ERR "call_usermodehelper[%s]: no root fs\n",
+ path);
+ return -EPERM;
+ }
+ if ((pid = kernel_thread (exec_helper, (void *) params, 0)) < 0) {
+ printk(KERN_ERR "failed fork %s, errno = %d", argv [0], -pid);


+ return -1;
+ }
+

+ fs = get_fs ();
+ set_fs (KERNEL_DS);
+ pid2 = waitpid (pid, &retval, __WCLONE);
+ set_fs (fs);
+
+ if (pid2 != pid) {
+ printk(KERN_ERR "waitpid(%d) failed, %d\n", pid, pid2);
+ return -1;
+ }
+ return retval;
+}
+
X #endif
X
diff -u --recursive --new-file v2.4.0-test8/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v2.4.0-test8/linux/kernel/ksyms.c Tue Sep 5 18:56:47 2000
+++ linux/kernel/ksyms.c Mon Sep 25 16:18:55 2000
@@ -76,6 +76,7 @@
X EXPORT_SYMBOL(exec_usermodehelper);
X #ifdef CONFIG_HOTPLUG
X EXPORT_SYMBOL(hotplug_path);
+EXPORT_SYMBOL(call_usermodehelper);


X #endif
X #endif
X

@@ -214,6 +215,9 @@
X EXPORT_SYMBOL(page_hash_bits);
X EXPORT_SYMBOL(page_hash_table);
X EXPORT_SYMBOL(file_lock_list);
+EXPORT_SYMBOL(file_lock_sem);
+EXPORT_SYMBOL(locks_init_lock);
+EXPORT_SYMBOL(locks_copy_lock);
X EXPORT_SYMBOL(posix_lock_file);
X EXPORT_SYMBOL(posix_test_lock);
X EXPORT_SYMBOL(posix_block_lock);
@@ -253,6 +257,10 @@
X EXPORT_SYMBOL(page_symlink_inode_operations);
X EXPORT_SYMBOL(block_symlink);
X EXPORT_SYMBOL(vfs_readdir);
+EXPORT_SYMBOL(__get_lease);
+EXPORT_SYMBOL(lease_get_mtime);
+EXPORT_SYMBOL(lock_may_read);
+EXPORT_SYMBOL(lock_may_write);
X EXPORT_SYMBOL(dcache_readdir);
X
X /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
@@ -361,8 +369,6 @@
X #if !defined(CONFIG_ARCH_S390)
X EXPORT_SYMBOL(probe_irq_on);
X EXPORT_SYMBOL(probe_irq_off);
-EXPORT_SYMBOL(autoirq_setup);
-EXPORT_SYMBOL(autoirq_report);
X #endif
X
X #ifdef CONFIG_SMP
diff -u --recursive --new-file v2.4.0-test8/linux/kernel/sched.c linux/kernel/sched.c
--- v2.4.0-test8/linux/kernel/sched.c Fri Sep 1 14:05:25 2000
+++ linux/kernel/sched.c Mon Oct 2 11:45:01 2000
@@ -141,61 +141,54 @@
X int weight;
X
X /*
- * Realtime process, select the first one on the
- * runqueue (taking priorities within processes
- * into account).
+ * select the current process after every other
+ * runnable process, but before the idle thread.
+ * Also, dont trigger a counter recalculation.
X */
- if (p->policy != SCHED_OTHER) {
- weight = 1000 + p->rt_priority;
+ weight = -1;
+ if (p->policy & SCHED_YIELD)
X goto out;
- }
X
X /*
- * Give the process a first-approximation goodness value
- * according to the number of clock-ticks it has left.
- *
- * Don't do any other calculations if the time slice is
- * over..
+ * Non-RT process - normal case first.
X */
- weight = p->counter;
- if (!weight)
- goto out;
+ if (p->policy == SCHED_OTHER) {
+ /*
+ * Give the process a first-approximation goodness value
+ * according to the number of clock-ticks it has left.
+ *
+ * Don't do any other calculations if the time slice is
+ * over..
+ */
+ weight = p->counter;
+ if (!weight)
+ goto out;
X
X #ifdef CONFIG_SMP
- /* Give a largish advantage to the same processor... */
- /* (this is equivalent to penalizing other processors) */
- if (p->processor == this_cpu)
- weight += PROC_CHANGE_PENALTY;
+ /* Give a largish advantage to the same processor... */
+ /* (this is equivalent to penalizing other processors) */
+ if (p->processor == this_cpu)
+ weight += PROC_CHANGE_PENALTY;
X #endif
X
- /* .. and a slight advantage to the current MM */
- if (p->mm == this_mm || !p->mm)
- weight += 1;
- weight += 20 - p->nice;
+ /* .. and a slight advantage to the current MM */
+ if (p->mm == this_mm || !p->mm)
+ weight += 1;
+ weight += 20 - p->nice;
+ goto out;
+ }
X
+ /*
+ * Realtime process, select the first one on the
+ * runqueue (taking priorities within processes
+ * into account).
+ */
+ weight = 1000 + p->rt_priority;
X out:
X return weight;
X }
X
X /*
- * subtle. We want to discard a yielded process only if it's being
- * considered for a reschedule. Wakeup-time 'queries' of the scheduling
- * state do not count. Another optimization we do: sched_yield()-ed
- * processes are runnable (and thus will be considered for scheduling)
- * right when they are calling schedule(). So the only place we need
- * to care about SCHED_YIELD is when we calculate the previous process'
- * goodness ...
- */
-static inline int prev_goodness(struct task_struct * p, int this_cpu, struct mm_struct *this_mm)
-{
- if (p->policy & SCHED_YIELD) {
- p->policy &= ~SCHED_YIELD;
- return 0;
- }
- return goodness(p, this_cpu, this_mm);
-}
-
-/*
X * the 'goodness value' of replacing a process on a given CPU.
X * positive value means 'replace', zero or negative means 'dont'.
X */
@@ -451,6 +444,7 @@
X static inline void __schedule_tail(struct task_struct *prev)
X {
X #ifdef CONFIG_SMP
+ int yield;


X unsigned long flags;
X

X /*
@@ -462,6 +456,8 @@
X * cache.
X */
X spin_lock_irqsave(&runqueue_lock, flags);
+ yield = prev->policy & SCHED_YIELD;
+ prev->policy &= ~SCHED_YIELD;
X prev->has_cpu = 0;
X if (prev->state == TASK_RUNNING)
X goto running_again;
@@ -476,9 +472,11 @@
X * current process as well.)
X */
X running_again:
- if (prev != idle_task(smp_processor_id()))
+ if ((prev != idle_task(smp_processor_id())) && !yield)
X reschedule_idle(prev);
X goto out_unlock;
+#else
+ prev->policy &= ~SCHED_YIELD;
X #endif /* CONFIG_SMP */
X }
X
@@ -669,7 +667,7 @@
X goto repeat_schedule;
X
X still_running:
- c = prev_goodness(prev, this_cpu, prev->active_mm);
+ c = goodness(prev, this_cpu, prev->active_mm);
X next = prev;
X goto still_running_back;
X
@@ -1030,12 +1028,13 @@
X
X asmlinkage long sys_sched_yield(void)
X {
- spin_lock_irq(&runqueue_lock);
+ /*
+ * This process can only be rescheduled by us,
+ * so this is safe without any locking.
+ */
X if (current->policy == SCHED_OTHER)
X current->policy |= SCHED_YIELD;
X current->need_resched = 1;
- move_last_runqueue(current);
- spin_unlock_irq(&runqueue_lock);


X return 0;
X }
X

diff -u --recursive --new-file v2.4.0-test8/linux/kernel/signal.c linux/kernel/signal.c
--- v2.4.0-test8/linux/kernel/signal.c Tue Sep 5 09:53:59 2000
+++ linux/kernel/signal.c Mon Sep 25 14:44:14 2000
@@ -41,7 +41,7 @@
X __alignof__(struct sigqueue),
X SIG_SLAB_DEBUG, NULL, NULL);
X if (!sigqueue_cachep)
- panic("signals_init(): cannot create sigueue SLAB cache");
+ panic("signals_init(): cannot create sigqueue SLAB cache");
X }
X
X
@@ -191,6 +191,7 @@
X /* Ok, it wasn't in the queue. We must have
X been out of queue space. So zero out the
X info. */
+ sigdelset(&list->signal, sig);
X info->si_signo = sig;
X info->si_errno = 0;
X info->si_code = 0;
@@ -939,25 +940,28 @@
X spin_lock_irq(&current->sigmask_lock);
X sig = dequeue_signal(&these, &info);
X if (!sig) {
- /* None ready -- temporarily unblock those we're interested
- in so that we'll be awakened when they arrive. */
- sigset_t oldblocked = current->blocked;
- sigandsets(&current->blocked, &current->blocked, &these);
- recalc_sigpending(current);
- spin_unlock_irq(&current->sigmask_lock);
-
X timeout = MAX_SCHEDULE_TIMEOUT;
X if (uts)
X timeout = (timespec_to_jiffies(&ts)
X + (ts.tv_sec || ts.tv_nsec));
X
- current->state = TASK_INTERRUPTIBLE;
- timeout = schedule_timeout(timeout);
-
- spin_lock_irq(&current->sigmask_lock);
- sig = dequeue_signal(&these, &info);
- current->blocked = oldblocked;
- recalc_sigpending(current);
+ if (timeout) {
+ /* None ready -- temporarily unblock those we're
+ * interested while we are sleeping in so that we'll
+ * be awakened when they arrive. */
+ sigset_t oldblocked = current->blocked;
+ sigandsets(&current->blocked, &current->blocked, &these);
+ recalc_sigpending(current);
+ spin_unlock_irq(&current->sigmask_lock);
+


+ current->state = TASK_INTERRUPTIBLE;

+ timeout = schedule_timeout(timeout);
+
+ spin_lock_irq(&current->sigmask_lock);
+ sig = dequeue_signal(&these, &info);
+ current->blocked = oldblocked;
+ recalc_sigpending(current);
+ }
X }
X spin_unlock_irq(&current->sigmask_lock);
X
diff -u --recursive --new-file v2.4.0-test8/linux/kernel/softirq.c linux/kernel/softirq.c
--- v2.4.0-test8/linux/kernel/softirq.c Sun Aug 6 12:42:21 2000
+++ linux/kernel/softirq.c Fri Sep 22 14:07:43 2000
@@ -44,7 +44,7 @@
X irq_cpustat_t irq_stat[NR_CPUS];
X #endif /* CONFIG_ARCH_S390 */
X
-static struct softirq_action softirq_vec[32];
+static struct softirq_action softirq_vec[32] __cacheline_aligned;
X
X asmlinkage void do_softirq()
X {
@@ -140,6 +140,14 @@
X clear_bit(TASKLET_STATE_SCHED, &t->state);
X
X t->func(t->data);
+ /*
+ * talklet_trylock() uses test_and_set_bit that imply
+ * an mb when it returns zero, thus we need the explicit
+ * mb only here: while closing the critical section.
+ */
+#ifdef CONFIG_SMP
+ smp_mb__before_clear_bit();
+#endif
X tasklet_unlock(t);
X continue;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/kernel/sys.c linux/kernel/sys.c
--- v2.4.0-test8/linux/kernel/sys.c Wed Aug 9 18:59:17 2000
+++ linux/kernel/sys.c Mon Sep 11 08:48:53 2000
@@ -123,18 +123,15 @@
X int ret=NOTIFY_DONE;
X struct notifier_block *nb = *n;
X
- read_lock(&notifier_lock);
X while(nb)
X {
X ret=nb->notifier_call(nb,val,v);
X if(ret&NOTIFY_STOP_MASK)
X {
- read_unlock(&notifier_lock);
X return ret;
X }
X nb=nb->next;
X }
- read_unlock(&notifier_lock);
X return ret;
X }
X
diff -u --recursive --new-file v2.4.0-test8/linux/kernel/sysctl.c linux/kernel/sysctl.c
--- v2.4.0-test8/linux/kernel/sysctl.c Mon Jul 31 19:36:11 2000
+++ linux/kernel/sysctl.c Fri Sep 22 14:21:22 2000
@@ -235,7 +235,7 @@
X
X static ctl_table vm_table[] = {
X {VM_FREEPG, "freepages",
- &freepages, sizeof(freepages_t), 0644, NULL, &proc_dointvec},
+ &freepages, sizeof(freepages_t), 0444, NULL, &proc_dointvec},
X {VM_BDFLUSH, "bdflush", &bdf_prm, 9*sizeof(int), 0644, NULL,
X &proc_dointvec_minmax, &sysctl_intvec, NULL,
X &bdflush_min, &bdflush_max},
@@ -283,6 +283,12 @@
X {FS_OVERFLOWGID, "overflowgid", &fs_overflowgid, sizeof(int), 0644, NULL,
X &proc_dointvec_minmax, &sysctl_intvec, NULL,
X &minolduid, &maxolduid},
+ {FS_LEASES, "leases-enable", &leases_enable, sizeof(int),
+ 0644, NULL, &proc_dointvec},
+ {FS_DIR_NOTIFY, "dir-notify-enable", &dir_notify_enable,
+ sizeof(int), 0644, NULL, &proc_dointvec},
+ {FS_LEASE_TIME, "lease-break-time", &lease_break_time, sizeof(int),
+ 0644, NULL, &proc_dointvec},
X {0}
X };
X
diff -u --recursive --new-file v2.4.0-test8/linux/kernel/timer.c linux/kernel/timer.c
--- v2.4.0-test8/linux/kernel/timer.c Mon Aug 28 14:28:27 2000
+++ linux/kernel/timer.c Sun Oct 1 19:55:17 2000
@@ -22,7 +22,6 @@
X #include <linux/smp_lock.h>
X #include <linux/interrupt.h>
X #include <linux/kernel_stat.h>
-#include <linux/slab.h>


X
X #include <asm/uaccess.h>
X

@@ -596,9 +595,6 @@
X kstat.per_cpu_system[cpu] += system;
X } else if (local_bh_count(cpu) || local_irq_count(cpu) > 1)
X kstat.per_cpu_system[cpu] += system;
-
- if (slab_cache_drain_mask & (1UL << cpu))
- slab_drain_local_cache();
X }
X
X /*
diff -u --recursive --new-file v2.4.0-test8/linux/mm/filemap.c linux/mm/filemap.c
--- v2.4.0-test8/linux/mm/filemap.c Fri Sep 8 12:37:34 2000
+++ linux/mm/filemap.c Mon Oct 2 11:28:38 2000
@@ -44,9 +44,8 @@
X atomic_t page_cache_size = ATOMIC_INIT(0);
X unsigned int page_hash_bits;
X struct page **page_hash_table;
-struct list_head lru_cache;
X
-static spinlock_t pagecache_lock = SPIN_LOCK_UNLOCKED;
+spinlock_t pagecache_lock = SPIN_LOCK_UNLOCKED;
X /*
X * NOTE: to avoid deadlocking you must never acquire the pagecache_lock with
X * the pagemap_lru_lock held.
@@ -92,7 +91,7 @@
X * sure the page is locked and that nobody else uses it - or that usage
X * is safe.
X */
-static inline void __remove_inode_page(struct page *page)
+void __remove_inode_page(struct page *page)
X {
X remove_page_from_inode_queue(page);
X remove_page_from_hash_queue(page);
@@ -235,141 +234,6 @@
X spin_unlock(&pagecache_lock);
X }
X
-/*
- * nr_dirty represents the number of dirty pages that we will write async
- * before doing sync writes. We can only do sync writes if we can
- * wait for IO (__GFP_IO set).
- */
-int shrink_mmap(int priority, int gfp_mask)
-{
- int ret = 0, count, nr_dirty;
- struct list_head * page_lru;
- struct page * page = NULL;
-
- count = nr_lru_pages / (priority + 1);
- nr_dirty = priority;
-
- /* we need pagemap_lru_lock for list_del() ... subtle code below */
- spin_lock(&pagemap_lru_lock);
- while (count > 0 && (page_lru = lru_cache.prev) != &lru_cache) {
- page = list_entry(page_lru, struct page, lru);
- list_del(page_lru);
-
- if (PageTestandClearReferenced(page))
- goto dispose_continue;
-
- count--;
- /*
- * Avoid unscalable SMP locking for pages we can
- * immediate tell are untouchable..
- */
- if (!page->buffers && page_count(page) > 1)
- goto dispose_continue;
-
- if (TryLockPage(page))
- goto dispose_continue;
-
- /* Release the pagemap_lru lock even if the page is not yet
- queued in any lru queue since we have just locked down
- the page so nobody else may SMP race with us running
- a lru_cache_del() (lru_cache_del() always run with the
- page locked down ;). */
- spin_unlock(&pagemap_lru_lock);
-
- /* avoid freeing the page while it's locked */
- page_cache_get(page);
-
- /*
- * Is it a buffer page? Try to clean it up regardless
- * of zone - it's old.
- */
- if (page->buffers) {
- int wait;
- /*
- * 0 - free it if can do so without IO
- * 1 - start write-out of dirty buffers
- * 2 - wait for locked buffers
- */
- wait = (gfp_mask & __GFP_IO) ? (nr_dirty-- < 0) ? 2 : 1 : 0;
- if (!try_to_free_buffers(page, wait))
- goto unlock_continue;
- /* page was locked, inode can't go away under us */
- if (!page->mapping) {
- atomic_dec(&buffermem_pages);
- goto made_buffer_progress;
- }
- }
-
- /* Take the pagecache_lock spinlock held to avoid
- other tasks to notice the page while we are looking at its
- page count. If it's a pagecache-page we'll free it
- in one atomic transaction after checking its page count. */
- spin_lock(&pagecache_lock);
-
- /*
- * We can't free pages unless there's just one user
- * (count == 2 because we added one ourselves above).
- */
- if (page_count(page) != 2)
- goto cache_unlock_continue;
-
- /*
- * Is it a page swap page? If so, we want to
- * drop it if it is no longer used, even if it
- * were to be marked referenced..
- */
- if (PageSwapCache(page)) {
- spin_unlock(&pagecache_lock);
- __delete_from_swap_cache(page);
- goto made_inode_progress;
- }
-
- /*
- * Page is from a zone we don't care about.
- * Don't drop page cache entries in vain.
- */
- if (page->zone->free_pages > page->zone->pages_high)
- goto cache_unlock_continue;
-
- /* is it a page-cache page? */
- if (page->mapping) {
- if (!PageDirty(page) && !pgcache_under_min()) {
- __remove_inode_page(page);
- spin_unlock(&pagecache_lock);
- goto made_inode_progress;
- }
- goto cache_unlock_continue;
- }
-
- printk(KERN_ERR "shrink_mmap: unknown LRU page!\n");
-
-cache_unlock_continue:
- spin_unlock(&pagecache_lock);
-unlock_continue:
- spin_lock(&pagemap_lru_lock);
- UnlockPage(page);
- page_cache_release(page);
-dispose_continue:
- list_add(page_lru, &lru_cache);
- }
- goto out;
-
-made_inode_progress:
- page_cache_release(page);
-made_buffer_progress:
- UnlockPage(page);
- page_cache_release(page);
- ret = 1;
- spin_lock(&pagemap_lru_lock);
- /* nr_lru_pages needs the spinlock */
- nr_lru_pages--;
-
-out:
- spin_unlock(&pagemap_lru_lock);
-


- return ret;
-}
-

X static inline struct page * __find_page_nolock(struct address_space *mapping, unsigned long offset, struct page *page)
X {
X goto inside;
@@ -384,7 +248,14 @@
X if (page->index == offset)
X break;
X }
- SetPageReferenced(page);
+ /*
+ * Touching the page may move it to the active list.
+ * If we end up with too few inactive pages, we wake
+ * up kswapd.
+ */
+ age_page_up(page);
+ if (inactive_shortage() > inactive_target / 2 && free_shortage())
+ wakeup_kswapd(0);
X not_found:
X return page;
X }
@@ -616,6 +487,7 @@
X set_task_state(tsk, TASK_UNINTERRUPTIBLE);
X if (!PageLocked(page))
X break;
+ run_task_queue(&tq_disk);
X schedule();
X } while (PageLocked(page));
X tsk->state = TASK_RUNNING;
@@ -739,6 +611,53 @@
X #endif
X
X /*
+ * We combine this with read-ahead to deactivate pages when we
+ * think there's sequential IO going on. Note that this is
+ * harmless since we don't actually evict the pages from memory
+ * but just move them to the inactive list.
+ *
+ * TODO:
+ * - make the readahead code smarter
+ * - move readahead to the VMA level so we can do the same
+ * trick with mmap()
+ *
+ * Rik van Riel, 2000
+ */
+static void drop_behind(struct file * file, unsigned long index)
+{
+ struct inode *inode = file->f_dentry->d_inode;
+ struct address_space *mapping = inode->i_mapping;
+ struct page **hash;
+ struct page *page;
+ unsigned long start;
+
+ /* Nothing to drop-behind if we're on the first page. */
+ if (!index)
+ return;
+
+ if (index > file->f_rawin)
+ start = index - file->f_rawin;
+ else
+ start = 0;
+
+ /*
+ * Go backwards from index-1 and drop all pages in the
+ * readahead window. Since the readahead window may have
+ * been increased since the last time we were called, we
+ * stop when the page isn't there.
+ */
+ spin_lock(&pagecache_lock);
+ while (--index >= start) {
+ hash = page_hash(mapping, index);
+ page = __find_page_nolock(mapping, index, *hash);
+ if (!page)
+ break;
+ deactivate_page(page);
+ }
+ spin_unlock(&pagecache_lock);
+}
+
+/*
X * Read-ahead profiling information
X * --------------------------------
X * Every PROFILE_MAXREADCOUNT, the following information is written
@@ -961,6 +880,12 @@
X if (filp->f_ramax > max_readahead)
X filp->f_ramax = max_readahead;
X
+ /*
+ * Move the pages that have already been passed
+ * to the inactive list.
+ */
+ drop_behind(filp, index);
+
X #ifdef PROFILE_READAHEAD
X profile_readahead((reada_ok == 2), filp);
X #endif
@@ -1999,10 +1924,10 @@
X * Application no longer needs these pages. If the pages are dirty,
X * it's OK to just throw them away. The app will be more careful about
X * data it wants to keep. Be sure to free swap resources too. The
- * zap_page_range call sets things up for shrink_mmap to actually free
+ * zap_page_range call sets things up for refill_inactive to actually free
X * these pages later if no one else has touched them in the meantime,
X * although we could add these pages to a global reuse list for
- * shrink_mmap to pick up before reclaiming other pages.
+ * refill_inactive to pick up before reclaiming other pages.
X *
X * NB: This interface discards data rather than pushes it out to swap,
X * as some implementations do. This has performance implications for
@@ -2527,6 +2452,7 @@
X unlock:
X /* Mark it unlocked again and drop the page.. */
X UnlockPage(page);
+ deactivate_page(page);
X page_cache_release(page);
X
X if (status < 0)
diff -u --recursive --new-file v2.4.0-test8/linux/mm/memory.c linux/mm/memory.c
--- v2.4.0-test8/linux/mm/memory.c Fri Sep 1 13:51:10 2000
+++ linux/mm/memory.c Fri Sep 15 16:51:21 2000
@@ -67,7 +67,7 @@
X copy_user_highpage(to, from, address);
X }
X
-mem_map_t * mem_map = NULL;
+mem_map_t * mem_map;
X
X /*
X * Note: this doesn't free the actual pages themselves. That
@@ -1040,7 +1040,8 @@
X num = valid_swaphandles(entry, &offset);
X for (i = 0; i < num; offset++, i++) {
X /* Don't block on I/O for read-ahead */
- if (atomic_read(&nr_async_pages) >= pager_daemon.swap_cluster) {
+ if (atomic_read(&nr_async_pages) >= pager_daemon.swap_cluster
+ * (1 << page_cluster)) {
X while (i++ < num)
X swap_free(SWP_ENTRY(SWP_TYPE(entry), offset++));
X break;
@@ -1239,7 +1240,7 @@
X
X pgd = pgd_offset(mm, address);
X pmd = pmd_alloc(pgd, address);
-
+
X if (pmd) {
X pte_t * pte = pte_alloc(pmd, address);
X if (pte)
diff -u --recursive --new-file v2.4.0-test8/linux/mm/mremap.c linux/mm/mremap.c
--- v2.4.0-test8/linux/mm/mremap.c Mon Jun 19 13:45:51 2000
+++ linux/mm/mremap.c Thu Sep 28 13:54:32 2000
@@ -225,6 +225,10 @@
X /* We can't remap across vm area boundaries */
X if (old_len > vma->vm_end - addr)
X goto out;
+ if (vma->vm_flags & VM_DONTEXPAND) {
+ if (new_len > old_len)
+ goto out;
+ }
X if (vma->vm_flags & VM_LOCKED) {
X unsigned long locked = current->mm->locked_vm << PAGE_SHIFT;
X locked += new_len - old_len;
diff -u --recursive --new-file v2.4.0-test8/linux/mm/page_alloc.c linux/mm/page_alloc.c
--- v2.4.0-test8/linux/mm/page_alloc.c Thu Sep 7 08:44:50 2000
+++ linux/mm/page_alloc.c Mon Oct 2 12:02:20 2000
@@ -25,7 +25,8 @@
X #endif
X
X int nr_swap_pages;
-int nr_lru_pages;
+int nr_active_pages;
+int nr_inactive_dirty_pages;
X pg_data_t *pgdat_list;
X
X static char *zone_names[MAX_NR_ZONES] = { "DMA", "Normal", "HighMem" };
@@ -33,6 +34,8 @@
X static int zone_balance_min[MAX_NR_ZONES] = { 10 , 10, 10, };
X static int zone_balance_max[MAX_NR_ZONES] = { 255 , 255, 255, };
X
+struct list_head active_list;
+struct list_head inactive_dirty_list;
X /*
X * Free_page() adds the page to the free lists. This is optimized for
X * fast normal cases (no error jumps taken normally).
@@ -96,7 +99,16 @@
X BUG();
X if (PageDirty(page))
X BUG();
+ if (PageActive(page))
+ BUG();
+ if (PageInactiveDirty(page))
+ BUG();
+ if (PageInactiveClean(page))
+ BUG();
X
+ page->flags &= ~(1<<PG_referenced);
+ page->age = PAGE_AGE_START;
+
X zone = page->zone;
X
X mask = (~0UL) << order;
@@ -142,10 +154,13 @@
X
X spin_unlock_irqrestore(&zone->lock, flags);
X
- if (zone->free_pages > zone->pages_high) {
- zone->zone_wake_kswapd = 0;
- zone->low_on_memory = 0;
- }
+ /*
+ * We don't want to protect this variable from race conditions
+ * since it's nothing important, but we do want to make sure
+ * it never gets negative.
+ */
+ if (memory_pressure > NR_CPUS)
+ memory_pressure--;
X }
X
X #define MARK_USED(index, order, area) \
@@ -203,6 +218,7 @@
X set_page_count(page, 1);
X if (BAD_RANGE(zone,page))
X BUG();
+ DEBUG_ADD_PAGE
X return page;
X }
X curr_order++;
@@ -213,13 +229,77 @@


X return NULL;
X }
X

+#define PAGES_MIN 0
+#define PAGES_LOW 1
+#define PAGES_HIGH 2
+
+/*
+ * This function does the dirty work for __alloc_pages
+ * and is separated out to keep the code size smaller.
+ * (suggested by Davem at 1:30 AM, typed by Rik at 6 AM)
+ */
+static struct page * __alloc_pages_limit(zonelist_t *zonelist,
+ unsigned long order, int limit, int direct_reclaim)
+{
+ zone_t **zone = zonelist->zones;
+
+ for (;;) {
+ zone_t *z = *(zone++);
+ unsigned long water_mark;
+
+ if (!z)
+ break;
+ if (!z->size)


+ BUG();
+
+ /*

+ * We allocate if the number of free + inactive_clean
+ * pages is above the watermark.
+ */
+ switch (limit) {
+ default:
+ case PAGES_MIN:
+ water_mark = z->pages_min;
+ break;
+ case PAGES_LOW:
+ water_mark = z->pages_low;
+ break;
+ case PAGES_HIGH:
+ water_mark = z->pages_high;
+ }
+
+ if (z->free_pages + z->inactive_clean_pages > water_mark) {
+ struct page *page = NULL;
+ /* If possible, reclaim a page directly. */
+ if (direct_reclaim && z->free_pages < z->pages_min + 8)
+ page = reclaim_page(z);
+ /* If that fails, fall back to rmqueue. */
+ if (!page)
+ page = rmqueue(z, order);
+ if (page)
+ return page;
+ }
+ }
+
+ /* Found nothing. */


+ return NULL;
+}
+

+
X /*
X * This is the 'heart' of the zoned buddy allocator:
X */
X struct page * __alloc_pages(zonelist_t *zonelist, unsigned long order)
X {
X zone_t **zone;
- extern wait_queue_head_t kswapd_wait;
+ int direct_reclaim = 0;
+ unsigned int gfp_mask = zonelist->gfp_mask;
+ struct page * page = NULL;
+
+ /*
+ * Allocations put pressure on the VM subsystem.
+ */
+ memory_pressure++;
X
X /*
X * (If anyone calls gfp from interrupts nonatomically then it
@@ -229,6 +309,36 @@
X * in a higher zone fails.
X */
X
+ /*
+ * Can we take pages directly from the inactive_clean
+ * list?
+ */
+ if (order == 0 && (gfp_mask & __GFP_WAIT) &&
+ !(current->flags & PF_MEMALLOC))
+ direct_reclaim = 1;
+
+ /*
+ * If we are about to get low on free pages and we also have
+ * an inactive page shortage, wake up kswapd.
+ */
+ if (inactive_shortage() > inactive_target / 2 && free_shortage())
+ wakeup_kswapd(0);
+ /*
+ * If we are about to get low on free pages and cleaning
+ * the inactive_dirty pages would fix the situation,
+ * wake up bdflush.
+ */
+ else if (free_shortage() && nr_inactive_dirty_pages > free_shortage()
+ && nr_inactive_dirty_pages > freepages.high)
+ wakeup_bdflush(0);
+
+try_again:
+ /*
+ * First, see if we have any zones with lots of free memory.
+ *
+ * We allocate free memory first because it doesn't contain
+ * any data ... DUH!
+ */
X zone = zonelist->zones;
X for (;;) {
X zone_t *z = *(zone++);
@@ -237,82 +347,193 @@
X if (!z->size)
X BUG();
X
- /* Are we supposed to free memory? Don't make it worse.. */
- if (!z->zone_wake_kswapd) {
- struct page *page = rmqueue(z, order);
- if (z->free_pages < z->pages_low) {
- z->zone_wake_kswapd = 1;
- if (waitqueue_active(&kswapd_wait))
- wake_up_interruptible(&kswapd_wait);
- }
+ if (z->free_pages > z->pages_low) {
+ page = rmqueue(z, order);
X if (page)
X return page;
+ } else if (z->free_pages < z->pages_min &&
+ waitqueue_active(&kreclaimd_wait)) {
+ wake_up_interruptible(&kreclaimd_wait);
X }
X }
X
- /* Three possibilities to get here
- * - Previous alloc_pages resulted in last zone set to have
- * zone_wake_kswapd and start it. kswapd has not been able
- * to release enough pages so that one zone does not have
- * zone_wake_kswapd set.
- * - Different sets of zones (zonelist)
- * previous did not have all zones with zone_wake_kswapd but
- * this one has... should kswapd be woken up? it will run once.
- * - SMP race, kswapd went to sleep slightly after it as running
- * in 'if (waitqueue_active(...))' above.
- * + anyway the test is very cheap to do...
+ /*
+ * Try to allocate a page from a zone with a HIGH
+ * amount of free + inactive_clean pages.
+ *
+ * If there is a lot of activity, inactive_target
+ * will be high and we'll have a good chance of
+ * finding a page using the HIGH limit.
X */
- if (waitqueue_active(&kswapd_wait))
- wake_up_interruptible(&kswapd_wait);
+ page = __alloc_pages_limit(zonelist, order, PAGES_HIGH, direct_reclaim);
+ if (page)
+ return page;
X
X /*
- * Ok, we don't have any zones that don't need some
- * balancing.. See if we have any that aren't critical..
+ * Then try to allocate a page from a zone with more
+ * than zone->pages_low free + inactive_clean pages.
+ *
+ * When the working set is very large and VM activity
+ * is low, we're most likely to have our allocation
+ * succeed here.
X */
- zone = zonelist->zones;
- for (;;) {
- zone_t *z = *(zone++);
- if (!z)
- break;
- if (!z->low_on_memory) {
- struct page *page = rmqueue(z, order);
- if (z->free_pages < z->pages_min)
- z->low_on_memory = 1;
- if (page)
- return page;
- }
+ page = __alloc_pages_limit(zonelist, order, PAGES_LOW, direct_reclaim);
+ if (page)
+ return page;
+
+ /*
+ * OK, none of the zones on our zonelist has lots
+ * of pages free.
+ *
+ * We wake up kswapd, in the hope that kswapd will
+ * resolve this situation before memory gets tight.
+ *
+ * We also yield the CPU, because that:
+ * - gives kswapd a chance to do something
+ * - slows down allocations, in particular the
+ * allocations from the fast allocator that's
+ * causing the problems ...
+ * - ... which minimises the impact the "bad guys"
+ * have on the rest of the system
+ * - if we don't have __GFP_IO set, kswapd may be
+ * able to free some memory we can't free ourselves
+ */
+ wakeup_kswapd(0);
+ if (gfp_mask & __GFP_WAIT) {
+ __set_current_state(TASK_RUNNING);
+ current->policy |= SCHED_YIELD;
+ schedule();
X }
X
X /*
- * Uhhuh. All the zones have been critical, which means that
- * we'd better do some synchronous swap-out. kswapd has not
- * been able to cope..
+ * After waking up kswapd, we try to allocate a page
+ * from any zone which isn't critical yet.
+ *
+ * Kswapd should, in most situations, bring the situation
+ * back to normal in no time.
+ */
+ page = __alloc_pages_limit(zonelist, order, PAGES_MIN, direct_reclaim);
+ if (page)
+ return page;
+
+ /*
+ * Damn, we didn't succeed.
+ *
+ * This can be due to 2 reasons:
+ * - we're doing a higher-order allocation
+ * --> move pages to the free list until we succeed
+ * - we're /really/ tight on memory
+ * --> wait on the kswapd waitqueue until memory is freed
X */
X if (!(current->flags & PF_MEMALLOC)) {
- int gfp_mask = zonelist->gfp_mask;
- if (!try_to_free_pages(gfp_mask)) {
- if (!(gfp_mask & __GFP_HIGH))
- goto fail;
+ /*
+ * Are we dealing with a higher order allocation?
+ *
+ * Move pages from the inactive_clean to the free list
+ * in the hope of creating a large, physically contiguous
+ * piece of free memory.
+ */
+ if (order > 0 && (gfp_mask & __GFP_WAIT)) {
+ zone = zonelist->zones;
+ /* First, clean some dirty pages. */
+ page_launder(gfp_mask, 1);
+ for (;;) {
+ zone_t *z = *(zone++);
+ if (!z)
+ break;
+ if (!z->size)
+ continue;
+ while (z->inactive_clean_pages) {
+ struct page * page;
+ /* Move one page to the free list. */
+ page = reclaim_page(z);
+ if (!page)
+ break;
+ __free_page(page);
+ /* Try if the allocation succeeds. */
+ page = rmqueue(z, order);
+ if (page)
+ return page;
+ }
+ }
+ }
+ /*
+ * When we arrive here, we are really tight on memory.
+ *
+ * We wake up kswapd and sleep until kswapd wakes us
+ * up again. After that we loop back to the start.
+ *
+ * We have to do this because something else might eat
+ * the memory kswapd frees for us and we need to be
+ * reliable. Note that we don't loop back for higher
+ * order allocations since it is possible that kswapd
+ * simply cannot free a large enough contiguous area
+ * of memory *ever*.
+ */
+ if ((gfp_mask & (__GFP_WAIT|__GFP_IO)) == (__GFP_WAIT|__GFP_IO)) {
+ wakeup_kswapd(1);
+ memory_pressure++;
+ if (!order)
+ goto try_again;
+ /*
+ * If __GFP_IO isn't set, we can't wait on kswapd because
+ * kswapd just might need some IO locks /we/ are holding ...
+ *
+ * SUBTLE: The scheduling point above makes sure that
+ * kswapd does get the chance to free memory we can't
+ * free ourselves...
+ */
+ } else if (gfp_mask & __GFP_WAIT) {
+ try_to_free_pages(gfp_mask);
+ memory_pressure++;
+ if (!order)
+ goto try_again;
X }
+
X }
X
X /*
X * Final phase: allocate anything we can!
+ *
+ * Higher order allocations, GFP_ATOMIC allocations and
+ * recursive allocations (PF_MEMALLOC) end up here.
+ *
+ * Only recursive allocations can use the very last pages
+ * in the system, otherwise it would be just too easy to
+ * deadlock the system...
X */
X zone = zonelist->zones;
X for (;;) {
- struct page *page;
-
X zone_t *z = *(zone++);
+ struct page * page = NULL;
X if (!z)
X break;
- page = rmqueue(z, order);
+ if (!z->size)


+ BUG();
+
+ /*

+ * SUBTLE: direct_reclaim is only possible if the task
+ * becomes PF_MEMALLOC while looping above. This will
+ * happen when the OOM killer selects this task for
+ * instant execution...
+ */
+ if (direct_reclaim)
+ page = reclaim_page(z);
+ if (page)
+ return page;
+
+ /* XXX: is pages_min/4 a good amount to reserve for this? */
+ if (z->free_pages < z->pages_min / 4 &&
+ !(current->flags & PF_MEMALLOC))
+ continue;
+ if (!page)
+ page = rmqueue(z, order);
X if (page)
X return page;
X }
X
-fail:
X /* No luck.. */
+ printk(KERN_ERR "__alloc_pages: %lu-order allocation failed.\n", order);


X return NULL;
X }
X

@@ -377,18 +598,46 @@
X }
X
X /*
- * Amount of free RAM allocatable as buffer memory:
+ * Total amount of inactive_clean (allocatable) RAM:
X */
-unsigned int nr_free_buffer_pages (void)
+unsigned int nr_inactive_clean_pages (void)
X {
X unsigned int sum;
X zone_t *zone;
X int i;
X
- sum = nr_lru_pages / 3;
+ sum = 0;
X for (i = 0; i < NUMNODES; i++)
- for (zone = NODE_DATA(i)->node_zones; zone <= NODE_DATA(i)->node_zones+ZONE_NORMAL; zone++)
- sum += zone->free_pages;
+ for (zone = NODE_DATA(i)->node_zones; zone < NODE_DATA(i)->node_zones + MAX_NR_ZONES; zone++)
+ sum += zone->inactive_clean_pages;
+ return sum;
+}
+
+/*
+ * Amount of free RAM allocatable as buffer memory:
+ */
+unsigned int nr_free_buffer_pages (void)
+{
+ unsigned int sum;
+
+ sum = nr_free_pages();
+ sum += nr_inactive_clean_pages();
+ sum += nr_inactive_dirty_pages;
+
+ /*
+ * Keep our write behind queue filled, even if
+ * kswapd lags a bit right now.
+ */
+ if (sum < freepages.high + inactive_target)
+ sum = freepages.high + inactive_target;
+ /*
+ * We don't want dirty page writebehind to put too
+ * much pressure on the working set, but we want it
+ * to be possible to have some dirty pages in the
+ * working set without upsetting the writebehind logic.
+ */
+ sum += nr_active_pages >> 4;
+
X return sum;
X }
X
@@ -418,9 +667,11 @@
X nr_free_pages() << (PAGE_SHIFT-10),
X nr_free_highpages() << (PAGE_SHIFT-10));
X
- printk("( Free: %d, lru_cache: %d (%d %d %d) )\n",
+ printk("( Active: %d, inactive_dirty: %d, inactive_clean: %d, free: %d (%d %d %d) )\n",
+ nr_active_pages,
+ nr_inactive_dirty_pages,
+ nr_inactive_clean_pages(),
X nr_free_pages(),
- nr_lru_pages,
X freepages.min,
X freepages.low,
X freepages.high);
@@ -430,17 +681,6 @@
X zone_t *zone = NODE_DATA(nid)->node_zones + type;
X unsigned long nr, total, flags;
X
- printk(" %c%d%d %s: ",
- (zone->free_pages > zone->pages_low
- ? (zone->free_pages > zone->pages_high
- ? ' '
- : 'H')
- : (zone->free_pages > zone->pages_min
- ? 'M'
- : 'L')),
- zone->zone_wake_kswapd, zone->low_on_memory,
- zone->name);
-
X total = 0;
X if (zone->size) {
X spin_lock_irqsave(&zone->lock, flags);
@@ -570,7 +810,8 @@
X freepages.min += i;
X freepages.low += i * 2;
X freepages.high += i * 3;
- memlist_init(&lru_cache);
+ memlist_init(&active_list);
+ memlist_init(&inactive_dirty_list);
X
X /*
X * Some architectures (with lots of mem and discontinous memory
@@ -618,6 +859,9 @@
X zone->lock = SPIN_LOCK_UNLOCKED;
X zone->zone_pgdat = pgdat;
X zone->free_pages = 0;
+ zone->inactive_clean_pages = 0;
+ zone->inactive_dirty_pages = 0;
+ memlist_init(&zone->inactive_clean_list);
X if (!size)
X continue;
X
@@ -631,8 +875,6 @@
X zone->pages_min = mask;
X zone->pages_low = mask*2;
X zone->pages_high = mask*3;
- zone->low_on_memory = 0;
- zone->zone_wake_kswapd = 0;
X zone->zone_mem_map = mem_map + offset;
X zone->zone_start_mapnr = offset;
X zone->zone_start_paddr = zone_start_paddr;
diff -u --recursive --new-file v2.4.0-test8/linux/mm/page_io.c linux/mm/page_io.c
--- v2.4.0-test8/linux/mm/page_io.c Mon Aug 7 21:01:36 2000
+++ linux/mm/page_io.c Fri Sep 15 16:51:21 2000
@@ -43,7 +43,8 @@
X struct inode *swapf = 0;
X
X /* Don't allow too many pending pages in flight.. */
- if (atomic_read(&nr_async_pages) > pager_daemon.swap_cluster)
+ if ((rw == WRITE) && atomic_read(&nr_async_pages) >
+ pager_daemon.swap_cluster * (1 << page_cluster))
X wait = 1;
X
X if (rw == READ) {
diff -u --recursive --new-file v2.4.0-test8/linux/mm/slab.c linux/mm/slab.c
--- v2.4.0-test8/linux/mm/slab.c Fri Aug 11 15:04:54 2000
+++ linux/mm/slab.c Sun Oct 1 19:55:17 2000
@@ -579,7 +579,6 @@
X kmem_cache_free(cachep->slabp_cache, slabp);
X }
X
-
X /**
X * kmem_cache_create - Create a cache.
X * @name: A string which is used in /proc/slabinfo to identify this cache.
@@ -838,48 +837,60 @@
X }
X
X #ifdef CONFIG_SMP
-static DECLARE_MUTEX(cache_drain_sem);
-static kmem_cache_t *cache_to_drain = NULL;
-static DECLARE_WAIT_QUEUE_HEAD(cache_drain_wait);
-unsigned long slab_cache_drain_mask;
-
X /*
- * Waits for all CPUs to execute slab_drain_local_cache().
- * Caller must be holding cache_drain_sem.
+ * Waits for all CPUs to execute func().
X */
-static void slab_drain_all_sync(void)
+static void smp_call_function_all_cpus(void (*func) (void *arg), void *arg)
X {
- DECLARE_WAITQUEUE(wait, current);
-
X local_irq_disable();
- slab_drain_local_cache();
+ func(arg);
X local_irq_enable();
X
- add_wait_queue(&cache_drain_wait, &wait);
- current->state = TASK_UNINTERRUPTIBLE;
- while (slab_cache_drain_mask != 0UL)
- schedule();


- current->state = TASK_RUNNING;

- remove_wait_queue(&cache_drain_wait, &wait);
+ if (smp_call_function(func, arg, 1, 1))
+ BUG();
+}
+typedef struct ccupdate_struct_s
+{
+ kmem_cache_t *cachep;
+ cpucache_t *new[NR_CPUS];
+} ccupdate_struct_t;
+
+static void do_ccupdate_local(void *info)
+{
+ ccupdate_struct_t *new = (ccupdate_struct_t *)info;
+ cpucache_t *old = cc_data(new->cachep);
+
+ cc_data(new->cachep) = new->new[smp_processor_id()];
+ new->new[smp_processor_id()] = old;
X }
X
+static void free_block (kmem_cache_t* cachep, void** objpp, int len);
+
X static void drain_cpu_caches(kmem_cache_t *cachep)
X {
- unsigned long cpu_mask = 0;
+ ccupdate_struct_t new;
X int i;
X
- for (i = 0; i < smp_num_cpus; i++)
- cpu_mask |= (1UL << cpu_logical_map(i));
+ memset(&new.new,0,sizeof(new.new));
X
- down(&cache_drain_sem);
+ new.cachep = cachep;
X
- cache_to_drain = cachep;
- slab_cache_drain_mask = cpu_mask;
- slab_drain_all_sync();
- cache_to_drain = NULL;
+ down(&cache_chain_sem);
+ smp_call_function_all_cpus(do_ccupdate_local, (void *)&new);
X
- up(&cache_drain_sem);
+ for (i = 0; i < smp_num_cpus; i++) {
+ cpucache_t* ccold = new.new[cpu_logical_map(i)];
+ if (!ccold || (ccold->avail == 0))
+ continue;
+ local_irq_disable();
+ free_block(cachep, cc_entry(ccold), ccold->avail);
+ local_irq_enable();
+ ccold->avail = 0;
+ }
+ smp_call_function_all_cpus(do_ccupdate_local, (void *)&new);
+ up(&cache_chain_sem);
X }
+
X #else
X #define drain_cpu_caches(cachep) do { } while (0)
X #endif
@@ -1593,56 +1604,6 @@


X
X #ifdef CONFIG_SMP
X

-typedef struct ccupdate_struct_s
-{
- kmem_cache_t *cachep;
- cpucache_t *new[NR_CPUS];
-} ccupdate_struct_t;
-
-static ccupdate_struct_t *ccupdate_state = NULL;
-
-/* Called from per-cpu timer interrupt. */
-void slab_drain_local_cache(void)
-{
- if (ccupdate_state != NULL) {
- ccupdate_struct_t *new = ccupdate_state;
- cpucache_t *old = cc_data(new->cachep);
-
- cc_data(new->cachep) = new->new[smp_processor_id()];
- new->new[smp_processor_id()] = old;
- } else {
- kmem_cache_t *cachep = cache_to_drain;
- cpucache_t *cc = cc_data(cachep);
-
- if (cc && cc->avail) {
- free_block(cachep, cc_entry(cc), cc->avail);
- cc->avail = 0;
- }
- }
-
- clear_bit(smp_processor_id(), &slab_cache_drain_mask);
- if (slab_cache_drain_mask == 0)
- wake_up(&cache_drain_wait);
-}
-
-static void do_ccupdate(ccupdate_struct_t *data)
-{
- unsigned long cpu_mask = 0;
- int i;
-
- for (i = 0; i < smp_num_cpus; i++)
- cpu_mask |= (1UL << cpu_logical_map(i));
-
- down(&cache_drain_sem);
-
- ccupdate_state = data;
- slab_cache_drain_mask = cpu_mask;
- slab_drain_all_sync();
- ccupdate_state = NULL;
-
- up(&cache_drain_sem);
-}
-
X /* called with cache_chain_sem acquired. */
X static int kmem_tune_cpucache (kmem_cache_t* cachep, int limit, int batchcount)
X {
@@ -1666,7 +1627,6 @@
X for (i = 0; i< smp_num_cpus; i++) {
X cpucache_t* ccnew;
X
-
X ccnew = kmalloc(sizeof(void*)*limit+
X sizeof(cpucache_t), GFP_KERNEL);
X if (!ccnew)
@@ -1681,7 +1641,7 @@
X cachep->batchcount = batchcount;
X spin_unlock_irq(&cachep->spinlock);
X
- do_ccupdate(&new);
+ smp_call_function_all_cpus(do_ccupdate_local, (void *)&new);
X
X for (i = 0; i < smp_num_cpus; i++) {
X cpucache_t* ccold = new.new[cpu_logical_map(i)];
@@ -1772,14 +1732,6 @@
X /* It's safe to test this without holding the cache-lock. */
X if (searchp->flags & SLAB_NO_REAP)
X goto next;
- /* FIXME: is this really a good idea? */
- if (gfp_mask & GFP_DMA) {
- if (!(searchp->gfpflags & GFP_DMA))
- goto next;
- } else {
- if (searchp->gfpflags & GFP_DMA)
- goto next;
- }
X spin_lock_irq(&searchp->spinlock);
X if (searchp->growing)
X goto next_unlock;
diff -u --recursive --new-file v2.4.0-test8/linux/mm/swap.c linux/mm/swap.c
--- v2.4.0-test8/linux/mm/swap.c Mon Dec 6 10:14:13 1999
+++ linux/mm/swap.c Mon Oct 2 11:28:38 2000
@@ -40,7 +40,18 @@
X };
X
X /* How many pages do we try to swap or page in/out together? */
-int page_cluster = 4; /* Default value modified in swap_setup() */
+int page_cluster;
+
+/*
+ * This variable contains the amount of page steals the system
+ * is doing, averaged over a minute. We use this to determine how
+ * many inactive pages we should have.
+ *
+ * In reclaim_page and __alloc_pages: memory_pressure++
+ * In __free_pages_ok: memory_pressure--
+ * In recalculate_vm_stats the value is decayed (once a second)
+ */
+int memory_pressure;
X
X /* We track the number of pages currently being asynchronously swapped
X out, so that we don't try to swap TOO many pages out at once */
@@ -61,13 +72,250 @@
X pager_daemon_t pager_daemon = {
X 512, /* base number for calculating the number of tries */
X SWAP_CLUSTER_MAX, /* minimum number of tries */
- SWAP_CLUSTER_MAX, /* do swap I/O in clusters of this size */
+ 8, /* do swap I/O in clusters of this size */
X };
X
+/**
+ * age_page_{up,down} - page aging helper functions
+ * @page - the page we want to age
+ * @nolock - are we already holding the pagelist_lru_lock?
+ *
+ * If the page is on one of the lists (active, inactive_dirty or
+ * inactive_clean), we will grab the pagelist_lru_lock as needed.
+ * If you're already holding the lock, call this function with the
+ * nolock argument non-zero.
+ */
+void age_page_up_nolock(struct page * page)
+{
+ /*
+ * We're dealing with an inactive page, move the page
+ * to the active list.
+ */
+ if (!page->age)
+ activate_page_nolock(page);
+
+ /* The actual page aging bit */
+ page->age += PAGE_AGE_ADV;
+ if (page->age > PAGE_AGE_MAX)
+ page->age = PAGE_AGE_MAX;
+}
+
X /*
- * Perform any setup for the swap system
+ * We use this (minimal) function in the case where we
+ * know we can't deactivate the page (yet).
+ */
+void age_page_down_ageonly(struct page * page)
+{
+ page->age /= 2;
+}
+
+void age_page_down_nolock(struct page * page)
+{
+ /* The actual page aging bit */
+ page->age /= 2;
+
+ /*
+ * The page is now an old page. Move to the inactive
+ * list (if possible ... see below).
+ */
+ if (!page->age)
+ deactivate_page_nolock(page);
+}
+
+void age_page_up(struct page * page)
+{
+ /*
+ * We're dealing with an inactive page, move the page
+ * to the active list.
+ */
+ if (!page->age)
+ activate_page(page);
+
+ /* The actual page aging bit */
+ page->age += PAGE_AGE_ADV;
+ if (page->age > PAGE_AGE_MAX)
+ page->age = PAGE_AGE_MAX;
+}
+
+void age_page_down(struct page * page)
+{
+ /* The actual page aging bit */
+ page->age /= 2;
+
+ /*
+ * The page is now an old page. Move to the inactive
+ * list (if possible ... see below).
+ */
+ if (!page->age)
+ deactivate_page(page);
+}
+
+
+/**
+ * (de)activate_page - move pages from/to active and inactive lists
+ * @page: the page we want to move
+ * @nolock - are we already holding the pagemap_lru_lock?
+ *
+ * Deactivate_page will move an active page to the right
+ * inactive list, while activate_page will move a page back
+ * from one of the inactive lists to the active list. If
+ * called on a page which is not on any of the lists, the
+ * page is left alone.
X */
+void deactivate_page_nolock(struct page * page)
+{
+ /*
+ * One for the cache, one for the extra reference the
+ * caller has and (maybe) one for the buffers.
+ *
+ * This isn't perfect, but works for just about everything.
+ * Besides, as long as we don't move unfreeable pages to the
+ * inactive_clean list it doesn't need to be perfect...
+ */
+ int maxcount = (page->buffers ? 3 : 2);
+ page->age = 0;
+
+ /*
+ * Don't touch it if it's not on the active list.
+ * (some pages aren't on any list at all)
+ */
+ if (PageActive(page) && page_count(page) <= maxcount &&
+ !page_ramdisk(page)) {
+
+ /*
+ * We can move the page to the inactive_dirty list
+ * if we have the strong suspicion that they might
+ * become freeable in the near future.
+ *
+ * That is, the page has buffer heads attached (that
+ * need to be cleared away) and/or the function calling
+ * us has an extra reference count on the page.
+ */
+ if (page->buffers || page_count(page) == 2) {
+ del_page_from_active_list(page);
+ add_page_to_inactive_dirty_list(page);
+ /*
+ * Only if we are SURE the page is clean and immediately
+ * reusable, we move it to the inactive_clean list.
+ */
+ } else if (page->mapping && !PageDirty(page) &&
+ !PageLocked(page)) {
+ del_page_from_active_list(page);
+ add_page_to_inactive_clean_list(page);
+ }
+ /*
+ * OK, we cannot free the page. Leave it alone.


+ */
+ }
+}
X

+void deactivate_page(struct page * page)
+{
+ spin_lock(&pagemap_lru_lock);
+ deactivate_page_nolock(page);
+ spin_unlock(&pagemap_lru_lock);
+}
+
+/*
+ * Move an inactive page to the active list.
+ */
+void activate_page_nolock(struct page * page)
+{
+ if (PageInactiveDirty(page)) {
+ del_page_from_inactive_dirty_list(page);
+ add_page_to_active_list(page);
+ } else if (PageInactiveClean(page)) {
+ del_page_from_inactive_clean_list(page);
+ add_page_to_active_list(page);
+ } else {
+ /*
+ * The page was not on any list, so we take care
+ * not to do anything.
+ */
+ }
+
+ /* Make sure the page gets a fair chance at staying active. */
+ if (page->age < PAGE_AGE_START)
+ page->age = PAGE_AGE_START;
+}
+
+void activate_page(struct page * page)
+{
+ spin_lock(&pagemap_lru_lock);
+ activate_page_nolock(page);
+ spin_unlock(&pagemap_lru_lock);
+}
+
+/**
+ * lru_cache_add: add a page to the page lists
+ * @page: the page to add
+ */
+void lru_cache_add(struct page * page)
+{
+ spin_lock(&pagemap_lru_lock);
+ if (!PageLocked(page))
+ BUG();
+ DEBUG_ADD_PAGE
+ add_page_to_active_list(page);
+ /* This should be relatively rare */
+ if (!page->age)
+ deactivate_page_nolock(page);
+ spin_unlock(&pagemap_lru_lock);
+}
+
+/**
+ * __lru_cache_del: remove a page from the page lists
+ * @page: the page to add
+ *
+ * This function is for when the caller already holds
+ * the pagemap_lru_lock.
+ */
+void __lru_cache_del(struct page * page)
+{
+ if (PageActive(page)) {
+ del_page_from_active_list(page);
+ } else if (PageInactiveDirty(page)) {
+ del_page_from_inactive_dirty_list(page);
+ } else if (PageInactiveClean(page)) {
+ del_page_from_inactive_clean_list(page);
+ } else {
+ printk("VM: __lru_cache_del, found unknown page ?!\n");
+ }
+ DEBUG_ADD_PAGE
+}
+
+/**
+ * lru_cache_del: remove a page from the page lists
+ * @page: the page to remove
+ */
+void lru_cache_del(struct page * page)
+{
+ if (!PageLocked(page))
+ BUG();
+ spin_lock(&pagemap_lru_lock);
+ __lru_cache_del(page);
+ spin_unlock(&pagemap_lru_lock);
+}
+
+/**
+ * recalculate_vm_stats - recalculate VM statistics
+ *
+ * This function should be called once a second to recalculate
+ * some useful statistics the VM subsystem uses to determine
+ * its behaviour.
+ */
+void recalculate_vm_stats(void)
+{
+ /*
+ * Substract one second worth of memory_pressure from
+ * memory_pressure.
+ */
+ memory_pressure -= (memory_pressure >> INACTIVE_SHIFT);
+}
+
+/*
+ * Perform any setup for the swap system
+ */
X void __init swap_setup(void)
X {
X /* Use a smaller cluster for memory <16MB or <32MB */
diff -u --recursive --new-file v2.4.0-test8/linux/mm/swap_state.c linux/mm/swap_state.c
--- v2.4.0-test8/linux/mm/swap_state.c Mon Aug 7 21:01:36 2000
+++ linux/mm/swap_state.c Sun Sep 24 12:36:46 2000
@@ -73,7 +73,7 @@
X PAGE_BUG(page);
X
X PageClearSwapCache(page);
- remove_inode_page(page);
+ __remove_inode_page(page);
X }
X
X /*
@@ -105,7 +105,9 @@
X if (block_flushpage(page, 0))
X lru_cache_del(page);
X
+ spin_lock(&pagecache_lock);
X __delete_from_swap_cache(page);
+ spin_unlock(&pagecache_lock);
X page_cache_release(page);
X }
X
@@ -164,7 +166,7 @@
X return 0;
X /*
X * Though the "found" page was in the swap cache an instant
- * earlier, it might have been removed by shrink_mmap etc.
+ * earlier, it might have been removed by refill_inactive etc.
X * Re search ... Since find_lock_page grabs a reference on
X * the page, it can not be reused for anything else, namely
X * it can not be associated with another swaphandle, so it
diff -u --recursive --new-file v2.4.0-test8/linux/mm/vmalloc.c linux/mm/vmalloc.c
--- v2.4.0-test8/linux/mm/vmalloc.c Mon Aug 7 21:01:36 2000
+++ linux/mm/vmalloc.c Sun Oct 1 20:35:16 2000
@@ -14,7 +14,7 @@
X #include <asm/pgalloc.h>
X
X rwlock_t vmlist_lock = RW_LOCK_UNLOCKED;
-struct vm_struct * vmlist = NULL;
+struct vm_struct * vmlist;
X
X static inline void free_area_pte(pmd_t * pmd, unsigned long address, unsigned long size)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/mm/vmscan.c linux/mm/vmscan.c
--- v2.4.0-test8/linux/mm/vmscan.c Fri Sep 1 14:25:26 2000
+++ linux/mm/vmscan.c Mon Oct 2 12:02:20 2000
@@ -9,6 +9,7 @@
X * to bring the system back to freepages.high: 2.4.97, Rik van Riel.
X * Version: $Id: vmscan.c,v 1.5 1998/02/23 22:14:28 sct Exp $
X * Zone aware kswapd started 02/00, Kanoj Sarcar (ka...@sgi.com).
+ * Multiqueue VM started 5.8.00, Rik van Riel.
X */
X
X #include <linux/slab.h>
@@ -40,6 +41,7 @@
X swp_entry_t entry;
X struct page * page;
X int (*swapout)(struct page *, struct file *);
+ int onlist;
X
X pte = *page_table;
X if (!pte_present(pte))
@@ -51,16 +53,37 @@
X if (mm->swap_cnt)
X mm->swap_cnt--;
X
+ onlist = PageActive(page);
X /* Don't look at this pte if it's been accessed recently. */
X if (pte_young(pte)) {
- /*
- * Transfer the "accessed" bit from the page
- * tables to the global page map.
- */
X set_pte(page_table, pte_mkold(pte));
- SetPageReferenced(page);
+ if (onlist) {
+ /*
+ * Transfer the "accessed" bit from the page
+ * tables to the global page map. Page aging
+ * will be done by refill_inactive_scan().
+ */
+ SetPageReferenced(page);
+ } else {
+ /*
+ * The page is not on the active list, so
+ * we have to do the page aging ourselves.
+ */
+ age_page_up(page);
+ }
X goto out_failed;
X }
+ if (!onlist)
+ /* The page is still mapped, so it can't be freeable... */
+ age_page_down_ageonly(page);
+
+ /*
+ * If the page is in active use by us, or if the page
+ * is in active use by others, don't unmap it or
+ * (worse) start unneeded IO.
+ */
+ if (page->age > 0)
+ goto out_failed;
X
X if (TryLockPage(page))
X goto out_failed;
@@ -79,8 +102,9 @@
X set_pte(page_table, swp_entry_to_pte(entry));
X drop_pte:
X UnlockPage(page);
- vma->vm_mm->rss--;
+ mm->rss--;
X flush_tlb_page(vma, address);
+ deactivate_page(page);
X page_cache_release(page);
X goto out_failed;
X }
@@ -96,7 +120,7 @@
X * our scan.
X *
X * Basically, this just makes it possible for us to do
- * some real work in the future in "shrink_mmap()".
+ * some real work in the future in "refill_inactive()".
X */
X if (!pte_dirty(pte)) {
X flush_cache_page(vma, address);
@@ -116,7 +140,9 @@
X * Don't do any of the expensive stuff if
X * we're not really interested in this zone.
X */
- if (page->zone->free_pages > page->zone->pages_high)
+ if (page->zone->free_pages + page->zone->inactive_clean_pages
+ + page->zone->inactive_dirty_pages
+ > page->zone->pages_high + inactive_target)
X goto out_unlock;
X
X /*
@@ -134,7 +160,7 @@
X * NOTE NOTE NOTE! This should just set a
X * dirty bit in 'page', and just drop the
X * pte. All the hard work would be done by
- * shrink_mmap().
+ * refill_inactive().
X *
X * That would get rid of a lot of problems.
X */
@@ -144,14 +170,15 @@
X struct file *file = vma->vm_file;
X if (file) get_file(file);
X pte_clear(page_table);
- vma->vm_mm->rss--;
+ mm->rss--;
X flush_tlb_page(vma, address);
- vmlist_access_unlock(vma->vm_mm);
+ vmlist_access_unlock(mm);
X error = swapout(page, file);
X UnlockPage(page);
X if (file) fput(file);
X if (!error)
X goto out_free_success;
+ deactivate_page(page);
X page_cache_release(page);
X return error;
X }
@@ -175,13 +202,14 @@
X add_to_swap_cache(page, entry);
X
X /* Put the swap entry into the pte after the page is in swapcache */
- vma->vm_mm->rss--;
+ mm->rss--;
X set_pte(page_table, swp_entry_to_pte(entry));
X flush_tlb_page(vma, address);
- vmlist_access_unlock(vma->vm_mm);
+ vmlist_access_unlock(mm);
X
X /* OK, do a physical asynchronous write to swap. */
X rw_swap_page(WRITE, page, 0);
+ deactivate_page(page);
X
X out_free_success:
X page_cache_release(page);
@@ -230,7 +258,7 @@
X
X do {
X int result;
- vma->vm_mm->swap_address = address + PAGE_SIZE;
+ mm->swap_address = address + PAGE_SIZE;
X result = try_to_swap_out(mm, vma, address, pte, gfp_mask);
X if (result)
X return result;
@@ -282,7 +310,7 @@
X if (vma->vm_flags & VM_LOCKED)
X return 0;
X
- pgdir = pgd_offset(vma->vm_mm, address);
+ pgdir = pgd_offset(mm, address);
X
X end = vma->vm_end;
X if (address >= end)
@@ -323,17 +351,22 @@
X int result = swap_out_vma(mm, vma, address, gfp_mask);
X if (result)
X return result;
+ if (!mm->swap_cnt)
+ goto out_unlock;
X vma = vma->vm_next;
X if (!vma)
X break;
X address = vma->vm_start;
X }
X }
+ /* Reset to 0 when we reach the end of address space */
+ mm->swap_address = 0;
+ mm->swap_cnt = 0;
+
+out_unlock:
X vmlist_access_unlock(mm);
X
X /* We didn't find anything for the process */
- mm->swap_cnt = 0;
- mm->swap_address = 0;


X return 0;
X }
X

@@ -342,7 +375,10 @@
X * N.B. This function returns only 0 or 1. Return values != 1 from
X * the lower level routines result in continued processing.
X */
-static int swap_out(unsigned int priority, int gfp_mask)
+#define SWAP_SHIFT 5
+#define SWAP_MIN 8
+
+static int swap_out(unsigned int priority, int gfp_mask, unsigned long idle_time)


X {
X struct task_struct * p;

X int counter;
@@ -363,7 +399,7 @@
X * Think of swap_cnt as a "shadow rss" - it tells us which process
X * we want to page out (always try largest first).
X */
- counter = (nr_threads << 2) >> (priority >> 2);
+ counter = (nr_threads << SWAP_SHIFT) >> priority;
X if (counter < 1)
X counter = 1;
X
@@ -372,6 +408,7 @@
X struct mm_struct *best = NULL;
X int pid = 0;
X int assign = 0;
+ int found_task = 0;
X select:
X read_lock(&tasklist_lock);
X p = init_task.next_task;
@@ -381,9 +418,17 @@
X continue;
X if (mm->rss <= 0)
X continue;
+ /* Skip tasks which haven't slept long enough yet when idle-swapping. */
+ if (idle_time && !assign && (!(p->state & TASK_INTERRUPTIBLE) ||
+ time_after(p->sleep_time + idle_time * HZ, jiffies)))
+ continue;
+ found_task++;
X /* Refresh swap_cnt? */
- if (assign == 1)
- mm->swap_cnt = mm->rss;
+ if (assign == 1) {
+ mm->swap_cnt = (mm->rss >> SWAP_SHIFT);
+ if (mm->swap_cnt < SWAP_MIN)
+ mm->swap_cnt = SWAP_MIN;
+ }
X if (mm->swap_cnt > max_cnt) {
X max_cnt = mm->swap_cnt;
X best = mm;


@@ -392,7 +437,7 @@
X }

X read_unlock(&tasklist_lock);
X if (!best) {
- if (!assign) {
+ if (!assign && found_task > 0) {
X assign = 1;
X goto select;
X }
@@ -418,50 +463,409 @@
X return __ret;
X }
X
-/*
- * Check if there is any memory pressure (free_pages < pages_low)
+
+/**
+ * reclaim_page - reclaims one page from the inactive_clean list
+ * @zone: reclaim a page from this zone
+ *
+ * The pages on the inactive_clean can be instantly reclaimed.
+ * The tests look impressive, but most of the time we'll grab
+ * the first page of the list and exit successfully.
X */
-static inline int memory_pressure(void)
+struct page * reclaim_page(zone_t * zone)
X {
- pg_data_t *pgdat = pgdat_list;
+ struct page * page = NULL;
+ struct list_head * page_lru;
+ int maxscan;
X
- do {
- int i;
- for(i = 0; i < MAX_NR_ZONES; i++) {
- zone_t *zone = pgdat->node_zones+ i;
- if (zone->size &&
- zone->free_pages < zone->pages_low)


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 110'
echo 'File patch-2.4.0-test9 is continued in part 111'
echo "111" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part112

#!/bin/sh -x
# this is part 112 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 112; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

- int clear = 0;
+ if (flags&(MSG_PEEK|MSG_DONTWAIT)) {


+ struct sk_buff *skb2;
+

X spin_lock_irq(&sk->receive_queue.lock);
- if (skb == skb_peek(&sk->receive_queue)) {
+ skb2 = skb_peek(&sk->receive_queue);
+ if ((flags & MSG_PEEK) && skb == skb2) {
X __skb_unlink(skb, &sk->receive_queue);
- clear = 1;
X }
X spin_unlock_irq(&sk->receive_queue.lock);
- if (clear)
- kfree_skb(skb);
- }
-
- skb_free_datagram(sk, skb);
-
- /*
- * Error for blocking case is chosen to masquerade
- * as some normal condition.
- */
- return (flags&MSG_DONTWAIT) ? -EAGAIN : -EHOSTUNREACH;
+ skb_free_datagram(sk, skb);
+ if ((flags & MSG_DONTWAIT) && !skb2)
+ return -EAGAIN;
+ } else
+ skb_free_datagram(sk, skb);
+ goto retry;
X }
X
X int udp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
@@ -797,10 +793,21 @@
X */
X
X sk->state = TCP_CLOSE;
- sk->rcv_saddr = 0;
X sk->daddr = 0;
X sk->dport = 0;
X sk->bound_dev_if = 0;
+ if (!(sk->userlocks&SOCK_BINDADDR_LOCK)) {
+ sk->rcv_saddr = 0;
+ sk->saddr = 0;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+ memset(&sk->net_pinfo.af_inet6.saddr, 0, 16);
+ memset(&sk->net_pinfo.af_inet6.rcv_saddr, 0, 16);
+#endif
+ }
+ if (!(sk->userlocks&SOCK_BINDPORT_LOCK)) {
+ sk->prot->unhash(sk);
+ sk->sport = 0;
+ }
X sk_dst_reset(sk);
X return 0;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/net/ipv4/utils.c linux/net/ipv4/utils.c
--- v2.4.0-test8/linux/net/ipv4/utils.c Wed Jun 9 14:45:37 1999
+++ linux/net/ipv4/utils.c Mon Oct 2 14:13:29 2000
@@ -57,12 +57,6 @@
X return(buff);
X }
X
-char *in_ntoa2(__u32 in, char *buff)
-{
- sprintf(buff, "%d.%d.%d.%d", NIPQUAD(in));
- return buff;
-}
-
X /*
X * Convert an ASCII string to binary IP.
X */
diff -u --recursive --new-file v2.4.0-test8/linux/net/ipv6/af_inet6.c linux/net/ipv6/af_inet6.c
--- v2.4.0-test8/linux/net/ipv6/af_inet6.c Wed Apr 26 12:13:17 2000
+++ linux/net/ipv6/af_inet6.c Mon Sep 18 15:04:13 2000
@@ -7,10 +7,11 @@
X *
X * Adapted from linux/net/ipv4/af_inet.c
X *
- * $Id: af_inet6.c,v 1.56 2000/04/25 04:13:34 davem Exp $
+ * $Id: af_inet6.c,v 1.58 2000/09/18 05:59:48 davem Exp $
X *
X * Fixes:
X * Hideaki YOSHIFUJI : sin6_scope_id support
+ * Arnaldo Melo : check proc_net_create return, cleanups


X *
X * This program is free software; you can redistribute it and/or
X * modify it under the terms of the GNU General Public License

@@ -189,7 +190,7 @@
X if (sk->prot->init) {
X int err = sk->prot->init(sk);
X if (err != 0) {
- sk->dead = 1;
+ MOD_DEC_USE_COUNT;
X inet_sock_release(sk);
X return(err);
X }
@@ -295,10 +296,13 @@
X return -EADDRINUSE;
X }
X
+ if (addr_type != IPV6_ADDR_ANY)
+ sk->userlocks |= SOCK_BINDADDR_LOCK;
+ if (snum)
+ sk->userlocks |= SOCK_BINDPORT_LOCK;
X sk->sport = ntohs(sk->num);
X sk->dport = 0;
X sk->daddr = 0;
- sk->prot->hash(sk);
X release_sock(sk);
X
X return 0;
@@ -395,10 +399,8 @@
X {
X case FIOSETOWN:
X case SIOCSPGRP:
- err = get_user(pid, (int *) arg);
- if(err)
- return err;
-
+ if (get_user(pid, (int *) arg))
+ return -EFAULT;
X /* see sock_no_fcntl */
X if (current->pid != pid && current->pgrp != -pid &&
X !capable(CAP_NET_ADMIN))
@@ -407,10 +409,7 @@
X return(0);
X case FIOGETOWN:
X case SIOCGPGRP:
- err = put_user(sk->proc,(int *)arg);
- if(err)
- return err;
- return(0);
+ return put_user(sk->proc,(int *)arg);
X case SIOCGSTAMP:
X if(sk->stamp.tv_sec==0)
X return -ENOENT;
@@ -550,6 +549,20 @@
X err = igmp6_init(&inet6_family_ops);
X if (err)
X goto igmp_fail;
+ /* Create /proc/foo6 entries. */
+#ifdef CONFIG_PROC_FS
+ err = -ENOMEM;
+ if (!proc_net_create("raw6", 0, raw6_get_info))
+ goto proc_raw6_fail;
+ if (!proc_net_create("tcp6", 0, tcp6_get_info))
+ goto proc_tcp6_fail;
+ if (!proc_net_create("udp6", 0, udp6_get_info))
+ goto proc_udp6_fail;
+ if (!proc_net_create("sockstat6", 0, afinet6_get_info))
+ goto proc_sockstat6_fail;
+ if (!proc_net_create("snmp6", 0, afinet6_get_snmp))
+ goto proc_snmp6_fail;
+#endif
X ipv6_netdev_notif_init();
X ipv6_packet_init();
X ip6_route_init();
@@ -561,15 +574,6 @@
X udpv6_init();
X tcpv6_init();
X
- /* Create /proc/foo6 entries. */
-#ifdef CONFIG_PROC_FS
- proc_net_create("raw6", 0, raw6_get_info);
- proc_net_create("tcp6", 0, tcp6_get_info);
- proc_net_create("udp6", 0, udp6_get_info);
- proc_net_create("sockstat6", 0, afinet6_get_info);
- proc_net_create("snmp6", 0, afinet6_get_snmp);
-#endif
-
X /* Now the userspace is allowed to create INET6 sockets. */
X (void) sock_register(&inet6_family_ops);
X
@@ -579,6 +583,18 @@
X return;
X #endif
X
+#ifdef CONFIG_PROC_FS
+proc_snmp6_fail:
+ proc_net_remove("sockstat6");
+proc_sockstat6_fail:
+ proc_net_remove("udp6");
+proc_udp6_fail:
+ proc_net_remove("tcp6");
+proc_tcp6_fail:
+ proc_net_remove("raw6");
+proc_raw6_fail:
+ igmp6_cleanup();
+#endif
X igmp_fail:
X ndisc_cleanup();
X ndisc_fail:
diff -u --recursive --new-file v2.4.0-test8/linux/net/ipv6/ip6_fib.c linux/net/ipv6/ip6_fib.c
--- v2.4.0-test8/linux/net/ipv6/ip6_fib.c Wed May 3 01:48:04 2000
+++ linux/net/ipv6/ip6_fib.c Sun Sep 17 10:03:43 2000
@@ -5,7 +5,7 @@


X * Authors:
X * Pedro Roque <ro...@di.fc.ul.pt>
X *

- * $Id: ip6_fib.c,v 1.21 2000/05/03 06:37:07 davem Exp $
+ * $Id: ip6_fib.c,v 1.22 2000/09/12 00:38:34 davem Exp $


X *
X * This program is free software; you can redistribute it and/or
X * modify it under the terms of the GNU General Public License

@@ -638,10 +638,8 @@
X if (narg->addr) {
X st = fib6_lookup_1(fn->subtree, narg);
X
- if (!(st->fn_flags & RTN_ROOT))
- {
+ if (st && !(st->fn_flags & RTN_ROOT))
X return st;
- }
X }
X }
X #endif
diff -u --recursive --new-file v2.4.0-test8/linux/net/ipv6/mcast.c linux/net/ipv6/mcast.c
--- v2.4.0-test8/linux/net/ipv6/mcast.c Fri Aug 4 18:18:49 2000
+++ linux/net/ipv6/mcast.c Mon Sep 18 15:04:13 2000
@@ -5,7 +5,7 @@


X * Authors:
X * Pedro Roque <ro...@di.fc.ul.pt>
X *

- * $Id: mcast.c,v 1.32 2000/07/26 01:04:21 davem Exp $
+ * $Id: mcast.c,v 1.33 2000/09/18 05:59:48 davem Exp $
X *
X * Based on linux/ipv4/igmp.c and linux/ipv4/ip_sockglue.c
X *
@@ -766,7 +766,6 @@
X return 0;
X }
X
-#ifdef MODULE
X void igmp6_cleanup(void)
X {
X sock_release(igmp6_socket);
@@ -775,4 +774,3 @@
X remove_proc_entry("net/igmp6", 0);
X #endif
X }
-#endif
diff -u --recursive --new-file v2.4.0-test8/linux/net/ipv6/protocol.c linux/net/ipv6/protocol.c
--- v2.4.0-test8/linux/net/ipv6/protocol.c Sat Feb 26 22:34:27 2000
+++ linux/net/ipv6/protocol.c Mon Oct 2 11:57:01 2000
@@ -32,11 +32,8 @@
X #include <net/ipv6.h>
X #include <net/protocol.h>
X
-struct inet6_protocol *inet6_protocol_base = NULL;
-struct inet6_protocol *inet6_protos[MAX_INET_PROTOS] =
-{
- NULL
-};
+struct inet6_protocol *inet6_protocol_base;
+struct inet6_protocol *inet6_protos[MAX_INET_PROTOS];
X
X void inet6_add_protocol(struct inet6_protocol *prot)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/net/ipv6/udp.c linux/net/ipv6/udp.c
--- v2.4.0-test8/linux/net/ipv6/udp.c Thu Aug 10 13:01:26 2000
+++ linux/net/ipv6/udp.c Mon Sep 18 15:04:13 2000
@@ -7,7 +7,7 @@
X *
X * Based on linux/ipv4/udp.c
X *
- * $Id: udp.c,v 1.56 2000/08/09 11:59:04 davem Exp $
+ * $Id: udp.c,v 1.57 2000/09/18 05:59:48 davem Exp $
X *
X * Fixes:
X * Hideaki YOSHIFUJI : sin6_scope_id support
@@ -119,6 +119,15 @@
X }
X
X sk->num = snum;
+ if (sk->pprev == NULL) {
+ struct sock **skp = &udp_hash[snum & (UDP_HTABLE_SIZE - 1)];
+ if ((sk->next = *skp) != NULL)
+ (*skp)->pprev = &sk->next;
+ *skp = sk;
+ sk->pprev = skp;
+ sock_prot_inc_use(sk->prot);
+ sock_hold(sk);
+ }
X write_unlock_bh(&udp_hash_lock);
X return 0;
X
@@ -129,16 +138,7 @@
X
X static void udp_v6_hash(struct sock *sk)
X {
- struct sock **skp = &udp_hash[sk->num & (UDP_HTABLE_SIZE - 1)];
-
- write_lock_bh(&udp_hash_lock);
- if ((sk->next = *skp) != NULL)
- (*skp)->pprev = &sk->next;
- *skp = sk;
- sk->pprev = skp;
- sock_prot_inc_use(sk->prot);
- sock_hold(sk);
- write_unlock_bh(&udp_hash_lock);
+ BUG();
X }
X
X static void udp_v6_unhash(struct sock *sk)
@@ -149,6 +149,7 @@
X sk->next->pprev = sk->pprev;
X *sk->pprev = sk->next;
X sk->pprev = NULL;
+ sk->num = 0;
X sock_prot_dec_use(sk->prot);
X __sock_put(sk);
X }
diff -u --recursive --new-file v2.4.0-test8/linux/net/socket.c linux/net/socket.c
--- v2.4.0-test8/linux/net/socket.c Mon Aug 28 12:04:42 2000
+++ linux/net/socket.c Thu Sep 21 13:20:12 2000
@@ -822,7 +822,7 @@
X * Check protocol is in range
X */
X if(family<0 || family>=NPROTO)
- return -EINVAL;
+ return -EAFNOSUPPORT;
X
X /* Compatibility.
X
diff -u --recursive --new-file v2.4.0-test8/linux/net/sunrpc/auth_unix.c linux/net/sunrpc/auth_unix.c
--- v2.4.0-test8/linux/net/sunrpc/auth_unix.c Mon Mar 20 08:14:04 2000
+++ linux/net/sunrpc/auth_unix.c Mon Sep 25 13:13:53 2000
@@ -180,7 +180,8 @@
X memcpy(p, clnt->cl_nodename, n);
X p += (n + 3) >> 2;
X
- if (ruid) {
+ /* Note: we don't use real uid if it involves raising priviledge */
+ if (ruid && cred->uc_uid != 0 && cred->uc_gid != 0) {
X *p++ = htonl((u32) cred->uc_uid);
X *p++ = htonl((u32) cred->uc_gid);
X } else {
diff -u --recursive --new-file v2.4.0-test8/linux/net/sunrpc/clnt.c linux/net/sunrpc/clnt.c
--- v2.4.0-test8/linux/net/sunrpc/clnt.c Fri Jul 7 15:57:49 2000
+++ linux/net/sunrpc/clnt.c Mon Sep 25 13:13:53 2000
@@ -708,7 +708,7 @@
X * The following is an NFS-specific hack to cater for setuid
X * processes whose uid is mapped to nobody on the server.
X */
- if (task->tk_client->cl_prog == NFS_PROGRAM &&
+ if (task->tk_client->cl_droppriv &&
X (ntohl(*p) == NFSERR_ACCES || ntohl(*p) == NFSERR_PERM)) {
X if (RPC_IS_SETUID(task) && task->tk_suid_retry) {
X dprintk("RPC: %4d retry squashed uid\n", task->tk_pid);
@@ -824,6 +824,7 @@
X case RPC_AUTH_TOOWEAK:
X printk(KERN_NOTICE "call_verify: server requires stronger "
X "authentication.\n");
+ break;
X default:
X printk(KERN_WARNING "call_verify: unknown auth error: %x\n", n);
X error = -EIO;
diff -u --recursive --new-file v2.4.0-test8/linux/net/sunrpc/sched.c linux/net/sunrpc/sched.c
--- v2.4.0-test8/linux/net/sunrpc/sched.c Wed Aug 23 09:50:19 2000
+++ linux/net/sunrpc/sched.c Sun Oct 1 20:35:16 2000
@@ -24,7 +24,7 @@
X
X #ifdef RPC_DEBUG
X #define RPCDBG_FACILITY RPCDBG_SCHED
-static int rpc_task_id = 0;
+static int rpc_task_id;


X #endif
X
X /*

@@ -56,7 +56,7 @@
X /*
X * All RPC tasks are linked into this list
X */
-static struct rpc_task * all_tasks = NULL;
+static struct rpc_task * all_tasks;
X
X /*
X * rpciod-related stuff
@@ -64,9 +64,9 @@
X static DECLARE_WAIT_QUEUE_HEAD(rpciod_idle);
X static DECLARE_WAIT_QUEUE_HEAD(rpciod_killer);
X static DECLARE_MUTEX(rpciod_sema);
-static unsigned int rpciod_users = 0;
-static pid_t rpciod_pid = 0;
-static int rpc_inhibit = 0;
+static unsigned int rpciod_users;
+static pid_t rpciod_pid;
+static int rpc_inhibit;
X
X /*
X * Spinlock for wait queues. Access to the latter also has to be
@@ -82,7 +82,7 @@
X * This is the last-ditch buffer for NFS swap requests
X */
X static u32 swap_buffer[PAGE_SIZE >> 2];
-static int swap_buffer_used = 0;
+static int swap_buffer_used;
X
X /*
X * Make allocation of the swap_buffer SMP-safe
diff -u --recursive --new-file v2.4.0-test8/linux/net/sunrpc/sysctl.c linux/net/sunrpc/sysctl.c
--- v2.4.0-test8/linux/net/sunrpc/sysctl.c Fri Apr 21 16:08:52 2000
+++ linux/net/sunrpc/sysctl.c Sun Oct 1 20:35:16 2000
@@ -25,14 +25,14 @@
X /*
X * Declare the debug flags here
X */
-unsigned int rpc_debug = 0;
-unsigned int nfs_debug = 0;
-unsigned int nfsd_debug = 0;
-unsigned int nlm_debug = 0;
+unsigned int rpc_debug;
+unsigned int nfs_debug;
+unsigned int nfsd_debug;
+unsigned int nlm_debug;
X
X #ifdef RPC_DEBUG
X
-static struct ctl_table_header *sunrpc_table_header = NULL;
+static struct ctl_table_header *sunrpc_table_header;
X static ctl_table sunrpc_table[];
X
X void
diff -u --recursive --new-file v2.4.0-test8/linux/net/sunrpc/xprt.c linux/net/sunrpc/xprt.c
--- v2.4.0-test8/linux/net/sunrpc/xprt.c Tue Jul 18 12:39:29 2000
+++ linux/net/sunrpc/xprt.c Mon Sep 18 15:19:49 2000
@@ -1037,7 +1037,7 @@
X return;
X
X /* Wait until we have enough socket memory */
- if (sock_wspace(sk) < min(sk->sndbuf,XPRT_MIN_WRITE_SPACE))
+ if (!sock_writeable(sk))
X return;
X
X spin_lock_bh(&xprt_sock_lock);
@@ -1212,9 +1212,6 @@
X */
X while (1) {
X xprt->write_space = 0;
- status = -ENOMEM;
- if (sock_wspace(xprt->inet) < req->rq_slen + SOCK_MIN_WRITE_SPACE)
- break;
X status = xprt_sendmsg(xprt, req);


X
X if (status < 0)

diff -u --recursive --new-file v2.4.0-test8/linux/net/x25/af_x25.c linux/net/x25/af_x25.c
--- v2.4.0-test8/linux/net/x25/af_x25.c Mon Aug 28 21:16:05 2000
+++ linux/net/x25/af_x25.c Sun Sep 17 10:03:43 2000
@@ -21,6 +21,8 @@
X * facilities negotiation and increased
X * the throughput upper limit.
X * 2000-27-08 Arnaldo C. Melo s/suser/capable/ + micro cleanups
+ * 2000-04-09 Henner Eisen Set sock->state in x25_accept().
+ * Fixed x25_output() related skb leakage.
X */
X
X #include <linux/config.h>
@@ -721,6 +723,7 @@
X kfree_skb(skb);
X sk->ack_backlog--;
X newsock->sk = newsk;
+ newsock->state = SS_CONNECTED;
X
X return 0;
X }
@@ -971,7 +974,11 @@
X if (msg->msg_flags & MSG_OOB) {
X skb_queue_tail(&sk->protinfo.x25->interrupt_out_queue, skb);
X } else {
- x25_output(sk, skb);
+ err = x25_output(sk, skb);
+ if(err){
+ len = err;
+ kfree_skb(skb);
+ }
X }
X
X x25_kick(sk);
diff -u --recursive --new-file v2.4.0-test8/linux/net/x25/x25_dev.c linux/net/x25/x25_dev.c
--- v2.4.0-test8/linux/net/x25/x25_dev.c Mon Aug 23 10:01:02 1999
+++ linux/net/x25/x25_dev.c Sun Sep 17 10:03:43 2000
@@ -14,6 +14,7 @@
X *
X * History
X * X.25 001 Jonathan Naylor Started coding.
+ * 2000-09-04 Henner Eisen Prevent freeing a dangling skb.
X */
X
X #include <linux/config.h>
@@ -78,12 +79,13 @@
X return x25_rx_call_request(skb, neigh, lci);
X
X /*
- * Its not a Call Request, nor is it a control frame, throw it awa
+ * Its not a Call Request, nor is it a control frame.
+ * Let caller throw it away.
X */
X /*
X x25_transmit_clear_request(neigh, lci, 0x0D);
X */
- kfree_skb(skb);
+ printk(KERN_DEBUG "x25_receive_data(): unknown frame type %2x\n",frametype);
X
X return 0;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/net/x25/x25_link.c linux/net/x25/x25_link.c
--- v2.4.0-test8/linux/net/x25/x25_link.c Fri Apr 14 09:38:10 2000
+++ linux/net/x25/x25_link.c Sun Sep 17 10:03:43 2000
@@ -17,6 +17,7 @@
X * X.25 002 Jonathan Naylor New timer architecture.
X * mar/20/00 Daniela Squassoni Disabling/enabling of facilities
X * negotiation.
+ * 2000-09-04 Henner Eisen dev_hold() / dev_put() for x25_neigh.
X */
X
X #include <linux/config.h>


@@ -292,6 +293,7 @@
X

X init_timer(&x25_neigh->t20timer);
X
+ dev_hold(dev);
X x25_neigh->dev = dev;
X x25_neigh->state = X25_LINK_STATE_0;
X x25_neigh->extended = 0;
@@ -349,8 +351,10 @@
X neigh = x25_neigh;
X x25_neigh = x25_neigh->next;
X
- if (neigh->dev == dev)
+ if (neigh->dev == dev){
X x25_remove_neigh(neigh);
+ dev_put(dev);
+ }
X }
X }
X
diff -u --recursive --new-file v2.4.0-test8/linux/net/x25/x25_out.c linux/net/x25/x25_out.c
--- v2.4.0-test8/linux/net/x25/x25_out.c Tue Feb 10 13:07:49 1998
+++ linux/net/x25/x25_out.c Sun Sep 17 10:03:43 2000
@@ -15,6 +15,7 @@
X * History
X * X.25 001 Jonathan Naylor Started coding.
X * X.25 002 Jonathan Naylor New timer architecture.
+ * 2000-09-04 Henner Eisen Prevented x25_output() skb leakage.
X */
X
X #include <linux/config.h>
@@ -56,7 +57,7 @@
X /*
X * This is where all X.25 information frames pass;
X */
-void x25_output(struct sock *sk, struct sk_buff *skb)
+int x25_output(struct sock *sk, struct sk_buff *skb)
X {
X struct sk_buff *skbn;
X unsigned char header[X25_EXT_MIN_LEN];
@@ -73,9 +74,12 @@
X frontlen = skb_headroom(skb);
X
X while (skb->len > 0) {
- if ((skbn = sock_alloc_send_skb(sk, frontlen + max_len, 0, 0, &err)) == NULL)
- return;
-
+ if ((skbn = sock_alloc_send_skb(sk, frontlen + max_len, 0, 0, &err)) == NULL){
+ int unsent = skb->len - header_len;
+ SOCK_DEBUG(sk, "x25_output: framgent allocation failed, err=%d, %d bytes unsent\n", err, unsent);

+ return err;
+ }
+

X skb_reserve(skbn, frontlen);
X
X len = (max_len > skb->len) ? skb->len : max_len;
@@ -102,6 +106,7 @@
X } else {
X skb_queue_tail(&sk->write_queue, skb);
X }
+ return 0;
X }
X
X /*
diff -u --recursive --new-file v2.4.0-test8/linux/scripts/Configure linux/scripts/Configure
--- v2.4.0-test8/linux/scripts/Configure Fri Aug 4 18:38:44 2000
+++ linux/scripts/Configure Thu Sep 21 13:20:16 2000
@@ -570,7 +570,7 @@
X if [ ! -f .hdepend -o "$CONFIG_MODVERSIONS" = "y" ] ; then
X echo "*** Next, you must run 'make dep'."
X else
- echo "*** Next, you may run 'make zImage', 'make zdisk', or 'make zlilo'."
+ echo "*** Next, you may run 'make bzImage', 'make bzdisk', or 'make install'."
X fi
X echo
X
diff -u --recursive --new-file v2.4.0-test8/linux/scripts/ksymoops/README linux/scripts/ksymoops/README
--- v2.4.0-test8/linux/scripts/ksymoops/README Thu Jul 1 10:54:31 1999
+++ linux/scripts/ksymoops/README Tue Oct 3 09:24:41 2000
@@ -1,7 +1,8 @@
X ksymoops has been removed from the kernel. It was always meant to be a
X free standing utility, not linked to any particular kernel version.
-The latest version can be found in ftp://ftp.ocs.com.au/pub/ksymoops,
-together with patches to other utilities in order to give more accurate
-Oops debugging.
+The latest version can be found in
+ftp://ftp.<country>.kernel.org/pub/linux/utils/kernel/ksymoops together
+with patches to other utilities in order to give more accurate Oops
+debugging.
X
X Keith Owens <ka...@ocs.com.au> Sat Jun 19 10:30:34 EST 1999
diff -u --recursive --new-file v2.4.0-test8/linux/scripts/makelst linux/scripts/makelst
--- v2.4.0-test8/linux/scripts/makelst Wed Dec 31 16:00:00 1969
+++ linux/scripts/makelst Mon Sep 18 14:59:23 2000
@@ -0,0 +1,21 @@
+#!/bin/bash
+# A script to dump mixed source code & assembly
+# with correct relocations from System.map
+# Requires the following lines in Rules.make.
+#
+#%.lst: %.c
+# $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -g -c -o $*.o $<
+# $(TOPDIR)/scripts/makelst $* $(TOPDIR) $(OBJDUMP)
+#
+# Copyright (C) 2000 IBM Corporation
+# Author(s): DJ Barrow (djba...@de.ibm.com,barr...@yahoo.com)
+#
+
+t1=`$3 --syms $2/$1.o | grep .text | grep " F " | head -n 1`
+t2=`echo $t1 | gawk '{ print $6 }'`
+t3=`grep $t2 $2/System.map`
+t4=`echo $t3 | gawk '{ print $1 }'`
+t5=`echo $t1 | gawk '{ print $1 }'`
+t6=`echo $t4 - $t5 | sed s/a/A/g | sed s/b/B/g | sed s/c/C/g | sed s/d/D/g | sed s/e/E/g | sed s/f/F/g`
+t7=`( echo ibase=16 ; echo $t6 ) | bc`
+$3 --source --adjust-vma=$t7 $2/$1.o > $2/$1.lst
diff -u --recursive --new-file v2.4.0-test8/linux/scripts/mkdep.c linux/scripts/mkdep.c
--- v2.4.0-test8/linux/scripts/mkdep.c Wed May 24 08:29:47 2000
+++ linux/scripts/mkdep.c Wed Sep 27 14:09:30 2000
@@ -81,15 +81,9 @@
X */
X void grow_config(int len)
X {
- if (str_config == NULL) {
- len_config = 0;
- size_config = 4096;
- str_config = malloc(4096);
- if (str_config == NULL)
- { perror("malloc"); exit(1); }
- }
-
X while (len_config + len > size_config) {
+ if (size_config == 0)
+ size_config = 2048;
X str_config = realloc(str_config, size_config *= 2);
X if (str_config == NULL)
X { perror("malloc config"); exit(1); }
@@ -157,15 +151,9 @@
X */
X void grow_precious(int len)
X {
- if (str_precious == NULL) {
- len_precious = 0;
- size_precious = 4096;
- str_precious = malloc(4096);
- if (str_precious == NULL)
- { perror("malloc precious"); exit(1); }
- }
-
X while (len_precious + len > size_precious) {
+ if (size_precious == 0)
+ size_precious = 2048;
X str_precious = realloc(str_precious, size_precious *= 2);
X if (str_precious == NULL)
X { perror("malloc"); exit(1); }
@@ -294,6 +282,7 @@
X * The state machine looks for (approximately) these Perl regular expressions:
X *
X * m|\/\*.*?\*\/|
+ * m|\/\/.*|
X * m|'.*?'|
X * m|".*?"|
X * m|#\s*include\s*"(.*?)"|
@@ -326,9 +315,18 @@
X CASE('C', cee);
X goto start;
X
+/* // */
+slash_slash:
+ GETNEXT
+ CASE('\n', start);
+ NOTCASE('\\', slash_slash);
+ GETNEXT
+ goto slash_slash;
+
X /* / */
X slash:
X GETNEXT
+ CASE('/', slash_slash);
X NOTCASE('*', __start);
X slash_star_dot_star:
X GETNEXT
diff -u --recursive --new-file v2.4.0-test8/linux/scripts/ver_linux linux/scripts/ver_linux
--- v2.4.0-test8/linux/scripts/ver_linux Tue Dec 14 23:05:03 1999
+++ linux/scripts/ver_linux Sun Sep 17 09:45:06 2000
@@ -10,6 +10,8 @@
X uname -a
X insmod -V 2>&1 | awk 'NR==1 {print "Kernel modules ",$NF}'
X echo "Gnu C " `gcc --version`
+make --version 2>&1 | awk -F, '{print $1}' | awk \
+ '/GNU Make/{print "Gnu Make ",$NF}'
X ld -v 2>&1 | awk -F\) '{print $1}' | awk \
X '/BFD/{print "Binutils ",$NF}'
X ls -l `ldd /bin/sh | awk '/libc/{print $3}'` | sed -e 's/\.so$//' \


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'

echo 'File patch-2.4.0-test9 is complete' &&
chmod 644 patch-2.4.0-test9 ||


echo 'restore of patch-2.4.0-test9 failed'

Cksum="`cksum < 'patch-2.4.0-test9'`"
if ! test "833867922 6409766" = "$Cksum" ; then
echo 'patch-2.4.0-test9: original Checksum 833867922 6409766, current one' "$Cksum"
rm -f _shar_wnt_.tmp
rm -f _shar_seq_.tmp
exit 1
fi
rm -f _shar_wnt_.tmp
fi
rm -f _shar_seq_.tmp
echo 'You have unpacked the last part.'
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part111

#!/bin/sh -x
# this is part 111 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 111; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

- return 1;
+ /*
+ * We only need the pagemap_lru_lock if we don't reclaim the page,
+ * but we have to grab the pagecache_lock before the pagemap_lru_lock
+ * to avoid deadlocks and most of the time we'll succeed anyway.
+ */
+ spin_lock(&pagecache_lock);
+ spin_lock(&pagemap_lru_lock);
+ maxscan = zone->inactive_clean_pages;
+ while ((page_lru = zone->inactive_clean_list.prev) !=
+ &zone->inactive_clean_list && maxscan--) {
+ page = list_entry(page_lru, struct page, lru);
+
+ /* Wrong page on list?! (list corruption, should not happen) */
+ if (!PageInactiveClean(page)) {
+ printk("VM: reclaim_page, wrong page on list.\n");
+ list_del(page_lru);
+ page->zone->inactive_clean_pages--;
+ continue;
X }
- pgdat = pgdat->node_next;
- } while (pgdat);
X
- return 0;
+ /* Page is or was in use? Move it to the active list. */
+ if (PageTestandClearReferenced(page) || page->age > 0 ||
+ (!page->buffers && page_count(page) > 1)) {
+ del_page_from_inactive_clean_list(page);
+ add_page_to_active_list(page);
+ continue;
+ }
+
+ /* The page is dirty, or locked, move to inactive_diry list. */
+ if (page->buffers || TryLockPage(page)) {
+ del_page_from_inactive_clean_list(page);
+ add_page_to_inactive_dirty_list(page);
+ continue;
+ }
+
+ /* OK, remove the page from the caches. */
+ if (PageSwapCache(page)) {
+ __delete_from_swap_cache(page);
+ goto found_page;
+ }
+
+ if (page->mapping) {
+ __remove_inode_page(page);
+ goto found_page;
+ }
+
+ /* We should never ever get here. */
+ printk(KERN_ERR "VM: reclaim_page, found unknown page\n");
+ list_del(page_lru);
+ zone->inactive_clean_pages--;
+ UnlockPage(page);
+ }
+ /* Reset page pointer, maybe we encountered an unfreeable page. */
+ page = NULL;
+ goto out;
+
+found_page:
+ del_page_from_inactive_clean_list(page);
+ UnlockPage(page);


+ page->age = PAGE_AGE_START;

+ if (page_count(page) != 1)
+ printk("VM: reclaim_page, found page with count %d!\n",
+ page_count(page));
+out:
+ spin_unlock(&pagemap_lru_lock);
+ spin_unlock(&pagecache_lock);
+ memory_pressure++;


+ return page;
+}
+

+/**
+ * page_launder - clean dirty inactive pages, move to inactive_clean list
+ * @gfp_mask: what operations we are allowed to do
+ * @sync: should we wait synchronously for the cleaning of pages
+ *
+ * When this function is called, we are most likely low on free +
+ * inactive_clean pages. Since we want to refill those pages as
+ * soon as possible, we'll make two loops over the inactive list,
+ * one to move the already cleaned pages to the inactive_clean lists
+ * and one to (often asynchronously) clean the dirty inactive pages.
+ *
+ * In situations where kswapd cannot keep up, user processes will
+ * end up calling this function. Since the user process needs to
+ * have a page before it can continue with its allocation, we'll
+ * do synchronous page flushing in that case.
+ *
+ * This code is heavily inspired by the FreeBSD source code. Thanks
+ * go out to Matthew Dillon.
+ */
+#define MAX_LAUNDER (4 * (1 << page_cluster))
+int page_launder(int gfp_mask, int sync)
+{
+ int launder_loop, maxscan, cleaned_pages, maxlaunder;
+ int can_get_io_locks;


+ struct list_head * page_lru;

+ struct page * page;
+

+ /*
+ * We can only grab the IO locks (eg. for flushing dirty
+ * buffers to disk) if __GFP_IO is set.
+ */
+ can_get_io_locks = gfp_mask & __GFP_IO;
+
+ launder_loop = 0;
+ maxlaunder = 0;
+ cleaned_pages = 0;
+
+dirty_page_rescan:
+ spin_lock(&pagemap_lru_lock);
+ maxscan = nr_inactive_dirty_pages;
+ while ((page_lru = inactive_dirty_list.prev) != &inactive_dirty_list &&
+ maxscan-- > 0) {
+ page = list_entry(page_lru, struct page, lru);
+
+ /* Wrong page on list?! (list corruption, should not happen) */
+ if (!PageInactiveDirty(page)) {
+ printk("VM: page_launder, wrong page on list.\n");
+ list_del(page_lru);
+ nr_inactive_dirty_pages--;
+ page->zone->inactive_dirty_pages--;
+ continue;
+ }
+
+ /* Page is or was in use? Move it to the active list. */
+ if (PageTestandClearReferenced(page) || page->age > 0 ||
+ (!page->buffers && page_count(page) > 1) ||
+ page_ramdisk(page)) {
+ del_page_from_inactive_dirty_list(page);
+ add_page_to_active_list(page);
+ continue;
+ }
+
+ /*
+ * The page is locked. IO in progress?
+ * Move it to the back of the list.
+ */
+ if (TryLockPage(page)) {
+ list_del(page_lru);
+ list_add(page_lru, &inactive_dirty_list);
+ continue;
+ }
+
+ /*
+ * If the page has buffers, try to free the buffer mappings
+ * associated with this page. If we succeed we either free
+ * the page (in case it was a buffercache only page) or we
+ * move the page to the inactive_clean list.
+ *
+ * On the first round, we should free all previously cleaned
+ * buffer pages
+ */
+ if (page->buffers) {
+ int wait, clearedbuf;
+ int freed_page = 0;
+ /*
+ * Since we might be doing disk IO, we have to
+ * drop the spinlock and take an extra reference
+ * on the page so it doesn't go away from under us.
+ */
+ del_page_from_inactive_dirty_list(page);
+ page_cache_get(page);
+ spin_unlock(&pagemap_lru_lock);
+
+ /* Will we do (asynchronous) IO? */
+ if (launder_loop && maxlaunder == 0 && sync)
+ wait = 2; /* Synchrounous IO */
+ else if (launder_loop && maxlaunder-- > 0)
+ wait = 1; /* Async IO */
+ else
+ wait = 0; /* No IO */
+
+ /* Try to free the page buffers. */
+ clearedbuf = try_to_free_buffers(page, wait);
+
+ /*
+ * Re-take the spinlock. Note that we cannot
+ * unlock the page yet since we're still
+ * accessing the page_struct here...
+ */
+ spin_lock(&pagemap_lru_lock);
+
+ /* The buffers were not freed. */
+ if (!clearedbuf) {
+ add_page_to_inactive_dirty_list(page);
+
+ /* The page was only in the buffer cache. */
+ } else if (!page->mapping) {
+ atomic_dec(&buffermem_pages);
+ freed_page = 1;
+ cleaned_pages++;
+
+ /* The page has more users besides the cache and us. */
+ } else if (page_count(page) > 2) {
+ add_page_to_active_list(page);
+
+ /* OK, we "created" a freeable page. */
+ } else /* page->mapping && page_count(page) == 2 */ {
+ add_page_to_inactive_clean_list(page);
+ cleaned_pages++;
+ }
+
+ /*
+ * Unlock the page and drop the extra reference.
+ * We can only do it here because we ar accessing
+ * the page struct above.
+ */
+ UnlockPage(page);
+ page_cache_release(page);
+
+ /*
+ * If we're freeing buffer cache pages, stop when
+ * we've got enough free memory.
+ */
+ if (freed_page && !free_shortage())
+ break;
+ continue;
+ } else if (page->mapping && !PageDirty(page)) {
+ /*
+ * If a page had an extra reference in
+ * deactivate_page(), we will find it here.
+ * Now the page is really freeable, so we
+ * move it to the inactive_clean list.
+ */
+ del_page_from_inactive_dirty_list(page);
+ add_page_to_inactive_clean_list(page);
+ UnlockPage(page);
+ cleaned_pages++;
+ } else {
+ /*
+ * OK, we don't know what to do with the page.
+ * It's no use keeping it here, so we move it to
+ * the active list.
+ */
+ del_page_from_inactive_dirty_list(page);
+ add_page_to_active_list(page);
+ UnlockPage(page);
+ }
+ }
+ spin_unlock(&pagemap_lru_lock);
+
+ /*
+ * If we don't have enough free pages, we loop back once
+ * to queue the dirty pages for writeout. When we were called
+ * by a user process (that /needs/ a free page) and we didn't
+ * free anything yet, we wait synchronously on the writeout of
+ * MAX_SYNC_LAUNDER pages.
+ *
+ * We also wake up bdflush, since bdflush should, under most
+ * loads, flush out the dirty pages before we have to wait on
+ * IO.
+ */
+ if (can_get_io_locks && !launder_loop && free_shortage()) {
+ launder_loop = 1;
+ /* If we cleaned pages, never do synchronous IO. */
+ if (cleaned_pages)
+ sync = 0;
+ /* We only do a few "out of order" flushes. */
+ maxlaunder = MAX_LAUNDER;
+ /* Kflushd takes care of the rest. */
+ wakeup_bdflush(0);
+ goto dirty_page_rescan;
+ }
+
+ /* Return the number of pages moved to the inactive_clean list. */
+ return cleaned_pages;
+}
+
+/**
+ * refill_inactive_scan - scan the active list and find pages to deactivate
+ * @priority: the priority at which to scan
+ * @oneshot: exit after deactivating one page
+ *
+ * This function will scan a portion of the active list to find
+ * unused pages, those pages will then be moved to the inactive list.
+ */
+int refill_inactive_scan(unsigned int priority, int oneshot)
+{


+ struct list_head * page_lru;

+ struct page * page;

+ int maxscan, page_active = 0;
+ int ret = 0;
+
+ /* Take the lock while messing with the list... */
+ spin_lock(&pagemap_lru_lock);
+ maxscan = nr_active_pages >> priority;
+ while (maxscan-- > 0 && (page_lru = active_list.prev) != &active_list) {
+ page = list_entry(page_lru, struct page, lru);
+
+ /* Wrong page on list?! (list corruption, should not happen) */
+ if (!PageActive(page)) {
+ printk("VM: refill_inactive, wrong page on list.\n");
+ list_del(page_lru);
+ nr_active_pages--;
+ continue;
+ }
+
+ /* Do aging on the pages. */
+ if (PageTestandClearReferenced(page)) {
+ age_page_up_nolock(page);
+ page_active = 1;
+ } else {
+ age_page_down_ageonly(page);
+ /*
+ * Since we don't hold a reference on the page
+ * ourselves, we have to do our test a bit more
+ * strict then deactivate_page(). This is needed
+ * since otherwise the system could hang shuffling
+ * unfreeable pages from the active list to the
+ * inactive_dirty list and back again...
+ *
+ * SUBTLE: we can have buffer pages with count 1.
+ */
+ if (page_count(page) <= (page->buffers ? 2 : 1)) {
+ deactivate_page_nolock(page);
+ page_active = 0;
+ } else {
+ page_active = 1;
+ }
+ }
+ /*
+ * If the page is still on the active list, move it
+ * to the other end of the list. Otherwise it was
+ * deactivated by age_page_down and we exit successfully.
+ */
+ if (page_active || PageActive(page)) {
+ list_del(page_lru);
+ list_add(page_lru, &active_list);
+ } else {
+ ret = 1;
+ if (oneshot)
+ break;
+ }
+ }
+ spin_unlock(&pagemap_lru_lock);
+
+ return ret;
X }
X
X /*
- * Check if all zones have recently had memory_pressure (zone_wake_kswapd)
+ * Check if there are zones with a severe shortage of free pages,
+ * or if all zones have a minor shortage.
X */
-static inline int keep_kswapd_awake(void)
+int free_shortage(void)
X {
- int all_recent = 1;
X pg_data_t *pgdat = pgdat_list;
+ int sum = 0;
+ int freeable = nr_free_pages() + nr_inactive_clean_pages();
+ int freetarget = freepages.high + inactive_target / 3;
+
+ /* Are we low on free pages globally? */
+ if (freeable < freetarget)
+ return freetarget - freeable;
X
+ /* If not, are we very low on any particular zone? */
X do {
X int i;
X for(i = 0; i < MAX_NR_ZONES; i++) {
X zone_t *zone = pgdat->node_zones+ i;
- if (zone->size) {
- if (zone->free_pages < zone->pages_min)
- return 1;
- if (!zone->zone_wake_kswapd)
- all_recent = 0;
+ if (zone->size && (zone->inactive_clean_pages +
+ zone->free_pages < zone->pages_min)) {
+ sum += zone->pages_min;
+ sum -= zone->free_pages;
+ sum -= zone->inactive_clean_pages;
X }
X }
X pgdat = pgdat->node_next;
X } while (pgdat);
X
- return all_recent;


+ return sum;
+}
+
+/*

+ * How many inactive pages are we short?
+ */
+int inactive_shortage(void)
+{
+ int shortage = 0;
+
+ shortage += freepages.high;
+ shortage += inactive_target;
+ shortage -= nr_free_pages();
+ shortage -= nr_inactive_clean_pages();
+ shortage -= nr_inactive_dirty_pages;
+
+ if (shortage > 0)
+ return shortage;
+
+ return 0;
X }
X
X /*
@@ -472,96 +876,140 @@
X * We want to try to free "count" pages, and we want to
X * cluster them so that we get good swap-out behaviour.
X *
- * Don't try _too_ hard, though. We don't want to have bad
- * latency.
- *
- * Note: only called by kswapd and try_to_free_pages
- * both can WAIT at top level.
+ * OTOH, if we're a user process (and not kswapd), we
+ * really care about latency. In that case we don't try
+ * to free too many pages.
X */
-#define FREE_COUNT 8
-#define SWAP_COUNT 16
-static int do_try_to_free_pages(unsigned int gfp_mask)
-{
- int priority;
- int count = FREE_COUNT;
- int swap_count;
+static int refill_inactive(unsigned int gfp_mask, int user)
+{
+ int priority, count, start_count, made_progress;
+ unsigned long idle_time;
+
+ count = inactive_shortage() + free_shortage();
+ if (user)
+ count = (1 << page_cluster);
+ start_count = count;
X
X /* Always trim SLAB caches when memory gets low. */
X kmem_cache_reap(gfp_mask);
X
- priority = 64;
+ /*
+ * Calculate the minimum time (in seconds) a process must
+ * have slept before we consider it for idle swapping.
+ * This must be the number of seconds it takes to go through
+ * all of the cache. Doing this idle swapping makes the VM
+ * smoother once we start hitting swap.
+ */
+ idle_time = atomic_read(&page_cache_size);
+ idle_time += atomic_read(&buffermem_pages);
+ idle_time /= (inactive_target + 1);
+
+ priority = 6;
X do {
+ made_progress = 0;
+
X if (current->need_resched) {
+ __set_current_state(TASK_RUNNING);
X schedule();
- /* time has passed - pressure too? */
- if (!memory_pressure())
- goto done;
X }
X
- while (shrink_mmap(priority, gfp_mask)) {
- if (!--count)
+ while (refill_inactive_scan(priority, 1) ||
+ swap_out(priority, gfp_mask, idle_time)) {
+ made_progress = 1;
+ if (--count <= 0)
X goto done;
X }
X
- /* check if mission completed */
- if (!keep_kswapd_awake())
- goto done;
+ /*
+ * don't be too light against the d/i cache since
+ * refill_inactive() almost never fail when there's
+ * really plenty of memory free.
+ */
+ shrink_dcache_memory(priority, gfp_mask);
+ shrink_icache_memory(priority, gfp_mask);
X
X /* Try to get rid of some shared memory pages.. */
- if (gfp_mask & __GFP_IO) {
- /*
- * don't be too light against the d/i cache since
- * shrink_mmap() almost never fail when there's
- * really plenty of memory free.
- */
- count -= shrink_dcache_memory(priority, gfp_mask);
- count -= shrink_icache_memory(priority, gfp_mask);
- /*
- * Not currently working, see fixme in shrink_?cache_memory
- * In the inner funtions there is a comment:
- * "To help debugging, a zero exit status indicates
- * all slabs were released." (-arca?)
- * lets handle it in a primitive but working way...
- * if (count <= 0)
- * goto done;
- */
- if (!keep_kswapd_awake())
+ while (shm_swap(priority, gfp_mask)) {
+ made_progress = 1;
+ if (--count <= 0)
X goto done;
-
- while (shm_swap(priority, gfp_mask)) {
- if (!--count)
- goto done;
- }
X }
X
X /*
X * Then, try to page stuff out..
- *
- * This will not actually free any pages (they get
- * put in the swap cache), so we must not count this
- * as a "count" success.
- */
- swap_count = SWAP_COUNT;
- while (swap_out(priority, gfp_mask))
- if (--swap_count < 0)
- break;
+ */
+ while (swap_out(priority, gfp_mask, 0)) {
+ made_progress = 1;
+ if (--count <= 0)
+ goto done;
+ }
X
- } while (--priority >= 0);
+ /*
+ * If we either have enough free memory, or if
+ * page_launder() will be able to make enough
+ * free memory, then stop.
+ */
+ if (!inactive_shortage() || !free_shortage())
+ goto done;
X
- /* Always end on a shrink_mmap.., may sleep... */
- while (shrink_mmap(0, gfp_mask)) {
- if (!--count)
+ /*
+ * Only switch to a lower "priority" if we
+ * didn't make any useful progress in the
+ * last loop.
+ */
+ if (!made_progress)
+ priority--;
+ } while (priority >= 0);
+
+ /* Always end on a refill_inactive.., may sleep... */
+ while (refill_inactive_scan(0, 1)) {
+ if (--count <= 0)
X goto done;
X }
- /* Return 1 if any page is freed, or
- * there are no more memory pressure */
- return (count < FREE_COUNT || !keep_kswapd_awake());
-
+
X done:
- return 1;
+ return (count < start_count);
+}
+
+static int do_try_to_free_pages(unsigned int gfp_mask, int user)
+{
+ int ret = 0;
+
+ /*
+ * If we're low on free pages, move pages from the
+ * inactive_dirty list to the inactive_clean list.
+ *
+ * Usually bdflush will have pre-cleaned the pages
+ * before we get around to moving them to the other
+ * list, so this is a relatively cheap operation.
+ */
+ if (free_shortage() || nr_inactive_dirty_pages > nr_free_pages() +
+ nr_inactive_clean_pages())
+ ret += page_launder(gfp_mask, user);
+
+ /*
+ * If needed, we move pages from the active list
+ * to the inactive list. We also "eat" pages from
+ * the inode and dentry cache whenever we do this.
+ */
+ if (free_shortage() || inactive_shortage()) {
+ shrink_dcache_memory(6, gfp_mask);
+ shrink_icache_memory(6, gfp_mask);
+ ret += refill_inactive(gfp_mask, user);
+ } else {
+ /*
+ * Reclaim unused slab cache memory.
+ */
+ kmem_cache_reap(gfp_mask);
+ ret = 1;
+ }
+


+ return ret;
X }
X

X DECLARE_WAIT_QUEUE_HEAD(kswapd_wait);
+DECLARE_WAIT_QUEUE_HEAD(kswapd_done);
+struct task_struct *kswapd_task;
X
X /*
X * The background pageout daemon, started as a kernel thread
@@ -584,6 +1032,7 @@
X tsk->pgrp = 1;
X strcpy(tsk->comm, "kswapd");
X sigfillset(&tsk->blocked);
+ kswapd_task = tsk;
X
X /*
X * Tell the memory management that we're a "memory allocator",
@@ -599,54 +1048,166 @@
X */
X tsk->flags |= PF_MEMALLOC;
X
+ /*
+ * Kswapd main loop.
+ */
X for (;;) {
- if (!keep_kswapd_awake()) {
- interruptible_sleep_on(&kswapd_wait);
+ static int recalc = 0;
+
+ /* If needed, try to free some memory. */
+ if (inactive_shortage() || free_shortage()) {
+ int wait = 0;
+ /* Do we need to do some synchronous flushing? */
+ if (waitqueue_active(&kswapd_done))
+ wait = 1;
+ do_try_to_free_pages(GFP_KSWAPD, wait);
+ }
+
+ /*
+ * Do some (very minimal) background scanning. This
+ * will scan all pages on the active list once
+ * every minute. This clears old referenced bits
+ * and moves unused pages to the inactive list.
+ */
+ refill_inactive_scan(6, 0);
+
+ /* Once a second, recalculate some VM stats. */
+ if (time_after(jiffies, recalc + HZ)) {
+ recalc = jiffies;
+ recalculate_vm_stats();
X }
X
- do_try_to_free_pages(GFP_KSWAPD);
+ /*
+ * Wake up everybody waiting for free memory
+ * and unplug the disk queue.
+ */
+ wake_up_all(&kswapd_done);
+ run_task_queue(&tq_disk);
+
+ /*
+ * We go to sleep if either the free page shortage
+ * or the inactive page shortage is gone. We do this
+ * because:
+ * 1) we need no more free pages or
+ * 2) the inactive pages need to be flushed to disk,
+ * it wouldn't help to eat CPU time now ...
+ *
+ * We go to sleep for one second, but if it's needed
+ * we'll be woken up earlier...
+ */
+ if (!free_shortage() || !inactive_shortage())
+ interruptible_sleep_on_timeout(&kswapd_wait, HZ);
+ /*
+ * TODO: insert out of memory check & oom killer
+ * invocation in an else branch here.


+ */
+ }
+}
+

+void wakeup_kswapd(int block)
+{
+ DECLARE_WAITQUEUE(wait, current);
+
+ if (current == kswapd_task)
+ return;
+
+ if (!block) {
+ if (waitqueue_active(&kswapd_wait))
+ wake_up(&kswapd_wait);
+ return;
X }
+
+ /*
+ * Kswapd could wake us up before we get a chance
+ * to sleep, so we have to be very careful here to
+ * prevent SMP races...
+ */
+ __set_current_state(TASK_UNINTERRUPTIBLE);
+ add_wait_queue(&kswapd_done, &wait);
+
+ if (waitqueue_active(&kswapd_wait))
+ wake_up(&kswapd_wait);
+ schedule();
+
+ remove_wait_queue(&kswapd_done, &wait);
+ __set_current_state(TASK_RUNNING);
X }
X
X /*
X * Called by non-kswapd processes when they want more
- * memory.
- *
- * In a perfect world, this should just wake up kswapd
- * and return. We don't actually want to swap stuff out
- * from user processes, because the locking issues are
- * nasty to the extreme (file write locks, and MM locking)
- *
- * One option might be to let kswapd do all the page-out
- * and VM page table scanning that needs locking, and this
- * process thread could do just the mmap shrink stage that
- * can be done by just dropping cached pages without having
- * any deadlock issues.
+ * memory but are unable to sleep on kswapd because
+ * they might be holding some IO locks ...
X */
X int try_to_free_pages(unsigned int gfp_mask)
X {
- int retval = 1;
+ int ret = 1;
X
X if (gfp_mask & __GFP_WAIT) {


- current->state = TASK_RUNNING;

X current->flags |= PF_MEMALLOC;
- retval = do_try_to_free_pages(gfp_mask);
+ ret = do_try_to_free_pages(gfp_mask, 1);
X current->flags &= ~PF_MEMALLOC;
X }
X
- /* someone needed memory that kswapd had not provided
- * make sure kswapd runs, should not happen often */


- if (waitqueue_active(&kswapd_wait))
- wake_up_interruptible(&kswapd_wait);

+ return ret;
+}
+
+DECLARE_WAIT_QUEUE_HEAD(kreclaimd_wait);
+/*
+ * Kreclaimd will move pages from the inactive_clean list to the
+ * free list, in order to keep atomic allocations possible under
+ * all circumstances. Even when kswapd is blocked on IO.
+ */
+int kreclaimd(void *unused)
+{
+ struct task_struct *tsk = current;
+ pg_data_t *pgdat;
X
- return retval;
+ tsk->session = 1;
+ tsk->pgrp = 1;
+ strcpy(tsk->comm, "kreclaimd");
+ sigfillset(&tsk->blocked);
+ current->flags |= PF_MEMALLOC;
+
+ while (1) {
+
+ /*
+ * We sleep until someone wakes us up from
+ * page_alloc.c::__alloc_pages().
+ */
+ interruptible_sleep_on(&kreclaimd_wait);
+
+ /*
+ * Move some pages from the inactive_clean lists to
+ * the free lists, if it is needed.
+ */
+ pgdat = pgdat_list;
+ do {
+ int i;
+ for(i = 0; i < MAX_NR_ZONES; i++) {
+ zone_t *zone = pgdat->node_zones + i;
+ if (!zone->size)
+ continue;
+
+ while (zone->free_pages < zone->pages_low) {


+ struct page * page;

+ page = reclaim_page(zone);


+ if (!page)
+ break;
+ __free_page(page);
+ }

+ }
+ pgdat = pgdat->node_next;
+ } while (pgdat);
+ }
X }
X
+
X static int __init kswapd_init(void)
X {
- printk("Starting kswapd v1.7\n");
+ printk("Starting kswapd v1.8\n");
X swap_setup();
X kernel_thread(kswapd, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);
+ kernel_thread(kreclaimd, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);


X return 0;
X }
X

diff -u --recursive --new-file v2.4.0-test8/linux/net/Makefile linux/net/Makefile
--- v2.4.0-test8/linux/net/Makefile Sun Aug 6 11:23:41 2000
+++ linux/net/Makefile Wed Sep 27 14:14:34 2000
@@ -1,217 +1,70 @@
X #
X # Makefile for the linux networking.


X #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here

-# unless it's something special (ie not a .c file).
+# 2 Sep 2000, Christoph Hellwig <h...@caldera.de>


+# Rewritten to use lists instead of if-statements.

X #
-# Note 2! The CFLAGS definition is now in the main makefile...
X
-MOD_SUB_DIRS := ipv4
-ALL_SUB_DIRS := 802 ax25 bridge core ethernet ipv4 ipv6 ipx unix appletalk \
- netrom rose lapb x25 wanrouter netlink sched packet sunrpc \
- econet irda decnet atm khttpd ipv4/netfilter ipv6/netfilter
-SUB_DIRS := core ethernet
+O_TARGET := network.o
X
-ifeq ($(CONFIG_NET),y)
-SUB_DIRS += 802 sched
-endif
-
-ifeq ($(CONFIG_INET),y)
-SUB_DIRS += ipv4
-ifeq ($(CONFIG_NETFILTER),y)
-SUB_DIRS += ipv4/netfilter
-MOD_SUB_DIRS += ipv4/netfilter
-endif
-endif
-
-ifeq ($(CONFIG_UNIX),y)
-SUB_DIRS += unix
-else
- ifeq ($(CONFIG_UNIX),m)
- MOD_SUB_DIRS += unix
- endif
-endif
-
-ifeq ($(CONFIG_IPV6),y)
-SUB_DIRS += ipv6
-ifeq ($(CONFIG_NETFILTER),y)
-SUB_DIRS += ipv6/netfilter
-MOD_SUB_DIRS += ipv6/netfilter
-endif
-else
- ifeq ($(CONFIG_IPV6),m)
- MOD_SUB_DIRS += ipv6
- ifeq ($(CONFIG_NETFILTER),y)
- MOD_SUB_DIRS += ipv6/netfilter
- endif
- endif
-endif
-
-ifeq ($(CONFIG_KHTTPD),y)
-SUB_DIRS += khttpd
-else
- ifeq ($(CONFIG_KHTTPD),m)
- MOD_SUB_DIRS += khttpd
- endif
-endif
-
-ifeq ($(CONFIG_NETLINK),y)
-SUB_DIRS += netlink
- ifeq ($(CONFIG_NETLINK_DEV),m)
- MOD_SUB_DIRS += netlink
- endif
-endif
-
-ifeq ($(CONFIG_PACKET),y)
-SUB_DIRS += packet
-else
- ifeq ($(CONFIG_PACKET),m)
- MOD_SUB_DIRS += packet
- endif
-endif
-
-ifeq ($(CONFIG_NET_SCHED),y)
- MOD_SUB_DIRS += sched
-endif
-
-ifeq ($(CONFIG_BRIDGE),y)
-SUB_DIRS += bridge
-else
- ifeq ($(CONFIG_BRIDGE),m)
- MOD_SUB_DIRS += bridge
- endif
-endif
-
-ifeq ($(CONFIG_IPX),y)
-SUB_DIRS += ipx
-# SPX can be still a module
-MOD_SUB_DIRS += ipx
-else
- ifeq ($(CONFIG_IPX),m)
- MOD_SUB_DIRS += ipx
- endif
-endif
-
-ifeq ($(CONFIG_ATALK),y)
-SUB_DIRS += appletalk
-else
- ifeq ($(CONFIG_ATALK),m)
- MOD_SUB_DIRS += appletalk
- endif
-endif
-
-ifeq ($(CONFIG_WAN_ROUTER),y)
-SUB_DIRS += wanrouter
-else
- ifeq ($(CONFIG_WAN_ROUTER),m)
- MOD_SUB_DIRS += wanrouter
- endif
-endif
+mod-subdirs := ipv4/netfilter ipv6/netfilter ipx irda atm
+export-objs := netsyms.o
X
-ifeq ($(CONFIG_X25),y)
-SUB_DIRS += x25
-else
- ifeq ($(CONFIG_X25),m)
- MOD_SUB_DIRS += x25
- endif
-endif
-
-ifeq ($(CONFIG_LAPB),y)
-SUB_DIRS += lapb
-else
- ifeq ($(CONFIG_LAPB),m)
- MOD_SUB_DIRS += lapb
- endif
-endif
+subdir-y := core ethernet
+subdir-m := ipv4 # hum?
X
-ifeq ($(CONFIG_NETROM),y)
-SUB_DIRS += netrom
-else
- ifeq ($(CONFIG_NETROM),m)
- MOD_SUB_DIRS += netrom
- endif
-endif
X
-ifeq ($(CONFIG_ROSE),y)
-SUB_DIRS += rose
-else
- ifeq ($(CONFIG_ROSE),m)
- MOD_SUB_DIRS += rose
- endif
+subdir-$(CONFIG_NET) += 802 sched
+subdir-$(CONFIG_INET) += ipv4
+subdir-$(CONFIG_NETFILTER) += ipv4/netfilter
+subdir-$(CONFIG_UNIX) += unix
+subdir-$(CONFIG_IPV6) += ipv6
+
+ifneq ($(CONFIG_IPV6),n)
+ifneq ($(CONFIG_IPV6),)
+subdir-$(CONFIG_NETFILTER) += ipv6/netfilter
X endif
-
-ifeq ($(CONFIG_AX25),y)
-SUB_DIRS += ax25
-else
- ifeq ($(CONFIG_AX25),m)
- MOD_SUB_DIRS += ax25
- endif
X endif
X
-ifeq ($(CONFIG_IRDA),y)
-SUB_DIRS += irda
-# There might be some irda features that are compiled as modules
-MOD_IN_SUB_DIRS += irda
-else
- ifeq ($(CONFIG_IRDA),m)
- MOD_SUB_DIRS += irda
- endif
-endif
+subdir-$(CONFIG_KHTTPD) += khttpd
+subdir-$(CONFIG_NETLINK) += netlink
+subdir-$(CONFIG_PACKET) += packet
+subdir-$(CONFIG_NET_SCHED) += sched
+subdir-$(CONFIG_BRIDGE) += bridge
+subdir-$(CONFIG_IPX) += ipx
+subdir-$(CONFIG_ATALK) += appletalk
+subdir-$(CONFIG_WAN_ROUTER) += wanrouter
+subdir-$(CONFIG_X25) += x25
+subdir-$(CONFIG_LAPB) += lapb
+subdir-$(CONFIG_NETROM) += netrom
+subdir-$(CONFIG_ROSE) += rose
+subdir-$(CONFIG_AX25) += ax25
+subdir-$(CONFIG_IRDA) += irda
+subdir-$(CONFIG_SUNRPC) += sunrpc
+subdir-$(CONFIG_ATM) += atm
+subdir-$(CONFIG_DECNET) += decnet
+subdir-$(CONFIG_ECONET) += econet
X
-ifeq ($(CONFIG_SUNRPC),y)
-SUB_DIRS += sunrpc
-else
- ifeq ($(CONFIG_SUNRPC),m)
- MOD_SUB_DIRS += sunrpc
- endif
-endif
X
-ifeq ($(CONFIG_ATM),y)
-SUB_DIRS += atm
-ifeq ($(CONFIG_ATM_LANE),m)
- MOD_ATM = atm
-endif
-ifeq ($(CONFIG_ATM_MPOA),m)
- MOD_ATM = atm
-endif
-MOD_SUB_DIRS += $(MOD_ATM)
+obj-y := socket.o protocols.o $(join $(subdir-y), $(patsubst %,/%.o,$(notdir $(subdir-y))))
+ifeq ($(CONFIG_NET),y)
+obj-$(CONFIG_MODULES) += netsyms.o
+obj-$(CONFIG_SYSCTL) += sysctl_net.o
X endif
X
-ifeq ($(CONFIG_DECNET),y)
-SUB_DIRS += decnet
-else
- ifeq ($(CONFIG_DECNET),m)
- MOD_SUB_DIRS += decnet
- endif
-endif
X
-ifeq ($(CONFIG_ECONET),y)
-SUB_DIRS += econet
-else
- ifeq ($(CONFIG_ECONET),m)
- MOD_SUB_DIRS += econet


- endif
-endif
+# Subdirectories that should be entered when MAKING_MODULES=1, even if set to 'y'.
+both-m := $(filter $(mod-subdirs), $(subdir-y))
X

-# We must attach netsyms.o to socket.o, as otherwise there is nothing
-# to pull the object file from the archive.


+# Translate to Rules.make lists.
+O_OBJS := $(filter-out $(export-objs), $(obj-y))
+OX_OBJS := $(filter $(export-objs), $(obj-y))
+M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m)))
+MX_OBJS := $(sort $(filter $(export-objs), $(obj-m)))
X

-ifeq ($(CONFIG_NET),y)
-ifeq ($(CONFIG_MODULES),y)
-OX_OBJS := netsyms.o
-endif


-endif
+SUB_DIRS := $(subdir-y)
+MOD_SUB_DIRS := $(sort $(subdir-m) $(both-m))
+ALL_SUB_DIRS := $(sort $(subdir-y) $(subdir-m) $(subdir-n) $(subdir-))
X

-O_TARGET := network.o
-O_OBJS := socket.o protocols.o $(join $(SUB_DIRS), $(patsubst %,/%.o,$(notdir $(SUB_DIRS))))
-
-M_OBJS :=
-
-ifeq ($(CONFIG_SYSCTL),y)
-ifeq ($(CONFIG_NET),y)
-O_OBJS += sysctl_net.o
-endif
-endif
X
X include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.0-test8/linux/net/appletalk/aarp.c linux/net/appletalk/aarp.c
--- v2.4.0-test8/linux/net/appletalk/aarp.c Tue Jul 18 16:09:27 2000
+++ linux/net/appletalk/aarp.c Mon Sep 18 14:57:01 2000
@@ -1017,7 +1017,10 @@
X * cycle during probing of a slow to respond host addr.
X */
X if (a != NULL)
+ {
X a->expires_at = jiffies - 1;
+ mod_timer(&aarp_timer, jiffies + sysctl_aarp_tick_time);
+ }
X }
X
X if (sa.s_node != ma->s_node)
diff -u --recursive --new-file v2.4.0-test8/linux/net/core/dev.c linux/net/core/dev.c
--- v2.4.0-test8/linux/net/core/dev.c Thu Sep 7 08:32:01 2000
+++ linux/net/core/dev.c Fri Sep 22 14:07:43 2000
@@ -295,37 +295,20 @@
X * netdev_boot_setup_check - check boot time settings
X * @dev: the netdevice
X *
- * Check boot time settings for the device. If device's name is a
- * mask (eg. eth%d) and settings are found then this will allocate
- * name for the device. The found settings are set for the device
- * to be used later in the device probing. Returns 0 if no settings
- * found, 1 if they are.
+ * Check boot time settings for the device.
+ * The found settings are set for the device to be used
+ * later in the device probing.
+ * Returns 0 if no settings found, 1 if they are.
X */
X int netdev_boot_setup_check(struct net_device *dev)
X {
X struct netdev_boot_setup *s;
- char buf[IFNAMSIZ + 1];
- int i, mask = 0;
-
- memset(buf, 0, sizeof(buf));
- strcpy(buf, dev->name);
- if (strchr(dev->name, '%')) {
- *strchr(buf, '%') = '\0';
- mask = 1;
- }
+ int i;
X
X s = dev_boot_setup;
X for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) {
X if (s[i].name[0] != '\0' && s[i].name[0] != ' ' &&
- !strncmp(buf, s[i].name, mask ? strlen(buf) :
- strlen(s[i].name))) {
- if (__dev_get_by_name(s[i].name)) {
- if (!mask)
- return 0;
- continue;
- }
- memset(dev->name, 0, IFNAMSIZ);
- strcpy(dev->name, s[i].name);
+ !strncmp(dev->name, s[i].name, strlen(s[i].name))) {
X dev->irq = s[i].map.irq;
X dev->base_addr = s[i].map.base_addr;
X dev->mem_start = s[i].map.mem_start;
@@ -333,7 +316,6 @@


X return 1;
X }
X }
-

X return 0;
X }
X

@@ -1159,6 +1141,7 @@
X struct net_device *dev = head;
X head = head->next_sched;
X
+ smp_mb__before_clear_bit();
X clear_bit(__LINK_STATE_SCHED, &dev->state);
X
X if (spin_trylock(&dev->queue_lock)) {
@@ -2463,27 +2446,26 @@
X dev->iflink = -1;
X dev_hold(dev);
X
+ /*
+ * Allocate name. If the init() fails
+ * the name will be reissued correctly.
+ */
+ if (strchr(dev->name, '%'))
+ dev_alloc_name(dev, dev->name);
+
X /*
X * Check boot time settings for the device.
X */
- if (!netdev_boot_setup_check(dev)) {
- /*
- * No settings found - allocate name. If the init()
- * fails the name will be reissued correctly.
- */
- if (strchr(dev->name, '%'))
- dev_alloc_name(dev, dev->name);
- }
+ netdev_boot_setup_check(dev);
X
X if (dev->init && dev->init(dev)) {
X /*
- * It failed to come up. Unhook it.
+ * It failed to come up. It will be unhooked later.
+ * dev_alloc_name can now advance to next suitable
+ * name that is checked next.
X */
- write_lock_bh(&dev_base_lock);
- *dp = dev->next;
X dev->deadbeaf = 1;
- write_unlock_bh(&dev_base_lock);
- dev_put(dev);
+ dp = &dev->next;
X } else {
X dp = &dev->next;
X dev->ifindex = dev_new_index();
@@ -2493,6 +2475,21 @@
X dev->rebuild_header = default_rebuild_header;
X dev_init_scheduler(dev);
X set_bit(__LINK_STATE_PRESENT, &dev->state);


+ }
+ }
+
+ /*

+ * Unhook devices that failed to come up
+ */
+ dp = &dev_base;
+ while ((dev = *dp) != NULL) {
+ if (dev->deadbeaf) {
+ write_lock_bh(&dev_base_lock);
+ *dp = dev->next;
+ write_unlock_bh(&dev_base_lock);
+ dev_put(dev);
+ } else {
+ dp = &dev->next;
X }
X }
X
diff -u --recursive --new-file v2.4.0-test8/linux/net/core/sock.c linux/net/core/sock.c
--- v2.4.0-test8/linux/net/core/sock.c Fri Aug 18 10:26:25 2000
+++ linux/net/core/sock.c Mon Sep 18 15:04:13 2000
@@ -7,7 +7,7 @@
X * handler for protocols to use and generic option handler.
X *
X *
- * Version: $Id: sock.c,v 1.98 2000/08/16 16:09:15 davem Exp $
+ * Version: $Id: sock.c,v 1.100 2000/09/18 05:59:48 davem Exp $
X *
X * Authors: Ross Biro, <bi...@leland.Stanford.Edu>
X * Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -609,7 +609,9 @@
X {
X sk_cachep = kmem_cache_create("sock", sizeof(struct sock), 0,
X SLAB_HWCACHE_ALIGN, 0, 0);
-
+ if (!sk_cachep)
+ printk(KERN_CRIT "sk_init: Cannot create sock SLAB cache!");
+
X if (num_physpages <= 4096) {
X sysctl_wmem_max = 32767;
X sysctl_rmem_max = 32767;
@@ -1142,6 +1144,7 @@
X } else
X sk->sleep = NULL;
X
+ sk->dst_lock = RW_LOCK_UNLOCKED;
X sk->callback_lock = RW_LOCK_UNLOCKED;
X
X sk->state_change = sock_def_wakeup;
diff -u --recursive --new-file v2.4.0-test8/linux/net/ipv4/af_inet.c linux/net/ipv4/af_inet.c
--- v2.4.0-test8/linux/net/ipv4/af_inet.c Fri Aug 18 10:26:25 2000
+++ linux/net/ipv4/af_inet.c Mon Sep 18 15:04:13 2000


@@ -5,7 +5,7 @@
X *

X * PF_INET protocol family socket handler.
X *
- * Version: $Id: af_inet.c,v 1.112 2000/08/16 16:20:56 davem Exp $
+ * Version: $Id: af_inet.c,v 1.114 2000/09/18 05:59:48 davem Exp $
X *
X * Authors: Ross Biro, <bi...@leland.Stanford.Edu>
X * Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -258,7 +258,6 @@
X return -EAGAIN;
X }
X sk->sport = htons(sk->num);


- sk->prot->hash(sk);
X }

X release_sock(sk);
X return 0;
@@ -390,7 +389,6 @@


X if (sk->prot->init) {
X int err = sk->prot->init(sk);
X if (err != 0) {
- sk->dead = 1;

X inet_sock_release(sk);
X return(err);
X }

@@ -460,7 +458,7 @@
X
X if (addr_len < sizeof(struct sockaddr_in))
X return -EINVAL;
-
+
X chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr);
X
X snum = ntohs(addr->sin_port);
@@ -495,10 +493,11 @@
X
X if (sk->rcv_saddr)
X sk->userlocks |= SOCK_BINDADDR_LOCK;


+ if (snum)
+ sk->userlocks |= SOCK_BINDPORT_LOCK;

X sk->sport = htons(sk->num);


X sk->daddr = 0;
X sk->dport = 0;

- sk->prot->hash(sk);
X sk_dst_reset(sk);
X err = 0;
X out:
diff -u --recursive --new-file v2.4.0-test8/linux/net/ipv4/arp.c linux/net/ipv4/arp.c
--- v2.4.0-test8/linux/net/ipv4/arp.c Fri Aug 4 18:18:49 2000
+++ linux/net/ipv4/arp.c Tue Oct 3 09:24:41 2000
@@ -1066,16 +1066,13 @@
X {
X char tbuf[16];
X sprintf(tbuf, "%u.%u.%u.%u", NIPQUAD(*(u32*)n->primary_key));
-
- size = sprintf(buffer+len, "%-16s 0x%-10x0x%-10x%s",
+ size = sprintf(buffer+len, "%-16s 0x%-10x0x%-10x%s"
+ " * %s\n",
X tbuf,
X hatype,
X arp_state_to_flags(n),
- hbuffer);
-
- size += sprintf(buffer+len+size,
- " %-8s %s\n",
- "*", dev->name);
+ hbuffer,
+ dev->name);
X }
X
X read_unlock(&n->lock);
@@ -1099,15 +1096,17 @@
X struct net_device *dev = n->dev;
X int hatype = dev ? dev->type : 0;
X
- size = sprintf(buffer+len,
- "%u.%u.%u.%u0x%-10x0x%-10x%s",
- NIPQUAD(*(u32*)n->key),
- hatype,
- ATF_PUBL|ATF_PERM,
- "00:00:00:00:00:00");
- size += sprintf(buffer+len+size,
- " %-17s %s\n",
- "*", dev ? dev->name : "*");
+ {
+ char tbuf[16];
+ sprintf(tbuf, "%u.%u.%u.%u", NIPQUAD(*(u32*)n->key));
+ size = sprintf(buffer+len, "%-16s 0x%-10x0x%-10x%s"
+ " * %s\n",
+ tbuf,
+ hatype,
+ ATF_PUBL|ATF_PERM,
+ "00:00:00:00:00:00",
+ dev ? dev->name : "*");
+ }
X
X len += size;
X pos += size;
diff -u --recursive --new-file v2.4.0-test8/linux/net/ipv4/inetpeer.c linux/net/ipv4/inetpeer.c
--- v2.4.0-test8/linux/net/ipv4/inetpeer.c Wed May 3 01:48:03 2000
+++ linux/net/ipv4/inetpeer.c Sun Oct 1 20:35:16 2000
@@ -82,12 +82,12 @@
X static rwlock_t peer_pool_lock = RW_LOCK_UNLOCKED;
X #define PEER_MAXDEPTH 40 /* sufficient for about 2^27 nodes */
X
-static volatile int peer_total = 0;
+static volatile int peer_total;
X int inet_peer_threshold = 65536 + 128; /* start to throw entries more
X * aggressively at this stage */
X int inet_peer_minttl = 120 * HZ; /* TTL under high load: 120 sec */
X int inet_peer_maxttl = 10 * 60 * HZ; /* usual time to live: 10 min */
-struct inet_peer *inet_peer_unused_head = NULL,
+struct inet_peer *inet_peer_unused_head,
X **inet_peer_unused_tailp = &inet_peer_unused_head;
X spinlock_t inet_peer_unused_lock = SPIN_LOCK_UNLOCKED;
X #define PEER_MAX_CLEANUP_WORK 30
diff -u --recursive --new-file v2.4.0-test8/linux/net/ipv4/ip_sockglue.c linux/net/ipv4/ip_sockglue.c
--- v2.4.0-test8/linux/net/ipv4/ip_sockglue.c Thu Aug 10 13:01:26 2000
+++ linux/net/ipv4/ip_sockglue.c Sun Sep 17 10:03:43 2000


@@ -5,7 +5,7 @@
X *

X * The IP to API glue.
X *
- * Version: $Id: ip_sockglue.c,v 1.51 2000/08/09 11:59:04 davem Exp $
+ * Version: $Id: ip_sockglue.c,v 1.52 2000/09/09 08:26:04 davem Exp $
X *
X * Authors: see ip.c
X *
@@ -380,31 +380,39 @@
X {
X int val=0,err;
X
- if(optlen>=sizeof(int)) {
- if(get_user(val, (int *) optval))
- return -EFAULT;
- } else if(optlen>=sizeof(char)) {
- unsigned char ucval;
- if(get_user(ucval, (unsigned char *) optval))
- return -EFAULT;
- val = (int)ucval;
+ if (optname == IP_PKTINFO || optname == IP_RECVTTL ||
+ optname == IP_RECVTOS || optname == IP_RECVOPTS ||
+ optname == IP_RETOPTS || optname == IP_TOS ||
+ optname == IP_TTL || optname == IP_HDRINCL ||
+ optname == IP_MTU_DISCOVER || optname == IP_RECVERR ||
+ optname == IP_MULTICAST_TTL || optname == IP_MULTICAST_LOOP ||
+ optname == IP_ROUTER_ALERT) {
+ if (optlen >= sizeof(int)) {
+ if (get_user(val, (int *) optval))
+ return -EFAULT;
+ } else if (optlen >= sizeof(char)) {
+ unsigned char ucval;
+
+ if (get_user(ucval, (unsigned char *) optval))
+ return -EFAULT;
+ val = (int) ucval;
+ }
X }
+
X /* If optlen==0, it is equivalent to val == 0 */
X
- if(level!=SOL_IP)
+ if (level != SOL_IP)
X return -ENOPROTOOPT;
+
X #ifdef CONFIG_IP_MROUTE
- if(optname>=MRT_BASE && optname <=MRT_BASE+10)
- {
+ if (optname >= MRT_BASE && optname <= (MRT_BASE + 10))
X return ip_mroute_setsockopt(sk,optname,optval,optlen);
- }
X #endif
X
X err = 0;
X lock_sock(sk);
X
- switch(optname)
- {
+ switch (optname) {
X case IP_OPTIONS:
X {
X struct ip_options * opt = NULL;
diff -u --recursive --new-file v2.4.0-test8/linux/net/ipv4/netfilter/ip_fw_compat.c linux/net/ipv4/netfilter/ip_fw_compat.c
--- v2.4.0-test8/linux/net/ipv4/netfilter/ip_fw_compat.c Fri Aug 4 13:07:24 2000
+++ linux/net/ipv4/netfilter/ip_fw_compat.c Mon Sep 18 15:09:55 2000
@@ -15,6 +15,10 @@
X #include <linux/netfilter_ipv4/ip_conntrack.h>
X #include <linux/netfilter_ipv4/ip_conntrack_core.h>
X
+/* Theoretically, we could one day use 2.4 helpers, but for now it
+ just confuses depmod --RR */
+EXPORT_NO_SYMBOLS;
+
X static struct firewall_ops *fwops;
X
X /* From ip_fw_compat_redir.c */
diff -u --recursive --new-file v2.4.0-test8/linux/net/ipv4/netfilter/ip_fw_compat_masq.c linux/net/ipv4/netfilter/ip_fw_compat_masq.c
--- v2.4.0-test8/linux/net/ipv4/netfilter/ip_fw_compat_masq.c Fri Jul 14 12:20:22 2000
+++ linux/net/ipv4/netfilter/ip_fw_compat_masq.c Mon Sep 18 15:09:55 2000
@@ -85,7 +85,12 @@
X newsrc, newsrc,
X { htons(61000) }, { htons(65095) } } } });
X
- ip_nat_setup_info(ct, &range, NF_IP_POST_ROUTING);
+ ret = ip_nat_setup_info(ct, &range, NF_IP_POST_ROUTING);
+ if (ret != NF_ACCEPT) {
+ WRITE_UNLOCK(&ip_nat_lock);


+ return ret;
+ }
+

X place_in_hashes(ct, info);
X info->initialized = 1;
X } else
diff -u --recursive --new-file v2.4.0-test8/linux/net/ipv4/netfilter/ip_nat_ftp.c linux/net/ipv4/netfilter/ip_nat_ftp.c
--- v2.4.0-test8/linux/net/ipv4/netfilter/ip_nat_ftp.c Thu Aug 10 12:35:15 2000
+++ linux/net/ipv4/netfilter/ip_nat_ftp.c Sun Sep 17 10:15:00 2000
@@ -372,8 +372,9 @@
X newseq = ntohl(tcph->seq) + ftp[dir].syn_offset_before;
X newseq = htonl(newseq);
X
- /* Ack adjust */
- if (after(ntohl(tcph->ack_seq), ftp[!dir].syn_correction_pos))
+ /* Ack adjust: other dir sees offset seq numbers */
+ if (after(ntohl(tcph->ack_seq) - ftp[!dir].syn_offset_before,
+ ftp[!dir].syn_correction_pos))
X newack = ntohl(tcph->ack_seq) - ftp[!dir].syn_offset_after;
X else
X newack = ntohl(tcph->ack_seq) - ftp[!dir].syn_offset_before;
diff -u --recursive --new-file v2.4.0-test8/linux/net/ipv4/netfilter/ip_nat_standalone.c linux/net/ipv4/netfilter/ip_nat_standalone.c
--- v2.4.0-test8/linux/net/ipv4/netfilter/ip_nat_standalone.c Thu Sep 7 08:32:01 2000
+++ linux/net/ipv4/netfilter/ip_nat_standalone.c Fri Sep 15 21:37:23 2000
@@ -7,6 +7,7 @@
X /* (c) 1999 Paul `Rusty' Russell. Licenced under the GNU General
X Public Licence. */
X
+#include <linux/config.h>
X #include <linux/types.h>
X #include <linux/ip.h>
X #include <linux/netfilter.h>
diff -u --recursive --new-file v2.4.0-test8/linux/net/ipv4/netfilter/ip_queue.c linux/net/ipv4/netfilter/ip_queue.c
--- v2.4.0-test8/linux/net/ipv4/netfilter/ip_queue.c Thu Aug 10 12:35:15 2000
+++ linux/net/ipv4/netfilter/ip_queue.c Mon Sep 18 15:09:55 2000
@@ -414,7 +414,7 @@
X return skb;
X nlmsg_failure:
X if (skb)
- kfree(skb);
+ kfree_skb(skb);
X *errp = 0;
X printk(KERN_ERR "ip_queue: error creating netlink message\n");
X return NULL;
diff -u --recursive --new-file v2.4.0-test8/linux/net/ipv4/netfilter/ipt_MIRROR.c linux/net/ipv4/netfilter/ipt_MIRROR.c
--- v2.4.0-test8/linux/net/ipv4/netfilter/ipt_MIRROR.c Thu Jul 6 21:20:00 2000
+++ linux/net/ipv4/netfilter/ipt_MIRROR.c Mon Sep 18 15:09:55 2000
@@ -89,7 +89,7 @@
X dst->neighbour->output(skb);
X else {
X printk(KERN_DEBUG "khm in MIRROR\n");
- kfree(skb);
+ kfree_skb(skb);
X }
X }
X
diff -u --recursive --new-file v2.4.0-test8/linux/net/ipv4/netfilter/ipt_REJECT.c linux/net/ipv4/netfilter/ipt_REJECT.c
--- v2.4.0-test8/linux/net/ipv4/netfilter/ipt_REJECT.c Thu Aug 10 12:35:15 2000
+++ linux/net/ipv4/netfilter/ipt_REJECT.c Tue Sep 19 08:31:53 2000
@@ -21,12 +21,13 @@
X #endif
X
X /* Send RST reply */
-static void send_reset(struct sk_buff *oldskb)
+static void send_reset(struct sk_buff *oldskb, int local)
X {
X struct sk_buff *nskb;
X struct tcphdr *otcph, *tcph;
X struct rtable *rt;
X unsigned int otcplen;
+ u_int16_t tmp;
X int needs_ack;
X
X /* IP header checks: fragment, too short. */
@@ -64,8 +65,11 @@
X
X tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);
X
+ /* Swap source and dest */
X nskb->nh.iph->daddr = xchg(&nskb->nh.iph->saddr, nskb->nh.iph->daddr);
- tcph->source = xchg(&tcph->dest, tcph->source);
+ tmp = tcph->source;
+ tcph->source = tcph->dest;
+ tcph->dest = tmp;
X
X /* Truncate to length (no data) */
X tcph->doff = sizeof(struct tcphdr)/4;
@@ -110,8 +114,9 @@
X nskb->nh.iph->check = ip_fast_csum((unsigned char *)nskb->nh.iph,
X nskb->nh.iph->ihl);
X
- /* Routing */
- if (ip_route_output(&rt, nskb->nh.iph->daddr, nskb->nh.iph->saddr,
+ /* Routing: if not headed for us, route won't like source */
+ if (ip_route_output(&rt, nskb->nh.iph->daddr,
+ local ? nskb->nh.iph->saddr : 0,
X RT_TOS(nskb->nh.iph->tos) | RTO_CONN,
X 0) != 0)
X goto free_nskb;
@@ -184,7 +189,7 @@
X }
X break;
X case IPT_TCP_RESET:
- send_reset(*pskb);
+ send_reset(*pskb, hooknum == NF_IP_LOCAL_IN);
X break;
X }
X
diff -u --recursive --new-file v2.4.0-test8/linux/net/ipv4/netfilter/iptable_mangle.c linux/net/ipv4/netfilter/iptable_mangle.c
--- v2.4.0-test8/linux/net/ipv4/netfilter/iptable_mangle.c Thu Sep 7 08:32:01 2000
+++ linux/net/ipv4/netfilter/iptable_mangle.c Fri Sep 15 21:37:23 2000
@@ -3,6 +3,7 @@
X *
X * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
X */
+#include <linux/config.h>
X #include <linux/module.h>
X #include <linux/netfilter_ipv4/ip_tables.h>
X #include <linux/netdevice.h>
diff -u --recursive --new-file v2.4.0-test8/linux/net/ipv4/protocol.c linux/net/ipv4/protocol.c
--- v2.4.0-test8/linux/net/ipv4/protocol.c Sat Feb 26 22:34:27 2000
+++ linux/net/ipv4/protocol.c Sun Oct 1 20:35:16 2000
@@ -112,10 +112,7 @@
X
X struct inet_protocol *inet_protocol_base = IPPROTO_PREVIOUS;
X
-struct inet_protocol *inet_protos[MAX_INET_PROTOS] =
-{
- NULL
-};
+struct inet_protocol *inet_protos[MAX_INET_PROTOS];
X
X /*
X * Add a protocol handler to the hash tables
diff -u --recursive --new-file v2.4.0-test8/linux/net/ipv4/route.c linux/net/ipv4/route.c
--- v2.4.0-test8/linux/net/ipv4/route.c Thu Sep 7 08:32:01 2000
+++ linux/net/ipv4/route.c Sun Oct 1 20:35:16 2000
@@ -117,7 +117,7 @@


X int ip_rt_min_pmtu = 512+20+20;

X int ip_rt_min_advmss = 536;
X
-static unsigned long rt_deadline = 0;
+static unsigned long rt_deadline;
X
X #define RTprint(a...) printk(KERN_DEBUG a)
X
diff -u --recursive --new-file v2.4.0-test8/linux/net/ipv4/sysctl_net_ipv4.c linux/net/ipv4/sysctl_net_ipv4.c
--- v2.4.0-test8/linux/net/ipv4/sysctl_net_ipv4.c Thu Sep 7 08:32:01 2000
+++ linux/net/ipv4/sysctl_net_ipv4.c Sun Sep 17 10:03:43 2000
@@ -1,7 +1,7 @@
X /*
X * sysctl_net_ipv4.c: sysctl interface to net IPV4 subsystem.
X *
- * $Id: sysctl_net_ipv4.c,v 1.45 2000/09/06 23:30:29 davem Exp $
+ * $Id: sysctl_net_ipv4.c,v 1.46 2000/09/16 09:38:30 davem Exp $
X *
X * Begun April 1, 1996, Mike Shaver.
X * Added /proc/sys/net/ipv4 directory entry (empty =) ). [MS]
@@ -15,19 +15,6 @@
X #include <net/route.h>
X #include <net/tcp.h>
X
-/*
- * TCP configuration parameters
- */
-
-#define TCP_PMTU_DISC 0x00000001 /* perform PMTU discovery */
-#define TCP_CONG_AVOID 0x00000002 /* congestion avoidance algorithm */
-#define TCP_DELAY_ACKS 0x00000003 /* delayed ack stategy */
-
-#if 0
-static int boolean_min = 0;
-static int boolean_max = 1;
-#endif
-
X /* From icmp.c */
X extern int sysctl_icmp_echo_ignore_all;
X extern int sysctl_icmp_echo_ignore_broadcasts;
@@ -57,7 +44,10 @@
X extern int inet_peer_gc_mintime;
X extern int inet_peer_gc_maxtime;
X
-int tcp_retr1_max = 255;
+static int tcp_retr1_max = 255;
+
+static int ip_local_port_range_min[] = { 1, 1 };
+static int ip_local_port_range_max[] = { 65535, 65535 };
X
X struct ipv4_config ipv4_config;
X
@@ -170,7 +160,8 @@
X sizeof(int), 0644, NULL, &proc_dointvec},
X {NET_IPV4_LOCAL_PORT_RANGE, "ip_local_port_range",
X &sysctl_local_port_range, sizeof(sysctl_local_port_range), 0644,
- NULL, &proc_dointvec},
+ NULL, &proc_dointvec_minmax, &sysctl_intvec, NULL,
+ ip_local_port_range_min, ip_local_port_range_max },
X {NET_IPV4_ICMP_ECHO_IGNORE_ALL, "icmp_echo_ignore_all",
X &sysctl_icmp_echo_ignore_all, sizeof(int), 0644, NULL,
X &proc_dointvec},
diff -u --recursive --new-file v2.4.0-test8/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c
--- v2.4.0-test8/linux/net/ipv4/tcp.c Fri Aug 18 10:26:25 2000
+++ linux/net/ipv4/tcp.c Sun Oct 1 20:35:16 2000


@@ -5,7 +5,7 @@
X *

X * Implementation of the Transmission Control Protocol(TCP).
X *
- * Version: $Id: tcp.c,v 1.173 2000/08/15 20:15:23 davem Exp $
+ * Version: $Id: tcp.c,v 1.174 2000/09/18 05:59:48 davem Exp $
X *
X * Authors: Ross Biro, <bi...@leland.Stanford.Edu>
X * Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>


@@ -436,7 +436,7 @@
X

X atomic_t tcp_orphan_count = ATOMIC_INIT(0);
X
-int sysctl_tcp_mem[3] = { 0, };
+int sysctl_tcp_mem[3];
X int sysctl_tcp_wmem[3] = { 4*1024, 16*1024, 128*1024 };
X int sysctl_tcp_rmem[3] = { 4*1024, 87380, 87380*2 };
X
@@ -1952,12 +1952,14 @@
X

X sk->dport = 0;
X

- sk->rcv_saddr = 0;

- sk->saddr = 0;


+ if (!(sk->userlocks&SOCK_BINDADDR_LOCK)) {
+ sk->rcv_saddr = 0;
+ sk->saddr = 0;

X #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
- memset(&sk->net_pinfo.af_inet6.saddr, 0, 16);
- memset(&sk->net_pinfo.af_inet6.rcv_saddr, 0, 16);


+ memset(&sk->net_pinfo.af_inet6.saddr, 0, 16);
+ memset(&sk->net_pinfo.af_inet6.rcv_saddr, 0, 16);

X #endif
+ }
X
X sk->shutdown = 0;
X sk->done = 0;
@@ -2281,6 +2283,68 @@
X case TCP_WINDOW_CLAMP:
X val = tp->window_clamp;
X break;
+ case TCP_INFO:
+ {
+ struct tcp_info info;
+ u32 now = tcp_time_stamp;
+
+ if(get_user(len,optlen))
+ return -EFAULT;
+ info.tcpi_state = sk->state;
+ info.tcpi_ca_state = tp->ca_state;
+ info.tcpi_retransmits = tp->retransmits;
+ info.tcpi_probes = tp->probes_out;
+ info.tcpi_backoff = tp->backoff;
+ info.tcpi_options = 0;
+ if (tp->tstamp_ok)
+ info.tcpi_options |= TCPI_OPT_TIMESTAMPS;
+ if (tp->sack_ok)
+ info.tcpi_options |= TCPI_OPT_SACK;
+ if (tp->wscale_ok) {
+ info.tcpi_options |= TCPI_OPT_WSCALE;
+ info.tcpi_snd_wscale = tp->snd_wscale;
+ info.tcpi_rcv_wscale = tp->rcv_wscale;
+ } else {
+ info.tcpi_snd_wscale = 0;
+ info.tcpi_rcv_wscale = 0;
+ }
+#ifdef CONFIG_INET_ECN
+ if (tp->ecn_flags&TCP_ECN_OK)
+ info.tcpi_options |= TCPI_OPT_ECN;
+#endif
+
+ info.tcpi_rto = (1000000*tp->rto)/HZ;
+ info.tcpi_ato = (1000000*tp->ack.ato)/HZ;
+ info.tcpi_snd_mss = tp->mss_cache;
+ info.tcpi_rcv_mss = tp->ack.rcv_mss;
+
+ info.tcpi_unacked = tp->packets_out;
+ info.tcpi_sacked = tp->sacked_out;
+ info.tcpi_lost = tp->lost_out;
+ info.tcpi_retrans = tp->retrans_out;
+ info.tcpi_fackets = tp->fackets_out;
+
+ info.tcpi_last_data_sent = ((now - tp->lsndtime)*1000)/HZ;
+ info.tcpi_last_ack_sent = 0;
+ info.tcpi_last_data_recv = ((now - tp->ack.lrcvtime)*1000)/HZ;
+ info.tcpi_last_ack_recv = ((now - tp->rcv_tstamp)*1000)/HZ;
+
+ info.tcpi_pmtu = tp->pmtu_cookie;
+ info.tcpi_rcv_ssthresh = tp->rcv_ssthresh;
+ info.tcpi_rtt = ((1000000*tp->srtt)/HZ)>>3;
+ info.tcpi_rttvar = ((1000000*tp->mdev)/HZ)>>2;
+ info.tcpi_snd_ssthresh = tp->snd_ssthresh;
+ info.tcpi_snd_cwnd = tp->snd_cwnd;
+ info.tcpi_advmss = tp->advmss;
+ info.tcpi_reordering = tp->reordering;
+
+ len = min(len, sizeof(info));
+ if(put_user(len, optlen))
+ return -EFAULT;
+ if(copy_to_user(optval, &info,len))
+ return -EFAULT;
+ return 0;
+ }
X default:
X return -ENOPROTOOPT;
X };
diff -u --recursive --new-file v2.4.0-test8/linux/net/ipv4/tcp_input.c linux/net/ipv4/tcp_input.c
--- v2.4.0-test8/linux/net/ipv4/tcp_input.c Thu Sep 7 08:32:01 2000
+++ linux/net/ipv4/tcp_input.c Thu Sep 21 13:20:12 2000


@@ -5,7 +5,7 @@
X *

X * Implementation of the Transmission Control Protocol(TCP).
X *
- * Version: $Id: tcp_input.c,v 1.199 2000/09/06 23:30:29 davem Exp $
+ * Version: $Id: tcp_input.c,v 1.202 2000/09/21 01:05:38 davem Exp $
X *
X * Authors: Ross Biro, <bi...@leland.Stanford.Edu>
X * Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -58,6 +58,7 @@
X * J Hadi Salim: ECN support
X */
X
+#include <linux/config.h>
X #include <linux/mm.h>
X #include <linux/sysctl.h>
X #include <net/tcp.h>
@@ -1492,10 +1493,8 @@
X
X case TCP_CA_Disorder:
X tcp_try_undo_dsack(sk, tp);
- if (IsReno(tp) || !tp->undo_marker) {
- tp->undo_marker = 0;
- tp->ca_state = TCP_CA_Open;
- }
+ tp->undo_marker = 0;
+ tp->ca_state = TCP_CA_Open;
X break;
X
X case TCP_CA_Recovery:
@@ -1823,7 +1822,9 @@
X #ifdef TCP_DEBUG
X if (before(tp->snd_una + tp->snd_wnd, tp->snd_nxt)) {
X if (net_ratelimit())
- printk(KERN_DEBUG "TCP: peer shrinks window. Bad, what else can I say?\n");
+ printk(KERN_DEBUG "TCP: peer %u.%u.%u.%u:%u/%u shrinks window %u:%u:%u. Bad, what else can I say?\n",
+ NIPQUAD(sk->daddr), htons(sk->dport), sk->num,
+ tp->snd_una, tp->snd_wnd, tp->snd_nxt);
X }
X #endif
X
@@ -1952,7 +1953,7 @@
X if (opsize < 2) /* "silly options" */
X return;
X if (opsize > length)
- break; /* don't parse partial options */
+ return; /* don't parse partial options */
X switch(opcode) {
X case TCPOPT_MSS:
X if(opsize==TCPOLEN_MSS && th->syn) {
diff -u --recursive --new-file v2.4.0-test8/linux/net/ipv4/tcp_ipv4.c linux/net/ipv4/tcp_ipv4.c
--- v2.4.0-test8/linux/net/ipv4/tcp_ipv4.c Fri Aug 18 10:26:25 2000
+++ linux/net/ipv4/tcp_ipv4.c Sun Oct 1 20:35:16 2000


@@ -5,7 +5,7 @@
X *

X * Implementation of the Transmission Control Protocol(TCP).
X *
- * Version: $Id: tcp_ipv4.c,v 1.212 2000/08/18 17:10:04 davem Exp $
+ * Version: $Id: tcp_ipv4.c,v 1.213 2000/09/18 05:59:48 davem Exp $
X *
X * IPv4 specific functions
X *
@@ -82,21 +82,21 @@
X * First half of the table is for sockets not in TIME_WAIT, second half
X * is for TIME_WAIT sockets only.
X */
-struct tcp_ehash_bucket *tcp_ehash = NULL;
+struct tcp_ehash_bucket *tcp_ehash;
X
X /* Ok, let's try this, I give up, we do need a local binding
X * TCP hash as well as the others for fast bind/connect.
X */
-struct tcp_bind_hashbucket *tcp_bhash = NULL;
+struct tcp_bind_hashbucket *tcp_bhash;
X
-int tcp_bhash_size = 0;
-int tcp_ehash_size = 0;
+int tcp_bhash_size;
+int tcp_ehash_size;
X
X /* All sockets in TCP_LISTEN state will be in here. This is the only table
X * where wildcard'd TCP sockets can exist. Hash function here is just local
X * port number.
X */
-struct sock *tcp_listening_hash[TCP_LHTABLE_SIZE] = { NULL, };
+struct sock *tcp_listening_hash[TCP_LHTABLE_SIZE];
X char __tcp_clean_cacheline_pad[(SMP_CACHE_BYTES -
X (((sizeof(void *) * (TCP_LHTABLE_SIZE + 2)) +
X (sizeof(int) * 2)) % SMP_CACHE_BYTES))] = { 0, };
@@ -300,6 +300,7 @@
X sk->bind_next->bind_pprev = sk->bind_pprev;
X *(sk->bind_pprev) = sk->bind_next;
X sk->prev = NULL;


+ sk->num = 0;

X if (tb->owners == NULL) {
X if (tb->next)
X tb->next->pprev = tb->pprev;
diff -u --recursive --new-file v2.4.0-test8/linux/net/ipv4/tcp_minisocks.c linux/net/ipv4/tcp_minisocks.c
--- v2.4.0-test8/linux/net/ipv4/tcp_minisocks.c Thu Sep 7 08:32:01 2000
+++ linux/net/ipv4/tcp_minisocks.c Mon Sep 18 15:04:13 2000


@@ -5,7 +5,7 @@
X *

X * Implementation of the Transmission Control Protocol(TCP).
X *
- * Version: $Id: tcp_minisocks.c,v 1.3 2000/09/05 23:13:48 davem Exp $
+ * Version: $Id: tcp_minisocks.c,v 1.4 2000/09/18 05:59:48 davem Exp $
X *
X * Authors: Ross Biro, <bi...@leland.Stanford.Edu>
X * Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -662,6 +662,7 @@
X sock_lock_init(newsk);
X bh_lock_sock(newsk);
X
+ newsk->dst_lock = RW_LOCK_UNLOCKED;
X atomic_set(&newsk->rmem_alloc, 0);
X skb_queue_head_init(&newsk->receive_queue);
X atomic_set(&newsk->wmem_alloc, 0);
@@ -671,6 +672,7 @@
X newsk->forward_alloc = 0;
X
X newsk->done = 0;
+ newsk->userlocks = sk->userlocks & ~SOCK_BINDPORT_LOCK;
X newsk->proc = 0;
X newsk->backlog.head = newsk->backlog.tail = NULL;
X newsk->callback_lock = RW_LOCK_UNLOCKED;
diff -u --recursive --new-file v2.4.0-test8/linux/net/ipv4/tcp_timer.c linux/net/ipv4/tcp_timer.c
--- v2.4.0-test8/linux/net/ipv4/tcp_timer.c Sat Aug 12 12:09:55 2000
+++ linux/net/ipv4/tcp_timer.c Sun Oct 1 20:35:16 2000
@@ -29,7 +29,7 @@
X int sysctl_tcp_keepalive_intvl = TCP_KEEPALIVE_INTVL;
X int sysctl_tcp_retries1 = TCP_RETR1;
X int sysctl_tcp_retries2 = TCP_RETR2;
-int sysctl_tcp_orphan_retries = 0;
+int sysctl_tcp_orphan_retries;
X
X static void tcp_write_timer(unsigned long);
X static void tcp_delack_timer(unsigned long);
diff -u --recursive --new-file v2.4.0-test8/linux/net/ipv4/udp.c linux/net/ipv4/udp.c
--- v2.4.0-test8/linux/net/ipv4/udp.c Thu Aug 10 13:01:26 2000
+++ linux/net/ipv4/udp.c Sun Oct 1 20:35:16 2000


@@ -5,7 +5,7 @@
X *

X * The User Datagram Protocol (UDP).
X *
- * Version: $Id: udp.c,v 1.85 2000/08/09 11:59:04 davem Exp $
+ * Version: $Id: udp.c,v 1.87 2000/09/20 02:11:34 davem Exp $
X *
X * Authors: Ross Biro, <bi...@leland.Stanford.Edu>
X * Fred N. van Kempen, <wal...@uWalt.NL.Mugnet.ORG>
@@ -126,7 +126,7 @@
X rwlock_t udp_hash_lock = RW_LOCK_UNLOCKED;
X
X /* Shared by v4/v6 udp. */
-int udp_port_rover = 0;
+int udp_port_rover;
X
X static int udp_v4_get_port(struct sock *sk, unsigned short snum)
X {
@@ -188,6 +188,15 @@


X }
X }
X sk->num = snum;
+ if (sk->pprev == NULL) {
+ struct sock **skp = &udp_hash[snum & (UDP_HTABLE_SIZE - 1)];
+ if ((sk->next = *skp) != NULL)
+ (*skp)->pprev = &sk->next;
+ *skp = sk;
+ sk->pprev = skp;
+ sock_prot_inc_use(sk->prot);
+ sock_hold(sk);
+ }
X write_unlock_bh(&udp_hash_lock);
X return 0;
X

@@ -198,16 +207,7 @@
X
X static void udp_v4_hash(struct sock *sk)


X {
- struct sock **skp = &udp_hash[sk->num & (UDP_HTABLE_SIZE - 1)];
-
- write_lock_bh(&udp_hash_lock);
- if ((sk->next = *skp) != NULL)
- (*skp)->pprev = &sk->next;
- *skp = sk;
- sk->pprev = skp;
- sock_prot_inc_use(sk->prot);
- sock_hold(sk);
- write_unlock_bh(&udp_hash_lock);
+ BUG();
X }
X

X static void udp_v4_unhash(struct sock *sk)
@@ -218,6 +218,7 @@


X sk->next->pprev = sk->pprev;
X *sk->pprev = sk->next;
X sk->pprev = NULL;
+ sk->num = 0;
X sock_prot_dec_use(sk->prot);
X __sock_put(sk);
X }

@@ -493,8 +494,6 @@
X if (usin->sin_family != AF_INET) {
X if (usin->sin_family != AF_UNSPEC)
X return -EINVAL;
- if (net_ratelimit())
- printk("Remind Kuznetsov, he has to repair %s eventually\n", current->comm);
X }
X
X ufh.daddr = usin->sin_addr.s_addr;
@@ -678,6 +677,8 @@
X if (flags & MSG_ERRQUEUE)
X return ip_recv_error(sk, msg, len);
X
+
+ retry:
X /*
X * From here the generic datagram does a lot of the work. Come
X * the finished NET3, it will do _ALL_ the work!
@@ -733,26 +734,21 @@
X csum_copy_err:
X UDP_INC_STATS_BH(UdpInErrors);
X
- /* Clear queue. */
- if (flags&MSG_PEEK) {


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 111'
echo 'File patch-2.4.0-test9 is continued in part 112'
echo "112" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part106

#!/bin/sh -x
# this is part 106 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 106; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

X #define outl(val, port) out_be32((u32 *)((port)+_IO_BASE), (val))
-#else
+
+#else /* not APUS or ALL_PPC */
+#define inb(port) in_8((u8 *)((port)+_IO_BASE))
+#define outb(val, port) out_8((u8 *)((port)+_IO_BASE), (val))
X #define inw(port) in_le16((u16 *)((port)+_IO_BASE))
X #define outw(val, port) out_le16((u16 *)((port)+_IO_BASE), (val))
X #define inl(port) in_le32((u32 *)((port)+_IO_BASE))
X #define outl(val, port) out_le32((u32 *)((port)+_IO_BASE), (val))
X #endif
X
-#define inb_p(port) in_8((u8 *)((port)+_IO_BASE))
-#define outb_p(val, port) out_8((u8 *)((port)+_IO_BASE), (val))
-#define inw_p(port) in_le16((u16 *)((port)+_IO_BASE))
-#define outw_p(val, port) out_le16((u16 *)((port)+_IO_BASE), (val))
-#define inl_p(port) in_le32((u32 *)((port)+_IO_BASE))
-#define outl_p(val, port) out_le32((u32 *)((port)+_IO_BASE), (val))
+#define inb_p(port) inb((port))
+#define outb_p(val, port) outb((val), (port))
+#define inw_p(port) inw((port))
+#define outw_p(val, port) outw((val), (port))
+#define inl_p(port) inl((port))
+#define outl_p(val, port) outl((val), (port))
X
X extern void _insb(volatile u8 *port, void *buf, int ns);
X extern void _outsb(volatile u8 *port, const void *buf, int ns);
@@ -123,6 +181,8 @@
X */
X extern void *__ioremap(unsigned long address, unsigned long size,
X unsigned long flags);
+extern void *__ioremap_at(unsigned long phys, unsigned long size,
+ unsigned long flags);
X extern void *ioremap(unsigned long address, unsigned long size);
X #define ioremap_nocache(addr, size) ioremap((addr), (size))
X extern void iounmap(void *addr);
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/irq.h linux/include/asm-ppc/irq.h
--- v2.4.0-test8/linux/include/asm-ppc/irq.h Tue May 2 13:05:40 2000
+++ linux/include/asm-ppc/irq.h Sun Sep 17 09:48:08 2000
@@ -184,6 +184,9 @@
X */
X #define SIU_INT_SMC1 ((uint)0x04)
X #define SIU_INT_SMC2 ((uint)0x05)
+#define SIU_INT_FCC1 ((uint)0x20)
+#define SIU_INT_FCC2 ((uint)0x21)
+#define SIU_INT_FCC3 ((uint)0x22)
X #define SIU_INT_SCC1 ((uint)0x28)
X #define SIU_INT_SCC2 ((uint)0x29)
X #define SIU_INT_SCC3 ((uint)0x2a)
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/keylargo.h linux/include/asm-ppc/keylargo.h
--- v2.4.0-test8/linux/include/asm-ppc/keylargo.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-ppc/keylargo.h Sun Sep 17 09:48:08 2000
@@ -0,0 +1,103 @@
+/*
+ * keylargo.h: definitions for using the "KeyLargo" I/O controller chip.
+ *
+ */
+
+/* offset from base for feature control registers */
+#define KEYLARGO_MBCR 0x34 /* Media bay control/status */
+#define KEYLARGO_FCR0 0x38
+#define KEYLARGO_FCR1 0x3c
+#define KEYLARGO_FCR2 0x40
+#define KEYLARGO_FCR3 0x44
+#define KEYLARGO_FCR4 0x48
+
+/* GPIO registers */
+#define KEYLARGO_GPIO_LEVELS0 0x50
+#define KEYLARGO_GPIO_LEVELS1 0x54
+#define KEYLARGO_GPIO_EXTINT_0 0x58
+#define KEYLARGO_GPIO_EXTINT_CNT 18
+#define KEYLARGO_GPIO_0 0x6A
+#define KEYLARGO_GPIO_CNT 17
+
+/* Specific GPIO regs */
+#define KL_GPIO_ETH_PHY_RESET (KEYLARGO_GPIO_0+0x10)
+#define KL_GPIO_ETH_PHY_RESET_ASSERT 0x04
+#define KL_GPIO_ETH_PHY_RESET_RELEASE 0x05
+#define KL_GPIO_ETH_PHY_RESET_TRISTATE 0x00
+/*
+ * Bits in feature control register
+ */
+#define KL_MBCR_MBDEV_ENABLE 0x00001000
+
+#define KL0_SCC_B_INTF_ENABLE 0x00000001 /* ??? */
+#define KL0_SCC_A_INTF_ENABLE 0x00000002 /* ??? */
+#define KL0_SCC_SLOWPCLK 0x00000004
+#define KL0_SCC_RESET 0x00000008
+#define KL0_SCCA_ENABLE 0x00000010
+#define KL0_SCCB_ENABLE 0x00000020
+#define KL0_SCC_CELL_ENABLE 0x00000040
+#define KL0_IRDA_ENABLE 0x00008000
+#define KL0_IRDA_CLK32_ENABLE 0x00010000
+#define KL0_IRDA_CLK19_ENABLE 0x00020000
+#define KL0_USB0_PAD_SUSPEND0 0x00040000
+#define KL0_USB0_PAD_SUSPEND1 0x00080000
+#define KL0_USB0_CELL_ENABLE 0x00100000
+#define KL0_USB1_PAD_SUSPEND0 0x00400000
+#define KL0_USB1_PAD_SUSPEND1 0x00800000
+#define KL0_USB1_CELL_ENABLE 0x01000000
+#define KL0_USB_REF_SUSPEND 0x10000000
+
+#define KL0_SERIAL_ENABLE (KL0_SCC_B_INTF_ENABLE | \
+ KL0_SCC_SLOWPCLK | \
+ KL0_SCC_CELL_ENABLE | KL0_SCCA_ENABLE)
+
+#define KL1_AUDIO_SEL_22MCLK 0x00000002
+#define KL1_AUDIO_CLK_ENABLE_BIT 0x00000008
+#define KL1_AUDIO_CLK_OUT_ENABLE 0x00000020 /* Burgundy only ? */
+#define KL1_AUDIO_CELL_ENABLE 0x00000040
+#define KL1_AUDIO_CHOOSE 0x00000080 /* Burgundy only ? */
+#define KL1_I2S0_CELL_ENABLE 0x00000400
+#define KL1_I2S0_CLK_ENABLE_BIT 0x00001000
+#define KL1_I2S0_ENABLE 0x00002000
+#define KL1_I2S1_CELL_ENABLE 0x00020000
+#define KL1_I2S1_CLK_ENABLE_BIT 0x00080000
+#define KL1_I2S1_ENABLE 0x00100000
+#define KL1_EIDE0_ENABLE 0x00800000
+#define KL1_EIDE0_RESET_N 0x01000000
+#define KL1_EIDE1_ENABLE 0x04000000
+#define KL1_EIDE1_RESET_N 0x08000000
+#define KL1_UIDE_ENABLE 0x20000000
+#define KL1_UIDE_RESET_N 0x40000000
+
+#define KL2_IOBUS_ENABLE 0x00000002
+#define KL2_SLEEP_STATE_BIT 0x00000100
+#define KL2_MPIC_ENABLE 0x00020000
+#define KL2_MODEM_POWER_N 0x02000000
+#define KL2_AIRPORT_RESET_N 0x08000000 /* Or power ? */
+
+#define KL3_SHUTDOWN_PLL_TOTAL 0x00000001
+#define KL3_SHUTDOWN_PLLKW6 0x00000002
+#define KL3_SHUTDOWN_PLLKW4 0x00000004
+#define KL3_SHUTDOWN_PLLKW35 0x00000008
+#define KL3_SHUTDOWN_PLLKW12 0x00000010
+#define KL3_PLL_RESET 0x00000020
+#define KL3_SHUTDOWN_PLL2X 0x00000080
+#define KL3_CLK66_ENABLE 0x00000100
+#define KL3_CLK49_ENABLE 0x00000200
+#define KL3_CLK45_ENABLE 0x00000400
+#define KL3_CLK31_ENABLE 0x00000800
+#define KL3_TIMER_CLK18_ENABLE 0x00001000
+#define KL3_I2S1_CLK18_ENABLE 0x00002000
+#define KL3_I2S0_CLK18_ENABLE 0x00004000
+#define KL3_VIA_CLK16_ENABLE 0x00008000
+#define KL3_STOPPING33_ENABLED 0x00080000
+
+/* Port 0,1 : bus 0, port 2,3 : bus 1 */
+#define KL4_SET_PORT_ENABLE(p) (0x00000008 << (p<<3))
+#define KL4_SET_PORT_RESUME(p) (0x00000004 << (p<<3))
+#define KL4_SET_PORT_CONNECT(p) (0x00000002 << (p<<3))
+#define KL4_SET_PORT_DISCONNECT(p) (0x00000001 << (p<<3))
+#define KL4_GET_PORT_RESUME(p) (0x00000040 << (p<<3))
+#define KL4_GET_PORT_CONNECT(p) (0x00000020 << (p<<3))
+#define KL4_GET_PORT_DISCONNECT(p) (0x00000010 << (p<<3))
+
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/kmap_types.h linux/include/asm-ppc/kmap_types.h
--- v2.4.0-test8/linux/include/asm-ppc/kmap_types.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-ppc/kmap_types.h Sun Sep 17 09:48:08 2000
@@ -0,0 +1,10 @@
+#ifndef _ASM_KMAP_TYPES_H
+#define _ASM_KMAP_TYPES_H
+
+enum km_type {
+ KM_BOUNCE_READ,
+ KM_BOUNCE_WRITE,
+ KM_TYPE_NR
+};
+
+#endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/machdep.h linux/include/asm-ppc/machdep.h
--- v2.4.0-test8/linux/include/asm-ppc/machdep.h Tue Jul 18 23:02:09 2000
+++ linux/include/asm-ppc/machdep.h Sun Sep 17 09:48:08 2000
@@ -31,7 +31,7 @@
X void (*power_off)(void);
X void (*halt)(void);
X
- void (*time_init)(void); /* Optional, may be NULL */
+ long (*time_init)(void); /* Optional, may be NULL */
X int (*set_rtc_time)(unsigned long nowtime);
X unsigned long (*get_rtc_time)(void);
X void (*calibrate_decr)(void);
@@ -75,7 +75,7 @@
X void (*pcibios_fixup)(void);
X void (*pcibios_fixup_bus)(struct pci_bus *);
X
- void* (*pci_dev_io_base)(unsigned char bus, unsigned char devfn);
+ void* (*pci_dev_io_base)(unsigned char bus, unsigned char devfn, int physical);
X void* (*pci_dev_mem_base)(unsigned char bus, unsigned char devfn);
X int (*pci_dev_root_bridge)(unsigned char bus, unsigned char devfn);
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/mbx.h linux/include/asm-ppc/mbx.h
--- v2.4.0-test8/linux/include/asm-ppc/mbx.h Sat Nov 27 15:42:33 1999
+++ linux/include/asm-ppc/mbx.h Sun Sep 17 09:48:08 2000
@@ -25,6 +25,7 @@
X unsigned int bi_busfreq; /* Bus Freq, in Hz */
X unsigned int bi_clun; /* Boot device controller */
X unsigned int bi_dlun; /* Boot device logical dev */
+ unsigned int bi_baudrate; /* ...to be like everyone else */
X } bd_t;
X
X /* Memory map for the MBX as configured by EPPC-Bug. We could reprogram
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/mman.h linux/include/asm-ppc/mman.h
--- v2.4.0-test8/linux/include/asm-ppc/mman.h Tue Mar 21 10:49:32 2000
+++ linux/include/asm-ppc/mman.h Sun Sep 17 09:48:08 2000
@@ -22,8 +22,8 @@
X #define MS_INVALIDATE 2 /* invalidate the caches */
X #define MS_SYNC 4 /* synchronous memory sync */
X
-#define MCL_CURRENT 1 /* lock all current mappings */
-#define MCL_FUTURE 2 /* lock all future mappings */
+#define MCL_CURRENT 0x2000 /* lock all currently mapped pages */
+#define MCL_FUTURE 0x4000 /* lock all additions to address space */
X
X #define MADV_NORMAL 0x0 /* default page-in behavior */
X #define MADV_RANDOM 0x1 /* page-in minimum required */
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/nvram.h linux/include/asm-ppc/nvram.h
--- v2.4.0-test8/linux/include/asm-ppc/nvram.h Tue May 2 13:05:40 2000
+++ linux/include/asm-ppc/nvram.h Sun Sep 17 09:48:08 2000
@@ -38,6 +38,8 @@
X pmac_nvram_NR /* MacOS Name Registry partition */
X };
X
+#ifdef __KERNEL__
+
X /* Return partition offset in nvram */
X extern int pmac_get_partition(int partition);


X
@@ -45,15 +47,20 @@

X extern u8 pmac_xpram_read(int xpaddr);
X extern void pmac_xpram_write(int xpaddr, u8 data);
X

+#endif /* __KERNEL__ */
+

X /* Some offsets in XPRAM */
X #define PMAC_XPRAM_MACHINE_LOC 0xe4
X #define PMAC_XPRAM_SOUND_VOLUME 0x08
X
X /* Machine location structure in XPRAM */
X struct pmac_machine_location {
- u32 latitude; /* 2+30 bit Fractional number */
- u32 longitude; /* 2+30 bit Fractional number */
- u32 delta; /* mix of GMT delta and DLS */
+ unsigned int latitude; /* 2+30 bit Fractional number */
+ unsigned int longitude; /* 2+30 bit Fractional number */
+ unsigned int delta; /* mix of GMT delta and DLS */
X };
+
+/* /dev/nvram ioctls */
+#define PMAC_NVRAM_GET_OFFSET _IOWR('p', 0x40, int) /* Get NVRAM partition offset */
X
X #endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/pci-bridge.h linux/include/asm-ppc/pci-bridge.h
--- v2.4.0-test8/linux/include/asm-ppc/pci-bridge.h Thu Jul 13 09:42:51 2000
+++ linux/include/asm-ppc/pci-bridge.h Sun Sep 17 09:48:08 2000
@@ -15,8 +15,12 @@
X /* This version handles the new Uni-N host bridge, the iobase is now
X * a per-device thing. I also added the memory base so PReP can
X * be fixed to return 0xc0000000 (I didn't actually implement it)
+ *
+ * pci_dev_io_base() returns either a virtual (ioremap'ed) address or
+ * a physical address. In-kernel clients will use logical while the
+ * sys_pciconfig_iobase syscall returns a physical one to userland.
X */
-void *pci_dev_io_base(unsigned char bus, unsigned char devfn);
+void *pci_dev_io_base(unsigned char bus, unsigned char devfn, int physical);
X void *pci_dev_mem_base(unsigned char bus, unsigned char devfn);
X
X /* Returns the root-bridge number (Uni-N number) of a device */
@@ -33,7 +37,8 @@
X struct bridge_data {
X volatile unsigned int *cfg_addr;
X volatile unsigned char *cfg_data;
- void *io_base;
+ void *io_base; /* virtual */
+ unsigned long io_base_phys;
X int bus_number;
X int max_bus;
X struct bridge_data *next;
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/pgtable.h linux/include/asm-ppc/pgtable.h
--- v2.4.0-test8/linux/include/asm-ppc/pgtable.h Mon Aug 7 21:02:27 2000
+++ linux/include/asm-ppc/pgtable.h Sun Sep 17 09:48:08 2000
@@ -69,7 +69,7 @@
X
X extern void flush_icache_range(unsigned long, unsigned long);
X extern void __flush_page_to_ram(unsigned long page_va);
-#define flush_page_to_ram(page) __flush_page_to_ram((unsigned long) page_address(page))
+extern void flush_page_to_ram(struct page *page);
X
X #define flush_dcache_page(page) do { } while (0)
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/processor.h linux/include/asm-ppc/processor.h
--- v2.4.0-test8/linux/include/asm-ppc/processor.h Mon Aug 7 21:02:27 2000
+++ linux/include/asm-ppc/processor.h Sun Sep 17 09:48:08 2000
@@ -287,6 +287,7 @@
X #define SPRN_UPMC3 0x3AD /* User Performance Counter Register 3 */
X #define SPRN_UPMC4 0x3AE /* User Performance Counter Register 4 */
X #define SPRN_USIA 0x3AB /* User Sampled Instruction Address Register */
+#define SPRN_VRSAVE 0x100 /* Vector Register Save Register */
X #define SPRN_XER 0x001 /* Fixed Point Exception Register */
X #define SPRN_ZPR 0x3B0 /* Zone Protection Register */
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/prom.h linux/include/asm-ppc/prom.h
--- v2.4.0-test8/linux/include/asm-ppc/prom.h Thu Jul 13 09:42:51 2000
+++ linux/include/asm-ppc/prom.h Tue Sep 19 08:31:53 2000
@@ -7,11 +7,16 @@
X #ifndef _PPC_PROM_H
X #define _PPC_PROM_H
X
+#include <linux/config.h>
+
X typedef void *phandle;
X typedef void *ihandle;
X
X extern char *prom_display_paths[];
X extern unsigned int prom_num_displays;
+#ifndef CONFIG_MACH_SPECIFIC
+extern int have_of;
+#endif
X
X struct address_range {
X unsigned int space;
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/resource.h linux/include/asm-ppc/resource.h
--- v2.4.0-test8/linux/include/asm-ppc/resource.h Tue May 2 13:05:40 2000
+++ linux/include/asm-ppc/resource.h Fri Sep 22 14:21:21 2000
@@ -11,8 +11,9 @@


X #define RLIMIT_NOFILE 7 /* max number of open files */
X #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */

X #define RLIMIT_AS 9 /* address space limit(?) */


+#define RLIMIT_LOCKS 10 /* maximum file locks held */
X
-#define RLIM_NLIMITS 10
+#define RLIM_NLIMITS 11
X

X #ifdef __KERNEL__
X
@@ -33,6 +34,7 @@


X { RLIM_INFINITY, RLIM_INFINITY }, \
X { 0, 0 }, \
X { INR_OPEN, INR_OPEN }, \
+ { RLIM_INFINITY, RLIM_INFINITY }, \
X { RLIM_INFINITY, RLIM_INFINITY }, \
X { RLIM_INFINITY, RLIM_INFINITY }, \
X }

diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/serial.h linux/include/asm-ppc/serial.h
--- v2.4.0-test8/linux/include/asm-ppc/serial.h Sat Nov 27 15:42:33 1999
+++ linux/include/asm-ppc/serial.h Sun Sep 17 09:48:08 2000
@@ -23,16 +23,6 @@
X #define RS_TABLE_SIZE 4
X #endif
X
-#ifdef CONFIG_PMAC
-/*
- * Auto-probing will cause machine checks on powermacs.
- */
-#define SERIAL_PORT_DFNS
-#else
-/*
- * PReP, CHRP, etc.
- */
-
X /* Standard COM flags (except for COM4, because of the 8514 problem) */
X #ifdef CONFIG_SERIAL_DETECT_IRQ
X #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ)
@@ -136,5 +126,4 @@
X HUB6_SERIAL_PORT_DFNS \
X MCA_SERIAL_PORT_DFNS
X
-#endif /* CONFIG_PMAC */
X #endif /* CONFIG_GEMINI */
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/smp.h linux/include/asm-ppc/smp.h
--- v2.4.0-test8/linux/include/asm-ppc/smp.h Mon Jun 19 17:59:37 2000
+++ linux/include/asm-ppc/smp.h Sun Sep 17 09:48:08 2000
@@ -24,10 +24,11 @@
X
X extern unsigned long smp_proc_in_lock[NR_CPUS];
X
-extern void smp_message_pass(int target, int msg, unsigned long data, int wait);
X extern void smp_store_cpu_info(int id);
-extern void smp_message_recv(int);
-void smp_send_tlb_invalidate(int);
+extern void smp_send_tlb_invalidate(int);
+extern void smp_send_xmon_break(int cpu);
+struct pt_regs;
+extern void smp_message_recv(int, struct pt_regs *);
X
X #define NO_PROC_ID 0xFF /* No processor magic marker */
X #define PROC_CHANGE_PENALTY 20
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/spinlock.h linux/include/asm-ppc/spinlock.h
--- v2.4.0-test8/linux/include/asm-ppc/spinlock.h Sun Feb 13 10:47:01 2000
+++ linux/include/asm-ppc/spinlock.h Sun Sep 17 09:48:08 2000
@@ -41,6 +41,7 @@
X } rwlock_t;
X
X #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
+#define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0)
X
X extern void _read_lock(rwlock_t *rw);
X extern void _read_unlock(rwlock_t *rw);
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/system.h linux/include/asm-ppc/system.h
--- v2.4.0-test8/linux/include/asm-ppc/system.h Thu Aug 3 15:38:11 2000
+++ linux/include/asm-ppc/system.h Wed Sep 27 13:41:33 2000
@@ -36,6 +36,16 @@
X #define set_mb(var, value) do { var = value; mb(); } while (0)


X #define set_wmb(var, value) do { var = value; wmb(); } while (0)
X

+#ifdef CONFIG_SMP
+#define smp_mb() mb()
+#define smp_rmb() rmb()
+#define smp_wmb() wmb()
+#else

+#define smp_mb() __asm__ __volatile__("": : :"memory")
+#define smp_rmb() __asm__ __volatile__("": : :"memory")
+#define smp_wmb() __asm__ __volatile__("": : :"memory")
+#endif /* CONFIG_SMP */
+
X extern void xmon_irq(int, void *, struct pt_regs *);
X extern void xmon(struct pt_regs *excp);
X
@@ -67,6 +77,7 @@
X extern void cvt_df(double *from, float *to, unsigned long *fpscr);
X extern int call_rtas(const char *, int, int, unsigned long *, ...);
X extern int abs(int);
+extern void cacheable_memzero(void *p, unsigned int nb);
X
X struct device_node;
X extern void note_scsi_host(struct device_node *, void *);
@@ -114,16 +125,25 @@
X
X #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
X
-extern unsigned long xchg_u64(void *ptr, unsigned long val);
-extern unsigned long xchg_u32(void *ptr, unsigned long val);
+static __inline__ unsigned long
+xchg_u32(volatile void *p, unsigned long val)
+{
+ unsigned long prev;
+
+ __asm__ __volatile__ ("
+1: lwarx %0,0,%2
+ stwcx. %3,0,%2
+ bne- 1b"
+ : "=&r" (prev), "=m" (*(volatile unsigned long *)p)
+ : "r" (p), "r" (val), "m" (*(volatile unsigned long *)p)


+ : "cc", "memory");
+

+ return prev;
+}
X
X /*
X * This function doesn't exist, so you'll get a linker error
X * if something tries to do an invalid xchg().
- *
- * This only works if the compiler isn't horribly bad at optimizing.
- * gcc-2.5.8 reportedly can't handle this, but as that doesn't work
- * too well on the alpha anyway..
X */
X extern void __xchg_called_with_bad_pointer(void);
X
@@ -135,8 +155,10 @@
X switch (size) {
X case 4:
X return (unsigned long )xchg_u32(ptr, x);
+#if 0 /* xchg_u64 doesn't exist on 32-bit PPC */
X case 8:
X return (unsigned long )xchg_u64(ptr, x);
+#endif /* 0 */
X }
X __xchg_called_with_bad_pointer();
X return x;
@@ -149,4 +171,56 @@
X return (void *) xchg_u32(m, (unsigned long) val);
X }
X
-#endif
+
+#define __HAVE_ARCH_CMPXCHG 1
+
+static __inline__ unsigned long
+__cmpxchg_u32(volatile int *p, int old, int new)
+{
+ int prev;
+
+ __asm__ __volatile__ ("
+1: lwarx %0,0,%2
+ cmpw 0,%0,%3
+ bne 2f
+ stwcx. %4,0,%2
+ bne- 1b\n"
+#ifdef CONFIG_SMP
+" sync\n"
+#endif /* CONFIG_SMP */
+"2:"
+ : "=&r" (prev), "=m" (*p)
+ : "r" (p), "r" (old), "r" (new), "m" (*p)


+ : "cc", "memory");
+

+ return prev;
+}
+
+/* This function doesn't exist, so you'll get a linker error
+ if something tries to do an invalid cmpxchg(). */
+extern void __cmpxchg_called_with_bad_pointer(void);
+
+static __inline__ unsigned long
+__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
+{
+ switch (size) {
+ case 4:
+ return __cmpxchg_u32(ptr, old, new);
+#if 0 /* we don't have __cmpxchg_u64 on 32-bit PPC */
+ case 8:
+ return __cmpxchg_u64(ptr, old, new);
+#endif /* 0 */
+ }
+ __cmpxchg_called_with_bad_pointer();
+ return old;
+}
+
+#define cmpxchg(ptr,o,n) \
+ ({ \
+ __typeof__(*(ptr)) _o_ = (o); \
+ __typeof__(*(ptr)) _n_ = (n); \
+ (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
+ (unsigned long)_n_, sizeof(*(ptr))); \
+ })
+
+#endif /* __PPC_SYSTEM_H */
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/time.h linux/include/asm-ppc/time.h
--- v2.4.0-test8/linux/include/asm-ppc/time.h Thu Jul 13 09:42:51 2000
+++ linux/include/asm-ppc/time.h Sun Sep 17 09:48:08 2000
@@ -12,11 +12,10 @@
X #include <asm/processor.h>
X
X /* time.c */
-extern unsigned decrementer_count;
-extern unsigned count_period_num;
-extern unsigned count_period_den;
-extern unsigned long mktime(unsigned int, unsigned int, unsigned int,
- unsigned int, unsigned int, unsigned int);
+extern unsigned tb_ticks_per_jiffy;
+extern unsigned tb_to_us;
+extern unsigned tb_last_stamp;
+
X extern void to_tm(int tim, struct rtc_time * tm);
X extern time_t last_rtc_update;
X
@@ -37,6 +36,80 @@
X #if defined(CONFIG_4xx)
X mtspr(SPRN_PIT, val);
X #else
+#ifdef CONFIG_8xx_CPU6
+ set_dec_cpu6(val);
+#else
X mtspr(SPRN_DEC, val);
X #endif
+#endif
+}
+
+/* Accessor functions for the timebase (RTC on 601) registers. */
+/* If one day CONFIG_POWER is added just define __USE_RTC as 1 */
+#ifdef CONFIG_6xx
+extern __inline__ int const __USE_RTC(void) {
+ return (mfspr(SPRN_PVR)>>16) == 1;
+}
+#else
+#define __USE_RTC() 0
+#endif
+
+extern __inline__ unsigned long get_tbl(void) {
+ unsigned long tbl;
+ asm volatile("mftb %0" : "=r" (tbl));
+ return tbl;
+}
+
+extern __inline__ unsigned long get_rtcl(void) {
+ unsigned long rtcl;
+ asm volatile("mfrtcl %0" : "=r" (rtcl));
+ return rtcl;
X }
+
+extern __inline__ unsigned get_native_tbl(void) {
+ if (__USE_RTC())
+ return get_rtcl();
+ else
+ return get_tbl();
+}
+
+/* On machines with RTC, this function can only be used safely
+ * after the timestamp and for 1 second. It is only used by gettimeofday
+ * however so it should not matter.
+ */
+extern __inline__ unsigned tb_ticks_since(unsigned tstamp) {
+ if (__USE_RTC()) {
+ int delta = get_rtcl() - tstamp;
+ return delta<0 ? delta + 1000000000 : delta;
+ } else {
+ return get_tbl() - tstamp;


+ }
+}
+
+#if 0

+extern __inline__ unsigned long get_bin_rtcl(void) {
+ unsigned long rtcl, rtcu1, rtcu2;
+ asm volatile("\
+1: mfrtcu %0\n\
+ mfrtcl %1\n\
+ mfrtcu %2\n\
+ cmpw %0,%2\n\
+ bne- 1b\n"
+ : "=r" (rtcu1), "=r" (rtcl), "=r" (rtcu2)
+ : : "cr0");
+ return rtcu2*1000000000+rtcl;
+}
+
+extern __inline__ unsigned binary_tbl(void) {
+ if (__USE_RTC())
+ return get_bin_rtcl();
+ else
+ return get_tbl();
+}
+#endif
+
+/* Use mulhwu to scale processor timebase to timeval */
+#define mulhwu(x,y) \
+({unsigned z; asm ("mulhwu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;})
+
+unsigned mulhwu_scale_factor(unsigned, unsigned);
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/uaccess.h linux/include/asm-ppc/uaccess.h
--- v2.4.0-test8/linux/include/asm-ppc/uaccess.h Tue Aug 29 14:09:15 2000
+++ linux/include/asm-ppc/uaccess.h Sun Sep 17 09:48:08 2000
@@ -57,7 +57,7 @@
X
X /* Returns 0 if exception not found and fixup otherwise. */
X extern unsigned long search_exception_table(unsigned long);
-
+extern void sort_exception_table(void);
X
X /*
X * These are the main single-value transfer routines. They automatically
@@ -131,10 +131,11 @@
X ".section .fixup,\"ax\"\n" \
X "3: li %0,%3\n" \
X " b 2b\n" \
+ ".previous\n" \
X ".section __ex_table,\"a\"\n" \
X " .align 2\n" \
X " .long 1b,3b\n" \
- ".text" \
+ ".previous" \
X : "=r"(err) \
X : "r"(x), "b"(addr), "i"(-EFAULT), "0"(err))
X
@@ -178,10 +179,11 @@
X "3: li %0,%3\n" \
X " li %1,0\n" \
X " b 2b\n" \
+ ".previous\n" \
X ".section __ex_table,\"a\"\n" \
X " .align 2\n" \
X " .long 1b,3b\n" \
- ".text" \
+ ".previous" \
X : "=r"(err), "=r"(x) \
X : "b"(addr), "i"(-EFAULT), "0"(err))
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/uninorth.h linux/include/asm-ppc/uninorth.h
--- v2.4.0-test8/linux/include/asm-ppc/uninorth.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-ppc/uninorth.h Sun Sep 17 09:48:08 2000
@@ -0,0 +1,83 @@
+/*
+ * uninorth.h: definitions for using the "UniNorth" host bridge chip
+ * from Apple. This chip is used on "Core99" machines
+ *
+ */
+
+
+/*
+ * Uni-N config space reg. definitions
+ *
+ * (Little endian)
+ */
+
+/* Address ranges selection. This one should work with Bandit too */
+#define UNI_N_ADDR_SELECT 0x48
+#define UNI_N_ADDR_COARSE_MASK 0xffff0000 /* 256Mb regions at *0000000 */
+#define UNI_N_ADDR_FINE_MASK 0x0000ffff /* 16Mb regions at f*000000 */
+
+/* AGP registers */
+#define UNI_N_CFG_GART_BASE 0x8c
+#define UNI_N_CFG_AGP_BASE 0x90
+#define UNI_N_CFG_GART_CTRL 0x94
+#define UNI_N_CFG_INTERNAL_STATUS 0x98
+
+/* UNI_N_CFG_GART_CTRL bits definitions */
+#define UNI_N_CFG_GART_INVAL 0x00000001
+#define UNI_N_CFG_GART_ENABLE 0x00000100
+#define UNI_N_CFG_GART_2xRESET 0x00010000
+
+
+/*
+ * Uni-N memory mapped reg. definitions
+ *
+ * Those registers are Big-Endian !!
+ *
+ * Their meaning come from either Darwin and/or from experiments I made with
+ * the bootrom, I'm not sure about their exact meaning yet
+ *
+ */
+
+/* Version of the UniNorth chip */
+#define UNI_N_VERSION 0x0000 /* Known versions: 3,7 and 8 */
+
+/* This register is used to enable/disable various parts */
+#define UNI_N_CLOCK_CNTL 0x0020
+#define UNI_N_CLOCK_CNTL_PCI 0x00000001 /* guess ? */
+#define UNI_N_CLOCK_CNTL_GMAC 0x00000002
+#define UNI_N_CLOCK_CNTL_FW 0x00000004 /* guess ? */
+
+/* Power Management control ? (from Darwin) */
+#define UNI_N_POWER_MGT 0x0030
+#define UNI_N_POWER_MGT_NORMAL 0x00
+#define UNI_N_POWER_MGT_IDLE2 0x01
+#define UNI_N_POWER_MGT_SLEEP 0x02
+
+/* This register is configured by Darwin depending on the UniN
+ * revision
+ */
+#define UNI_N_ARB_CTRL 0x0040
+#define UNI_N_ARB_CTRL_QACK_DELAY_SHIFT 15
+#define UNI_N_ARB_CTRL_QACK_DELAY_MASK 0x0e1f8000
+#define UNI_N_ARB_CTRL_QACK_DELAY 0x30
+#define UNI_N_ARB_CTRL_QACK_DELAY105 0x00
+
+/* This one _might_ return the CPU number of the CPU reading it;
+ * the bootROM decides wether to boot or to sleep/spinloop depending
+ * on this register beeing 0 or not
+ */
+#define UNI_N_CPU_NUMBER 0x0050
+
+/* This register appear to be read by the bootROM to decide what
+ * to do on a non-recoverable reset (powerup or wakeup)
+ */
+#define UNI_N_HWINIT_STATE 0x0070
+#define UNI_N_HWINIT_STATE_SLEEPING 0x01
+#define UNI_N_HWINIT_STATE_RUNNING 0x02
+/* This last bit appear to be used by the bootROM to know the second
+ * CPU has started and will enter it's sleep loop with IP=0
+ */
+#define UNI_N_HWINIT_STATE_CPU1_FLAG 0x10000000
+
+
+
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-ppc/unistd.h linux/include/asm-ppc/unistd.h
--- v2.4.0-test8/linux/include/asm-ppc/unistd.h Fri Aug 11 14:29:03 2000
+++ linux/include/asm-ppc/unistd.h Sun Sep 17 09:48:08 2000
@@ -201,10 +201,10 @@
X #define __NR_stat64 195
X #define __NR_lstat64 196
X #define __NR_fstat64 197
-#define __NR_sys_pciconfig_read 198
-#define __NR_sys_pciconfig_write 199
-#define __NR_sys_pciconfig_iobase 200
-#define __NR_multiplexer 201
+#define __NR_pciconfig_read 198
+#define __NR_pciconfig_write 199
+#define __NR_pciconfig_iobase 200
+#define __NR_multiplexer 201
X #define __NR_getdents64 202
X
X #define __NR(n) #n
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-s390/fcntl.h linux/include/asm-s390/fcntl.h
--- v2.4.0-test8/linux/include/asm-s390/fcntl.h Wed Jul 5 11:13:39 2000
+++ linux/include/asm-s390/fcntl.h Fri Sep 22 14:21:21 2000
@@ -54,6 +54,9 @@


X #define F_EXLCK 4 /* or 3 */
X #define F_SHLCK 8 /* or 4 */
X
+/* for leases */
+#define F_INPROGRESS 16
+
X /* operations for bsd flock(), also used by the kernel implementation */
X #define LOCK_SH 1 /* shared lock */
X #define LOCK_EX 2 /* exclusive lock */

@@ -61,6 +64,11 @@


X blocking */
X #define LOCK_UN 8 /* remove lock */
X
+#define LOCK_MAND 32 /* This is a mandatory flock */
+#define LOCK_READ 64 /* ... Which allows concurrent read operations */
+#define LOCK_WRITE 128 /* ... Which allows concurrent write operations */
+#define LOCK_RW 192 /* ... Which allows concurrent read & write ops */
+
X struct flock {
X short l_type;
X short l_whence;

@@ -69,4 +77,5 @@


X pid_t l_pid;
X };
X
+#define F_LINUX_SPECIFIC_BASE 1024
X #endif

diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-s390/resource.h linux/include/asm-s390/resource.h
--- v2.4.0-test8/linux/include/asm-s390/resource.h Fri May 12 11:41:44 2000
+++ linux/include/asm-s390/resource.h Fri Sep 22 14:21:21 2000
@@ -23,8 +23,9 @@


X #define RLIMIT_NOFILE 7 /* max number of open files */
X #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
X #define RLIMIT_AS 9 /* address space limit */

+#define RLIMIT_AS 10 /* maximum file locks held */


X
-#define RLIM_NLIMITS 10
+#define RLIM_NLIMITS 11
X
X /*
X * SuS says limits have to be unsigned.

@@ -44,6 +45,7 @@
X { LONG_MAX, LONG_MAX }, \
X { MAX_TASKS_PER_USER, MAX_TASKS_PER_USER }, \


X { INR_OPEN, INR_OPEN }, \
+ { LONG_MAX, LONG_MAX }, \
X { LONG_MAX, LONG_MAX }, \

X { LONG_MAX, LONG_MAX }, \
X }
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sh/atomic.h linux/include/asm-sh/atomic.h
--- v2.4.0-test8/linux/include/asm-sh/atomic.h Tue Apr 25 16:53:13 2000
+++ linux/include/asm-sh/atomic.h Tue Oct 3 09:24:40 2000
@@ -7,13 +7,7 @@


X *
X */
X

-#include <linux/config.h>
-
-#ifdef CONFIG_SMP
X typedef struct { volatile int counter; } atomic_t;
-#else
-typedef struct { int counter; } atomic_t;
-#endif
X

X #define ATOMIC_INIT(i) ( (atomic_t) { (i) } )
X

@@ -23,19 +17,12 @@
X #include <asm/system.h>
X
X /*


- * Make sure gcc doesn't try to be clever and move things around

- * on us. We need to use _exactly_ the address the user gave us,
- * not some alias that contains the same information.
- */


-#define __atomic_fool_gcc(x) (*(volatile struct { int a[100]; } *)x)
-

-/*
X * To get proper branch prediction for the main line, we must branch
X * forward to code at the end of this object's .text section, then
X * branch back to restart the operation.

X */
X

-extern __inline__ void atomic_add(int i, atomic_t * v)

+static __inline__ void atomic_add(int i, atomic_t * v)
X {

X unsigned long flags;
X

@@ -44,7 +31,7 @@
X restore_flags(flags);
X }
X
-extern __inline__ void atomic_sub(int i, atomic_t *v)


+static __inline__ void atomic_sub(int i, atomic_t *v)
X {

X unsigned long flags;
X

@@ -53,7 +40,7 @@
X restore_flags(flags);
X }
X
-extern __inline__ int atomic_add_return(int i, atomic_t * v)
+static __inline__ int atomic_add_return(int i, atomic_t * v)
X {
X unsigned long temp, flags;
X
@@ -66,7 +53,7 @@
X return temp;
X }
X
-extern __inline__ int atomic_sub_return(int i, atomic_t * v)
+static __inline__ int atomic_sub_return(int i, atomic_t * v)
X {
X unsigned long temp, flags;
X
@@ -88,7 +75,7 @@
X #define atomic_inc(v) atomic_add(1,(v))
X #define atomic_dec(v) atomic_sub(1,(v))
X
-extern __inline__ void atomic_clear_mask(unsigned int mask, atomic_t *v)
+static __inline__ void atomic_clear_mask(unsigned int mask, atomic_t *v)
X {


X unsigned long flags;
X

@@ -97,7 +84,7 @@
X restore_flags(flags);
X }
X
-extern __inline__ void atomic_set_mask(unsigned int mask, atomic_t *v)
+static __inline__ void atomic_set_mask(unsigned int mask, atomic_t *v)


X {
X unsigned long flags;

X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sh/bitops.h linux/include/asm-sh/bitops.h
--- v2.4.0-test8/linux/include/asm-sh/bitops.h Fri Jul 21 14:21:06 2000
+++ linux/include/asm-sh/bitops.h Mon Oct 2 11:57:34 2000
@@ -6,7 +6,7 @@
X /* For __swab32 */
X #include <asm/byteorder.h>
X

-extern __inline__ void set_bit(int nr, volatile void * addr)
+static __inline__ void set_bit(int nr, volatile void * addr)
X {

X int mask;
X volatile unsigned int *a = addr;
@@ -19,7 +19,12 @@
X restore_flags(flags);


X }
X
-extern __inline__ void clear_bit(int nr, volatile void * addr)
+/*

+ * clear_bit() doesn't provide any barrier for the compiler.
+ */
+#define smp_mb__before_clear_bit() barrier()
+#define smp_mb__after_clear_bit() barrier()
+static __inline__ void clear_bit(int nr, volatile void * addr)
X {

X int mask;
X volatile unsigned int *a = addr;
@@ -32,7 +37,7 @@
X restore_flags(flags);


X }
X
-extern __inline__ void change_bit(int nr, volatile void * addr)
+static __inline__ void change_bit(int nr, volatile void * addr)
X {

X int mask;
X volatile unsigned int *a = addr;
@@ -45,7 +50,7 @@
X restore_flags(flags);


X }
X
-extern __inline__ int test_and_set_bit(int nr, volatile void * addr)

+static __inline__ int test_and_set_bit(int nr, volatile void * addr)
X {

X int mask, retval;
X volatile unsigned int *a = addr;
@@ -61,7 +66,7 @@
X return retval;


X }
X
-extern __inline__ int test_and_clear_bit(int nr, volatile void * addr)
+static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
X {

X int mask, retval;
X volatile unsigned int *a = addr;
@@ -77,7 +82,7 @@
X return retval;


X }
X
-extern __inline__ int test_and_change_bit(int nr, volatile void * addr)
+static __inline__ int test_and_change_bit(int nr, volatile void * addr)
X {

X int mask, retval;
X volatile unsigned int *a = addr;
@@ -94,12 +99,12 @@
X }
X
X
-extern __inline__ int test_bit(int nr, const volatile void *addr)
+static __inline__ int test_bit(int nr, const volatile void *addr)
X {
X return 1UL & (((const volatile unsigned int *) addr)[nr >> 5] >> (nr & 31));
X }
X

-extern __inline__ unsigned long ffz(unsigned long word)
+static __inline__ unsigned long ffz(unsigned long word)
X {

X unsigned long result;
X
@@ -108,11 +113,12 @@
X "bt/s 1b\n\t"
X " add #1, %0"
X : "=r" (result), "=r" (word)
- : "0" (~0L), "1" (word));
+ : "0" (~0L), "1" (word)
+ : "t");


X return result;
X }
X

-extern __inline__ int find_next_zero_bit(void *addr, int size, int offset)
+static __inline__ int find_next_zero_bit(void *addr, int size, int offset)
X {
X unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
X unsigned long result = offset & ~31UL;
@@ -159,7 +165,7 @@
X #define ext2_find_next_zero_bit(addr, size, offset) \
X find_next_zero_bit((addr), (size), (offset))
X #else
-extern __inline__ int ext2_set_bit(int nr, volatile void * addr)
+static __inline__ int ext2_set_bit(int nr, volatile void * addr)
X {
X int mask, retval;
X unsigned long flags;
@@ -174,7 +180,7 @@
X return retval;
X }
X
-extern __inline__ int ext2_clear_bit(int nr, volatile void * addr)
+static __inline__ int ext2_clear_bit(int nr, volatile void * addr)
X {
X int mask, retval;
X unsigned long flags;
@@ -189,7 +195,7 @@
X return retval;
X }
X
-extern __inline__ int ext2_test_bit(int nr, const volatile void * addr)
+static __inline__ int ext2_test_bit(int nr, const volatile void * addr)
X {
X int mask;
X const volatile unsigned char *ADDR = (const unsigned char *) addr;
@@ -202,7 +208,7 @@


X #define ext2_find_first_zero_bit(addr, size) \
X ext2_find_next_zero_bit((addr), (size), 0)
X

-extern __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
+static __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset)
X {
X unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
X unsigned long result = offset & ~31UL;
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sh/checksum.h linux/include/asm-sh/checksum.h
--- v2.4.0-test8/linux/include/asm-sh/checksum.h Sat Jul 22 07:42:06 2000
+++ linux/include/asm-sh/checksum.h Mon Oct 2 11:57:34 2000
@@ -82,7 +82,8 @@
X "add %1, %0\n\t"
X "not %0, %0\n\t"
X : "=r" (sum), "=&r" (__dummy)
- : "0" (sum));
+ : "0" (sum)
+ : "t");


X return sum;
X }
X

@@ -115,7 +116,8 @@
X are modified, we must also specify them as outputs, or gcc
X will assume they contain their original values. */
X : "=r" (sum), "=r" (iph), "=r" (ihl), "=&r" (__dummy0), "=&z" (__dummy1)
- : "1" (iph), "2" (ihl));
+ : "1" (iph), "2" (ihl)
+ : "t");
X
X return csum_fold(sum);
X }
@@ -138,7 +140,8 @@
X "movt %0\n\t"
X "add %1, %0"
X : "=r" (sum), "=r" (len_proto)
- : "r" (daddr), "r" (saddr), "1" (len_proto), "0" (sum));
+ : "r" (daddr), "r" (saddr), "1" (len_proto), "0" (sum)
+ : "t");


X return sum;
X }
X

@@ -197,7 +200,8 @@
X "add %1, %0\n"
X : "=r" (sum), "=&r" (__dummy)
X : "r" (saddr), "r" (daddr),
- "r" (htonl(len)), "r" (htonl(proto)), "0" (sum));
+ "r" (htonl(len)), "r" (htonl(proto)), "0" (sum)
+ : "t");
X
X return csum_fold(sum);
X }
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sh/delay.h linux/include/asm-sh/delay.h
--- v2.4.0-test8/linux/include/asm-sh/delay.h Wed Aug 9 13:59:04 2000
+++ linux/include/asm-sh/delay.h Mon Oct 2 11:57:34 2000
@@ -15,7 +15,8 @@
X "bf/s 1b\n\t"
X " dt %0"
X : "=r" (loops)
- : "0" (loops));
+ : "0" (loops)
+ : "t");
X }
X
X extern __inline__ void __udelay(unsigned long usecs, unsigned long lps)
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sh/fcntl.h linux/include/asm-sh/fcntl.h
--- v2.4.0-test8/linux/include/asm-sh/fcntl.h Wed Jul 5 11:13:39 2000
+++ linux/include/asm-sh/fcntl.h Mon Oct 2 11:57:34 2000

X struct flock {
X short l_type;
X short l_whence;

@@ -62,5 +74,14 @@


X pid_t l_pid;
X };
X
+struct flock64 {
+ short l_type;
+ short l_whence;
+ loff_t l_start;
+ loff_t l_len;
+ pid_t l_pid;
+};
+
+#define F_LINUX_SPECIFIC_BASE 1024

X #endif /* __ASM_SH_FCNTL_H */
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sh/ide.h linux/include/asm-sh/ide.h
--- v2.4.0-test8/linux/include/asm-sh/ide.h Wed Aug 9 13:59:04 2000
+++ linux/include/asm-sh/ide.h Mon Oct 2 11:57:34 2000
@@ -18,7 +18,8 @@
X #include <asm/machvec.h>
X
X #ifndef MAX_HWIFS
-#define MAX_HWIFS 1
+/* Should never have less than 2, ide-pci.c(ide_match_hwif) requires it */
+#define MAX_HWIFS 2
X #endif
X
X #define ide__sti() __sti()
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sh/io_hd64461.h linux/include/asm-sh/io_hd64461.h
--- v2.4.0-test8/linux/include/asm-sh/io_hd64461.h Wed Aug 9 13:59:04 2000
+++ linux/include/asm-sh/io_hd64461.h Mon Oct 2 11:57:34 2000
@@ -62,6 +62,10 @@
X # define __writew generic_writew
X # define __writel generic_writel
X
+# define __isa_port2addr generic_isa_port2addr
+# define __ioremap generic_ioremap
+# define __iounmap generic_iounmap
+
X #endif
X
X #endif /* _ASM_SH_IO_HD64461_H */
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sh/irq.h linux/include/asm-sh/irq.h
--- v2.4.0-test8/linux/include/asm-sh/irq.h Wed Aug 9 13:59:04 2000
+++ linux/include/asm-sh/irq.h Mon Oct 2 11:57:34 2000
@@ -42,6 +42,7 @@
X #if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709)
X #define SCIF_ERI_IRQ 56
X #define SCIF_RXI_IRQ 57
+#define SCIF_BRI_IRQ 58
X #define SCIF_TXI_IRQ 59
X #define SCIF_IPR_ADDR INTC_IPRE
X #define SCIF_IPR_POS 1
@@ -49,6 +50,7 @@
X
X #define IRDA_ERI_IRQ 52
X #define IRDA_RXI_IRQ 53
+#define IRDA_BRI_IRQ 54
X #define IRDA_TXI_IRQ 55
X #define IRDA_IPR_ADDR INTC_IPRE
X #define IRDA_IPR_POS 2
@@ -56,6 +58,7 @@
X #elif defined(CONFIG_CPU_SUBTYPE_SH7750)
X #define SCIF_ERI_IRQ 40
X #define SCIF_RXI_IRQ 41
+#define SCIF_BRI_IRQ 42
X #define SCIF_TXI_IRQ 43
X #define SCIF_IPR_ADDR INTC_IPRC
X #define SCIF_IPR_POS 1
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sh/page.h linux/include/asm-sh/page.h
--- v2.4.0-test8/linux/include/asm-sh/page.h Wed Aug 9 13:46:01 2000
+++ linux/include/asm-sh/page.h Mon Oct 2 11:57:34 2000
@@ -9,7 +9,7 @@
X [ P0/U0 (virtual) ] 0x00000000 <------ User space
X [ P1 (fixed) cached ] 0x80000000 <------ Kernel space
X [ P2 (fixed) non-cachable] 0xA0000000 <------ Physical access
- [ P3 (virtual) cached] 0xC0000000 <------ not used
+ [ P3 (virtual) cached] 0xC0000000 <------ vmalloced area
X [ P4 control ] 0xE0000000
X */
X

@@ -26,8 +26,14 @@
X

X #define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
X #define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE)
+
+#if defined(__sh3__)
X #define clear_user_page(page, vaddr) clear_page(page)
X #define copy_user_page(to, from, vaddr) copy_page(to, from)
+#elif defined(__SH4__)
+extern void clear_user_page(void *to, unsigned long address);
+extern void copy_user_page(void *to, void *from, unsigned long address);
+#endif
X
X /*
X * These are used to make use of C type-checking..
@@ -62,7 +68,7 @@
X
X #define __MEMORY_START CONFIG_MEMORY_START
X
-#define PAGE_OFFSET (0x80000000)
+#define PAGE_OFFSET (0x80000000UL)
X #define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
X #define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
X #define virt_to_page(kaddr) (mem_map + ((__pa(kaddr)-__MEMORY_START) >> PAGE_SHIFT))
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sh/pci.h linux/include/asm-sh/pci.h
--- v2.4.0-test8/linux/include/asm-sh/pci.h Wed Aug 9 13:59:04 2000
+++ linux/include/asm-sh/pci.h Mon Oct 2 11:57:34 2000
@@ -18,12 +18,12 @@
X #define PCIBIOS_MIN_MEM 0x10000000
X #endif
X
-extern inline void pcibios_set_master(struct pci_dev *dev)
+static inline void pcibios_set_master(struct pci_dev *dev)
X {
X /* No special bus mastering setup handling */
X }
X
-extern inline void pcibios_penalize_isa_irq(int irq)
+static inline void pcibios_penalize_isa_irq(int irq)
X {
X /* We don't do dynamic PCI IRQ allocation */
X }
@@ -67,7 +67,7 @@
X * Once the device is given the dma address, the device owns this memory
X * until either pci_unmap_single or pci_dma_sync_single is performed.
X */
-extern inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
+static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr,
X size_t size,int directoin)
X {
X return virt_to_bus(ptr);
@@ -80,7 +80,7 @@
X * After this call, reads by the cpu to the buffer are guarenteed to see
X * whatever the device wrote there.
X */
-extern inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
+static inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
X size_t size,int direction)
X {
X /* Nothing to do */
@@ -101,7 +101,7 @@
X * Device ownership issues as mentioned above for pci_map_single are
X * the same here.
X */
-extern inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+static inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
X int nents,int direction)
X {
X return nents;
@@ -111,7 +111,7 @@
X * Again, cpu read rules concerning calls here are the same as for
X * pci_unmap_single() above.
X */
-extern inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
+static inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
X int nents,int direction)
X {
X /* Nothing to do */
@@ -126,7 +126,7 @@
X * next point you give the PCI dma address back to the card, the
X * device again owns the buffer.
X */
-extern inline void pci_dma_sync_single(struct pci_dev *hwdev,
+static inline void pci_dma_sync_single(struct pci_dev *hwdev,
X dma_addr_t dma_handle,
X size_t size,int direction)
X {
@@ -139,7 +139,7 @@
X * The same as pci_dma_sync_single but for a scatter-gather list,
X * same rules and usage.
X */
-extern inline void pci_dma_sync_sg(struct pci_dev *hwdev,
+static inline void pci_dma_sync_sg(struct pci_dev *hwdev,
X struct scatterlist *sg,
X int nelems,int direction)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sh/pgtable.h linux/include/asm-sh/pgtable.h
--- v2.4.0-test8/linux/include/asm-sh/pgtable.h Wed Aug 9 13:59:04 2000
+++ linux/include/asm-sh/pgtable.h Mon Oct 2 11:57:34 2000
@@ -92,45 +92,44 @@


X #define VMALLOC_VMADDR(x) ((unsigned long)(x))

X #define VMALLOC_END P4SEG
X
-#define _PAGE_PRESENT 0x001 /* software: page is present */
-#define _PAGE_ACCESSED 0x002 /* software: page referenced */
+/* 0x001 WT-bit on SH-4, 0 on SH-3 */
+#define _PAGE_HW_SHARED 0x002 /* SH-bit : page is shared among processes */
X #define _PAGE_DIRTY 0x004 /* D-bit : page changed */
X #define _PAGE_CACHABLE 0x008 /* C-bit : cachable */
-/* 0x010 SZ-bit : size of page */
+/* 0x010 SZ0-bit : Size of page */
X #define _PAGE_RW 0x020 /* PR0-bit : write access allowed */
X #define _PAGE_USER 0x040 /* PR1-bit : user space access allowed */
-#define _PAGE_PROTNONE 0x080 /* software: if not present */
-/* 0x100 V-bit : page is valid */
-/* 0x200 can be used as software flag */
-/* 0x400 can be used as software flag */
-/* 0x800 can be used as software flag */
+/* 0x080 SZ1-bit : Size of page (on SH-4) */
+#define _PAGE_PRESENT 0x100 /* V-bit : page is valid */
+#define _PAGE_PROTNONE 0x200 /* software: if not present */
+#define _PAGE_ACCESSED 0x400 /* software: page referenced */
+#define _PAGE_U0_SHARED 0x800 /* software: page is shared in user space */
X
-#if defined(__sh3__)
X /* Mask which drop software flags */
-#define _PAGE_FLAGS_HARDWARE_MASK 0x1ffff06c
-/* Flags defalult: SZ=1 (4k-byte), C=0 (non-cachable), SH=0 (not shared) */
-#define _PAGE_FLAGS_HARDWARE_DEFAULT 0x00000110
+#define _PAGE_FLAGS_HARDWARE_MASK 0x1ffff1ff
+/* Hardware flags: SZ=1 (4k-byte) */
+#define _PAGE_FLAGS_HARD 0x00000010
+
+#if defined(__sh3__)
+#define _PAGE_SHARED _PAGE_HW_SHARED
X #elif defined(__SH4__)
-/* Mask which drops software flags */
-#define _PAGE_FLAGS_HARDWARE_MASK 0x1ffff06c
-/* Flags defalult: SZ=01 (4k-byte), C=0 (non-cachable), SH=0 (not shared), WT=0 */
-#define _PAGE_FLAGS_HARDWARE_DEFAULT 0x00000110
+#define _PAGE_SHARED _PAGE_U0_SHARED
X #endif
X
X #define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
X #define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
-#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_CACHABLE | _PAGE_DIRTY)
+#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_CACHABLE | _PAGE_DIRTY | _PAGE_SHARED)
X
-#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_CACHABLE |_PAGE_ACCESSED)
-#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_CACHABLE |_PAGE_ACCESSED)
-#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_CACHABLE | _PAGE_ACCESSED)
-#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_CACHABLE | _PAGE_ACCESSED)
-#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_CACHABLE | _PAGE_DIRTY | _PAGE_ACCESSED)
-#define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_CACHABLE | _PAGE_DIRTY | _PAGE_ACCESSED)
+#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_CACHABLE |_PAGE_ACCESSED | _PAGE_FLAGS_HARD)
+#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_CACHABLE |_PAGE_ACCESSED | _PAGE_SHARED | _PAGE_FLAGS_HARD)
+#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_CACHABLE | _PAGE_ACCESSED | _PAGE_FLAGS_HARD)
+#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_CACHABLE | _PAGE_ACCESSED | _PAGE_FLAGS_HARD)
+#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_CACHABLE | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_HW_SHARED | _PAGE_FLAGS_HARD)
+#define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_CACHABLE | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_HW_SHARED | _PAGE_FLAGS_HARD)
X
X /*
X * As i386 and MIPS, SuperH can't do page protection for execute, and
- * considers that the same are read. Also, write permissions imply
+ * considers that the same as a read. Also, write permissions imply
X * read permissions. This is the closest we can get..
X */
X
@@ -184,6 +183,7 @@
X extern inline int pte_dirty(pte_t pte){ return pte_val(pte) & _PAGE_DIRTY; }
X extern inline int pte_young(pte_t pte){ return pte_val(pte) & _PAGE_ACCESSED; }
X extern inline int pte_write(pte_t pte){ return pte_val(pte) & _PAGE_RW; }
+extern inline int pte_shared(pte_t pte){ return pte_val(pte) & _PAGE_SHARED; }
X
X extern inline pte_t pte_rdprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
X extern inline pte_t pte_exprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
@@ -244,11 +244,15 @@
X unsigned long address, pte_t pte);
X
X /* Encode and de-code a swap entry */
-#define SWP_TYPE(x) (((x).val >> 1) & 0x3f)
-#define SWP_OFFSET(x) ((x).val >> 8)
-#define SWP_ENTRY(type, offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 8) })
-#define pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
-#define swp_entry_to_pte(x) ((pte_t) { (x).val })
+/*
+ * NOTE: We should set ZEROs at the position of _PAGE_PRESENT
+ * and _PAGE_PROTONOE bits
+ */
+#define SWP_TYPE(x) ((x).val & 0xff)
+#define SWP_OFFSET(x) ((x).val >> 10)
+#define SWP_ENTRY(type, offset) ((swp_entry_t) { (type) | ((offset) << 10) })
+#define pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
+#define swp_entry_to_pte(x) ((pte_t) { (x).val })


X
X #define module_map vmalloc
X #define module_unmap vfree

diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sh/resource.h linux/include/asm-sh/resource.h
--- v2.4.0-test8/linux/include/asm-sh/resource.h Sun Mar 5 09:33:55 2000
+++ linux/include/asm-sh/resource.h Fri Sep 22 14:21:21 2000


@@ -15,8 +15,9 @@
X #define RLIMIT_NOFILE 7 /* max number of open files */
X #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
X #define RLIMIT_AS 9 /* address space limit */
+#define RLIMIT_LOCKS 10 /* maximum file locks held */
X
-#define RLIM_NLIMITS 10
+#define RLIM_NLIMITS 11
X

X #ifdef __KERNEL__
X
@@ -36,6 +37,7 @@


X { RLIM_INFINITY, RLIM_INFINITY }, \
X { 0, 0 }, \
X { INR_OPEN, INR_OPEN }, \
+ { RLIM_INFINITY, RLIM_INFINITY }, \
X { RLIM_INFINITY, RLIM_INFINITY }, \
X { RLIM_INFINITY, RLIM_INFINITY }, \
X }

diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sh/string.h linux/include/asm-sh/string.h
--- v2.4.0-test8/linux/include/asm-sh/string.h Mon Mar 27 10:26:15 2000
+++ linux/include/asm-sh/string.h Mon Oct 2 11:57:34 2000
@@ -20,7 +20,7 @@
X " add #1, %0\n\t"
X : "=r" (__dest), "=r" (__src), "=&z" (__dummy)
X : "0" (__dest), "1" (__src)
- : "memory");
+ : "memory", "t");
X
X return __xdest;
X }
@@ -46,7 +46,7 @@
X "2:"
X : "=r" (__dest), "=r" (__src), "=&z" (__dummy)
X : "0" (__dest), "1" (__src), "r" (__src+__n)
- : "memory");
+ : "memory", "t");
X
X return __xdest;
X }
@@ -71,7 +71,8 @@
X "sub %3, %2\n"
X "2:"
X : "=r" (__cs), "=r" (__ct), "=&r" (__res), "=&z" (__dummy)
- : "0" (__cs), "1" (__ct));
+ : "0" (__cs), "1" (__ct)
+ : "t");
X
X return __res;
X }
@@ -82,6 +83,9 @@
X register int __res;
X unsigned long __dummy;
X
+ if (__n == 0)
+ return 0;
+
X __asm__ __volatile__(
X "mov.b @%1+, %3\n"
X "1:\n\t"
@@ -99,7 +103,8 @@
X "sub %3, %2\n"
X "3:"
X :"=r" (__cs), "=r" (__ct), "=&r" (__res), "=&z" (__dummy)
- : "0" (__cs), "1" (__ct), "r" (__cs+__n));
+ : "0" (__cs), "1" (__ct), "r" (__cs+__n)
+ : "t");
X
X return __res;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sh/system.h linux/include/asm-sh/system.h
--- v2.4.0-test8/linux/include/asm-sh/system.h Thu Aug 3 15:38:11 2000
+++ linux/include/asm-sh/system.h Mon Oct 2 11:57:34 2000
@@ -21,12 +21,12 @@
X #define prepare_to_switch() do { } while(0)
X #define switch_to(prev,next,last) do { \
X register struct task_struct *__last; \
- register unsigned long *__ts1 __asm__ ("$r1") = &prev->thread.sp; \
- register unsigned long *__ts2 __asm__ ("$r2") = &prev->thread.pc; \
- register unsigned long *__ts4 __asm__ ("$r4") = (unsigned long *)prev; \
- register unsigned long *__ts5 __asm__ ("$r5") = (unsigned long *)next; \
- register unsigned long *__ts6 __asm__ ("$r6") = &next->thread.sp; \
- register unsigned long __ts7 __asm__ ("$r7") = next->thread.pc; \
+ register unsigned long *__ts1 __asm__ ("r1") = &prev->thread.sp; \
+ register unsigned long *__ts2 __asm__ ("r2") = &prev->thread.pc; \
+ register unsigned long *__ts4 __asm__ ("r4") = (unsigned long *)prev; \
+ register unsigned long *__ts5 __asm__ ("r5") = (unsigned long *)next; \
+ register unsigned long *__ts6 __asm__ ("r6") = &next->thread.sp; \
+ register unsigned long __ts7 __asm__ ("r7") = next->thread.pc; \
X __asm__ __volatile__ (".balign 4\n\t" \
X "stc.l $gbr, @-$r15\n\t" \
X "sts.l $pr, @-$r15\n\t" \
@@ -63,7 +63,7 @@
X :"0" (prev), \
X "r" (__ts1), "r" (__ts2), \
X "r" (__ts4), "r" (__ts5), "r" (__ts6), "r" (__ts7) \
- :"r3"); \
+ :"r3", "t"); \
X last = __last; \
X } while (0)
X #endif
@@ -88,11 +88,22 @@
X #define mb() __asm__ __volatile__ ("": : :"memory")


X #define rmb() mb()
X #define wmb() __asm__ __volatile__ ("": : :"memory")
+
+#ifdef CONFIG_SMP
+#define smp_mb() mb()
+#define smp_rmb() rmb()
+#define smp_wmb() wmb()
+#else
+#define smp_mb() barrier()
+#define smp_rmb() barrier()
+#define smp_wmb() barrier()
+#endif
+
X #define set_mb(var, value) do { xchg(&var, value); } while (0)
X #define set_wmb(var, value) do { var = value; wmb(); } while (0)
X

X /* Interrupt Control */
-extern __inline__ void __sti(void)
+static __inline__ void __sti(void)
X {
X unsigned long __dummy0, __dummy1;
X
@@ -106,7 +117,7 @@


X : "memory");
X }
X

-extern __inline__ void __cli(void)
+static __inline__ void __cli(void)
X {
X unsigned long __dummy;
X __asm__ __volatile__("stc $sr, %0\n\t"
@@ -205,7 +216,7 @@
X
X #endif
X
-extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val)
+static __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val)
X {
X unsigned long flags, retval;
X
@@ -216,7 +227,7 @@
X return retval;
X }
X
-extern __inline__ unsigned long xchg_u8(volatile unsigned char * m, unsigned long val)
+static __inline__ unsigned long xchg_u8(volatile unsigned char * m, unsigned long val)
X {
X unsigned long flags, retval;
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sh/uaccess.h linux/include/asm-sh/uaccess.h
--- v2.4.0-test8/linux/include/asm-sh/uaccess.h Tue Aug 29 14:09:16 2000
+++ linux/include/asm-sh/uaccess.h Mon Oct 2 11:57:34 2000
@@ -45,11 +45,12 @@
X * sum := addr + size; carry? --> flag = true;
X * if (sum >= addr_limit) flag = true;
X */
-#define __range_ok(addr,size) ({ \
- unsigned long flag,sum; \
- __asm__("clrt; addc %3, %1; movt %0; cmp/hi %4, %1; rotcl %0" \
- :"=&r" (flag), "=r" (sum) \
- :"1" (addr), "r" ((int)(size)), "r" (current->addr_limit.seg)); \
+#define __range_ok(addr,size) ({ \
+ unsigned long flag,sum; \
+ __asm__("clrt; addc %3, %1; movt %0; cmp/hi %4, %1; rotcl %0" \
+ :"=&r" (flag), "=r" (sum) \
+ :"1" (addr), "r" ((int)(size)), "r" (current->addr_limit.seg) \
+ :"t"); \
X flag; })
X
X #define access_ok(type,addr,size) (__range_ok(addr,size) == 0)
@@ -186,7 +187,8 @@
X ".long 1b, 3b\n\t" \
X ".previous" \
X :"=&r" (__pu_err) \
- :"r" (__pu_val), "m" (__m(__pu_addr)), "i" (-EFAULT)); })
+ :"r" (__pu_val), "m" (__m(__pu_addr)), "i" (-EFAULT) \
+ :"memory"); })
X
X extern void __put_user_unknown(void);
X
@@ -224,7 +226,7 @@
X ".previous"
X : "=r" (res), "=&z" (__dummy), "=r" (_f), "=r" (_t)
X : "2" (__from), "3" (__to), "0" (res)
- : "memory");
+ : "memory", "t");
X
X return res;
X }
@@ -284,7 +286,8 @@
X " .long 1b,3b\n"
X ".previous"
X : "=r" (size), "=r" (__a)
- : "0" (size), "1" (addr), "r" (0));
+ : "0" (size), "1" (addr), "r" (0)
+ : "memory", "t");
X
X return size;
X }
@@ -330,7 +333,7 @@
X : "=r" (res), "=&z" (__dummy), "=r" (_s), "=r" (_d)
X : "0" (__count), "2" (__src), "3" (__dest), "r" (__count),
X "i" (-EFAULT)
- : "memory");
+ : "memory", "t");
X
X return res;
X }
@@ -376,7 +379,8 @@
X " .long 1b,3b\n"
X ".previous"
X : "=z" (res), "=&r" (__dummy)
- : "0" (0), "r" (__s), "r" (__n), "i" (-EFAULT));
+ : "0" (0), "r" (__s), "r" (__n), "i" (-EFAULT)
+ : "t");


X return res;
X }
X

diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sh/unistd.h linux/include/asm-sh/unistd.h
--- v2.4.0-test8/linux/include/asm-sh/unistd.h Fri Aug 11 14:29:03 2000
+++ linux/include/asm-sh/unistd.h Mon Oct 2 11:57:34 2000
@@ -230,6 +230,7 @@
X #define __NR_mincore 218
X #define __NR_madvise 219
X #define __NR_getdents64 220
+#define __NR_fcntl64 221
X
X /* user-visible error numbers are in the range -1 - -125: see <asm-sh/errno.h> */
X
@@ -249,7 +250,7 @@
X #define _syscall0(type,name) \
X type name(void) \
X { \
-register long __sc0 __asm__ ("$r3") = __NR_##name; \
+register long __sc0 __asm__ ("r3") = __NR_##name; \
X __asm__ __volatile__ ("trapa #0x10" \
X : "=z" (__sc0) \
X : "0" (__sc0) \
@@ -260,8 +261,8 @@
X #define _syscall1(type,name,type1,arg1) \
X type name(type1 arg1) \
X { \
-register long __sc0 __asm__ ("$r3") = __NR_##name; \
-register long __sc4 __asm__ ("$r4") = (long) arg1; \
+register long __sc0 __asm__ ("r3") = __NR_##name; \
+register long __sc4 __asm__ ("r4") = (long) arg1; \
X __asm__ __volatile__ ("trapa #0x11" \
X : "=z" (__sc0) \
X : "0" (__sc0), "r" (__sc4) \
@@ -272,9 +273,9 @@
X #define _syscall2(type,name,type1,arg1,type2,arg2) \


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 106'
echo 'File patch-2.4.0-test9 is continued in part 107'
echo "107" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part107

#!/bin/sh -x
# this is part 107 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 107; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

X type name(type1 arg1,type2 arg2) \


X { \
-register long __sc0 __asm__ ("$r3") = __NR_##name; \
-register long __sc4 __asm__ ("$r4") = (long) arg1; \

-register long __sc5 __asm__ ("$r5") = (long) arg2; \


+register long __sc0 __asm__ ("r3") = __NR_##name; \
+register long __sc4 __asm__ ("r4") = (long) arg1; \

+register long __sc5 __asm__ ("r5") = (long) arg2; \
X __asm__ __volatile__ ("trapa #0x12" \
X : "=z" (__sc0) \
X : "0" (__sc0), "r" (__sc4), "r" (__sc5) \
@@ -285,10 +286,10 @@
X #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
X type name(type1 arg1,type2 arg2,type3 arg3) \


X { \
-register long __sc0 __asm__ ("$r3") = __NR_##name; \
-register long __sc4 __asm__ ("$r4") = (long) arg1; \

-register long __sc5 __asm__ ("$r5") = (long) arg2; \
-register long __sc6 __asm__ ("$r6") = (long) arg3; \


+register long __sc0 __asm__ ("r3") = __NR_##name; \
+register long __sc4 __asm__ ("r4") = (long) arg1; \

+register long __sc5 __asm__ ("r5") = (long) arg2; \
+register long __sc6 __asm__ ("r6") = (long) arg3; \
X __asm__ __volatile__ ("trapa #0x13" \
X : "=z" (__sc0) \
X : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6) \
@@ -299,11 +300,11 @@
X #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
X type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \


X { \
-register long __sc0 __asm__ ("$r3") = __NR_##name; \
-register long __sc4 __asm__ ("$r4") = (long) arg1; \

-register long __sc5 __asm__ ("$r5") = (long) arg2; \
-register long __sc6 __asm__ ("$r6") = (long) arg3; \
-register long __sc7 __asm__ ("$r7") = (long) arg4; \


+register long __sc0 __asm__ ("r3") = __NR_##name; \
+register long __sc4 __asm__ ("r4") = (long) arg1; \

+register long __sc5 __asm__ ("r5") = (long) arg2; \
+register long __sc6 __asm__ ("r6") = (long) arg3; \
+register long __sc7 __asm__ ("r7") = (long) arg4; \
X __asm__ __volatile__ ("trapa #0x14" \
X : "=z" (__sc0) \
X : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6), \
@@ -315,12 +316,12 @@
X #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
X type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
X { \
-register long __sc3 __asm__ ("$r3") = __NR_##name; \


-register long __sc4 __asm__ ("$r4") = (long) arg1; \

-register long __sc5 __asm__ ("$r5") = (long) arg2; \
-register long __sc6 __asm__ ("$r6") = (long) arg3; \
-register long __sc7 __asm__ ("$r7") = (long) arg4; \
-register long __sc0 __asm__ ("$r0") = (long) arg5; \
+register long __sc3 __asm__ ("r3") = __NR_##name; \


+register long __sc4 __asm__ ("r4") = (long) arg1; \

+register long __sc5 __asm__ ("r5") = (long) arg2; \
+register long __sc6 __asm__ ("r6") = (long) arg3; \
+register long __sc7 __asm__ ("r7") = (long) arg4; \
+register long __sc0 __asm__ ("r0") = (long) arg5; \
X __asm__ __volatile__ ("trapa #0x15" \
X : "=z" (__sc0) \
X : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6), "r" (__sc7), \
@@ -345,7 +346,6 @@
X */
X #define __NR__exit __NR_exit
X static __inline__ _syscall0(int,pause)
-static __inline__ _syscall1(int,setup,int,magic)
X static __inline__ _syscall0(int,sync)
X static __inline__ _syscall0(pid_t,setsid)
X static __inline__ _syscall3(int,write,int,fd,const char *,buf,off_t,count)
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sparc/atomic.h linux/include/asm-sparc/atomic.h
--- v2.4.0-test8/linux/include/asm-sparc/atomic.h Thu Sep 7 08:32:01 2000
+++ linux/include/asm-sparc/atomic.h Tue Oct 3 09:24:41 2000
@@ -8,19 +8,12 @@


X
X #include <linux/config.h>
X

-#ifdef CONFIG_SMP
-/* This is a temporary measure. -DaveM */


X typedef struct { volatile int counter; } atomic_t;

-#define ATOMIC_INIT(i) { (i << 8) }


-#else
-typedef struct { int counter; } atomic_t;

-#define ATOMIC_INIT(i) { (i) }
-#endif
X
X #ifdef __KERNEL__
-
X #ifndef CONFIG_SMP
X
+#define ATOMIC_INIT(i) { (i) }


X #define atomic_read(v) ((v)->counter)

X #define atomic_set(v, i) (((v)->counter) = i)
X
@@ -38,6 +31,8 @@
X * ----------------------------------------
X * 31 8 7 0
X */
+
+#define ATOMIC_INIT(i) { (i << 8) }
X
X static __inline__ int atomic_read(atomic_t *v)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sparc/bitops.h linux/include/asm-sparc/bitops.h
--- v2.4.0-test8/linux/include/asm-sparc/bitops.h Sat Aug 12 12:08:50 2000
+++ linux/include/asm-sparc/bitops.h Tue Oct 3 09:24:41 2000
@@ -1,4 +1,4 @@
-/* $Id: bitops.h,v 1.60 2000/08/10 23:49:16 davem Exp $
+/* $Id: bitops.h,v 1.61 2000/09/23 02:11:22 davem Exp $
X * bitops.h: Bit string operations on the Sparc.
X *
X * Copyright 1995 David S. Miller (da...@caip.rutgers.edu)
@@ -155,6 +155,9 @@


X }
X
X #endif /* __KERNEL__ */

+
+#define smp_mb__before_clear_bit() do { } while(0)
+#define smp_mb__after_clear_bit() do { } while(0)
X
X /* The following routine need not be atomic. */
X extern __inline__ int test_bit(int nr, __const__ void *addr)
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sparc/fcntl.h linux/include/asm-sparc/fcntl.h
--- v2.4.0-test8/linux/include/asm-sparc/fcntl.h Sun Aug 13 12:01:54 2000
+++ linux/include/asm-sparc/fcntl.h Fri Sep 22 14:21:21 2000
@@ -50,6 +50,9 @@


X #define F_EXLCK 4 /* or 3 */
X #define F_SHLCK 8 /* or 4 */
X
+/* for leases */
+#define F_INPROGRESS 16
+
X /* operations for bsd flock(), also used by the kernel implementation */
X #define LOCK_SH 1 /* shared lock */
X #define LOCK_EX 2 /* exclusive lock */

@@ -57,6 +60,11 @@


X blocking */
X #define LOCK_UN 8 /* remove lock */
X
+#define LOCK_MAND 32 /* This is a mandatory flock */
+#define LOCK_READ 64 /* ... Which allows concurrent read operations */
+#define LOCK_WRITE 128 /* ... Which allows concurrent write operations */
+#define LOCK_RW 192 /* ... Which allows concurrent read & write ops */
+
X struct flock {
X short l_type;
X short l_whence;

@@ -75,4 +83,5 @@
X short __unused;


X };
X
+#define F_LINUX_SPECIFIC_BASE 1024
X #endif

diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sparc/io.h linux/include/asm-sparc/io.h
--- v2.4.0-test8/linux/include/asm-sparc/io.h Fri Apr 14 09:37:10 2000
+++ linux/include/asm-sparc/io.h Sun Sep 17 09:50:02 2000
@@ -1,5 +1,5 @@
X /*
- * $Id: io.h,v 1.27 2000/04/13 04:45:59 davem Exp $
+ * $Id: io.h,v 1.28 2000/09/17 05:12:00 davem Exp $
X */
X #ifndef __SPARC_IO_H
X #define __SPARC_IO_H
@@ -164,6 +164,8 @@
X return (void *) dst;


X }
X
+#ifdef __KERNEL__
+
X /*

X * Bus number may be embedded in the higher bits of the physical address.
X * This is why we have no bus number argument to ioremap().
@@ -199,5 +201,7 @@
X #define dma_cache_inv(_start,_size) do { } while (0)
X #define dma_cache_wback(_start,_size) do { } while (0)
X #define dma_cache_wback_inv(_start,_size) do { } while (0)
+
+#endif
X
X #endif /* !(__SPARC_IO_H) */
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sparc/resource.h linux/include/asm-sparc/resource.h
--- v2.4.0-test8/linux/include/asm-sparc/resource.h Thu Feb 17 09:35:07 2000
+++ linux/include/asm-sparc/resource.h Fri Sep 22 14:21:21 2000
@@ -21,8 +21,9 @@
X #define RLIMIT_NPROC 7 /* max number of processes */


X #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
X #define RLIMIT_AS 9 /* address space limit */
+#define RLIMIT_LOCKS 10 /* maximum file locks held */
X
-#define RLIM_NLIMITS 10
+#define RLIM_NLIMITS 11
X

X /*
X * SuS says limits have to be unsigned.

@@ -41,6 +42,7 @@
X { 0, RLIM_INFINITY}, \
X {RLIM_INFINITY, RLIM_INFINITY}, \
X {INR_OPEN, INR_OPEN}, {0, 0}, \


+ {RLIM_INFINITY, RLIM_INFINITY}, \
X {RLIM_INFINITY, RLIM_INFINITY}, \

X {RLIM_INFINITY, RLIM_INFINITY} \
X }
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sparc/system.h linux/include/asm-sparc/system.h
--- v2.4.0-test8/linux/include/asm-sparc/system.h Fri Aug 4 18:16:11 2000
+++ linux/include/asm-sparc/system.h Tue Oct 3 09:24:41 2000
@@ -1,4 +1,4 @@
-/* $Id: system.h,v 1.83 2000/08/04 05:35:55 davem Exp $ */
+/* $Id: system.h,v 1.84 2000/09/23 02:11:22 davem Exp $ */
X #include <linux/config.h>
X
X #ifndef __SPARC_SYSTEM_H
@@ -280,6 +280,9 @@
X #define wmb() mb()
X #define set_mb(__var, __value) do { __var = __value; mb(); } while(0)
X #define set_wmb(__var, __value) set_mb(__var, __value)


+#define smp_mb() __asm__ __volatile__("":::"memory");
+#define smp_rmb() __asm__ __volatile__("":::"memory");

+#define smp_wmb() __asm__ __volatile__("":::"memory");
X
X #define nop() __asm__ __volatile__ ("nop");
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sparc64/atomic.h linux/include/asm-sparc64/atomic.h
--- v2.4.0-test8/linux/include/asm-sparc64/atomic.h Thu Mar 16 11:40:17 2000
+++ linux/include/asm-sparc64/atomic.h Tue Oct 3 09:24:41 2000
@@ -8,7 +8,7 @@
X #ifndef __ARCH_SPARC64_ATOMIC__
X #define __ARCH_SPARC64_ATOMIC__
X

-typedef struct { int counter; } atomic_t;

+typedef struct { volatile int counter; } atomic_t;


X #define ATOMIC_INIT(i) { (i) }
X

X #define atomic_read(v) ((v)->counter)

diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sparc64/bitops.h linux/include/asm-sparc64/bitops.h
--- v2.4.0-test8/linux/include/asm-sparc64/bitops.h Sat Aug 12 12:08:50 2000
+++ linux/include/asm-sparc64/bitops.h Tue Oct 3 09:24:41 2000
@@ -1,4 +1,4 @@
-/* $Id: bitops.h,v 1.30 2000/08/10 23:49:16 davem Exp $
+/* $Id: bitops.h,v 1.31 2000/09/23 02:09:21 davem Exp $
X * bitops.h: Bit string operations on the V9.
X *
X * Copyright 1996, 1997 David S. Miller (da...@caip.rutgers.edu)
@@ -19,6 +19,9 @@
X #define set_bit(nr,addr) ((void)__test_and_set_bit(nr,addr))
X #define clear_bit(nr,addr) ((void)__test_and_clear_bit(nr,addr))
X #define change_bit(nr,addr) ((void)__test_and_change_bit(nr,addr))
+
+#define smp_mb__before_clear_bit() do { } while(0)
+#define smp_mb__after_clear_bit() do { } while(0)
X
X extern __inline__ int test_bit(int nr, __const__ void *addr)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sparc64/fcntl.h linux/include/asm-sparc64/fcntl.h
--- v2.4.0-test8/linux/include/asm-sparc64/fcntl.h Sun Aug 13 12:01:54 2000
+++ linux/include/asm-sparc64/fcntl.h Fri Sep 22 14:21:21 2000
@@ -52,6 +52,9 @@


X #define F_EXLCK 4 /* or 3 */
X #define F_SHLCK 8 /* or 4 */
X
+/* for leases */
+#define F_INPROGRESS 16
+
X /* operations for bsd flock(), also used by the kernel implementation */
X #define LOCK_SH 1 /* shared lock */
X #define LOCK_EX 2 /* exclusive lock */

@@ -59,6 +62,11 @@


X blocking */
X #define LOCK_UN 8 /* remove lock */
X
+#define LOCK_MAND 32 /* This is a mandatory flock */
+#define LOCK_READ 64 /* ... Which allows concurrent read operations */
+#define LOCK_WRITE 128 /* ... Which allows concurrent write operations */
+#define LOCK_RW 192 /* ... Which allows concurrent read & write ops */
+
X struct flock {
X short l_type;
X short l_whence;

@@ -83,4 +91,5 @@


X #define flock64 flock
X #endif

X
+#define F_LINUX_SPECIFIC_BASE 1024
X #endif /* !(_SPARC64_FCNTL_H) */
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sparc64/io.h linux/include/asm-sparc64/io.h
--- v2.4.0-test8/linux/include/asm-sparc64/io.h Fri Apr 14 09:37:10 2000
+++ linux/include/asm-sparc64/io.h Sun Sep 17 09:50:02 2000
@@ -1,4 +1,4 @@
-/* $Id: io.h,v 1.35 2000/04/13 04:45:59 davem Exp $ */
+/* $Id: io.h,v 1.36 2000/09/17 05:12:00 davem Exp $ */
X #ifndef __SPARC64_IO_H
X #define __SPARC64_IO_H
X
@@ -363,6 +363,8 @@


X return retval;
X }
X

+#ifdef __KERNEL__
+
X /* On sparc64 we have the whole physical IO address space accessible
X * using physically addressed loads and stores, so this does nothing.
X */
@@ -388,5 +390,7 @@
X #define dma_cache_inv(_start,_size) do { } while (0)
X #define dma_cache_wback(_start,_size) do { } while (0)
X #define dma_cache_wback_inv(_start,_size) do { } while (0)
+
+#endif
X
X #endif /* !(__SPARC64_IO_H) */
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sparc64/resource.h linux/include/asm-sparc64/resource.h
--- v2.4.0-test8/linux/include/asm-sparc64/resource.h Thu Feb 17 09:35:07 2000
+++ linux/include/asm-sparc64/resource.h Fri Sep 22 14:21:21 2000
@@ -21,8 +21,9 @@
X #define RLIMIT_NPROC 7 /* max number of processes */


X #define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
X #define RLIMIT_AS 9 /* address space limit */
+#define RLIMIT_LOCKS 10 /* maximum file locks held */
X
-#define RLIM_NLIMITS 10
+#define RLIM_NLIMITS 11
X

X /*
X * SuS says limits have to be unsigned.

@@ -40,6 +41,7 @@
X { 0, RLIM_INFINITY}, \
X {RLIM_INFINITY, RLIM_INFINITY}, \
X {INR_OPEN, INR_OPEN}, {0, 0}, \


+ {RLIM_INFINITY, RLIM_INFINITY}, \
X {RLIM_INFINITY, RLIM_INFINITY}, \

X {RLIM_INFINITY, RLIM_INFINITY} \
X }
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sparc64/smp.h linux/include/asm-sparc64/smp.h
--- v2.4.0-test8/linux/include/asm-sparc64/smp.h Fri Aug 4 16:15:37 2000
+++ linux/include/asm-sparc64/smp.h Tue Oct 3 09:24:41 2000
@@ -9,6 +9,7 @@
X #include <linux/config.h>
X #include <linux/threads.h>
X #include <asm/asi.h>
+#include <asm/starfire.h>
X
X #ifndef __ASSEMBLY__
X /* PROM provided per-processor information we need
@@ -82,11 +83,7 @@
X
X extern __inline__ int hard_smp_processor_id(void)
X {
- extern int this_is_starfire;
-
X if(this_is_starfire != 0) {
- extern int starfire_hard_smp_processor_id(void);
-
X return starfire_hard_smp_processor_id();
X } else {
X unsigned long upaconfig;
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sparc64/starfire.h linux/include/asm-sparc64/starfire.h
--- v2.4.0-test8/linux/include/asm-sparc64/starfire.h Wed Dec 31 16:00:00 1969
+++ linux/include/asm-sparc64/starfire.h Tue Oct 3 09:24:41 2000
@@ -0,0 +1,21 @@
+/* $Id: starfire.h,v 1.1 2000/09/21 06:18:53 anton Exp $
+ * starfire.h: Group all starfire specific code together.
+ *
+ * Copyright (C) 2000 Anton Blanchard (an...@linuxcare.com)
+ */
+
+#ifndef _SPARC64_STARFIRE_H
+#define _SPARC64_STARFIRE_H
+
+#ifndef __ASSEMBLY__
+
+extern int this_is_starfire;
+
+extern void check_if_starfire(void);
+extern void starfire_cpu_setup(void);
+extern int starfire_hard_smp_processor_id(void);
+extern void *starfire_hookup(int);
+extern unsigned int starfire_translate(unsigned long imap, unsigned int upaid);
+
+#endif
+#endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/asm-sparc64/system.h linux/include/asm-sparc64/system.h
--- v2.4.0-test8/linux/include/asm-sparc64/system.h Fri Aug 4 18:16:11 2000
+++ linux/include/asm-sparc64/system.h Tue Oct 3 09:24:41 2000
@@ -1,4 +1,4 @@
-/* $Id: system.h,v 1.61 2000/08/04 05:35:55 davem Exp $ */
+/* $Id: system.h,v 1.62 2000/09/23 02:09:21 davem Exp $ */
X #ifndef __SPARC64_SYSTEM_H
X #define __SPARC64_SYSTEM_H
X
@@ -95,17 +95,27 @@
X
X #endif
X
-#define mb() __asm__ __volatile__ ("stbar" : : : "memory")
-
X #define nop() __asm__ __volatile__ ("nop")
X
X #define membar(type) __asm__ __volatile__ ("membar " type : : : "memory");
-#define rmb() membar("#LoadLoad | #LoadStore")
-#define wmb() membar("#StoreLoad | #StoreStore")
+#define mb() \
+ membar("#LoadLoad | #LoadStore | #StoreStore | #StoreLoad");
+#define rmb() membar("#LoadLoad")
+#define wmb() membar("#StoreStore")
X #define set_mb(__var, __value) \
X do { __var = __value; membar("#StoreLoad | #StoreStore"); } while(0)
X #define set_wmb(__var, __value) \
X do { __var = __value; membar("#StoreStore"); } while(0)


+
+#ifdef CONFIG_SMP
+#define smp_mb() mb()
+#define smp_rmb() rmb()
+#define smp_wmb() wmb()
+#else

+#define smp_mb() __asm__ __volatile__("":::"memory");
+#define smp_rmb() __asm__ __volatile__("":::"memory");
+#define smp_wmb() __asm__ __volatile__("":::"memory");
+#endif

X
X #define flushi(addr) __asm__ __volatile__ ("flush %0" : : "r" (addr) : "memory")
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/ac97_codec.h linux/include/linux/ac97_codec.h
--- v2.4.0-test8/linux/include/linux/ac97_codec.h Tue Jun 20 07:52:36 2000
+++ linux/include/linux/ac97_codec.h Mon Oct 2 11:01:20 2000
@@ -142,6 +142,7 @@
X char *name;
X int id;
X int dev_mixer;
+ int type;
X
X /* codec specific init/reset routines, used mainly for 4 or 6 channel support */
X int (*codec_init) (struct ac97_codec *codec);
@@ -158,7 +159,9 @@
X int supported_mixers;
X int stereo_mixers;
X int record_sources;
-
+
+ int bit_resolution;
+
X /* OSS mixer interface */
X int (*read_mixer) (struct ac97_codec *codec, int oss_channel);
X void (*write_mixer)(struct ac97_codec *codec, int oss_channel,
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/adb.h linux/include/linux/adb.h
--- v2.4.0-test8/linux/include/linux/adb.h Tue Oct 12 10:00:58 1999
+++ linux/include/linux/adb.h Sun Sep 17 09:48:05 2000
@@ -58,7 +58,6 @@
X int (*probe)(void);
X int (*init)(void);
X int (*send_request)(struct adb_request *req, int sync);
- /*int (*write)(struct adb_request *req);*/
X int (*autopoll)(int devs);
X void (*poll)(void);
X int (*reset_bus)(void);
@@ -83,6 +82,7 @@
X int flags, int nbytes, ...);
X int adb_register(int default_id,int handler_id,struct adb_ids *ids,
X void (*handler)(unsigned char *, int, struct pt_regs *, int));
+int adb_unregister(int index);
X void adb_poll(void);
X void adb_input(unsigned char *, int, struct pt_regs *, int);
X int adb_reset_bus(void);
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/adfs_fs.h linux/include/linux/adfs_fs.h
--- v2.4.0-test8/linux/include/linux/adfs_fs.h Fri Sep 8 12:52:55 2000
+++ linux/include/linux/adfs_fs.h Mon Oct 2 11:01:25 2000
@@ -46,7 +46,7 @@
X * appear to be correct if the sector contains all zeros, so also check that
X * the disk size is non-zero!!!
X */
-extern inline int adfs_checkbblk(unsigned char *ptr)
+static inline int adfs_checkbblk(unsigned char *ptr)
X {
X unsigned int result = 0;
X unsigned char *p = ptr + 511;
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/arcdevice.h linux/include/linux/arcdevice.h
--- v2.4.0-test8/linux/include/linux/arcdevice.h Mon Jul 31 14:25:52 2000
+++ linux/include/linux/arcdevice.h Sun Sep 17 09:45:05 2000
@@ -340,7 +340,6 @@
X void arcnet_raw_init(void);
X
X int com90xx_probe(struct net_device *dev);
-void com20020pci_probe_all(void);
X
X #endif /* __KERNEL__ */
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/atalk.h linux/include/linux/atalk.h
--- v2.4.0-test8/linux/include/linux/atalk.h Fri Sep 8 12:52:42 2000
+++ linux/include/linux/atalk.h Mon Oct 2 11:01:18 2000
@@ -161,7 +161,7 @@
X * Give a device find its atif control structure
X */
X
-extern __inline__ struct atalk_iface *atalk_find_dev(struct net_device *dev)
+static inline struct atalk_iface *atalk_find_dev(struct net_device *dev)
X {
X return dev->atalk_ptr;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/blk.h linux/include/linux/blk.h
--- v2.4.0-test8/linux/include/linux/blk.h Fri Sep 8 12:54:09 2000
+++ linux/include/linux/blk.h Mon Oct 2 11:02:34 2000
@@ -308,7 +308,7 @@
X #elif (MAJOR_NR == I2O_MAJOR)
X
X #define DEVICE_NAME "I2O block"
-#define DEVICE_REQUEST do_i2ob_request
+#define DEVICE_REQUEST i2ob_request
X #define DEVICE_NR(device) (MINOR(device)>>4)
X
X #elif (MAJOR_NR == COMPAQ_SMART2_MAJOR)
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/brlock.h linux/include/linux/brlock.h
--- v2.4.0-test8/linux/include/linux/brlock.h Fri Sep 8 12:52:42 2000
+++ linux/include/linux/brlock.h Mon Oct 2 11:01:18 2000
@@ -114,10 +114,23 @@
X lock = &__br_write_locks[idx].lock;
X again:
X (*ctr)++;
- rmb();
+ mb();
X if (spin_is_locked(lock)) {
X (*ctr)--;
- rmb();
+ wmb(); /*
+ * The release of the ctr must become visible
+ * to the other cpus eventually thus wmb(),
+ * we don't care if spin_is_locked is reordered
+ * before the releasing of the ctr.
+ * However IMHO this wmb() is superflous even in theory.
+ * It would not be superflous only if on the
+ * other CPUs doing a ldl_l instead of an ldl
+ * would make a difference and I don't think this is
+ * the case.
+ * I'd like to clarify this issue further
+ * but for now this is a slow path so adding the
+ * wmb() will keep us on the safe side.
+ */
X while (spin_is_locked(lock))
X barrier();
X goto again;
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/byteorder/swab.h linux/include/linux/byteorder/swab.h
--- v2.4.0-test8/linux/include/linux/byteorder/swab.h Tue Sep 1 10:50:11 1998
+++ linux/include/linux/byteorder/swab.h Tue Sep 19 17:56:31 2000
@@ -43,33 +43,33 @@
X * provide defaults when no architecture-specific optimization is detected
X */
X #ifndef __arch__swab16
-# define __arch__swab16(x) ___swab16(x)
+# define __arch__swab16(x) ({ __u16 __tmp = (x) ; ___swab16(__tmp); })
X #endif
X #ifndef __arch__swab32
-# define __arch__swab32(x) ___swab32(x)
+# define __arch__swab32(x) ({ __u32 __tmp = (x) ; ___swab32(__tmp); })
X #endif
X #ifndef __arch__swab64
-# define __arch__swab64(x) ___swab64(x)
+# define __arch__swab64(x) ({ __u64 __tmp = (x) ; ___swab64(__tmp); })
X #endif
X
X #ifndef __arch__swab16p
-# define __arch__swab16p(x) __swab16(*(x))
+# define __arch__swab16p(x) __arch__swab16(*(x))
X #endif
X #ifndef __arch__swab32p
-# define __arch__swab32p(x) __swab32(*(x))
+# define __arch__swab32p(x) __arch__swab32(*(x))
X #endif
X #ifndef __arch__swab64p
-# define __arch__swab64p(x) __swab64(*(x))
+# define __arch__swab64p(x) __arch__swab64(*(x))
X #endif
X
X #ifndef __arch__swab16s
-# define __arch__swab16s(x) do { *(x) = __swab16p((x)); } while (0)
+# define __arch__swab16s(x) do { *(x) = __arch__swab16p((x)); } while (0)
X #endif
X #ifndef __arch__swab32s
-# define __arch__swab32s(x) do { *(x) = __swab32p((x)); } while (0)
+# define __arch__swab32s(x) do { *(x) = __arch__swab32p((x)); } while (0)
X #endif
X #ifndef __arch__swab64s
-# define __arch__swab64s(x) do { *(x) = __swab64p((x)); } while (0)
+# define __arch__swab64s(x) do { *(x) = __arch__swab64p((x)); } while (0)
X #endif
X
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/capability.h linux/include/linux/capability.h
--- v2.4.0-test8/linux/include/linux/capability.h Fri Sep 8 12:52:42 2000
+++ linux/include/linux/capability.h Mon Oct 2 11:01:19 2000
@@ -273,6 +273,10 @@
X
X #define CAP_MKNOD 27
X
+/* Allow taking of leases on files */
+
+#define CAP_LEASE 28
+
X #ifdef __KERNEL__
X /*
X * Bounding set
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/cciss_ioctl.h linux/include/linux/cciss_ioctl.h
--- v2.4.0-test8/linux/include/linux/cciss_ioctl.h Wed Dec 31 16:00:00 1969
+++ linux/include/linux/cciss_ioctl.h Fri Sep 22 17:11:37 2000
@@ -0,0 +1,186 @@
+#ifndef CCISS_IOCTLH
+#define CCISS_IOCTLH
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define CCISS_IOC_MAGIC 'B'
+
+
+typedef struct _cciss_pci_info_struct
+{
+ unsigned char bus;
+ unsigned char dev_fn;
+ __u32 board_id;
+} cciss_pci_info_struct;
+
+typedef struct _cciss_coalint_struct
+{
+ __u32 delay;
+ __u32 count;
+} cciss_coalint_struct;
+
+typedef char NodeName_type[16];
+
+typedef __u32 Heartbeat_type;
+
+#define CISS_PARSCSIU2 0x0001
+#define CISS_PARCSCIU3 0x0002
+#define CISS_FIBRE1G 0x0100
+#define CISS_FIBRE2G 0x0200
+typedef __u32 BusTypes_type;
+
+typedef char FirmwareVer_type[4];
+typedef __u32 DriverVer_type;
+
+
+#ifndef CCISS_CMD_H
+// This defines are duplicated in cciss_cmd.h in the driver directory
+
+//general boundary defintions
+#define SENSEINFOBYTES 32//note that this value may vary between host implementations
+
+//Command Status value
+#define CMD_SUCCESS 0x0000
+#define CMD_TARGET_STATUS 0x0001
+#define CMD_DATA_UNDERRUN 0x0002
+#define CMD_DATA_OVERRUN 0x0003
+#define CMD_INVALID 0x0004
+#define CMD_PROTOCOL_ERR 0x0005
+#define CMD_HARDWARE_ERR 0x0006
+#define CMD_CONNECTION_LOST 0x0007
+#define CMD_ABORTED 0x0008
+#define CMD_ABORT_FAILED 0x0009
+#define CMD_UNSOLICITED_ABORT 0x000A
+#define CMD_TIMEOUT 0x000B
+#define CMD_UNABORTABLE 0x000C
+
+//transfer direction
+#define XFER_NONE 0x00
+#define XFER_WRITE 0x01
+#define XFER_READ 0x02
+#define XFER_RSVD 0x03
+
+//task attribute
+#define ATTR_UNTAGGED 0x00
+#define ATTR_SIMPLE 0x04
+#define ATTR_HEADOFQUEUE 0x05
+#define ATTR_ORDERED 0x06
+#define ATTR_ACA 0x07
+
+//cdb type
+#define TYPE_CMD 0x00
+#define TYPE_MSG 0x01
+
+// Type defs used in the following structs
+#define BYTE __u8
+#define WORD __u16
+#define HWORD __u16
+#define DWORD __u32
+
+#define CISS_MAX_LUN 16
+
+#pragma pack(1)
+
+//Command List Structure
+typedef union _SCSI3Addr_struct {
+ struct {
+ BYTE Bus:6;
+ BYTE Mode:2; // b00
+ BYTE Dev;
+ } PeripDev;
+ struct {
+ BYTE DevMSB:6;
+ BYTE Mode:2; // b01
+ BYTE DevLSB;
+ } LogDev;
+ struct {
+ BYTE Targ:6;
+ BYTE Mode:2; // b10
+ BYTE Dev:5;
+ BYTE Bus:3;
+ } LogUnit;
+} SCSI3Addr_struct;
+
+typedef struct _PhysDevAddr_struct {
+ DWORD TargetId:24;
+ DWORD Bus:6;
+ DWORD Mode:2;
+ SCSI3Addr_struct Target[2]; //2 level target device addr
+} PhysDevAddr_struct;
+
+typedef struct _LogDevAddr_struct {
+ DWORD VolId:30;
+ DWORD Mode:2;
+ BYTE reserved[4];
+} LogDevAddr_struct;
+
+typedef union _LUNAddr_struct {
+ BYTE LunAddrBytes[8];
+ SCSI3Addr_struct SCSI3Lun[4];
+ PhysDevAddr_struct PhysDev;
+ LogDevAddr_struct LogDev;
+} LUNAddr_struct;
+
+typedef struct _RequestBlock_struct {
+ BYTE CDBLen;
+ struct {
+ BYTE Type:3;
+ BYTE Attribute:3;
+ BYTE Direction:2;
+ } Type;
+ HWORD Timeout;
+ BYTE CDB[16];
+} RequestBlock_struct;
+
+typedef union _MoreErrInfo_struct{
+ struct {
+ BYTE Reserved[3];
+ BYTE Type;
+ DWORD ErrorInfo;
+ }Common_Info;
+ struct{
+ BYTE Reserved[2];
+ BYTE offense_size;//size of offending entry
+ BYTE offense_num; //byte # of offense 0-base
+ DWORD offense_value;
+ }Invalid_Cmd;
+}MoreErrInfo_struct;
+typedef struct _ErrorInfo_struct {
+ BYTE ScsiStatus;
+ BYTE SenseLen;
+ HWORD CommandStatus;
+ DWORD ResidualCnt;
+ MoreErrInfo_struct MoreErrInfo;
+ BYTE SenseInfo[SENSEINFOBYTES];
+} ErrorInfo_struct;
+
+#pragma pack()
+#endif /* CCISS_CMD_H */
+
+typedef struct _IOCTL_Command_struct {
+ LUNAddr_struct LUN_info;
+ RequestBlock_struct Request;
+ ErrorInfo_struct error_info;
+ WORD buf_size; /* size in bytes of the buf */
+ BYTE *buf;
+} IOCTL_Command_struct;
+
+
+#define CCISS_GETPCIINFO _IOR(CCISS_IOC_MAGIC, 1, cciss_pci_info_struct)
+
+#define CCISS_GETINTINFO _IOR(CCISS_IOC_MAGIC, 2, cciss_coalint_struct)
+#define CCISS_SETINTINFO _IOW(CCISS_IOC_MAGIC, 3, cciss_coalint_struct)
+
+#define CCISS_GETNODENAME _IOR(CCISS_IOC_MAGIC, 4, NodeName_type)
+#define CCISS_SETNODENAME _IOW(CCISS_IOC_MAGIC, 5, NodeName_type)
+
+#define CCISS_GETHEARTBEAT _IOR(CCISS_IOC_MAGIC, 6, Heartbeat_type)
+#define CCISS_GETBUSTYPES _IOR(CCISS_IOC_MAGIC, 7, BusTypes_type)
+#define CCISS_GETFIRMVER _IOR(CCISS_IOC_MAGIC, 8, FirmwareVer_type)
+#define CCISS_GETDRIVVER _IOR(CCISS_IOC_MAGIC, 9, DriverVer_type)
+#define CCISS_REVALIDVOLS _IO(CCISS_IOC_MAGIC, 10)
+#define CCISS_PASSTHRU _IOWR(CCISS_IOC_MAGIC, 11, IOCTL_Command_struct)
+
+
+#endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/coda.h linux/include/linux/coda.h
--- v2.4.0-test8/linux/include/linux/coda.h Wed Jun 21 10:10:02 2000
+++ linux/include/linux/coda.h Tue Sep 19 15:08:59 2000
@@ -284,7 +284,7 @@
X */
X
X #define CODA_ROOT 2
-#define CODA_SYNC 3
+#define CODA_OPEN_BY_FD 3
X #define CODA_OPEN 4
X #define CODA_CLOSE 5
X #define CODA_IOCTL 6
@@ -298,11 +298,9 @@
X #define CODA_RENAME 14
X #define CODA_MKDIR 15
X #define CODA_RMDIR 16
-#define CODA_READDIR 17
X #define CODA_SYMLINK 18
X #define CODA_READLINK 19
X #define CODA_FSYNC 20
-#define CODA_INACTIVE 21
X #define CODA_VGET 22
X #define CODA_SIGNAL 23
X #define CODA_REPLACE 24 /* DOWNCALL */
@@ -315,12 +313,9 @@
X #define CODA_RESOLVE 32
X #define CODA_REINTEGRATE 33
X #define CODA_STATFS 34
-#define CODA_MAKE_CINODE 35 /* DOWNCALL */
-#define CODA_NCALLS 36
+#define CODA_NCALLS 35
X
-#define DOWNCALL(opcode) \
- ((opcode >= CODA_REPLACE && opcode <= CODA_PURGEFID) || \
- opcode == CODA_MAKE_CINODE)
+#define DOWNCALL(opcode) (opcode >= CODA_REPLACE && opcode <= CODA_PURGEFID)
X
X #define VC_MAXDATASIZE 8192
X #define VC_MAXMSGSIZE sizeof(union inputArgs)+sizeof(union outputArgs) +\
@@ -328,7 +323,7 @@
X
X #define CIOC_KERNEL_VERSION _IOWR('c', 10, sizeof (int))
X
-#if 0
+#if 0
X #define CODA_KERNEL_VERSION 0 /* don't care about kernel version number */
X #define CODA_KERNEL_VERSION 1 /* The old venus 4.6 compatible interface */
X #endif
@@ -363,9 +358,6 @@
X struct coda_in_hdr in;
X };
X
-/* coda_sync: */
-/* Nothing needed for coda_sync */
-
X /* coda_open: */
X struct coda_open_in {
X struct coda_in_hdr ih;
@@ -542,20 +534,6 @@
X struct coda_out_hdr out;
X };
X
-/* coda_readdir: */
-struct coda_readdir_in {
- struct coda_in_hdr ih;
- ViceFid VFid;
- int count;
- int offset;
-};
-
-struct coda_readdir_out {
- struct coda_out_hdr oh;
- int size;
- caddr_t data; /* Place holder for data. */
-};
-
X /* coda_symlink: NO_OUT */
X struct coda_symlink_in {
X struct coda_in_hdr ih;
@@ -592,12 +570,6 @@
X struct coda_out_hdr out;
X };
X
-/* coda_inactive: NO_OUT */
-struct coda_inactive_in {
- struct coda_in_hdr ih;
- ViceFid VFid;
-};
-
X /* coda_vget: */
X struct coda_vget_in {
X struct coda_in_hdr ih;
@@ -651,38 +623,24 @@
X ViceFid CodaFid;
X };
X
-struct coda_make_cinode_out {
+/* coda_replace: */
+/* CODA_REPLACE is a venus->kernel call */
+struct coda_replace_out { /* coda_replace is a venus->kernel call */
X struct coda_out_hdr oh;
- ViceFid CodaFid;
- struct coda_vattr attr;
- int fd;
+ ViceFid NewFid;
+ ViceFid OldFid;
X };
X
-/* coda_rdwr: */
-struct coda_rdwr_in {
+/* coda_open_by_fd: */
+struct coda_open_by_fd_in {
X struct coda_in_hdr ih;
- ViceFid VFid;
- int rwflag;
- int count;
- int offset;
- int ioflag;
- caddr_t data; /* Place holder for data. */
+ ViceFid VFid;
+ int flags;
X };
X
-struct coda_rdwr_out {
+struct coda_open_by_fd_out {
X struct coda_out_hdr oh;
- int rwflag;
- int count;
- caddr_t data; /* Place holder for data. */
-};
-
-
-/* coda_replace: */
-/* CODA_REPLACE is a venus->kernel call */
-struct coda_replace_out { /* coda_replace is a venus->kernel call */
- struct coda_out_hdr oh;
- ViceFid NewFid;
- ViceFid OldFid;
+ int fd;
X };
X
X /* coda_open_by_path: */
@@ -729,13 +687,11 @@
X struct coda_rename_in coda_rename;
X struct coda_mkdir_in coda_mkdir;
X struct coda_rmdir_in coda_rmdir;
- struct coda_readdir_in coda_readdir;
X struct coda_symlink_in coda_symlink;
X struct coda_readlink_in coda_readlink;
X struct coda_fsync_in coda_fsync;
- struct coda_inactive_in coda_inactive;
X struct coda_vget_in coda_vget;
- struct coda_rdwr_in coda_rdwr;
+ struct coda_open_by_fd_in coda_open_by_fd;
X struct coda_open_by_path_in coda_open_by_path;
X struct coda_statfs_in coda_statfs;
X };
@@ -749,7 +705,6 @@
X struct coda_lookup_out coda_lookup;
X struct coda_create_out coda_create;
X struct coda_mkdir_out coda_mkdir;
- struct coda_readdir_out coda_readdir;
X struct coda_readlink_out coda_readlink;
X struct coda_vget_out coda_vget;
X struct coda_purgeuser_out coda_purgeuser;
@@ -757,9 +712,8 @@
X struct coda_zapdir_out coda_zapdir;
X struct coda_zapvnode_out coda_zapvnode;
X struct coda_purgefid_out coda_purgefid;
- struct coda_rdwr_out coda_rdwr;
X struct coda_replace_out coda_replace;
- struct coda_make_cinode_out coda_make_cinode;
+ struct coda_open_by_fd_out coda_open_by_fd;
X struct coda_open_by_path_out coda_open_by_path;
X struct coda_statfs_out coda_statfs;
X };
@@ -805,5 +759,15 @@
X #define IS_CTL_FID(fidp) ((fidp)->Volume == CTL_VOL &&\
X (fidp)->Vnode == CTL_VNO &&\
X (fidp)->Unique == CTL_UNI)
+
+/* Data passed to mount */
+
+#define CODA_MOUNT_VERSION 1
+
+struct coda_mount_data {
+ int version;
+ int fd; /* Opened device */
+};
+
X #endif
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/coda_cache.h linux/include/linux/coda_cache.h
--- v2.4.0-test8/linux/include/linux/coda_cache.h Wed Jun 21 10:10:02 2000
+++ linux/include/linux/coda_cache.h Tue Sep 19 15:08:59 2000
@@ -10,22 +10,10 @@
X #ifndef _CFSNC_HEADER_
X #define _CFSNC_HEADER_
X
-/*
- * Structure for an element in the Coda Credential Cache.
- */
-
-struct coda_cache {
- struct list_head cc_cclist; /* list of all cache entries */
- struct list_head cc_cnlist; /* list of cache entries/cnode */
- int cc_mask;
- struct coda_cred cc_cred;
-};
-
X /* credential cache */
X void coda_cache_enter(struct inode *inode, int mask);
X void coda_cache_clear_inode(struct inode *);
-void coda_cache_clear_all(struct super_block *sb);
-void coda_cache_clear_cred(struct super_block *sb, struct coda_cred *cred);


+void coda_cache_clear_all(struct super_block *sb, struct coda_cred *cred);

X int coda_cache_check(struct inode *inode, int mask);
X

X /* for downcalls and attributes and lookups */
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/coda_fs_i.h linux/include/linux/coda_fs_i.h
--- v2.4.0-test8/linux/include/linux/coda_fs_i.h Fri Sep 8 12:52:41 2000
+++ linux/include/linux/coda_fs_i.h Mon Oct 2 11:01:17 2000
@@ -20,9 +20,12 @@
X struct coda_inode_info {
X struct ViceFid c_fid; /* Coda identifier */
X u_short c_flags; /* flags (see below) */
- struct list_head c_cnhead; /* head of cache entries */
X struct list_head c_volrootlist; /* list of volroot cnoddes */
- struct inode *c_vnode; /* inode associated with cnode */
+ struct list_head c_cilist; /* list of all coda inodes */
+ struct inode *c_vnode; /* inode associated with cnode */
+ unsigned int c_contcount; /* refcount for container inode */
+ struct coda_cred c_cached_cred; /* credentials of cached perms */
+ unsigned int c_cached_perm; /* cached access permissions */
X int c_magic; /* to verify the data structure */
X };
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/coda_linux.h linux/include/linux/coda_linux.h
--- v2.4.0-test8/linux/include/linux/coda_linux.h Tue Jul 18 16:54:19 2000
+++ linux/include/linux/coda_linux.h Tue Sep 19 15:08:59 2000
@@ -40,6 +40,8 @@
X int coda_permission(struct inode *inode, int mask);
X int coda_revalidate_inode(struct dentry *);
X int coda_notify_change(struct dentry *, struct iattr *);
+int coda_pioctl(struct inode * inode, struct file * filp,
+ unsigned int cmd, unsigned long arg);
X
X /* global variables */
X extern int coda_debug;
@@ -103,20 +105,20 @@
X
X #define CODA_ALLOC(ptr, cast, size) \
X do { \
- if (size < 3000) { \
+ if (size < PAGE_SIZE) { \
X ptr = (cast)kmalloc((unsigned long) size, GFP_KERNEL); \
- CDEBUG(D_MALLOC, "kmalloced: %lx at %p.\n", (long)size, ptr);\
- } else { \
+ CDEBUG(D_MALLOC, "kmalloced: %lx at %p.\n", (long)size, ptr); \
+ } else { \
X ptr = (cast)vmalloc((unsigned long) size); \
- CDEBUG(D_MALLOC, "vmalloced: %lx at %p .\n", (long)size, ptr);}\
+ CDEBUG(D_MALLOC, "vmalloced: %lx at %p .\n", (long)size, ptr);} \
X if (ptr == 0) { \
- printk("kernel malloc returns 0 at %s:%d\n", __FILE__, __LINE__); \
+ printk("kernel malloc returns 0 at %s:%d\n", __FILE__, __LINE__); \
X } \
- memset( ptr, 0, size ); \
+ else memset( ptr, 0, size ); \


X } while (0)
X
X

-#define CODA_FREE(ptr,size) do {if (size < 3000) { kfree((ptr)); CDEBUG(D_MALLOC, "kfreed: %lx at %p.\n", (long) size, ptr); } else { vfree((ptr)); CDEBUG(D_MALLOC, "vfreed: %lx at %p.\n", (long) size, ptr);} } while (0)
+#define CODA_FREE(ptr,size) do {if (size < PAGE_SIZE) { kfree((ptr)); CDEBUG(D_MALLOC, "kfreed: %lx at %p.\n", (long) size, ptr); } else { vfree((ptr)); CDEBUG(D_MALLOC, "vfreed: %lx at %p.\n", (long) size, ptr);} } while (0)
X
X /* inode to cnode access functions */
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/coda_psdev.h linux/include/linux/coda_psdev.h
--- v2.4.0-test8/linux/include/linux/coda_psdev.h Wed Jun 28 19:31:36 2000
+++ linux/include/linux/coda_psdev.h Tue Sep 19 15:08:59 2000
@@ -4,19 +4,13 @@
X #define CODA_PSDEV_MAJOR 67
X #define MAX_CODADEVS 5 /* how many do we allow */
X
-extern struct venus_comm coda_upc_comm;
-extern struct coda_sb_info coda_super_info;
X #define CODA_SUPER_MAGIC 0x73757245
X
X struct coda_sb_info
X {
- struct inode * sbi_psdev; /* /dev/cfs? Venus/kernel device */
- int sbi_refct;
X struct venus_comm * sbi_vcomm;
- struct inode * sbi_root;
X struct super_block *sbi_sb;
- struct list_head sbi_cchead;
- struct list_head sbi_volroothead;
+ struct list_head sbi_cihead;
X };
X
X /* communication pending/processing queues */
@@ -26,6 +20,7 @@
X struct list_head vc_pending;
X struct list_head vc_processing;
X int vc_inuse;
+ struct super_block *vc_sb;
X };
X
X
@@ -35,11 +30,6 @@
X }
X
X
-
-extern void coda_psdev_detach(int unit);
-extern int init_coda_psdev(void);
-
-
X /* upcalls */
X int venus_rootfid(struct super_block *sb, ViceFid *fidp);
X int venus_getattr(struct super_block *sb, struct ViceFid *fid,
@@ -112,6 +102,7 @@
X } ;
X
X extern struct coda_upcallstats coda_callstats;
+extern struct venus_comm coda_comms[];
X
X static inline void clstats(int opcode)
X {
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/cuda.h linux/include/linux/cuda.h
--- v2.4.0-test8/linux/include/linux/cuda.h Tue Oct 12 10:00:58 1999
+++ linux/include/linux/cuda.h Sun Sep 17 09:48:05 2000
@@ -28,7 +28,8 @@


X
X #ifdef __KERNEL__
X

-void find_via_cuda(void);
+extern int find_via_cuda(void);
+extern int via_cuda_start(void);
X extern int cuda_request(struct adb_request *req,
X void (*done)(struct adb_request *), int nbytes, ...);
X extern void cuda_poll(void);
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/dcache.h linux/include/linux/dcache.h
--- v2.4.0-test8/linux/include/linux/dcache.h Fri Sep 8 12:52:41 2000
+++ linux/include/linux/dcache.h Mon Oct 2 11:01:17 2000
@@ -163,11 +163,11 @@
X #define shrink_dcache() prune_dcache(0)
X struct zone_struct;
X /* dcache memory management */
-extern int shrink_dcache_memory(int, unsigned int);
+extern void shrink_dcache_memory(int, unsigned int);
X extern void prune_dcache(int);
X
X /* icache memory management (defined in linux/fs/inode.c) */
-extern int shrink_icache_memory(int, int);
+extern void shrink_icache_memory(int, int);
X extern void prune_icache(int);
X
X /* only used at mount-time */
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/devpts_fs.h linux/include/linux/devpts_fs.h
--- v2.4.0-test8/linux/include/linux/devpts_fs.h Fri Sep 8 12:53:45 2000
+++ linux/include/linux/devpts_fs.h Mon Oct 2 11:01:50 2000
@@ -46,14 +46,14 @@
X #endif
X
X #ifndef BUILDING_DEVPTS
-extern inline void
+static inline void
X devpts_pty_new(int line, kdev_t device)
X {
X if ( devpts_upcall_new )
X return devpts_upcall_new(line,device);


X }
X
-extern inline void

+static inline void
X devpts_pty_kill(int line)
X {
X if ( devpts_upcall_kill )
@@ -63,10 +63,10 @@
X
X #else /* No /dev/pts filesystem at all */
X
-extern inline void
+static inline void
X devpts_pty_new(int line, kdev_t device) { }
X
-extern inline void
+static inline void
X devpts_pty_kill(int line) { }
X
X #endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/dnotify.h linux/include/linux/dnotify.h
--- v2.4.0-test8/linux/include/linux/dnotify.h Wed Dec 31 16:00:00 1969
+++ linux/include/linux/dnotify.h Fri Sep 22 14:21:22 2000
@@ -0,0 +1,25 @@
+/*
+ * Directory notification for Linux
+ *
+ * Copyright 2000 (C) Stephen Rothwell
+ */
+
+struct dnotify_struct {
+ struct dnotify_struct * dn_next;
+ int dn_magic;
+ unsigned long dn_mask; /* Events to be notified
+ see linux/fcntl.h */
+ int dn_fd;
+ struct file * dn_filp;
+};
+
+#define DNOTIFY_MAGIC 0x444E4F54
+
+extern void __inode_dir_notify(struct inode *, unsigned long);
+extern int fcntl_dirnotify(int, struct file *, unsigned long);
+
+static inline void inode_dir_notify(struct inode *inode, unsigned long event)
+{
+ if ((inode)->i_dnotify_mask & (event))
+ __inode_dir_notify(inode, event);
+}
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/elf.h linux/include/linux/elf.h
--- v2.4.0-test8/linux/include/linux/elf.h Fri Sep 8 12:53:16 2000
+++ linux/include/linux/elf.h Mon Oct 2 11:01:38 2000


@@ -72,6 +72,8 @@
X

X #define EM_IA_64 50 /* HP/Intel IA-64 */
X
+#define EM_X8664 62 /* AMD x86-64 */
+
X /*
X * This is an interim value that we will use until the committee comes
X * up with a final number.
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/ext2_fs_sb.h linux/include/linux/ext2_fs_sb.h
--- v2.4.0-test8/linux/include/linux/ext2_fs_sb.h Fri Sep 8 12:52:41 2000
+++ linux/include/linux/ext2_fs_sb.h Wed Sep 27 13:41:33 2000
@@ -16,8 +16,6 @@
X #ifndef _LINUX_EXT2_FS_SB
X #define _LINUX_EXT2_FS_SB
X
-#include <linux/ext2_fs.h>
-
X /*
X * The following is not needed anymore since the descriptors buffer
X * heads are now dynamically allocated
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/fcntl.h linux/include/linux/fcntl.h
--- v2.4.0-test8/linux/include/linux/fcntl.h Fri Aug 11 15:08:03 2000
+++ linux/include/linux/fcntl.h Fri Sep 22 14:21:22 2000
@@ -3,4 +3,24 @@
X
X #include <asm/fcntl.h>
X
+#define F_SETLEASE (F_LINUX_SPECIFIC_BASE+0)
+#define F_GETLEASE (F_LINUX_SPECIFIC_BASE+1)
+
+/*
+ * Request nofications on a directory.
+ * See below for events that may be notified.
+ */
+#define F_NOTIFY (F_LINUX_SPECIFIC_BASE+2)
+
+/*
+ * Types of directory notifications that may be requested.
+ */
+#define DN_ACCESS 0x00000001 /* File accessed */
+#define DN_MODIFY 0x00000002 /* File modified */
+#define DN_CREATE 0x00000004 /* File created */
+#define DN_DELETE 0x00000008 /* File removed */
+#define DN_RENAME 0x00000010 /* File renamed */
+#define DN_ATTRIB 0x00000020 /* File changed attibutes */
+#define DN_MULTISHOT 0x80000000 /* Don't remove notifier */
+
X #endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/fs.h linux/include/linux/fs.h
--- v2.4.0-test8/linux/include/linux/fs.h Fri Sep 8 12:52:42 2000
+++ linux/include/linux/fs.h Mon Oct 2 11:01:19 2000
@@ -54,6 +54,7 @@
X };
X extern struct files_stat_struct files_stat;
X extern int max_super_blocks, nr_super_blocks;
+extern int leases_enable, dir_notify_enable, lease_break_time;
X
X #define NR_FILE 8192 /* this can well be larger on a larger system */
X #define NR_RESERVED_FILES 10 /* reserved for root */
@@ -93,7 +94,7 @@
X * as nfs_rename() will be cleaned up
X */
X /*
- * These are the fs-independent mount-flags: up to 16 flags are supported
+ * These are the fs-independent mount-flags: up to 32 flags are supported
X */
X #define MS_RDONLY 1 /* Mount read-only */
X #define MS_NOSUID 2 /* Ignore suid and sgid bits */
@@ -104,6 +105,7 @@
X #define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */
X #define MS_NOATIME 1024 /* Do not update access times. */
X #define MS_NODIRATIME 2048 /* Do not update directory access times */
+#define MS_BIND 4096
X
X /*
X * Flags that can be altered by MS_REMOUNT
@@ -409,6 +411,9 @@
X struct pipe_inode_info *i_pipe;
X struct block_device *i_bdev;
X
+ unsigned long i_dnotify_mask; /* Directory notify events */
+ struct dnotify_struct *i_dnotify; /* for directory notifications */
+
X unsigned long i_state;
X
X unsigned int i_flags;
@@ -498,6 +503,7 @@
X #define FL_BROKEN 4 /* broken flock() emulation */
X #define FL_ACCESS 8 /* for processes suspended by mandatory locking */
X #define FL_LOCKD 16 /* lock held by rpc.lockd */
+#define FL_LEASE 32 /* lease held on this file */
X
X /*
X * The POSIX file lock owner is determined by
@@ -512,6 +518,7 @@
X struct file_lock *fl_next; /* singly linked list for this inode */
X struct list_head fl_link; /* doubly linked list of all locks */
X struct list_head fl_block; /* circular list of blocked processes */
+ struct list_head fl_list; /* block list member */
X fl_owner_t fl_owner;
X unsigned int fl_pid;
X wait_queue_head_t fl_wait;
@@ -525,6 +532,8 @@
X void (*fl_insert)(struct file_lock *); /* lock insertion callback */
X void (*fl_remove)(struct file_lock *); /* lock removal callback */
X
+ struct fasync_struct * fl_fasync; /* for lease break notifications */
+
X union {
X struct nfs_lock_info nfs_fl;
X } fl_u;
@@ -538,6 +547,7 @@
X #endif
X
X extern struct list_head file_lock_list;
+extern struct semaphore file_lock_sem;
X
X #include <linux/fcntl.h>
X
@@ -548,12 +558,18 @@
X extern int fcntl_setlk64(unsigned int, unsigned int, struct flock64 *);
X
X /* fs/locks.c */
+extern void locks_init_lock(struct file_lock *);
+extern void locks_copy_lock(struct file_lock *, struct file_lock *);
X extern void locks_remove_posix(struct file *, fl_owner_t);
X extern void locks_remove_flock(struct file *);
X extern struct file_lock *posix_test_lock(struct file *, struct file_lock *);
X extern int posix_lock_file(struct file *, struct file_lock *, unsigned int);
X extern void posix_block_lock(struct file_lock *, struct file_lock *);
X extern void posix_unblock_lock(struct file_lock *);
+extern int __get_lease(struct inode *inode, unsigned int flags);
+extern time_t lease_get_mtime(struct inode *);
+extern int lock_may_read(struct inode *, loff_t start, unsigned long count);
+extern int lock_may_write(struct inode *, loff_t start, unsigned long count);
X
X struct fasync_struct {
X int magic;
@@ -886,6 +902,12 @@


X return 0;
X }
X

+extern inline int get_lease(struct inode *inode, unsigned int mode)
+{
+ if (inode->i_flock && (inode->i_flock->fl_flags & FL_LEASE))
+ return __get_lease(inode, mode);


+ return 0;
+}
X

X /* fs/open.c */
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/gameport.h linux/include/linux/gameport.h
--- v2.4.0-test8/linux/include/linux/gameport.h Wed Jun 21 08:22:21 2000
+++ linux/include/linux/gameport.h Fri Sep 22 14:21:17 2000
@@ -29,6 +29,7 @@
X * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
X */
X
+#include <linux/sched.h>
X #include <asm/io.h>
X
X struct gameport;
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/hdlcdrv.h linux/include/linux/hdlcdrv.h
--- v2.4.0-test8/linux/include/linux/hdlcdrv.h Tue Jul 11 11:12:24 2000
+++ linux/include/linux/hdlcdrv.h Fri Sep 22 14:21:17 2000
@@ -132,7 +132,7 @@
X unsigned char buffer[HDLCDRV_BITBUFFER];
X };
X
-extern inline void hdlcdrv_add_bitbuffer(struct hdlcdrv_bitbuffer *buf,
+static inline void hdlcdrv_add_bitbuffer(struct hdlcdrv_bitbuffer *buf,
X unsigned int bit)
X {
X unsigned char new;
@@ -147,7 +147,7 @@
X }
X }
X
-extern inline void hdlcdrv_add_bitbuffer_word(struct hdlcdrv_bitbuffer *buf,
+static inline void hdlcdrv_add_bitbuffer_word(struct hdlcdrv_bitbuffer *buf,
X unsigned int bits)
X {
X buf->buffer[buf->wr] = bits & 0xff;


@@ -250,7 +250,7 @@
X

X /* -------------------------------------------------------------------- */
X
-extern inline int hdlcdrv_hbuf_full(struct hdlcdrv_hdlcbuffer *hb)
+static inline int hdlcdrv_hbuf_full(struct hdlcdrv_hdlcbuffer *hb)

X {
X unsigned long flags;

X int ret;


@@ -263,7 +263,7 @@
X

X /* -------------------------------------------------------------------- */
X
-extern inline int hdlcdrv_hbuf_empty(struct hdlcdrv_hdlcbuffer *hb)
+static inline int hdlcdrv_hbuf_empty(struct hdlcdrv_hdlcbuffer *hb)


X {
X unsigned long flags;

X int ret;


@@ -276,7 +276,7 @@
X

X /* -------------------------------------------------------------------- */
X
-extern inline unsigned short hdlcdrv_hbuf_get(struct hdlcdrv_hdlcbuffer *hb)
+static inline unsigned short hdlcdrv_hbuf_get(struct hdlcdrv_hdlcbuffer *hb)


X {
X unsigned long flags;

X unsigned short val;
@@ -296,7 +296,7 @@
X
X /* -------------------------------------------------------------------- */
X
-extern inline void hdlcdrv_hbuf_put(struct hdlcdrv_hdlcbuffer *hb,
+static inline void hdlcdrv_hbuf_put(struct hdlcdrv_hdlcbuffer *hb,
X unsigned short val)
X {
X unsigned newp;


@@ -313,12 +313,12 @@
X

X /* -------------------------------------------------------------------- */
X
-extern inline void hdlcdrv_putbits(struct hdlcdrv_state *s, unsigned int bits)
+static inline void hdlcdrv_putbits(struct hdlcdrv_state *s, unsigned int bits)
X {
X hdlcdrv_hbuf_put(&s->hdlcrx.hbuf, bits);
X }
X
-extern inline unsigned int hdlcdrv_getbits(struct hdlcdrv_state *s)
+static inline unsigned int hdlcdrv_getbits(struct hdlcdrv_state *s)
X {
X unsigned int ret;
X
@@ -336,19 +336,19 @@
X return ret;
X }
X
-extern inline void hdlcdrv_channelbit(struct hdlcdrv_state *s, unsigned int bit)
+static inline void hdlcdrv_channelbit(struct hdlcdrv_state *s, unsigned int bit)
X {
X #ifdef HDLCDRV_DEBUG
X hdlcdrv_add_bitbuffer(&s->bitbuf_channel, bit);
X #endif /* HDLCDRV_DEBUG */
X }
X
-extern inline void hdlcdrv_setdcd(struct hdlcdrv_state *s, int dcd)
+static inline void hdlcdrv_setdcd(struct hdlcdrv_state *s, int dcd)
X {
X s->hdlcrx.dcd = !!dcd;
X }
X
-extern inline int hdlcdrv_ptt(struct hdlcdrv_state *s)
+static inline int hdlcdrv_ptt(struct hdlcdrv_state *s)
X {
X return s->hdlctx.ptt || (s->hdlctx.calibrate > 0);
X }
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/hfs_fs.h linux/include/linux/hfs_fs.h
--- v2.4.0-test8/linux/include/linux/hfs_fs.h Mon Mar 13 12:35:39 2000
+++ linux/include/linux/hfs_fs.h Fri Sep 22 14:21:17 2000
@@ -320,12 +320,12 @@
X #define HFS_I(X) (&((X)->u.hfs_i))
X #define HFS_SB(X) (&((X)->u.hfs_sb))
X
-extern __inline__ void hfs_nameout(struct inode *dir, struct hfs_name *out,
+static inline void hfs_nameout(struct inode *dir, struct hfs_name *out,
X const char *in, int len) {
X HFS_SB(dir->i_sb)->s_nameout(out, in, len);
X }
X
-extern __inline__ int hfs_namein(struct inode *dir, char *out,
+static inline int hfs_namein(struct inode *dir, char *out,
X const struct hfs_name *in) {
X int len = HFS_SB(dir->i_sb)->s_namein(out, in);
X if (HFS_SB(dir->i_sb)->s_lowercase) {
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/hfs_sysdep.h linux/include/linux/hfs_sysdep.h
--- v2.4.0-test8/linux/include/linux/hfs_sysdep.h Tue Sep 5 14:07:29 2000
+++ linux/include/linux/hfs_sysdep.h Fri Sep 22 14:21:17 2000
@@ -52,7 +52,7 @@
X extern long int hfs_alloc;
X #endif
X
-extern inline void *hfs_malloc(unsigned int size) {
+static inline void *hfs_malloc(unsigned int size) {
X #if defined(DEBUG_ALL) || defined(DEBUG_MEM)
X hfs_warn("%ld bytes allocation at %s:%u\n",
X (hfs_alloc += size), __FILE__, __LINE__);
@@ -60,7 +60,7 @@
X return kmalloc(size, GFP_KERNEL);
X }
X
-extern inline void hfs_free(void *ptr, unsigned int size) {
+static inline void hfs_free(void *ptr, unsigned int size) {
X kfree(ptr);
X #if defined(DEBUG_ALL) || defined(DEBUG_MEM)
X hfs_warn("%ld bytes allocation at %s:%u\n",
@@ -75,17 +75,17 @@
X * not a good thing to do. instead, we depend upon tz_minuteswest
X * having the correct daylight savings correction.
X */
-extern inline hfs_u32 hfs_from_utc(hfs_s32 time)
+static inline hfs_u32 hfs_from_utc(hfs_s32 time)
X {
X return time - sys_tz.tz_minuteswest*60;
X }
X
-extern inline hfs_s32 hfs_to_utc(hfs_u32 time)
+static inline hfs_s32 hfs_to_utc(hfs_u32 time)
X {
X return time + sys_tz.tz_minuteswest*60;
X }
X
-extern inline hfs_u32 hfs_time(void) {
+static inline hfs_u32 hfs_time(void) {
X return htonl(hfs_from_utc(CURRENT_TIME)+2082844800U);
X }
X
@@ -95,19 +95,19 @@
X */
X typedef wait_queue_head_t hfs_wait_queue;
X
-extern inline void hfs_init_waitqueue(hfs_wait_queue *queue) {
+static inline void hfs_init_waitqueue(hfs_wait_queue *queue) {
X init_waitqueue_head(queue);
X }
X
-extern inline void hfs_sleep_on(hfs_wait_queue *queue) {
+static inline void hfs_sleep_on(hfs_wait_queue *queue) {
X sleep_on(queue);
X }
X
-extern inline void hfs_wake_up(hfs_wait_queue *queue) {
+static inline void hfs_wake_up(hfs_wait_queue *queue) {
X wake_up(queue);
X }
X
-extern inline void hfs_relinquish(void) {
+static inline void hfs_relinquish(void) {
X schedule();
X }
X
@@ -117,11 +117,11 @@
X */
X typedef struct super_block *hfs_sysmdb;
X
-extern inline void hfs_mdb_dirty(hfs_sysmdb sys_mdb) {
+static inline void hfs_mdb_dirty(hfs_sysmdb sys_mdb) {
X sys_mdb->s_dirt = 1;
X }
X
-extern inline const char *hfs_mdb_name(hfs_sysmdb sys_mdb) {
+static inline const char *hfs_mdb_name(hfs_sysmdb sys_mdb) {
X return kdevname(sys_mdb->s_dev);
X }
X
@@ -141,19 +141,19 @@
X /* In sysdep.c, since it needs HFS_SECTOR_SIZE */
X extern hfs_buffer hfs_buffer_get(hfs_sysmdb, int, int);
X
-extern inline int hfs_buffer_ok(hfs_buffer buffer) {
+static inline int hfs_buffer_ok(hfs_buffer buffer) {
X return (buffer != NULL);
X }
X
-extern inline void hfs_buffer_put(hfs_buffer buffer) {
+static inline void hfs_buffer_put(hfs_buffer buffer) {
X brelse(buffer);
X }
X
-extern inline void hfs_buffer_dirty(hfs_buffer buffer) {
+static inline void hfs_buffer_dirty(hfs_buffer buffer) {
X mark_buffer_dirty(buffer);
X }
X
-extern inline void hfs_buffer_sync(hfs_buffer buffer) {
+static inline void hfs_buffer_sync(hfs_buffer buffer) {
X while (buffer_locked(buffer)) {
X wait_on_buffer(buffer);
X }
@@ -163,7 +163,7 @@
X }
X }
X
-extern inline void *hfs_buffer_data(const hfs_buffer buffer) {
+static inline void *hfs_buffer_data(const hfs_buffer buffer) {
X return buffer->b_data;
X }
X
@@ -199,15 +199,15 @@
X # error "Don't know if bytes are big- or little-endian!"
X #endif
X
-extern inline int hfs_clear_bit(int bitnr, hfs_u32 *lword) {
+static inline int hfs_clear_bit(int bitnr, hfs_u32 *lword) {
X return test_and_clear_bit(BITNR(bitnr), lword);
X }
X
-extern inline int hfs_set_bit(int bitnr, hfs_u32 *lword) {
+static inline int hfs_set_bit(int bitnr, hfs_u32 *lword) {
X return test_and_set_bit(BITNR(bitnr), lword);
X }
X
-extern inline int hfs_test_bit(int bitnr, const hfs_u32 *lword) {
+static inline int hfs_test_bit(int bitnr, const hfs_u32 *lword) {
X /* the kernel should declare the second arg of test_bit as const */
X return test_bit(BITNR(bitnr), (void *)lword);
X }
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/highmem.h linux/include/linux/highmem.h
--- v2.4.0-test8/linux/include/linux/highmem.h Fri Sep 8 12:52:42 2000
+++ linux/include/linux/highmem.h Mon Oct 2 11:01:19 2000
@@ -19,7 +19,7 @@
X
X #else /* CONFIG_HIGHMEM */
X
-extern inline unsigned int nr_free_highpages(void) { return 0; }
+static inline unsigned int nr_free_highpages(void) { return 0; }
X #define prepare_highmem_swapout(page) page
X #define replace_with_highmem(page) page
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/if_pppox.h linux/include/linux/if_pppox.h
--- v2.4.0-test8/linux/include/linux/if_pppox.h Fri Sep 8 12:53:54 2000
+++ linux/include/linux/if_pppox.h Mon Oct 2 12:06:32 2000
@@ -130,7 +130,7 @@
X
X extern struct ppp_channel_ops pppoe_chan_ops;
X
-extern void pppox_proto_init(struct net_proto *np);
+extern int pppox_proto_init(struct net_proto *np);
X
X #endif /* __KERNEL__ */
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/inet.h linux/include/linux/inet.h
--- v2.4.0-test8/linux/include/linux/inet.h Wed Jun 9 14:45:36 1999
+++ linux/include/linux/inet.h Mon Oct 2 14:14:29 2000
@@ -46,7 +46,6 @@
X
X extern void inet_proto_init(struct net_proto *pro);
X extern char *in_ntoa(__u32 in);
-extern char *in_ntoa2(__u32 in, char *buf);
X extern __u32 in_aton(const char *str);
X
X #endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/ixjuser.h linux/include/linux/ixjuser.h
--- v2.4.0-test8/linux/include/linux/ixjuser.h Wed Dec 29 17:13:02 1999
+++ linux/include/linux/ixjuser.h Mon Sep 18 15:02:03 2000
@@ -1,7 +1,8 @@
-/*
+/******************************************************************************
+ *
X * ixjuser.h
X *
- * User-space include file for the Internet PhoneJACK and
+ * Device Driver for the Internet PhoneJACK and


X * Internet LineJACK Telephony Cards.
X *

X * (c) Copyright 1999 Quicknet Technologies, Inc.
@@ -22,31 +23,48 @@


X * at our website: http://www.quicknet.net

X *
X * Fixes:

- */


+ *
+ * IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR

SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 107'
echo 'File patch-2.4.0-test9 is continued in part 108'
echo "108" > _shar_seq_.tmp
exit 0

Thomas Kobienia

unread,
Oct 4, 2000, 3:00:00 AM10/4/00
to
Archive-name: v2.4/patch-2.4.0-test9/part108

#!/bin/sh -x
# this is part 108 of a 112 - part archive


# do not concatenate these parts, unpack them in order with /bin/sh
# file patch-2.4.0-test9 continued
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck

if test "$Scheck" != 108; then


echo "Please unpack part $Scheck next!"
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping patch-2.4.0-test9'
else
echo 'x - continuing with patch-2.4.0-test9'
sed 's/^X//' << 'SHAR_EOF' >> 'patch-2.4.0-test9' &&

+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF QUICKNET
+ * TECHNOLOGIES, INC.HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * QUICKNET TECHNOLOGIES, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND QUICKNET TECHNOLOGIES, INC. HAS NO OBLIGATION
+ * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ *****************************************************************************/

X
-static char ixjuser_h_rcsid[] = "$Id: ixjuser.h,v 3.4 1999/12/16 22:18:36 root Exp root $";
+static char ixjuser_h_rcsid[] = "$Id: ixjuser.h,v 3.11 2000/03/30 22:06:48 eokerson Exp $";
X
-#include <linux/telephony.h>
+#include "telephony.h"
X
-/***************************************************************************
X
- If you use the IXJCTL_TESTRAM command, the card must be power
- cycled to reset the SRAM values before futher use.
+/******************************************************************************
+*
+* IOCTL's used for the Quicknet Cards
+*
+* If you use the IXJCTL_TESTRAM command, the card must be power cycled to
+* reset the SRAM values before futher use.
+*
+******************************************************************************/
X
-***************************************************************************/
X #define IXJCTL_DSP_RESET _IO ('q', 0xC0)
X
-#define IXJCTL_RING PHONE_RING
-#define IXJCTL_HOOKSTATE PHONE_HOOKSTATE
+#define IXJCTL_RING PHONE_RING
+#define IXJCTL_HOOKSTATE PHONE_HOOKSTATE
X #define IXJCTL_MAXRINGS PHONE_MAXRINGS
-#define IXJCTL_RING_CADENCE PHONE_RING_CADENCE
+#define IXJCTL_RING_CADENCE PHONE_RING_CADENCE
X #define IXJCTL_RING_START PHONE_RING_START
X #define IXJCTL_RING_STOP PHONE_RING_STOP
X
X #define IXJCTL_CARDTYPE _IOR ('q', 0xC1, int)
-#define IXJCTL_SERIAL _IOR ('q', 0xC2, int)
-#define IXJCTL_DSP_TYPE _IOR ('q', 0xC3, int)
-#define IXJCTL_DSP_VERSION _IOR ('q', 0xC4, int)
+#define IXJCTL_SERIAL _IOR ('q', 0xC2, int)
+#define IXJCTL_DSP_TYPE _IOR ('q', 0xC3, int)
+#define IXJCTL_DSP_VERSION _IOR ('q', 0xC4, int)
+#define IXJCTL_VERSION _IOR ('q', 0xDA, char *)
X #define IXJCTL_DSP_IDLE _IO ('q', 0xC5)
X #define IXJCTL_TESTRAM _IO ('q', 0xC6)
X
@@ -104,8 +122,22 @@
X char enable;
X } IXJ_FILTER;
X
+typedef struct {


+ char enable;
+ char en_filter;
+ unsigned int filter;

+ unsigned int on1;
+ unsigned int off1;
+ unsigned int on2;
+ unsigned int off2;
+ unsigned int on3;
+ unsigned int off3;
+} IXJ_FILTER_CADENCE;
+
X #define IXJCTL_SET_FILTER _IOW ('q', 0xC7, IXJ_FILTER *)
X #define IXJCTL_GET_FILTER_HIST _IOW ('q', 0xC8, int)
+#define IXJCTL_FILTER_CADENCE _IOW ('q', 0xD6, IXJ_FILTER_CADENCE *)
+#define IXJCTL_PLAY_CID _IO ('q', 0xD7)
X /******************************************************************************
X *
X * This IOCTL allows you to reassign values in the tone index table. The
@@ -222,7 +254,9 @@
X hz1800 = 0x1405,
X hz1860 = 0xe0b,
X hz2100 = 0xf5f6,
- hz2450 = 0xd3b3
+ hz2130 = 0xf2f5,
+ hz2450 = 0xd3b3,
+ hz2750 = 0xb8e4
X } IXJ_FREQ;
X
X typedef enum {
@@ -344,6 +378,7 @@
X #define AEC_LOW 1
X #define AEC_MED 2
X #define AEC_HIGH 3
+#define AEC_AUTO 4
X /******************************************************************************
X *
X * Call Progress Tones, DTMF, etc.
@@ -533,16 +568,16 @@


X
X /******************************************************************************
X *

-* The DAA Analog GAIN sets 2 parameters at one time, the receive gain (AGRR),
+* The DAA Analog GAIN sets 2 parameters at one time, the recieve gain (AGRR),
X * and the transmit gain (AGX). OR together the components and pass them
X * as the parameter to IXJCTL_DAA_AGAIN. The default setting is both at 0dB.
X *
X ******************************************************************************/
X #define IXJCTL_DAA_AGAIN _IOW ('q', 0xD2, int)
X
-#define AGRR00DB 0x00 // Analog gain in receive direction 0dB
-#define AGRR3_5DB 0x10 // Analog gain in receive direction 3.5dB
-#define AGRR06DB 0x30 // Analog gain in receive direction 6dB
+#define AGRR00DB 0x00 // Analog gain in recieve direction 0dB
+#define AGRR3_5DB 0x10 // Analog gain in recieve direction 3.5dB
+#define AGRR06DB 0x30 // Analog gain in recieve direction 6dB
X
X #define AGX00DB 0x00 // Analog gain in transmit direction 0dB
X #define AGX_6DB 0x04 // Analog gain in transmit direction -6dB
@@ -551,18 +586,9 @@
X
X #define IXJCTL_PSTN_LINETEST _IO ('q', 0xD3)
X
-typedef struct {
- char month[3];
- char day[3];
- char hour[3];
- char min[3];
- int numlen;
- char number[11];
- int namelen;
- char name[80];
-} IXJ_CID;
-
-#define IXJCTL_CID _IOR ('q', 0xD4, IXJ_CID *)
+#define IXJCTL_CID _IOR ('q', 0xD4, PHONE_CID *)
+#define IXJCTL_VMWI _IOR ('q', 0xD8, int)
+#define IXJCTL_CIDCW _IOW ('q', 0xD9, PHONE_CID *)
X /******************************************************************************
X *
X * The wink duration is tunable with this ioctl. The default wink duration
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/kernel.h linux/include/linux/kernel.h
--- v2.4.0-test8/linux/include/linux/kernel.h Tue Jun 20 07:52:36 2000
+++ linux/include/linux/kernel.h Fri Sep 22 14:21:16 2000


@@ -9,6 +9,7 @@
X

X #include <stdarg.h>
X #include <linux/linkage.h>
+#include <linux/stddef.h>
X
X /* Optimization barrier */
X /* The "volatile" is due to gcc bugs */
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/kmod.h linux/include/linux/kmod.h
--- v2.4.0-test8/linux/include/linux/kmod.h Fri Sep 8 12:52:41 2000
+++ linux/include/linux/kmod.h Mon Oct 2 11:01:18 2000
@@ -10,6 +10,7 @@
X extern int exec_usermodehelper(char *program_path, char *argv[], char *envp[]);
X #ifdef CONFIG_HOTPLUG
X extern char hotplug_path [];
+extern int call_usermodehelper(char *path, char *argv[], char *envp[]);
X #endif
X #else
X static inline int request_module(const char * name) { return -ENOSYS; }
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/locks.h linux/include/linux/locks.h
--- v2.4.0-test8/linux/include/linux/locks.h Fri Sep 8 12:53:34 2000
+++ linux/include/linux/locks.h Mon Oct 2 11:01:39 2000
@@ -29,7 +29,9 @@
X extern inline void unlock_buffer(struct buffer_head *bh)
X {
X clear_bit(BH_Lock, &bh->b_state);
- wake_up(&bh->b_wait);
+ smp_mb__after_clear_bit();
+ if (waitqueue_active(&bh->b_wait))
+ wake_up(&bh->b_wait);
X }
X
X /*
@@ -55,7 +57,12 @@
X extern inline void unlock_super(struct super_block * sb)
X {
X sb->s_lock = 0;
- wake_up(&sb->s_wait);
+ /*
+ * No need of any barrier, we're protected by
+ * the big kernel lock here... unfortunately :)
+ */
+ if (waitqueue_active(&sb->s_wait))
+ wake_up(&sb->s_wait);
X }
X
X #endif /* _LINUX_LOCKS_H */
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/major.h linux/include/linux/major.h
--- v2.4.0-test8/linux/include/linux/major.h Wed Aug 23 09:30:13 2000
+++ linux/include/linux/major.h Tue Oct 3 09:30:18 2000
@@ -108,6 +108,15 @@
X #define SPECIALIX_NORMAL_MAJOR 75
X #define SPECIALIX_CALLOUT_MAJOR 76
X
+#define COMPAQ_CISS_MAJOR 104
+#define COMPAQ_CISS_MAJOR1 105
+#define COMPAQ_CISS_MAJOR2 106
+#define COMPAQ_CISS_MAJOR3 107
+#define COMPAQ_CISS_MAJOR4 108
+#define COMPAQ_CISS_MAJOR5 109
+#define COMPAQ_CISS_MAJOR6 110
+#define COMPAQ_CISS_MAJOR7 111
+
X #define DASD_MAJOR 94 /* Official assignations from Peter */
X
X #define MDISK_MAJOR 95 /* Official assignations from Peter */
@@ -134,11 +143,13 @@
X #define USB_ACM_AUX_MAJOR 167
X #define USB_CHAR_MAJOR 180
X
-#define TUN_MAJOR 195
-
X #define UNIX98_PTY_MASTER_MAJOR 128
X #define UNIX98_PTY_MAJOR_COUNT 8
X #define UNIX98_PTY_SLAVE_MAJOR (UNIX98_PTY_MASTER_MAJOR+UNIX98_PTY_MAJOR_COUNT)
+
+#define VXVM_MAJOR 199 /* VERITAS volume i/o driver */
+#define VXSPEC_MAJOR 200 /* VERITAS volume config driver */
+#define VXDMP_MAJOR 201 /* VERITAS volume multipath driver */
X
X #define MSR_MAJOR 202
X #define CPUID_MAJOR 203
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/minix_fs.h linux/include/linux/minix_fs.h
--- v2.4.0-test8/linux/include/linux/minix_fs.h Thu Jun 29 15:00:31 2000
+++ linux/include/linux/minix_fs.h Wed Sep 27 19:23:40 2000
@@ -99,9 +99,14 @@
X extern struct buffer_head * minix_getblk(struct inode *, int, int);
X extern struct buffer_head * minix_bread(struct inode *, int, int);
X
+extern void V1_minix_truncate(struct inode *);
+extern void V2_minix_truncate(struct inode *);
X extern void minix_truncate(struct inode *);
X extern int minix_sync_inode(struct inode *);
-extern int minix_sync_file(struct file *, struct dentry *, int);
+extern int V1_minix_sync_file(struct inode *);
+extern int V2_minix_sync_file(struct inode *);
+extern int V1_minix_get_block(struct inode *, long, struct buffer_head *, int);
+extern int V2_minix_get_block(struct inode *, long, struct buffer_head *, int);
X
X extern struct address_space_operations minix_aops;
X extern struct inode_operations minix_file_inode_operations;
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/miscdevice.h linux/include/linux/miscdevice.h
--- v2.4.0-test8/linux/include/linux/miscdevice.h Fri Sep 8 12:52:44 2000
+++ linux/include/linux/miscdevice.h Mon Oct 2 11:01:19 2000
@@ -31,6 +31,8 @@
X /* drivers/sgi/char/usema.c */
X #define SGI_USEMACLONE 151
X
+#define TUN_MINOR 200
+
X extern int misc_init(void);
X
X struct miscdevice
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/mm.h linux/include/linux/mm.h
--- v2.4.0-test8/linux/include/linux/mm.h Fri Sep 8 12:52:42 2000
+++ linux/include/linux/mm.h Mon Oct 2 11:01:19 2000
@@ -15,7 +15,9 @@
X extern unsigned long num_physpages;
X extern void * high_memory;
X extern int page_cluster;
-extern struct list_head lru_cache;
+/* The inactive_clean lists are per zone. */
+extern struct list_head active_list;
+extern struct list_head inactive_dirty_list;
X
X #include <asm/page.h>
X #include <asm/pgtable.h>
@@ -92,6 +94,7 @@
X #define VM_RAND_READ 0x00010000 /* App will not benefit from clustered reads */
X
X #define VM_DONTCOPY 0x00020000 /* Do not copy this vma on fork */
+#define VM_DONTEXPAND 0x00040000 /* Cannot expand with mremap() */
X
X #define VM_STACK_FLAGS 0x00000177
X
@@ -149,6 +152,7 @@
X atomic_t count;
X unsigned long flags; /* atomic flags, some possibly updated asynchronously */
X struct list_head lru;
+ unsigned long age;
X wait_queue_head_t wait;
X struct page **pprev_hash;
X struct buffer_head * buffers;
@@ -169,12 +173,12 @@
X #define PG_uptodate 3
X #define PG_dirty 4
X #define PG_decr_after 5
-#define PG_unused_01 6
-#define PG__unused_02 7
+#define PG_active 6
+#define PG_inactive_dirty 7
X #define PG_slab 8
X #define PG_swap_cache 9
X #define PG_skip 10
-#define PG_unused_03 11
+#define PG_inactive_clean 11
X #define PG_highmem 12
X /* bits 21-30 unused */
X #define PG_reserved 31
@@ -190,15 +194,25 @@
X #define PageLocked(page) test_bit(PG_locked, &(page)->flags)
X #define LockPage(page) set_bit(PG_locked, &(page)->flags)
X #define TryLockPage(page) test_and_set_bit(PG_locked, &(page)->flags)
+/*
+ * The first mb is necessary to safely close the critical section opened by the
+ * TryLockPage(), the second mb is necessary to enforce ordering between
+ * the clear_bit and the read of the waitqueue (to avoid SMP races with a
+ * parallel wait_on_page).
+ */
X #define UnlockPage(page) do { \
+ smp_mb__before_clear_bit(); \
X clear_bit(PG_locked, &(page)->flags); \
- wake_up(&page->wait); \
+ smp_mb__after_clear_bit(); \
+ if (waitqueue_active(&page->wait)) \
+ wake_up(&page->wait); \
X } while (0)
X #define PageError(page) test_bit(PG_error, &(page)->flags)
X #define SetPageError(page) set_bit(PG_error, &(page)->flags)
X #define ClearPageError(page) clear_bit(PG_error, &(page)->flags)
X #define PageReferenced(page) test_bit(PG_referenced, &(page)->flags)
X #define SetPageReferenced(page) set_bit(PG_referenced, &(page)->flags)
+#define ClearPageReferenced(page) clear_bit(PG_referenced, &(page)->flags)
X #define PageTestandClearReferenced(page) test_and_clear_bit(PG_referenced, &(page)->flags)
X #define PageDecrAfter(page) test_bit(PG_decr_after, &(page)->flags)
X #define SetPageDecrAfter(page) set_bit(PG_decr_after, &(page)->flags)
@@ -217,6 +231,18 @@
X
X #define PageTestandClearSwapCache(page) test_and_clear_bit(PG_swap_cache, &(page)->flags)
X
+#define PageActive(page) test_bit(PG_active, &(page)->flags)
+#define SetPageActive(page) set_bit(PG_active, &(page)->flags)
+#define ClearPageActive(page) clear_bit(PG_active, &(page)->flags)
+
+#define PageInactiveDirty(page) test_bit(PG_inactive_dirty, &(page)->flags)
+#define SetPageInactiveDirty(page) set_bit(PG_inactive_dirty, &(page)->flags)
+#define ClearPageInactiveDirty(page) clear_bit(PG_inactive_dirty, &(page)->flags)
+
+#define PageInactiveClean(page) test_bit(PG_inactive_clean, &(page)->flags)
+#define SetPageInactiveClean(page) set_bit(PG_inactive_clean, &(page)->flags)
+#define ClearPageInactiveClean(page) clear_bit(PG_inactive_clean, &(page)->flags)
+
X #ifdef CONFIG_HIGHMEM
X #define PageHighMem(page) test_bit(PG_highmem, &(page)->flags)
X #else
@@ -416,7 +442,6 @@
X /* filemap.c */
X extern void remove_inode_page(struct page *);
X extern unsigned long page_unuse(struct page *);
-extern int shrink_mmap(int, int);
X extern void truncate_inode_pages(struct address_space *, loff_t);
X
X /* generic vm_area_ops exported for stackable file systems */
@@ -444,11 +469,11 @@
X
X #define GFP_BUFFER (__GFP_HIGH | __GFP_WAIT)
X #define GFP_ATOMIC (__GFP_HIGH)
-#define GFP_USER (__GFP_WAIT | __GFP_IO)
-#define GFP_HIGHUSER (GFP_USER | __GFP_HIGHMEM)
+#define GFP_USER ( __GFP_WAIT | __GFP_IO)
+#define GFP_HIGHUSER ( __GFP_WAIT | __GFP_IO | __GFP_HIGHMEM)
X #define GFP_KERNEL (__GFP_HIGH | __GFP_WAIT | __GFP_IO)
X #define GFP_NFS (__GFP_HIGH | __GFP_WAIT | __GFP_IO)
-#define GFP_KSWAPD (__GFP_IO)
+#define GFP_KSWAPD ( __GFP_IO)
X
X /* Flag - indicates that the buffer will be suitable for DMA. Ignored on some
X platforms, used as appropriate on others */
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/mmzone.h linux/include/linux/mmzone.h
--- v2.4.0-test8/linux/include/linux/mmzone.h Fri Sep 8 12:52:41 2000
+++ linux/include/linux/mmzone.h Mon Oct 2 11:01:17 2000
@@ -28,13 +28,14 @@
X spinlock_t lock;
X unsigned long offset;
X unsigned long free_pages;
- char low_on_memory;
- char zone_wake_kswapd;
+ unsigned long inactive_clean_pages;
+ unsigned long inactive_dirty_pages;
X unsigned long pages_min, pages_low, pages_high;
X
X /*
X * free areas of different sizes
X */
+ struct list_head inactive_clean_list;
X free_area_t free_area[MAX_ORDER];
X
X /*
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/module.h linux/include/linux/module.h
--- v2.4.0-test8/linux/include/linux/module.h Fri Sep 8 12:52:41 2000
+++ linux/include/linux/module.h Mon Oct 2 11:01:17 2000
@@ -279,14 +279,6 @@
X #define EXPORT_SYMBOL(var)
X #define EXPORT_SYMBOL_NOVERS(var)
X
-#elif !defined(EXPORT_SYMTAB)
-
-/* If things weren't set up in the Makefiles to get EXPORT_SYMTAB defined,
- then they weren't set up to run genksyms properly so MODVERSIONS breaks. */
-#define __EXPORT_SYMBOL(sym,str) error EXPORT_SYMTAB_not_defined
-#define EXPORT_SYMBOL(var) error EXPORT_SYMTAB_not_defined
-#define EXPORT_SYMBOL_NOVERS(var) error EXPORT_SYMTAB_not_defined
-
X #else
X
X #define __EXPORT_SYMBOL(sym, str) \
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/mount.h linux/include/linux/mount.h
--- v2.4.0-test8/linux/include/linux/mount.h Mon Jul 24 17:04:13 2000
+++ linux/include/linux/mount.h Sun Sep 17 09:51:57 2000
@@ -27,8 +27,7 @@
X struct list_head mnt_child; /* and going through their mnt_child */
X atomic_t mnt_count;
X int mnt_flags;
-
- char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */
+ char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */
X struct list_head mnt_list;
X uid_t mnt_owner;
X };
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/nfs_mount.h linux/include/linux/nfs_mount.h
--- v2.4.0-test8/linux/include/linux/nfs_mount.h Fri Sep 8 12:53:21 2000
+++ linux/include/linux/nfs_mount.h Mon Oct 2 11:01:41 2000
@@ -52,6 +52,7 @@
X #define NFS_MOUNT_VER3 0x0080 /* 3 */
X #define NFS_MOUNT_KERBEROS 0x0100 /* 3 */
X #define NFS_MOUNT_NONLM 0x0200 /* 3 */
+#define NFS_MOUNT_BROKEN_SUID 0x0400 /* 4 */
X #define NFS_MOUNT_FLAGMASK 0xFFFF
X
X #endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/nfsd/export.h linux/include/linux/nfsd/export.h
--- v2.4.0-test8/linux/include/linux/nfsd/export.h Fri Sep 8 12:53:25 2000
+++ linux/include/linux/nfsd/export.h Mon Oct 2 11:01:44 2000
@@ -38,7 +38,8 @@
X #define NFSEXP_CROSSMNT 0x0200
X #define NFSEXP_NOSUBTREECHECK 0x0400
X #define NFSEXP_NOAUTHNLM 0x0800 /* Don't authenticate NLM requests - just trust */
-#define NFSEXP_ALLFLAGS 0x0FFF
+#define NFSEXP_MSNFS 0x1000 /* do silly things that MS clients expect */
+#define NFSEXP_ALLFLAGS 0x1FFF
X
X
X #ifdef __KERNEL__
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/pci.h linux/include/linux/pci.h
--- v2.4.0-test8/linux/include/linux/pci.h Fri Sep 8 12:52:44 2000
+++ linux/include/linux/pci.h Mon Oct 2 12:06:32 2000
@@ -298,6 +298,16 @@
X #define DEVICE_COUNT_DMA 2
X #define DEVICE_COUNT_RESOURCE 12
X
+#define PCI_ANY_ID (~0)
+
+#define pci_present pcibios_present
+
+#define pci_for_each_dev(dev) \
+ for(dev = pci_dev_g(pci_devices.next); dev != pci_dev_g(&pci_devices); dev = pci_dev_g(dev->global_list.next))
+
+#define pci_for_each_dev_reverse(dev) \
+ for(dev = pci_dev_g(pci_devices.prev); dev != pci_dev_g(&pci_devices); dev = pci_dev_g(dev->global_list.prev))
+
X /*
X * The pci_dev structure is used to describe both PCI and ISAPnP devices.
X */
@@ -429,6 +439,27 @@
X unsigned long mem_start, mem_end;
X };
X
+struct pci_device_id {
+ unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */
+ unsigned int subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */
+ unsigned int class, class_mask; /* (class,subclass,prog-if) triplet */
+ unsigned long driver_data; /* Data private to the driver */
+};
+
+struct pci_driver {
+ struct list_head node;
+ char *name;
+ const struct pci_device_id *id_table; /* NULL if wants all devices */
+ int (*probe)(struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */
+ void (*remove)(struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */
+ void (*suspend)(struct pci_dev *dev); /* Device suspended */
+ void (*resume)(struct pci_dev *dev); /* Device woken up */
+};
+
+
+/* these external functions are only available when PCI support is enabled */
+#ifdef CONFIG_PCI
+
X void pcibios_init(void);
X void pcibios_fixup_bus(struct pci_bus *);
X int pcibios_enable_device(struct pci_dev *);
@@ -444,7 +475,6 @@
X /* Backward compatibility, don't use in new code! */
X
X int pcibios_present(void);
-#define pci_present pcibios_present
X int pcibios_read_config_byte (unsigned char bus, unsigned char dev_fn,
X unsigned char where, unsigned char *val);
X int pcibios_read_config_word (unsigned char bus, unsigned char dev_fn,
@@ -488,8 +518,6 @@
X struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn);
X int pci_find_capability (struct pci_dev *dev, int cap);
X
-#define PCI_ANY_ID (~0)
-
X int pci_read_config_byte(struct pci_dev *dev, int where, u8 *val);
X int pci_read_config_word(struct pci_dev *dev, int where, u16 *val);
X int pci_read_config_dword(struct pci_dev *dev, int where, u32 *val);
@@ -502,12 +530,6 @@
X int pci_set_power_state(struct pci_dev *dev, int state);
X int pci_assign_resource(struct pci_dev *dev, int i);
X
-#define pci_for_each_dev(dev) \
- for(dev = pci_dev_g(pci_devices.next); dev != pci_dev_g(&pci_devices); dev = pci_dev_g(dev->global_list.next))
-
-#define pci_for_each_dev_reverse(dev) \
- for(dev = pci_dev_g(pci_devices.prev); dev != pci_dev_g(&pci_devices); dev = pci_dev_g(dev->global_list.prev))
-
X /* Helper functions for low-level code (drivers/pci/setup.c) */
X
X int pci_claim_resource(struct pci_dev *, int);
@@ -518,24 +540,6 @@
X int (*)(struct pci_dev *, u8, u8));
X
X /* New-style probing supporting hot-pluggable devices */
-
-struct pci_device_id {
- unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */
- unsigned int subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */
- unsigned int class, class_mask; /* (class,subclass,prog-if) triplet */
- unsigned long driver_data; /* Data private to the driver */
-};
-
-struct pci_driver {
- struct list_head node;
- char *name;
- const struct pci_device_id *id_table; /* NULL if wants all devices */
- int (*probe)(struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */
- void (*remove)(struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */
- void (*suspend)(struct pci_dev *dev); /* Device suspended */
- void (*resume)(struct pci_dev *dev); /* Device woken up */
-};
-
X int pci_register_driver(struct pci_driver *);
X void pci_unregister_driver(struct pci_driver *);
X void pci_insert_device(struct pci_dev *, struct pci_bus *);
@@ -543,6 +547,8 @@
X struct pci_driver *pci_dev_driver(const struct pci_dev *);
X const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev);
X
+#endif /* CONFIG_PCI */
+
X /* Include architecture-dependent settings and functions */
X
X #include <asm/pci.h>
@@ -553,14 +559,14 @@
X */
X
X #ifndef CONFIG_PCI
-extern inline int pcibios_present(void) { return 0; }
-extern inline int pcibios_find_class (unsigned int class_code, unsigned short index, unsigned char *bus, unsigned char *dev_fn)
+static inline int pcibios_present(void) { return 0; }
+static inline int pcibios_find_class (unsigned int class_code, unsigned short index, unsigned char *bus, unsigned char *dev_fn)
X { return PCIBIOS_DEVICE_NOT_FOUND; }
X
X #define _PCI_NOP(o,s,t) \
- extern inline int pcibios_##o##_config_##s## (u8 bus, u8 dfn, u8 where, t val) \
+ static inline int pcibios_##o##_config_##s## (u8 bus, u8 dfn, u8 where, t val) \
X { return PCIBIOS_FUNC_NOT_SUPPORTED; } \
- extern inline int pci_##o##_config_##s## (struct pci_dev *dev, int where, t val) \
+ static inline int pci_##o##_config_##s## (struct pci_dev *dev, int where, t val) \
X { return PCIBIOS_FUNC_NOT_SUPPORTED; }
X #define _PCI_NOP_ALL(o,x) _PCI_NOP(o,byte,u8 x) \
X _PCI_NOP(o,word,u16 x) \
@@ -568,27 +574,27 @@
X _PCI_NOP_ALL(read, *)
X _PCI_NOP_ALL(write,)
X
-extern inline struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device, const struct pci_dev *from)
+static inline struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device, const struct pci_dev *from)
X { return NULL; }
X
-extern inline struct pci_dev *pci_find_class(unsigned int class, const struct pci_dev *from)
+static inline struct pci_dev *pci_find_class(unsigned int class, const struct pci_dev *from)
X { return NULL; }
X
-extern inline struct pci_dev *pci_find_slot(unsigned int bus, unsigned int devfn)
+static inline struct pci_dev *pci_find_slot(unsigned int bus, unsigned int devfn)
X { return NULL; }
X
-extern inline struct pci_dev *pci_find_subsys(unsigned int vendor, unsigned int device,
+static inline struct pci_dev *pci_find_subsys(unsigned int vendor, unsigned int device,
X unsigned int ss_vendor, unsigned int ss_device, const struct pci_dev *from)
X { return NULL; }
X
-extern inline void pci_set_master(struct pci_dev *dev) { }
-extern inline int pci_enable_device(struct pci_dev *dev) { return -EIO; }
-extern inline int pci_module_init(struct pci_driver *drv) { return -ENODEV; }
-extern inline int pci_assign_resource(struct pci_dev *dev, int i) { return -EBUSY;}
-extern inline int pci_register_driver(struct pci_driver *drv) { return 0;}
-extern inline void pci_unregister_driver(struct pci_driver *drv) { }
-extern inline int scsi_to_pci_dma_dir(unsigned char scsi_dir) { return scsi_dir; }
-extern inline int pci_find_capability (struct pci_dev *dev, int cap) {return 0; }
+static inline void pci_set_master(struct pci_dev *dev) { }
+static inline int pci_enable_device(struct pci_dev *dev) { return -EIO; }
+static inline int pci_module_init(struct pci_driver *drv) { return -ENODEV; }
+static inline int pci_assign_resource(struct pci_dev *dev, int i) { return -EBUSY;}
+static inline int pci_register_driver(struct pci_driver *drv) { return 0;}
+static inline void pci_unregister_driver(struct pci_driver *drv) { }
+static inline int scsi_to_pci_dma_dir(unsigned char scsi_dir) { return scsi_dir; }
+static inline int pci_find_capability (struct pci_dev *dev, int cap) {return 0; }
X
X #else
X
@@ -598,7 +604,7 @@
X *
X * This MUST stay in a header, as it checks for -DMODULE
X */
-extern inline int pci_module_init(struct pci_driver *drv)
+static inline int pci_module_init(struct pci_driver *drv)
X {
X int rc = pci_register_driver (drv);
X
@@ -635,6 +641,20 @@
X \
X (pci_resource_end((dev),(bar)) - \
X pci_resource_start((dev),(bar)) + 1))
+
+/* Similar to the helpers above, these manipulate per-pci_dev
+ * driver-specific data. Currently stored as pci_dev::driver_data,
+ * a void pointer, but it is not present on older kernels.
+ */
+static inline void *pci_get_drvdata (struct pci_dev *pdev)
+{
+ return pdev->driver_data;
+}
+
+static inline void pci_set_drvdata (struct pci_dev *pdev, void *data)
+{
+ pdev->driver_data = data;
+}
X
X /*
X * The world is not perfect and supplies us with broken PCI devices.
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/pci_ids.h linux/include/linux/pci_ids.h
--- v2.4.0-test8/linux/include/linux/pci_ids.h Mon Aug 28 21:25:25 2000
+++ linux/include/linux/pci_ids.h Wed Sep 27 13:53:52 2000
@@ -131,6 +131,7 @@
X #define PCI_DEVICE_ID_COMPAQ_NETEL100D 0xae40
X #define PCI_DEVICE_ID_COMPAQ_NETEL100PI 0xae43
X #define PCI_DEVICE_ID_COMPAQ_NETEL100I 0xb011
+#define PCI_DEVICE_ID_COMPAQ_CISS 0xb060
X #define PCI_DEVICE_ID_COMPAQ_THUNDER 0xf130
X #define PCI_DEVICE_ID_COMPAQ_NETFLEX3B 0xf150


X
@@ -463,6 +464,7 @@

X #define PCI_DEVICE_ID_APPLE_BANDIT 0x0001
X #define PCI_DEVICE_ID_APPLE_GC 0x0002
X #define PCI_DEVICE_ID_APPLE_HYDRA 0x000e
+#define PCI_DEVICE_ID_APPLE_UNINORTH 0x0020
X
X #define PCI_VENDOR_ID_NEXGEN 0x1074
X #define PCI_DEVICE_ID_NEXGEN_82C501 0x4e78
@@ -822,6 +824,11 @@
X #define PCI_DEVICE_ID_SERVERWORKS_CMIC_HE 0x0011
X #define PCI_DEVICE_ID_SERVERWORKS_CSB5 0x0201
X
+#define PCI_VENDOR_ID_SBE 0x1176
+#define PCI_DEVICE_ID_SBE_WANXL100 0x0301
+#define PCI_DEVICE_ID_SBE_WANXL200 0x0302
+#define PCI_DEVICE_ID_SBE_WANXL400 0x0104
+
X #define PCI_VENDOR_ID_TOSHIBA 0x1179
X #define PCI_DEVICE_ID_TOSHIBA_601 0x0601
X #define PCI_DEVICE_ID_TOSHIBA_TOPIC95 0x060a
@@ -913,6 +920,10 @@
X #define PCI_DEVICE_ID_CYCLOM_8Y_Hi 0x0105
X #define PCI_DEVICE_ID_CYCLOM_Z_Lo 0x0200
X #define PCI_DEVICE_ID_CYCLOM_Z_Hi 0x0201
+#define PCI_DEVICE_ID_PC300_RX_2 0x0300
+#define PCI_DEVICE_ID_PC300_RX_1 0x0301
+#define PCI_DEVICE_ID_PC300_TE_2 0x0310
+#define PCI_DEVICE_ID_PC300_TE_1 0x0311
X
X #define PCI_VENDOR_ID_ESSENTIAL 0x120f
X #define PCI_DEVICE_ID_ESSENTIAL_ROADRUNNER 0x0001
@@ -1073,11 +1084,6 @@
X #define PCI_DEVICE_ID_LAVA_QUAD_B 0x0202 /* 2x 16650, half of 4 port */
X #define PCI_DEVICE_ID_LAVA_SSERIAL 0x0500 /* 1x 16550 */
X #define PCI_DEVICE_ID_LAVA_PORT_650 0x0600 /* 1x 16650 */
-
-#define PCI_VENDOR_ID_SYBA 0x1592
-#define PCI_DEVICE_ID_SYBA_2P_EPP 0x0782
-#define PCI_DEVICE_ID_SYBA_1P_ECP 0x0783
-
X #define PCI_DEVICE_ID_LAVA_PARALLEL 0x8000
X #define PCI_DEVICE_ID_LAVA_DUAL_PAR_A 0x8002 /* The Lava Dual Parallel is */
X #define PCI_DEVICE_ID_LAVA_DUAL_PAR_B 0x8003 /* two PCI devices on a card */
@@ -1103,6 +1109,10 @@
X
X #define PCI_VENDOR_ID_AFAVLAB 0x14db
X #define PCI_DEVICE_ID_AFAVLAB_TK9902 0x2120
+
+#define PCI_VENDOR_ID_SYBA 0x1592
+#define PCI_DEVICE_ID_SYBA_2P_EPP 0x0782
+#define PCI_DEVICE_ID_SYBA_1P_ECP 0x0783
X
X #define PCI_VENDOR_ID_MORETON 0x15aa
X #define PCI_DEVICE_ID_RASTEL_2PORT 0x2000
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/pmu.h linux/include/linux/pmu.h
--- v2.4.0-test8/linux/include/linux/pmu.h Wed Feb 9 19:43:47 2000
+++ linux/include/linux/pmu.h Sun Sep 17 09:48:05 2000
@@ -10,6 +10,7 @@
X /*
X * PMU commands
X */
+#define PMU_POWER_CTRL0 0x10 /* control power of some devices */
X #define PMU_POWER_CTRL 0x11 /* control power of some devices */
X #define PMU_ADB_CMD 0x20 /* send ADB packet */
X #define PMU_ADB_POLL_OFF 0x21 /* disable ADB auto-poll */
@@ -26,15 +27,25 @@
X #define PMU_INT_ACK 0x78 /* read interrupt bits */
X #define PMU_SHUTDOWN 0x7e /* turn power off */
X #define PMU_SLEEP 0x7f /* put CPU to sleep */
+#define PMU_POWER_EVENTS 0x8f /* Send power-event commands to PMU */
X #define PMU_RESET 0xd0 /* reset CPU */
X #define PMU_GET_BRIGHTBUTTON 0xd9 /* report brightness up/down pos */
X #define PMU_GET_COVER 0xdc /* report cover open/closed */
+#define PMU_SYSTEM_READY 0xdf /* tell PMU we are awake */
+
+/* Bits to use with the PMU_POWER_CTRL0 command */
+#define PMU_POW0_ON 0x80 /* OR this to power ON the device */
+#define PMU_POW0_OFF 0x00 /* leave bit 7 to 0 to power it OFF */
+#define PMU_POW0_HARD_DRIVE 0x04 /* Hard drive power (on wallstreet/lombard ?) */
X
X /* Bits to use with the PMU_POWER_CTRL command */
X #define PMU_POW_ON 0x80 /* OR this to power ON the device */
X #define PMU_POW_OFF 0x00 /* leave bit 7 to 0 to power it OFF */
X #define PMU_POW_BACKLIGHT 0x01 /* backlight power */
+#define PMU_POW_CHARGER 0x02 /* battery charger power */
X #define PMU_POW_IRLED 0x04 /* IR led power (on wallstreet) */
+#define PMU_POW_MEDIABAY 0x08 /* media bay power (wallstreet/lombard ?) */
+
X
X /* Bits in PMU interrupt and interrupt mask bytes */
X #define PMU_INT_ADB_AUTO 0x04 /* ADB autopoll, when PMU_INT_ADB */
@@ -54,6 +65,25 @@
X PMU_KEYLARGO_BASED, /* Core99 motherboard (PMU99) */
X };
X
+/* PMU PMU_POWER_EVENTS commands */
+enum {
+ PMU_PWR_GET_POWERUP_EVENTS = 0x00,
+ PMU_PWR_SET_POWERUP_EVENTS = 0x01,
+ PMU_PWR_CLR_POWERUP_EVENTS = 0x02,
+ PMU_PWR_GET_WAKEUP_EVENTS = 0x03,
+ PMU_PWR_SET_WAKEUP_EVENTS = 0x04,
+ PMU_PWR_CLR_WAKEUP_EVENTS = 0x05,
+};
+
+/* Power events wakeup bits */
+enum {
+ PMU_PWR_WAKEUP_KEY = 0x01, /* Wake on key press */
+ PMU_PWR_WAKEUP_AC_INSERT = 0x02, /* Wake on AC adapter plug */
+ PMU_PWR_WAKEUP_AC_CHANGE = 0x04,
+ PMU_PWR_WAKEUP_LID_OPEN = 0x08,
+ PMU_PWR_WAKEUP_RING = 0x10,
+};
+
X /*
X * Ioctl commands for the /dev/pmu device
X */
@@ -61,34 +91,38 @@
X
X /* no param */
X #define PMU_IOC_SLEEP _IO('B', 0)
-/* out param: u32* backlight value: 0 to 31 */
+/* out param: u32* backlight value: 0 to 15 */
X #define PMU_IOC_GET_BACKLIGHT _IOR('B', 1, sizeof(__u32*))
-/* in param: u32 backlight value: 0 to 31 */
+/* in param: u32 backlight value: 0 to 15 */
X #define PMU_IOC_SET_BACKLIGHT _IOW('B', 2, sizeof(__u32))
-/* out param: u32* backlight value: 0 to 31 */
+/* out param: u32* PMU model */
X #define PMU_IOC_GET_MODEL _IOR('B', 3, sizeof(__u32*))
X /* out param: u32* has_adb: 0 or 1 */
X #define PMU_IOC_HAS_ADB _IOR('B', 4, sizeof(__u32*))

X
X #ifdef __KERNEL__
X

-int find_via_pmu(void);
-int via_pmu_init(void);
+extern int find_via_pmu(void);
+extern int via_pmu_start(void);
X
-int pmu_request(struct adb_request *req,
+extern int pmu_request(struct adb_request *req,


X void (*done)(struct adb_request *), int nbytes, ...);

-void pmu_poll(void);
X
-void pmu_enable_backlight(int on);
-void pmu_set_brightness(int level);
+extern void pmu_poll(void);
+
+/* For use before switching interrupts off for a long time;
+ * warning: not stackable
+ */
+extern void pmu_suspend(void);
+extern void pmu_resume(void);
X
-void pmu_enable_irled(int on);
+extern void pmu_enable_irled(int on);
X
-void pmu_restart(void);
-void pmu_shutdown(void);
+extern void pmu_restart(void);
+extern void pmu_shutdown(void);
X
-int pmu_present(void);
-int pmu_get_model(void);
+extern int pmu_present(void);
+extern int pmu_get_model(void);
X
X #ifdef CONFIG_PMAC_PBOOK
X /*
@@ -135,4 +169,4 @@
X #endif /* CONFIG_PMAC_PBOOK */
X
X
-#endif /* __KERNEL */
+#endif /* __KERNEL__ */
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/raid/md.h linux/include/linux/raid/md.h
--- v2.4.0-test8/linux/include/linux/raid/md.h Fri Sep 8 12:52:55 2000
+++ linux/include/linux/raid/md.h Mon Oct 2 12:06:33 2000
@@ -82,7 +82,7 @@
X extern int md_notify_reboot(struct notifier_block *this,
X unsigned long code, void *x);
X extern int md_error (kdev_t mddev, kdev_t rdev);
-extern void md_run_setup(void);
+extern int md_run_setup(void);
X
X extern void md_print_devices (void);
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/raid/md_compatible.h linux/include/linux/raid/md_compatible.h
--- v2.4.0-test8/linux/include/linux/raid/md_compatible.h Fri Sep 8 12:52:42 2000
+++ linux/include/linux/raid/md_compatible.h Mon Oct 2 12:04:52 2000
@@ -77,11 +77,7 @@
X /* 011 */
X #define md_signal_pending signal_pending
X
-/* 012 */
-extern inline void md_set_global_readahead(int * table)
-{
- max_readahead[MD_MAJOR] = table;
-}
+/* 012 - md_set_global_readahead - nowhere used */
X
X /* 013 */
X #define md_mdelay(x) mdelay(x)
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/sched.h linux/include/linux/sched.h
--- v2.4.0-test8/linux/include/linux/sched.h Fri Sep 8 12:52:42 2000
+++ linux/include/linux/sched.h Mon Oct 2 11:01:19 2000
@@ -298,6 +298,7 @@
X * that's just fine.)
X */
X struct list_head run_list;
+ unsigned long sleep_time;
X
X struct task_struct *next_task, *prev_task;
X struct mm_struct *active_mm;
@@ -356,6 +357,7 @@
X /* file system info */
X int link_count;
X struct tty_struct *tty; /* NULL if no tty */
+ unsigned int locks; /* How many file locks are being held */
X /* ipc stuff */
X struct sem_undo *semundo;
X struct sem_queue *semsleeping;
@@ -818,6 +820,7 @@
X static inline void del_from_runqueue(struct task_struct * p)
X {
X nr_running--;
+ p->sleep_time = jiffies;
X list_del(&p->run_list);
X p->run_list.next = NULL;
X }
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/signal.h linux/include/linux/signal.h
--- v2.4.0-test8/linux/include/linux/signal.h Fri Sep 8 12:52:42 2000
+++ linux/include/linux/signal.h Mon Oct 2 11:01:19 2000
@@ -28,7 +28,7 @@
X
X /* We don't use <asm/bitops.h> for these because there is no need to
X be atomic. */
-extern inline void sigaddset(sigset_t *set, int _sig)
+static inline void sigaddset(sigset_t *set, int _sig)
X {
X unsigned long sig = _sig - 1;
X if (_NSIG_WORDS == 1)
@@ -37,7 +37,7 @@
X set->sig[sig / _NSIG_BPW] |= 1UL << (sig % _NSIG_BPW);
X }
X
-extern inline void sigdelset(sigset_t *set, int _sig)
+static inline void sigdelset(sigset_t *set, int _sig)
X {
X unsigned long sig = _sig - 1;
X if (_NSIG_WORDS == 1)
@@ -46,7 +46,7 @@
X set->sig[sig / _NSIG_BPW] &= ~(1UL << (sig % _NSIG_BPW));
X }
X
-extern inline int sigismember(sigset_t *set, int _sig)
+static inline int sigismember(sigset_t *set, int _sig)
X {
X unsigned long sig = _sig - 1;
X if (_NSIG_WORDS == 1)
@@ -55,7 +55,7 @@
X return 1 & (set->sig[sig / _NSIG_BPW] >> (sig % _NSIG_BPW));
X }
X
-extern inline int sigfindinword(unsigned long word)
+static inline int sigfindinword(unsigned long word)
X {
X return ffz(~word);
X }
@@ -68,7 +68,7 @@
X #include <linux/string.h>
X
X #define _SIG_SET_BINOP(name, op) \
-extern inline void name(sigset_t *r, const sigset_t *a, const sigset_t *b) \
+static inline void name(sigset_t *r, const sigset_t *a, const sigset_t *b) \
X { \
X unsigned long a0, a1, a2, a3, b0, b1, b2, b3; \
X unsigned long i; \
@@ -119,7 +119,7 @@
X #undef _sig_nand
X
X #define _SIG_SET_OP(name, op) \
-extern inline void name(sigset_t *set) \
+static inline void name(sigset_t *set) \
X { \
X unsigned long i; \
X \
@@ -142,7 +142,7 @@
X #undef _SIG_SET_OP
X #undef _sig_not
X
-extern inline void sigemptyset(sigset_t *set)
+static inline void sigemptyset(sigset_t *set)
X {
X switch (_NSIG_WORDS) {
X default:
@@ -154,7 +154,7 @@
X }
X }
X
-extern inline void sigfillset(sigset_t *set)
+static inline void sigfillset(sigset_t *set)
X {
X switch (_NSIG_WORDS) {
X default:
@@ -170,22 +170,22 @@
X
X /* Some extensions for manipulating the low 32 signals in particular. */
X
-extern inline void sigaddsetmask(sigset_t *set, unsigned long mask)
+static inline void sigaddsetmask(sigset_t *set, unsigned long mask)
X {
X set->sig[0] |= mask;
X }
X
-extern inline void sigdelsetmask(sigset_t *set, unsigned long mask)
+static inline void sigdelsetmask(sigset_t *set, unsigned long mask)
X {
X set->sig[0] &= ~mask;
X }
X
-extern inline int sigtestsetmask(sigset_t *set, unsigned long mask)
+static inline int sigtestsetmask(sigset_t *set, unsigned long mask)
X {
X return (set->sig[0] & mask) != 0;
X }
X
-extern inline void siginitset(sigset_t *set, unsigned long mask)
+static inline void siginitset(sigset_t *set, unsigned long mask)
X {
X set->sig[0] = mask;
X switch (_NSIG_WORDS) {
@@ -197,7 +197,7 @@
X }
X }
X
-extern inline void siginitsetinv(sigset_t *set, unsigned long mask)
+static inline void siginitsetinv(sigset_t *set, unsigned long mask)
X {
X set->sig[0] = ~mask;
X switch (_NSIG_WORDS) {
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/slab.h linux/include/linux/slab.h
--- v2.4.0-test8/linux/include/linux/slab.h Fri Sep 8 12:52:42 2000
+++ linux/include/linux/slab.h Mon Oct 2 11:54:51 2000
@@ -11,7 +11,6 @@
X
X typedef struct kmem_cache_s kmem_cache_t;
X
-#include <linux/config.h>
X #include <linux/mm.h>
X #include <linux/cache.h>
X
@@ -75,14 +74,6 @@
X extern kmem_cache_t *bh_cachep;
X extern kmem_cache_t *fs_cachep;
X extern kmem_cache_t *sigact_cachep;
-
-#ifdef CONFIG_SMP
-extern unsigned long slab_cache_drain_mask;
-extern void slab_drain_local_cache(void);
-#else
-#define slab_cache_drain_mask 0
-#define slab_drain_local_cache() do { } while (0)
-#endif


X
X #endif /* __KERNEL__ */
X

diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/sunrpc/clnt.h linux/include/linux/sunrpc/clnt.h
--- v2.4.0-test8/linux/include/linux/sunrpc/clnt.h Fri Sep 8 12:53:21 2000
+++ linux/include/linux/sunrpc/clnt.h Mon Oct 2 12:05:07 2000
@@ -45,6 +45,7 @@
X cl_chatty : 1,/* be verbose */
X cl_autobind : 1,/* use getport() */
X cl_binding : 1,/* doing a getport() */
+ cl_droppriv : 1,/* enable NFS suid hack */
X cl_oneshot : 1,/* dispose after use */
X cl_dead : 1;/* abandoned */
X unsigned int cl_flags; /* misc client flags */
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/swap.h linux/include/linux/swap.h
--- v2.4.0-test8/linux/include/linux/swap.h Fri Sep 8 12:52:41 2000
+++ linux/include/linux/swap.h Mon Oct 2 11:28:38 2000
@@ -65,13 +65,16 @@
X
X extern int nr_swap_pages;
X FASTCALL(unsigned int nr_free_pages(void));
+FASTCALL(unsigned int nr_inactive_clean_pages(void));
X FASTCALL(unsigned int nr_free_buffer_pages(void));
-FASTCALL(unsigned int nr_free_highpages(void));
-extern int nr_lru_pages;
+extern int nr_active_pages;
+extern int nr_inactive_dirty_pages;
X extern atomic_t nr_async_pages;
X extern struct address_space swapper_space;
X extern atomic_t page_cache_size;
X extern atomic_t buffermem_pages;
+extern spinlock_t pagecache_lock;
+extern void __remove_inode_page(struct page *);
X
X /* Incomplete types for prototype declarations: */
X struct task_struct;
@@ -83,9 +86,30 @@
X extern int shm_swap(int, int);
X
X /* linux/mm/swap.c */
+extern int memory_pressure;
+extern void age_page_up(struct page *);
+extern void age_page_up_nolock(struct page *);
+extern void age_page_down(struct page *);
+extern void age_page_down_nolock(struct page *);
+extern void age_page_down_ageonly(struct page *);
+extern void deactivate_page(struct page *);
+extern void deactivate_page_nolock(struct page *);
+extern void activate_page(struct page *);
+extern void activate_page_nolock(struct page *);
+extern void lru_cache_add(struct page *);
+extern void __lru_cache_del(struct page *);
+extern void lru_cache_del(struct page *);
+extern void recalculate_vm_stats(void);
X extern void swap_setup(void);
X
X /* linux/mm/vmscan.c */
+extern struct page * reclaim_page(zone_t *);
+extern wait_queue_head_t kswapd_wait;
+extern wait_queue_head_t kreclaimd_wait;
+extern int page_launder(int, int);
+extern int free_shortage(void);
+extern int inactive_shortage(void);
+extern void wakeup_kswapd(int);
X extern int try_to_free_pages(unsigned int gfp_mask);
X
X /* linux/mm/page_io.c */
@@ -161,30 +185,102 @@
X extern spinlock_t pagemap_lru_lock;
X
X /*
- * Helper macros for lru_pages handling.
+ * Page aging defines.
+ * Since we do exponential decay of the page age, we
+ * can chose a fairly large maximum.
X */
-#define lru_cache_add(page) \
-do { \
- spin_lock(&pagemap_lru_lock); \
- list_add(&(page)->lru, &lru_cache); \
- nr_lru_pages++; \
- spin_unlock(&pagemap_lru_lock); \
-} while (0)
-
-#define __lru_cache_del(page) \
-do { \
- list_del(&(page)->lru); \
- nr_lru_pages--; \
-} while (0)
-
-#define lru_cache_del(page) \
-do { \
- if (!PageLocked(page)) \
- BUG(); \
- spin_lock(&pagemap_lru_lock); \
- __lru_cache_del(page); \
- spin_unlock(&pagemap_lru_lock); \
-} while (0)
+#define PAGE_AGE_START 2
+#define PAGE_AGE_ADV 3
+#define PAGE_AGE_MAX 64
+
+/*
+ * List add/del helper macros. These must be called
+ * with the pagemap_lru_lock held!
+ */
+#define DEBUG_ADD_PAGE \
+ if (PageActive(page) || PageInactiveDirty(page) || \
+ PageInactiveClean(page)) BUG();
+
+#define ZERO_PAGE_BUG \
+ if (page_count(page) == 0) BUG();
+
+#define add_page_to_active_list(page) { \
+ DEBUG_ADD_PAGE \
+ ZERO_PAGE_BUG \
+ SetPageActive(page); \
+ list_add(&(page)->lru, &active_list); \
+ nr_active_pages++; \
+}
+
+#define add_page_to_inactive_dirty_list(page) { \
+ DEBUG_ADD_PAGE \
+ ZERO_PAGE_BUG \
+ SetPageInactiveDirty(page); \
+ list_add(&(page)->lru, &inactive_dirty_list); \
+ nr_inactive_dirty_pages++; \
+ page->zone->inactive_dirty_pages++; \
+}
+
+#define add_page_to_inactive_clean_list(page) { \
+ DEBUG_ADD_PAGE \
+ ZERO_PAGE_BUG \
+ SetPageInactiveClean(page); \
+ list_add(&(page)->lru, &page->zone->inactive_clean_list); \
+ page->zone->inactive_clean_pages++; \
+}
+
+#define del_page_from_active_list(page) { \
+ list_del(&(page)->lru); \
+ ClearPageActive(page); \
+ nr_active_pages--; \
+ DEBUG_ADD_PAGE \
+ ZERO_PAGE_BUG \
+}
+
+#define del_page_from_inactive_dirty_list(page) { \
+ list_del(&(page)->lru); \
+ ClearPageInactiveDirty(page); \


+ nr_inactive_dirty_pages--; \
+ page->zone->inactive_dirty_pages--; \

+ DEBUG_ADD_PAGE \
+ ZERO_PAGE_BUG \
+}
+
+#define del_page_from_inactive_clean_list(page) { \
+ list_del(&(page)->lru); \
+ ClearPageInactiveClean(page); \
+ page->zone->inactive_clean_pages--; \
+ DEBUG_ADD_PAGE \
+ ZERO_PAGE_BUG \
+}
+
+/*
+ * In mm/swap.c::recalculate_vm_stats(), we substract
+ * inactive_target from memory_pressure every second.
+ * This means that memory_pressure is smoothed over
+ * 64 (1 << INACTIVE_SHIFT) seconds.
+ */
+#define INACTIVE_SHIFT 6
+#define inactive_min(a,b) ((a) < (b) ? (a) : (b))
+#define inactive_target inactive_min((memory_pressure >> INACTIVE_SHIFT), \
+ (num_physpages / 4))
+
+/*
+ * Ugly ugly ugly HACK to make sure the inactive lists
+ * don't fill up with unfreeable ramdisk pages. We really
+ * want to fix the ramdisk driver to mark its pages as
+ * unfreeable instead of using dirty buffer magic, but the
+ * next code-change time is when 2.5 is forked...
+ */
+#ifndef _LINUX_KDEV_T_H
+#include <linux/kdev_t.h>
+#endif
+#ifndef _LINUX_MAJOR_H
+#include <linux/major.h>
+#endif
+
+#define page_ramdisk(page) \
+ (page->buffers && (MAJOR(page->buffers->b_dev) == RAMDISK_MAJOR))
X
X extern spinlock_t swaplock;
X
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/sysctl.h linux/include/linux/sysctl.h
--- v2.4.0-test8/linux/include/linux/sysctl.h Thu Aug 10 13:01:26 2000
+++ linux/include/linux/sysctl.h Fri Sep 22 14:21:22 2000
@@ -186,7 +186,8 @@
X NET_CORE_MSG_COST=8,
X NET_CORE_MSG_BURST=9,
X NET_CORE_OPTMEM_MAX=10,
- NET_CORE_HOT_LIST_LENGTH=11
+ NET_CORE_HOT_LIST_LENGTH=11,
+ NET_CORE_DIVERT_VERSION=12
X };
X
X /* /proc/sys/net/ethernet */
@@ -512,7 +513,10 @@
X FS_NRSUPER=9, /* int:current number of allocated super_blocks */
X FS_MAXSUPER=10, /* int:maximum number of super_blocks that can be allocated */
X FS_OVERFLOWUID=11, /* int: overflow UID */
- FS_OVERFLOWGID=12 /* int: overflow GID */
+ FS_OVERFLOWGID=12, /* int: overflow GID */
+ FS_LEASES=13, /* int: leases enabled */
+ FS_DIR_NOTIFY=14, /* int: directory notification enabled */
+ FS_LEASE_TIME=15, /* int: maximum time to wait for a lease break */
X };
X
X /* CTL_DEBUG names: */
@@ -522,7 +526,8 @@
X DEV_CDROM=1,
X DEV_HWMON=2,
X DEV_PARPORT=3,
- DEV_RAID=4
+ DEV_RAID=4,
+ DEV_MAC_HID=5
X };
X
X /* /proc/sys/dev/cdrom */
@@ -571,6 +576,16 @@
X /* /proc/sys/dev/parport/parport n/devices/device n */
X enum {
X DEV_PARPORT_DEVICE_TIMESLICE=1,
+};
+
+/* /proc/sys/dev/mac_hid */
+enum {
+ DEV_MAC_HID_KEYBOARD_SENDS_LINUX_KEYCODES=1,
+ DEV_MAC_HID_KEYBOARD_LOCK_KEYCODES=2,
+ DEV_MAC_HID_MOUSE_BUTTON_EMULATION=3,
+ DEV_MAC_HID_MOUSE_BUTTON2_KEYCODE=4,
+ DEV_MAC_HID_MOUSE_BUTTON3_KEYCODE=5,
+ DEV_MAC_HID_ADB_MOUSE_SENDS_KEYCODES=6
X };
X
X #ifdef __KERNEL__
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/tcp.h linux/include/linux/tcp.h
--- v2.4.0-test8/linux/include/linux/tcp.h Fri Sep 8 12:52:42 2000
+++ linux/include/linux/tcp.h Mon Oct 2 11:01:18 2000
@@ -125,5 +125,63 @@
X #define TCP_LINGER2 8 /* Life time of orphaned FIN-WAIT-2 state */
X #define TCP_DEFER_ACCEPT 9 /* Wake up listener only when data arrive */
X #define TCP_WINDOW_CLAMP 10 /* Bound advertised window */
+#define TCP_INFO 11 /* Information about this connection. */
+
+#define TCPI_OPT_TIMESTAMPS 1
+#define TCPI_OPT_SACK 2
+#define TCPI_OPT_WSCALE 4
+#define TCPI_OPT_ECN 8
+
+enum tcp_ca_state
+{
+ TCP_CA_Open = 0,
+#define TCPF_CA_Open (1<<TCP_CA_Open)
+ TCP_CA_Disorder = 1,
+#define TCPF_CA_Disorder (1<<TCP_CA_Disorder)
+ TCP_CA_CWR = 2,
+#define TCPF_CA_CWR (1<<TCP_CA_CWR)
+ TCP_CA_Recovery = 3,
+#define TCPF_CA_Recovery (1<<TCP_CA_Recovery)
+ TCP_CA_Loss = 4
+#define TCPF_CA_Loss (1<<TCP_CA_Loss)
+};
+
+struct tcp_info
+{
+ __u8 tcpi_state;
+ __u8 tcpi_ca_state;
+ __u8 tcpi_retransmits;
+ __u8 tcpi_probes;
+ __u8 tcpi_backoff;
+ __u8 tcpi_options;
+ __u8 tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
+
+ __u32 tcpi_rto;
+ __u32 tcpi_ato;
+ __u32 tcpi_snd_mss;
+ __u32 tcpi_rcv_mss;
+
+ __u32 tcpi_unacked;
+ __u32 tcpi_sacked;
+ __u32 tcpi_lost;
+ __u32 tcpi_retrans;
+ __u32 tcpi_fackets;
+
+ /* Times. */
+ __u32 tcpi_last_data_sent;
+ __u32 tcpi_last_ack_sent; /* Not remembered, sorry. */
+ __u32 tcpi_last_data_recv;
+ __u32 tcpi_last_ack_recv;
+
+ /* Metrics. */
+ __u32 tcpi_pmtu;
+ __u32 tcpi_rcv_ssthresh;
+ __u32 tcpi_rtt;
+ __u32 tcpi_rttvar;
+ __u32 tcpi_snd_ssthresh;
+ __u32 tcpi_snd_cwnd;
+ __u32 tcpi_advmss;
+ __u32 tcpi_reordering;
+};
X
X #endif /* _LINUX_TCP_H */
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/telephony.h linux/include/linux/telephony.h
--- v2.4.0-test8/linux/include/linux/telephony.h Sun Mar 12 19:18:55 2000
+++ linux/include/linux/telephony.h Mon Sep 18 15:02:03 2000
@@ -1,32 +1,33 @@
-/*
- * telephony.h
+/******************************************************************************
+ *
+ * telephony.h
X *
- * Basic Linux Telephony Interface
+ * Basic Linux Telephony Interface
X *
- * (c) Copyright 1999 Quicknet Technologies, Inc.
+ * (c) Copyright 1999 Quicknet Technologies, Inc.
X *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
X *
- * Authors: Ed Okerson, <eoke...@quicknet.net>
- * Greg Herlein, <gher...@quicknet.net>
+ * Authors: Ed Okerson, <eoke...@quicknet.net>
+ * Greg Herlein, <gher...@quicknet.net>
X *
- * Contributors: Alan Cox, <ac...@redhat.com>
- * David Erhart, <der...@quicknet.net>
+ * Contributors: Alan Cox, <al...@redhat.com>
+ * David W. Erhart, <der...@quicknet.net>
X *
X * Version: 0.1.0 - December 19, 1999


X *
X * Fixes:
- */
+ *

+ *****************************************************************************/
X
X #ifndef TELEPHONY_H
X #define TELEPHONY_H
X
-/* vendor identification numbers */
X #define PHONE_VENDOR_IXJ 1
-#define PHONE_VENDOR_QUICKNET PHONE_IXJ
+#define PHONE_VENDOR_QUICKNET PHONE_VENDOR_IXJ
X #define PHONE_VENDOR_VOICETRONIX 2
X #define PHONE_VENDOR_ACULAB 3
X #define PHONE_VENDOR_DIGI 4
@@ -43,7 +44,6 @@
X *
X *****************************************************************************/
X
-
X /******************************************************************************
X *
X * The capabilities ioctls can inform you of the capabilities of each phone
@@ -81,11 +81,23 @@
X #define PHONE_CAPABILITIES_LIST _IOR ('q', 0x81, struct phone_capability *)
X #define PHONE_CAPABILITIES_CHECK _IOW ('q', 0x82, struct phone_capability *)
X
+typedef struct {
+ char month[3];
+ char day[3];
+ char hour[3];
+ char min[3];
+ int numlen;
+ char number[11];
+ int namelen;
+ char name[80];
+} PHONE_CID;
+
X #define PHONE_RING _IO ('q', 0x83)
X #define PHONE_HOOKSTATE _IO ('q', 0x84)
X #define PHONE_MAXRINGS _IOW ('q', 0x85, char)
X #define PHONE_RING_CADENCE _IOW ('q', 0x86, short)
-#define PHONE_RING_START _IO ('q', 0x87)
+#define OLD_PHONE_RING_START _IO ('q', 0x87)
+#define PHONE_RING_START _IOW ('q', 0x87, PHONE_CID *)
X #define PHONE_RING_STOP _IO ('q', 0x88)
X
X #define USA_RING_CADENCE 0xC0C0
@@ -167,6 +179,23 @@
X #define PHONE_QUERY_CODEC _IOWR ('q', 0xA7, struct phone_codec_data *)
X #define PHONE_PSTN_LINETEST _IO ('q', 0xA8)
X
+/******************************************************************************
+*
+* This controls the VAD/CNG functionality of G.723.1. The driver will
+* always pass full size frames, any unused bytes will be padded with zeros,
+* and frames passed to the driver should also be padded with zeros. The
+* frame type is encoded in the least significant two bits of the first
+* WORD of the frame as follows:
+*
+* bits 1-0 Frame Type Data Rate Significant Words
+* 00 0 G.723.1 6.3 12
+* 01 1 G.723.1 5.3 10
+* 10 2 VAD/CNG 2
+* 11 3 Repeat last CNG 2 bits
+*
+******************************************************************************/
+#define PHONE_VAD _IOW ('q', 0xA9, int)


+
X
X /******************************************************************************
X *

@@ -198,7 +227,12 @@
X unsigned int f1:1;
X unsigned int f2:1;
X unsigned int f3:1;
- unsigned int reserved:23;
+ unsigned int flash:1;
+ unsigned int fc0:1;
+ unsigned int fc1:1;
+ unsigned int fc2:1;
+ unsigned int fc3:1;
+ unsigned int reserved:18;
X };
X
X union telephony_exception {
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/time.h linux/include/linux/time.h
--- v2.4.0-test8/linux/include/linux/time.h Fri Sep 8 12:52:41 2000
+++ linux/include/linux/time.h Mon Oct 2 11:01:17 2000
@@ -45,7 +45,42 @@
X value->tv_nsec = (jiffies % HZ) * (1000000000L / HZ);
X value->tv_sec = jiffies / HZ;
X }
-
+
+
+/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
+ * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
+ * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
+ *
+ * [For the Julian calendar (which was used in Russia before 1917,
+ * Britain & colonies before 1752, anywhere else before 1582,
+ * and is still in use by some communities) leave out the
+ * -year/100+year/400 terms, and add 10.]
+ *
+ * This algorithm was first published by Gauss (I think).
+ *
+ * WARNING: this function will overflow on 2106-02-07 06:28:16 on
+ * machines were long is 32-bit! (However, as time_t is signed, we
+ * will already get problems at other places on 2038-01-19 03:14:08)
+ */
+static inline unsigned long
+mktime (unsigned int year, unsigned int mon,
+ unsigned int day, unsigned int hour,
+ unsigned int min, unsigned int sec)
+{
+ if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */
+ mon += 12; /* Puts Feb last since it has leap day */
+ year -= 1;
+ }
+
+ return (((
+ (unsigned long) (year/4 - year/100 + year/400 + 367*mon/12 + day) +
+ year*365 - 719499
+ )*24 + hour /* now have hours */
+ )*60 + min /* now have minutes */
+ )*60 + sec; /* finally seconds */
+}
+
+
X struct timeval {
X time_t tv_sec; /* seconds */
X suseconds_t tv_usec; /* microseconds */
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/timex.h linux/include/linux/timex.h
--- v2.4.0-test8/linux/include/linux/timex.h Fri Sep 8 12:52:41 2000
+++ linux/include/linux/timex.h Mon Oct 2 11:01:17 2000
@@ -51,6 +51,8 @@
X #ifndef _LINUX_TIMEX_H
X #define _LINUX_TIMEX_H
X
+#include <asm/param.h>
+
X /*
X * The following defines establish the engineering parameters of the PLL
X * model. The HZ variable establishes the timer interrupt frequency, 100 Hz
@@ -58,10 +60,20 @@
X * OSF/1 kernel. The SHIFT_HZ define expresses the same value as the
X * nearest power of two in order to avoid hardware multiply operations.
X */
-#ifdef __alpha__
-# define SHIFT_HZ 10 /* log2(HZ) */
+#if HZ >= 24 && HZ < 48
+# define SHIFT_HZ 5
+#elif HZ >= 48 && HZ < 96
+# define SHIFT_HZ 6
+#elif HZ >= 96 && HZ < 192
+# define SHIFT_HZ 7
+#elif HZ >= 192 && HZ < 384
+# define SHIFT_HZ 8
+#elif HZ >= 384 && HZ < 768
+# define SHIFT_HZ 9
+#elif HZ >= 768 && HZ < 1536
+# define SHIFT_HZ 10
X #else
-# define SHIFT_HZ 7 /* log2(HZ) */
+# error You lose.


X #endif
X
X /*

diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/toshiba.h linux/include/linux/toshiba.h
--- v2.4.0-test8/linux/include/linux/toshiba.h Wed Dec 31 16:00:00 1969
+++ linux/include/linux/toshiba.h Mon Sep 18 15:02:03 2000
@@ -0,0 +1,36 @@
+/* toshiba.h -- Linux driver for accessing the SMM on Toshiba laptops
+ *
+ * Copyright (c) 1996-2000 Jonathan A. Buzzard (jona...@buzzard.org.uk)
+ *
+ * Thanks to Juergen Heinzl <jue...@monocerus.demon.co.uk> for the pointers
+ * on making sure the structure is aligned and packed.
+ *


+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the

+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.


+ *
+ */
+

+#ifndef _LINUX_TOSHIBA_H
+#define _LINUX_TOSHIBA_H
+
+#define TOSH_PROC "/proc/toshiba"
+#define TOSH_DEVICE "/dev/toshiba"
+#define TOSH_SMM _IOWR('t', 0x90, 24)
+
+typedef struct {
+ unsigned int eax;
+ unsigned int ebx __attribute__ ((packed));
+ unsigned int ecx __attribute__ ((packed));
+ unsigned int edx __attribute__ ((packed));
+ unsigned int esi __attribute__ ((packed));
+ unsigned int edi __attribute__ ((packed));
+} SMMRegisters;
+
+#endif
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/tqueue.h linux/include/linux/tqueue.h
--- v2.4.0-test8/linux/include/linux/tqueue.h Fri Sep 8 12:52:41 2000
+++ linux/include/linux/tqueue.h Mon Oct 2 11:01:18 2000
@@ -114,7 +114,7 @@
X f = p -> routine;
X save_p = p;
X p = p -> next;
- mb();
+ smp_mb();
X save_p -> sync = 0;
X if (f)
X (*f)(arg);
diff -u --recursive --new-file v2.4.0-test8/linux/include/linux/usb.h linux/include/linux/usb.h
--- v2.4.0-test8/linux/include/linux/usb.h Tue Aug 22 09:06:31 2000
+++ linux/include/linux/usb.h Mon Oct 2 11:02:34 2000
@@ -29,6 +29,7 @@
X /*
X * USB recipients
X */
+#define USB_RECIP_MASK 0x1f
X #define USB_RECIP_DEVICE 0x00
X #define USB_RECIP_INTERFACE 0x01
X #define USB_RECIP_ENDPOINT 0x02
@@ -234,36 +235,36 @@
X
X /* Endpoint descriptor */
X struct usb_endpoint_descriptor {


- __u8 bLength;
- __u8 bDescriptorType;

- __u8 bEndpointAddress;
- __u8 bmAttributes;
- __u16 wMaxPacketSize;
- __u8 bInterval;
- __u8 bRefresh;
- __u8 bSynchAddress;


+ __u8 bLength __attribute__ ((packed));
+ __u8 bDescriptorType __attribute__ ((packed));

+ __u8 bEndpointAddress __attribute__ ((packed));


+ __u8 bmAttributes __attribute__ ((packed));

+ __u16 wMaxPacketSize __attribute__ ((packed));
+ __u8 bInterval __attribute__ ((packed));
+ __u8 bRefresh __attribute__ ((packed));


SHAR_EOF
true || echo 'restore of patch-2.4.0-test9 failed'
fi

echo 'End of part 108'
echo 'File patch-2.4.0-test9 is continued in part 109'
echo "109" > _shar_seq_.tmp
exit 0

0 new messages